def filter_list_by_value(self):
self.get_user_input("Insert number to filter by: ")
value = int(self.__user_input)
print(value)
new_list = list()
try:
self.history_stack.append(str(self.expense_list))
for item in self.expense_list:
try:
new_list.append(list(filter(lambda val: val > value, item.expense)))
except TypeError as te:
print("type error" , te)
self.expense_list = new_list
except TypeError as te:
print("Type error!", te)
class Expense:
def init(self, expense: int, category: str, day: int):
self.__expense = expense
self.__category = category
self.__day = day
def __repr__(self):
return str(self)
def __str__(self):
return str(self.__dict__)
#property
def day(self):
return self.__day
#day.setter
def day(self, day):
self.__day = day
#property
def expense(self):
return self.__expense
#expense.setter
def expense(self, expense):
self.__expense = expense
#property
def category(self):
return self.__category
#category.setter
def category(self, category):
self.__category = category
I keep getting 'int' object is not iterable. What should I do? expense_list is an class-made object.
Judging by:
new_list = list()
...
new_list.append(list(...))
...
self.expense_list = new_list
self.expense_list has to be a list of lists. However, by:
for item in self.expense_list:
...
item.expense
It cannot be, since lists don't have an expense attribute. Please verify you have all your datatypes straight.
Related
I'm doing the budget project in python. If I got it right, my class Category should return a value that when casted as a string, could be printed like this:
*************Food*************
initial deposit 1000.00
groceries -10.15
restaurant and more foo -15.89
Transfer to Clothing -50.00
Total: 923.96
The problem is if I make my object return something different of None, I get this error message:
TypeError: __init__() should return None, not 'str'
English isn't my first language, so it's quite possible that I messed up trying to understand what the projects want and what the test_module.py (test_to_string) really expects. Can you clarify for me?
My code:
class Category():
def __init__(self, c):
self.category = c
self.ledger = list()
length = len(self.category)
temp = int((30-length)/2)
n = temp if length <= 30 else 0
title = '*'* n + self.category + '*'*n
amount_f = []
amount_s = []
descr = []
for dic in self.ledger:
for info in dic.values():
if type(info) is int or type(info) is float:
info = float(info)
amount_f.append(info)
temp = '{0:>7.2f}'.format(info)
amount_s.append(temp)
elif type(info) is str:
descr.append(f'{info[:23]:<23}')
recipe = ''
for i in range(len(amount_s)):
recipe = f'{recipe}\n{descr[i]} {amount_s[i]}'
botton = '\nTotal: {:.2f}'.format(sum(amount_f))
self.category = (title + recipe + botton)
return self.category
def get_balance(self):
balance = []
for dictionary in self.ledger:
for value in dictionary.values():
if type(value) is int or type(value) is float:
balance.append(value)
return sum(balance)
def check_funds(self, amount):
if amount > self.get_balance():
return False
else:
return True
def deposit(self, amount, description=''):
self.ledger.append({'amount': amount, 'description': description})
def withdraw(self, amount, description=''):
if self.check_funds(amount) == False:
return False
self.ledger.append({'amount': -(amount), 'description': description})
return True
def transfer(self, amount, department):
if self.check_funds(amount) == False:
return False
self.withdraw(amount, 'Transfer to ' + department.category)
department.deposit(amount, 'Transfer from ' + self.category)
return True
def create_spend_chart(categories):
return 'aaaaaaaaaaa'
#####################################
#####################################
# Testing - Based in the test_module.py from FCC
entertaiment = Category('entertaiment')
food = Category('food')
food.deposit(900, "deposit")
food.withdraw(45.67, "milk, cereal, eggs, bacon, bread")
food.transfer(20, entertaiment)
actual = str(food)
print(actual)
#####################################
#####################################
The __init__ method isn't supposed to return a value at all. And that's what the error is telling you: should return None. You are trying to return a value from it.
So what you could do? Modify the code, so that the __init__ does not return any value :)
Feel free to copy and paste this in your project, it work's perfectly. So your code would be:
class Category():
def __init__(self, c):
self.category = c
self.ledger = list()
length = len(self.category)
temp = int((30-length)/2)
n = temp if length <= 30 else 0
title = '*'* n + self.category + '*'*n
amount_f = []
amount_s = []
descr = []
for dic in self.ledger:
for info in dic.values():
if type(info) is int or type(info) is float:
info = float(info)
amount_f.append(info)
temp = '{0:>7.2f}'.format(info)
amount_s.append(temp)
elif type(info) is str:
descr.append(f'{info[:23]:<23}')
recipe = ''
for i in range(len(amount_s)):
recipe = f'{recipe}\n{descr[i]} {amount_s[i]}'
botton = '\nTotal: {:.2f}'.format(sum(amount_f))
self.category = (title + recipe + botton)
print(self.category)
def get_balance(self):
balance = []
for dictionary in self.ledger:
for value in dictionary.values():
if type(value) is int or type(value) is float:
balance.append(value)
return sum(balance)
def check_funds(self, amount):
if amount > self.get_balance():
return False
else:
return True
def deposit(self, amount, description=''):
self.ledger.append({'amount': amount, 'description': description})
def withdraw(self, amount, description=''):
if self.check_funds(amount) == False:
return False
self.ledger.append({'amount': -(amount), 'description': description})
return True
def transfer(self, amount, department):
if self.check_funds(amount) == False:
return False
self.withdraw(amount, 'Transfer to ' + department.category)
department.deposit(amount, 'Transfer from ' + self.category)
return True
def create_spend_chart(categories):
return 'aaaaaaaaaaa'
entertaiment = Category('entertaiment')
food = Category('food')
food.deposit(900, "deposit")
food.withdraw(45.67, "milk, cereal, eggs, bacon, bread")
food.transfer(20, entertaiment)
actual = str(food)
print(actual)
This is the most strange error that I got since I started to program with Python years ago.
First, theses are my classes (Sorry for the long code):
class Quran(Iterable):
def __init__(self):
self.sourats = []
def __iadd__(self, other):
# There is some code here
pass
def __getitem__(self, sourat_num):
if not (isinstance(sourat_num, int) or isinstance(sourat_num, slice)):
raise TypeError('Indexing Quran can be done only using ints or slices')
if isinstance(sourat_num, int):
sourat_num -= 1
else:
sourat_num = slice(sourat_num.start - 1, sourat_num.stop)
try:
return self.sourats[sourat_num]
except IndexError:
return None
def __len__(self):
return len(self.sourats)
# Other methods ...
class Sourat(Iterable):
sourats_titles = [ # 114 strs here
]
def __init__(self, number, quran):
if not isinstance(number, int):
raise TypeError('number must be int')
if not isinstance(quran, Quran):
raise TypeError('quran must be Quran')
self.num = number
self.ayats = []
self.quran = quran
def __int__(self):
return self.num
def __iadd__(self, other):
# Some code here
pass
def __getitem__(self, ayat_num):
if not (isinstance(ayat_num, int) or isinstance(ayat_num, slice)):
raise TypeError('Indexing Sourat can be done only using ints or slices')
if isinstance(ayat_num, int):
ayat_num -= 1
else:
ayat_num = slice(ayat_num.start-1, ayat_num.stop)
try:
return self.ayats[ayat_num]
except IndexError:
return None
def __len__(self):
return len(self.ayats)
def location(self):
return self.num
def previous(self):
p_num = self.num-1
if p_num < 1:
return None
return self.quran[p_num]
def next(self):
n_num = self.num+1
if n_num > len(self.quran):
return None
return self.quran[n_num]
# Other methods ...
class Word(Iterable):
def __init__(self, number, text, features, ayat):
if not isinstance(number, int):
raise TypeError('number must be int')
if not isinstance(text, str):
raise TypeError('text must be str')
if not (isinstance(features, dict) and features['type'] in ('PREFIX', 'STEM', 'SUFFIX')):
raise TypeError('features[type] must be one of PREFIX, STEM, SUFFIX')
if not isinstance(ayat, Ayat):
raise TypeError('ayat must be Ayat')
self.num = number
self.text = text
self.root = features.get('ROOT', None)
self.lem = features.get('LEM', None)
self.type = features['type']
self.next = None
self.previous = None
self.ayat = ayat
def __iadd__(self, other):
# Some code here
def __hash__(self):
# Some code here
pass
def previous(self):
p_num = self.num-1
if p_num < 1:
previous_ayat = self.ayat.previous()
if previous_ayat:
return previous_ayat[-1]
else:
return None
return self.ayat[p_num]
def next(self):
n_num = self.num+1
if n_num > len(self.ayat):
next_ayat = self.ayat.next()
if next_ayat:
return next_ayat[0]
else:
return None
return self.ayat[n_num]
# Other methods ...
And this is what I am have in the main code :
quran_last_14_sourats = parse_quranic_corpus('quranic-corpus-morphology-0.4-last-14-sourats.txt')
sourat = quran_last_14_sourats[2]
ayat = sourat[2]
word = ayat[1]
assert isinstance(ayat, Ayat)
assert isinstance(word, Word)
print(ayat.previous())
print(ayat)
print(ayat.next())
print(Word.next(word)) # This works !!!
print(word.next()) # This doesn't work !!!
My problem is in the next(self) and previous(self) in the class Word, everything else works perfectly.
When I try to use word.next() or word.previous(), it complains that NoneType is not callable. I tried to print(word.next) and it showed None, but this is not logical because these two methods are inside the class Word. This problem doesn't happen in classes Sourat and Ayat even that they have the same structure. And the most crazy thing is that Word.next(word) works without any problem !
Is this a bug in Python 3 ? (BTW I am using the latest version: 3.5.2)
Is this a bug in Python 3 ?
In a word, no.
Instance members and instance methods share the same namespace. Thus, your line in Word.__init__():
self.next = None
obliterates the reference to the method Word.next() inside the newly-allocated Word object.
Here is a class:
class CoordinateRow(object):
def __init__(self):
self.coordinate_row = []
def add(self, input):
self.coordinate_row.append(input)
def weave(self, other):
result = CoordinateRow()
length = len(self.coordinate_row)
for i in range(min(length, len(other))):
result.add(self.coordinate_row[i])
result.add(other.coordinate_row[i])
return result
This is a part of my program:
def verwerk_regel(regel):
cr = CoordinateRow()
coordinaten = regel.split()
for coordinaat in coordinaten:
verwerkt_coordinaat = verwerk_coordinaat(coordinaat)
cr.add(verwerkt_coordinaat)
cr2 = CoordinateRow()
cr12 = cr.weave(cr2)
print cr12
def verwerk_coordinaat(coordinaat):
coordinaat = coordinaat.split(",")
x = coordinaat[0]
y = coordinaat[1]
nieuw_coordinaat = Coordinate(x)
adjusted_x = nieuw_coordinaat.pas_x_aan()
return str(adjusted_x) + ',' + str(y)
But I'm geting an error at "cr12 = cr.weave(cr2)":
for i in range(min(length, len(other))):
TypeError: object of type 'CoordinateRow' has no len()
You need to add a __len__ method, then you can use len(self) and len(other):
class CoordinateRow(object):
def __init__(self):
self.coordinate_row = []
def add(self, input):
self.coordinate_row.append(input)
def __len__(self):
return len(self.coordinate_row)
def weave(self, other):
result = CoordinateRow()
for i in range(min(len(self), len(other))):
result.add(self.coordinate_row[i])
result.add(other.coordinate_row[i])
return result
In [10]: c = CoordinateRow()
In [11]: c.coordinate_row += [1,2,3,4,5]
In [12]: otherc = CoordinateRow()
In [13]: otherc.coordinate_row += [4,5,6,7]
In [14]:c.weave(otherc).coordinate_row
[1, 4, 2, 5, 3, 6, 4, 7]
Iterating over a range of len(something) is very much an anti-pattern in Python. You should be iterating over the contents of the containers themselves.
In your case, you can just zip the lists together and iterate over that:
def weave(self, other):
result = CoordinateRow()
for a, b in zip(self.coordinate_row, other.coordinate_row):
result.add(a)
result.add(b)
return result
Here is the complete solution for the Cart and Item class implementation.
class Item:
def __init__(self, name, price):
self.name = name
self.price = price
def getPrice(self):
return self.price
def getName(self):
return self.name
class ShoppingCart:
def __init__(self):
self.list = []
def __len__(self):
return len(self.list)
def add(self, item):
self.list.append(item)
def total(self):
total = 0
for item in self.list:
total = total + item.getPrice()
return total
other is of type CoordinateRow, which does not have a length. Use len(other.coordinate_row) instead. This is the list that does have the length property.
This is what i currently have and says that it is missing one argument when it tries to push i
this is the class that I have for this code
class ArrayStack:
def __init__(self):
self._data = []
def __len__(self):
return len(self._data)
def is_empty(self):
return len(self._data) == 0
def push(self, a):
self._data.append(a)
def top(self):
if self.is_empty():
raise Empty('Stack is empty')
return self._data[-1]
def pop(self):
if self.is_empty():
raise Empty('Stack is empty')
return self._data.pop()
def reverselist():
expression = input("Enter whatever: ")
stacks = ArrayStack
listofstuff = []
for item in expression:
listofstuff.append(item)
print(listofstuff)
for token in listofstuff:
i = str(token)
stacks.push(i)
You need an instance of ArrayStack, not the class itself, change for ArrayStack(), this calls the constructor of your class.
def reverselist():
expression = input("Enter whatever: ")
stacks = ArrayStack()
listofstuff = []
for item in expression:
listofstuff.append(item)
print(listofstuff)
for token in listofstuff:
i = str(token)
stacks.push(i)
class client():
def __init__(self,identitate,nume,cnp,filme_inchiriate,inchirieri):
self.__identitate=identitate
self.__nume=nume
self.__cnp=cnp
self.__filme_inchiriate=filme_inchiriate
self.__inchirieri=inchirieri
def get_identitate(self):
return self.__identitate
def get_nume(self):
return self.__nume
def get_cnp(self):
return self.__cnp
def get_filme_inchiriate(self):
return self.__filme_inchiriate
def get_inchirieri(self):
return self.__inchirieri
def set_identitate(self, value):
self.__identitate = value
def set_nume(self, value):
self.__nume = value
def set_cnp(self, value):
self.__cnp = value
def set_filme_inchiriate(self, value):
self.__filme_inchiriate = value
def set_inchirieri(self, value):
self.__inchirieri = value
def del_identitate(self):
del self.__identitate
def del_nume(self):
del self.__nume
def del_cnp(self):
del self.__cnp
def del_filme_inchiriate(self):
del self.__filme_inchiriate
def del_inchirieri(self):
del self.__inchirieri
identitate = property(get_identitate, set_identitate, del_identitate, "identitate's docstring")
nume = property(get_nume, set_nume, del_nume, "nume's docstring")
cnp = property(get_cnp, set_cnp, del_cnp, "cnp's docstring")
filme_inchiriate = property(get_filme_inchiriate, set_filme_inchiriate, del_filme_inchiriate, "filme_inchiriate's docstring")
inchirieri = property(get_inchirieri, set_inchirieri, del_inchirieri, "inchirieri's docstring")
def __str__(self):
return "ID: " + str(self.get_identitate()) + " Nume: " + str(self.get_nume()) + " CNP: "+ str(self.get_cnp())
from entities import *
class validator_client():
def validate_client(self,client):
erori=[]
if client.get_identitate=="":
erori.append("Nu ati introdus ID!")
if client.get_nume=="":
erori.append("Nu ati indorus nume!")
if len(erori)>0:
raise ValidatorException(erori)
def haha(self,client):
if client.get_identitate()=="1":
print "hahahah"
class ValidatorException(Exception):
def __init__(self,erori):
self.__erori=erori
def get_erori(self):
return self.__erori
def __str__(self):
return self.erori
erori = property(get_erori, None, None, None)
client1=client("",2,3,4,5)
validare=validator_client()
try:
validare.validate_client(client1)
except:
ValidatorException
print (ValidatorException)
client() is a class that has 5 attributes from which the first one is id, it has a getter and setter so there is no problem with the class but why is not printed any errors when I run this?
A few things: you aren't calling that getter, you are getting the method (unless it is a property, in which case, why is it called get). Also, as #Martijn Pieters says in the comments, your except clause is catching all exceptions, then printing the string representation of the ValidatorException class, not the exception instance.
As far as the except clause, I think what you may be looking for is:
except ValidatorException as ve:
print(ve)