assert menu.__str__() == "" AssertionError - python

I get assertion error when i try to assert "" (empty string) into str function. Could anyone enlighten me as of why that happens. Totally clueless here. I know the str function needs to return a string but as far as i know it is returning a string when i run:
The error comes when i run:
menu = Menu()
assert menu.str() == ""
here is my code:
class Node:
def __init__(self):
self.counter = counter
my_list = []
self.my_list = my_list
def __str__(self):
for element in self.a_list:
if element:
return "\n".join(f"{counter}. {element}" for counter,
element in enumerate(self.my_list, 1))
print()

As the declaration is def __str__(self): you need to call it like
assert menu.__str__() == ""
Or using str method
assert str(menu) == ""
Also you have a for loop, that includes another loop on the same a_list. A good implementation is
# with classic for loop syntax
def __str__(self):
result = ""
for counter, element in enumerate(self.a_list, 1):
result += f"{counter}. {element}\n"
return result
# with generator syntax
def __str__(self):
return "\n".join(f"{c}. {elem}" for c, elem in enumerate(self.a_list, 1))

Your __str__() function does not return a string if nothing is added to the object before the assertion. An assertion error would be generated even if the function was called correctly.

Related

function within f-string is returning the function outside the string, and returning None inside the string

I'm new to python and trying to do an f-string as follows:
next_patient = East_Room.get_highest_priority()
print(f"The next patient is {next_patient.display_symptoms()} please")
Where East_Room is an instance of a Class and get_highest_priority is a method within the class to display a patient with the highest integer for the 'severity' attribute as follows:
def get_highest_priority(self):
tmp_priority_patient = None
current_size = self.SLL_waiting_list.size()
counter = 1
while counter <= current_size:
tmp_node = self.SLL_waiting_list.get_node(counter)
tmp_patient = tmp_node.get_obj()
if tmp_priority_patient == None:
tmp_priority_patient = tmp_patient
else:
if tmp_patient.severity > tmp_priority_patient.severity:
tmp_priority_patient = tmp_patient
counter = counter + 1
return tmp_priority_patient
def display_symptoms(self):
print(f"{self.firstname} {self.lastname}:{self.symptoms}")
This is the output:
Conor : Naseau
The next patient is None please
I know that this method works as it works perfectly if I call it without the f-string. thanks for you help!
display_symptoms only prints information but doesn't return anything.
In Python, function that don't return anything return None, hence the output you got: "The next patient is None please"
If you also want the function to return this string, you have to explicitly return it:
def display_symptoms(self):
print(f"{self.firstname} {self.lastname}: {self.symptoms}")
return f"{self.firstname} {self.lastname}: {self.symptoms}"
An even better way to do it would be to make it a property:
#property
def display_symptoms(self):
return f"{self.firstname} {self.lastname}: {self.symptoms}"

Call a function without really calling the function?

I know my question sounds weird, but I am searching for this but I can't find it nowhere. I want to simulate a TableScan statement from SQL with printing out a list of lists, so I call the method next() with the object 'x' as long as ("EOF" of list) is not returned. But if I write
while(x.next() != "EOF"): the function next() is already called once and this not what I want, because I skip already one tuple.
Here the code:
class TableScan(Iterator):
def __init__(self, collection):
super().__init__()
self.collection = collection
self.iter = None
def open(self):
self.iter = iter(self.collection)
def next(self):
try:
while(self.iter != None):
return next(self.iter)
except StopIteration:
return "EOF"
# The list.
cS = [[101,2,3,5,1],
[202,4,99,2,4],
[303,2,4,6,8],
[404,1,23,4,6],
[505,2,22,4,5]]
# Making object x and calling constructor of class TableScan.
x = TableScan(cS)
while(x.next() != "EOF"): ###Problem- lines###
print(x.next())
Can somebody please help me?
Assign the result to a variable so you can test it and print it.
while True:
n = x.next()
if n == 'EOF':
break
print(n)
i know this has an answer, but in python 3.8 and above you can do:
while (n := x.next()) != 'EOF':
print(n)

Tkinter: How to put user input into a list to access later?

When I try to access the list produced by the function stringToList, it always says TypeError: 'NoneType' object is not subscriptable.
class MyApp(Tk):
def __init__(self):
super().__init__()
# Many widgets defined and placed here
def my_fx(self):
def stringToList(input_str):
number_list = []
full_list = []
if list(input_str)[-1].isnumeric:
input_str += ","
for item in list(input_str):
if item.isnumeric():
number_list.append(item)
if not item.isnumeric():
num_str = ""
for item in number_list:
num_str += item
if int(num_str) not in full_list:
try:
full_list.append(int(num_str))
except ValueError:
pass
number_list = []
sorted_list = sorted(full_list).append(some_string)
return sorted_list
if True:
sorted_list = stringToList(some_entry_widget.get())
def do_stuff():
from my_other_file import my_other_fx
this_and_that = my_other_fx(sorted_list)
# More functions defined here
if __name__ == '__main__':
app = IntegratorApp()
app.mainloop()
This line in my_other_fx (which is properly named in my original code) is where I get the NoneType is not subscriptable error:
if sorted_list[-1] == some_value:
I've tried reworking stringToList so it uses IntVar and StringVar instead of regular int and str, but that didn't change anything. Why is it NoneType?
Also if anyone has other critique, it's more than welcome! I'm trying to learn!
EDIT: It seems to go "nope" and turn into NoneType when I try to append a string to the list. But why??
Try this:
full_list.append(some_string)
sorted_list = sorted(full_list)

__repr__ returned non-string type error

Below is a dummy example of my class method:
class A:
def __init__(self, name):
self.name = name
def __repr__(self):
for i in range(0,5):
if i == 0:
print(self.name)
else:
print("-")
i += 1
m1 = A("x")
m1
It prints out the result for me. However, in the meantime, it gives an error saying that __repr__ returned non-string. I understand that I need to use return instead of print for __repr__, however return would stop my program when the first condition is met. I also tried yield but had no luck.
I know this dummy program looks ridiculous and I could have used some other methods instead of __repr__ to print out the results. But this is just a simplified version of my actual program and I have to use __repr__ or __str__ for some reasons.
You have two basic problems. The first is that you altered the loop index within the loop -- bad form, but not at all fatal. The second is that you fail to return a value.
IMMEDIATE REPAIR
def __repr__(self):
for i in range(0,5):
if i == 0:
val = self.name
else:
val += "-"
return val
However, even this is ineffective.
EVEN BETTER
It appears that you want the name with four dashes appended. Why not just do that?
def __repr__(self):
return self.name + "----"
I am assuming that you want your __repr__ output exactly as you are printing it. For that you will just need to change the logic a bit. Something like this should work:
def __repr__(self):
string = ""
for i in range(0,5):
if i == 0:
string += self.name
else:
string += "-"
i += 1
return string

Which operator do I need to overwrite to check if a self-defined object exist in the list?

For example, I have a self defined class, like this:
class Alarm(object):
def __init__(self, alarmId, msg):
self.alarmId = alarmId
self.msg = msg
def __eq__(self, other):
return self.alarmId == other.alarmId
aList = list()
a = Alarm(1, "hello")
b = Alarm(1, "good")
aList.append(a)
aList.append(b)
Alarms with same Id are considered same, so "a" and "b" is actually same. I want to check if same Alarm already exist in the list, if it already existed , then no need to add it to the list.
if a in aList: # I wish when this "in" called, I could call one member function of a to match the whole list
pass
But which function do I need to overwrite to do this? I tried __eq__, but it could not accomplish what I want.
I think is what you are after (assuming you compering using self.alarmId):
class Alarm(object):
def __init__(self, alarmId, msg):
self.alarmId = alarmId
self.msg = msg
def __eq__(self, other):
return (isinstance(other, self.__class__)
and self.alarmId == other.alarmId)
aList = list()
a = Alarm(1, "hello")
b = Alarm(2, "good")
aList.append(a)
aList.append(b)
if a in aList:
print("a found")
c = Alarm(3, "good")
if c not in aList:
print("c not found")
Result is:
a found
c not found
Deducing from your question, I think you are looking for a conditionall append() function for your list. This would then be something like the following:
def listadd(list, toadd):
for alarm in list:
if alarm == toadd:
return false
list.append(toadd)
return true
You could use this function to add alarms to your list and it checks right away if the alarm is in the list. This is obviously not an overloaded function or operator but it should work.
Hope it helps.
EDIT:
You can call the function with the list you want to add to and the item you want to add. It returns a boolean flag if the item was added or not.

Categories

Resources