I am trying to make a time table scheduling program but found some errors. Please watch the following code and solve that error please.
Errors
These are the following errors
Traceback (most recent call last):
File "C:/Users/Muhammad Abbas/Downloads/ga02ClassScheduling.py", line 367, in <module>
population.get_schedules().sort(key=lambda x: x.get_fitness(), reverse=True)
File "C:/Users/Muhammad Abbas/Downloads/ga02ClassScheduling.py", line 367, in <lambda>
population.get_schedules().sort(key=lambda x: x.get_fitness(), reverse=True)
File "C:/Users/Muhammad Abbas/Downloads/ga02ClassScheduling.py", line 84, in get_fitness
self._fitness = self.calculate_fitness()
File "C:/Users/Muhammad Abbas/Downloads/ga02ClassScheduling.py", line 106, in calculate_fitness
if classes[i].get_room().get_seatingCapacity() < classes[i].get_course().get_maxNumbOfStudnets():
AttributeError: 'NoneType' object has no attribute 'get_seatingCapacity'
Source Code of the Program
Variables:
These are the variables which i declare for this program
import prettytable as prettytable
import random as rnd
POPULATION_SIZE = 9
NUMB_OF_ELITE_SCHEDULES = 1
TOURNAMENT_SELECTION_SIZE = 3
MUTATION_RATE = 0.1
Data Class
That is the first class which name is DATA
class Data:
ROOMS = [["R1", 25], ["R2", 45], ["R3", 35]]
MEETING_TIMES = [
["MT1", "MWF 09:00 - 10:00"],
["MT2", "MWF 10:00 - 11:00"],
["MT3", "TTH 09:00 - 10:30"],
["MT4", "TTH 10:30 - 12:00"]
]
INSTRUCTORS = [
["T1", "Dr James Web"],
["T2", "Mr Mike Brown"],
["T3", "Dr Steve Day"],
["T4", "Mrs Jane Doe"]
]
def __init__(self):
self._rooms = []
self._meetingTimes = []
self._instructors = []
for i in range(0, len(self.ROOMS)):
self._rooms.append(Room(self.ROOMS[i][0], self.ROOMS[i][1]))
for i in range(0, len(self.MEETING_TIMES)):
self._meetingTimes.append(MeetingTime(self.MEETING_TIMES[i][0], self.MEETING_TIMES[i][1]))
for i in range(0, len(self.INSTRUCTORS)):
self._instructors.append(Instructor(self.INSTRUCTORS[i][0], self.INSTRUCTORS[i][1]))
course1 = Course("C1", "325k", [self._instructors[0], self._instructors[1]], 25)
course2 = Course("C2", "319k", [self._instructors[0], self._instructors[1], self._instructors[2]], 35)
course3 = Course("C3", "462k", [self._instructors[0], self._instructors[1]], 25)
course4 = Course("C4", "464k", [self._instructors[2], self._instructors[3]], 30)
course5 = Course("C5", "360C", [self._instructors[3]], 35)
course6 = Course("C6", "303k", [self._instructors[0], self._instructors[2]], 45)
course7 = Course("C7", "303L", [self._instructors[1], self._instructors[3]], 45)
self._courses = [course1, course2, course3, course4, course5, course6, course7]
dept1 = Department("MATH", [course1, course3])
dept2 = Department("EE", [course2, course4, course5])
dept3 = Department("PHY", [course6, course7])
self._depts = [dept1, dept2, dept3]
self._numberOfClasses = 0
for i in range(0, len(self._depts)):
self._numberOfClasses += len(self._depts[i].get_courses())
def get_rooms(self):
return self._rooms
def get_instructors(self):
return self._instructors
def get_courses(self):
return self._courses
def get_depts(self):
return self._depts
def get_meetingTimes(self):
return self._meetingTimes
def get_numberOfClasses(self):
return self._numberOfClasses
Schedule Class
That is the second class which name is Schedule
class Schedule:
def __init__(self):
self._data = data
self._classes = []
self._numberOfConflicts = 0
self._fitness = -1
self._classNumb = 0
self._isFitnessChanged = True
def get_classes(self):
self._isFitnessChanged = True
return self._classes
def get_numberOfConflicts(self):
return self._numberOfConflicts
def get_fitness(self):
if(self._isFitnessChanged == True):
self._fitness = self.calculate_fitness()
self._isFitnessChanged = False
return self._fitness
def initialize(self):
depts = self._data.get_depts()
for i in range(0, len(depts)):
courses = depts[i].get_courses() #courses in each departments
for j in range(0, len(courses)):
newClass = Class(self._classNumb, depts[i], courses[j])
self._classNumb += 1
newClass.set_meetingTime(data.get_meetingTimes()[rnd.randrange(0, len(data.get_meetingTimes()))])
newClass.set_room(data.get_rooms()[rnd.randrange(0, len(data.get_rooms()))])
newClass.set_instructor(courses[j].get_instructors()[rnd.randrange(0, len(courses[j].get_instructors()))])
self._classes.append(newClass)
return self
def calculate_fitness(self):
self._numberOfConflicts = 0
classes = self.get_classes()
for i in range(0, len(classes)):
if classes[i].get_room().get_seatingCapacity() < classes[i].get_course().get_maxNumbOfStudnets():
self._numberOfConflicts += 1
for j in range(0, len(classes)):
if(j >= i):
if(classes[i].get_meetingTime() == classes[j].get_meetingTime() and
classes[i].get_id() != classes[j].get_id()):
if(classes[i].get_room() == classes[j].get_room()):
self._numberOfConflicts += 1
if(classes[i].get_instructor() == classes[j].get_instructor()):
self._numberOfConflicts += 1
return 1 / ((1.0*self._numberOfConflicts + 1))
def __str__(self):
# it returns all the classes of schedule separated by comas
returnValue = ""
for i in range(0, len(self._classes)):
returnValue += str(self._classes[i]) + ", "
returnValue += str(self._classes[len(self._classes)-1])
return returnValue
Population Class
Thats the third class which is Population class
class Population:
def __init__(self, size):
self._size = size
self._data = data
self._schedules = []
for i in range(0, size):
self._schedules.append(Schedule().initialize())
def get_schedules(self):
return self._schedules
GeneticAlgorithm Class
Thats the fourth class which is the GeneticAlgorithm class
class GeneticAlgorithm:
def evolve(self, population):
return self._mutate_population(self._crossover_population(population))
def _crossover_population(self, pop):
crossover_pop = Population(0)
for i in range(NUMB_OF_ELITE_SCHEDULES):
crossover_pop.get_schedules().append(pop.get_schedules()[i])
i = NUMB_OF_ELITE_SCHEDULES
while i < POPULATION_SIZE:
schedule1 = self._select_tournament_population(pop).get_schedules()[0]
schedule2 = self._select_tournament_population(pop).get_schedules()[0]
crossover_pop.get_schedules().append(self._crossover_schedule(schedule1, schedule2))
i += 1
return crossover_pop
def _mutate_population(self, population):
for i in range(NUMB_OF_ELITE_SCHEDULES, POPULATION_SIZE):
self._mutate_schedule(population.get_schedules()[i])
return population
def _crossover_schedule(self, schedule1, schedule2):
crossoverSchedule = Schedule().initialize()
for i in range(0, len(crossoverSchedule.get_classes())):
if (rnd.random() > 0.5):
crossoverSchedule.get_classes()[i] = schedule1.get_classes()[i]
else:
crossoverSchedule.get_classes()[i] = schedule2.get_classes()[i]
return crossoverSchedule
def _mutate_schedule(self,mutateSchedule):
schedule = Schedule().initialize()
for i in range(0, len(mutateSchedule.get_classes())):
if(MUTATION_RATE > rnd.random()):
mutateSchedule.get_classes()[i] = schedule.get_classes()[i]
return mutateSchedule
def _select_tournament_population(self, pop):
tournament_pop = Population(0)
i = 0
while i < TOURNAMENT_SELECTION_SIZE:
tournament_pop.get_schedules().append(pop.get_schedules()[rnd.randrange(0, POPULATION_SIZE)])
i += 1
tournament_pop.get_schedules().sort(key=lambda x:x.get_fitness(), reverse=True)
return tournament_pop
Course Class
Thats the fifth class which is the Course class
class Course:
def __init__(self, number, name, instructors, maxNumbOfStudents):
self._number = number
self._name = name
self._instructors = instructors
self._maxNumbOfStudents = maxNumbOfStudents
def get_name(self):
return self._name
def get_number(self):
return self._number
def get_instructors(self):
return self._instructors
def get_maxNumbOfStudents(self):
return self._maxNumbOfStudents
def __str__(self):
return self._name
Instructor Class
Thats the sixth class which is Instructor class
class Instructor:
def __init__(self, id, name):
self._id = id
self._name = name
def get_id(self):
return self._id
def get_name(self):
return self._name
def __str__(self):
return self._name
Room Class
Thats the seventh class which is the Room Class
class Room:
def __init__(self, number, seatingCapacity):
self._number = number
self._seatingCapacity = seatingCapacity
def get_number(self):
return self._number
def get_seatingCapacity(self):
return self._seatingCapacity
MeetingTime Class
Thats the eighth class which is MeetingTime class
class MeetingTime:
def __init__(self, id, time):
self._time = time
self._id = id
def get_id(self):
return self._id
def get_time(self):
return self._time
Department Class
Thats the ninth class which is the Department class
class Department:
# Batch for my case
def __init__(self, name, courses):
self._name = name
self._courses = courses # Courses that department offers
def get_name(self): return self._name
def get_courses(self): return self._courses
Class class
Thats is the tenth class which name is Class
class Class:
# Course to be scheduled at specific room of department host by an instructor at specific Meeting Time
def __init__(self, id, dept, course):
self._id = id
self._dept = dept
self._course = course
self._instructor = None
self._meetingTime = None
self._room = None
def get_id(self):
return self._id
def get_dept(self):
return self._dept
def get_room(self):
return self._room
def get_course(self):
return self._course
def get_instructor(self):
return self._instructor
def get_meetingTime(self):
return self._meetingTime
def set_instructor(self, instructor):
self._instructor = instructor
def set_meetingTime(self, meetingTime):
self._meetingTime = meetingTime
def set_room(self, room):
self_room = room
def __str__(self):
return str(self._dept.get_name()) + "," + str(self._course.get_number()) + "," + \
str(self._room.get_number()) + "," + str(self._instructor.get_id()) + "," + str(self._meetingTime.get_id())
DisplayMgr Class Plus End Code
Thats the eleventh class which is DisplayMgr Class and the end code of that program.
class DisplayMgr:
def print_available_data(self):
print("> All Available Data")
self.print_dept()
self.print_course()
self.print_room()
self.print_instructor()
self.print_meeting_times()
def print_dept(self):
depts = data.get_depts()
availableDeptsTable = prettytable.PrettyTable(['dept', 'courses'])
for i in range(0, len(depts)):
courses = depts.__getitem__(i).get_courses()
tempStr = "["
for j in range(0, len(courses) - 1):
tempStr += courses[j].__str__() + ", "
tempStr += courses[len(courses) - 1].__str__() + "]"
availableDeptsTable.add_row([depts.__getitem__(i).get_name(), tempStr])
print(availableDeptsTable)
def print_course(self):
availabelCoursesTable = prettytable.PrettyTable(['id', 'course # ', 'max # of students', 'instructors'])
courses = data.get_courses()
for i in range(0, len(courses)):
instructors = courses[i].get_instructors()
tempStr = ""
for j in range(0, len(instructors)-1):
tempStr += instructors[j].__str__() + ", "
tempStr += instructors[len(instructors) - 1].__str__()
availabelCoursesTable.add_row(
[courses[i].get_number(), courses[i].get_name(), str(courses[i].get_maxNumbOfStudents()), tempStr]
)
print(availabelCoursesTable)
def print_instructor(self):
availableInstructorsTable = prettytable.PrettyTable(['id', 'instructor'])
instructors = data.get_instructors()
for i in range(0, len(instructors)):
availableInstructorsTable.add_row([instructors[i].get_id(), instructors[i].get_name()])
print(availableInstructorsTable)
def print_room(self):
availableRoomsTable = prettytable.PrettyTable(['room #', 'max seating capacity'])
rooms = data.get_rooms()
for i in range(0, len(rooms)):
availableRoomsTable.add_row([str(rooms[i].get_number()), str(rooms[i].get_seatingCapacity())])
print(availableRoomsTable)
def print_meeting_times(self):
availableMeetingTimeTable = prettytable.PrettyTable(['id', 'Meeting Time'])
meetingTimes = data.get_meetingTimes()
for i in range(0, len(meetingTimes)):
availableMeetingTimeTable.add_row([meetingTimes[i].get_id(), meetingTimes[i].get_time()])
print(availableMeetingTimeTable)
def print_generation(self, population):
table1 = prettytable.PrettyTable(['schedule # ', 'fitness', '# of Conflicts','classes [dept, class, room, instructor'])
schedules = population.get_schedules()
for i in range(0, len(schedules)):
table1.add_row([str(i), round(schedules[i].get_fitness(),3), schedules[i].get_numberOfConflicts(), schedules[i]])
print(table1)
def print_schedule_as_table(self, schedule):
classes = schedule.get_classes()
table = prettytable.PrettyTable(['Class # ', 'Dept', 'Course (number, max # of students)', 'Room (Capacity', 'Instructor'])
for i in range(0, len(classes)):
table.add_row([str(i), classes[i].get_dept().get_name(), classes[i].get_course().get_name() + " (" +
classes[i].get_course().get_number() + ", " +
str(classes[i].get_course().get_maxNumbOfStudents()) + ")",
classes[i].get_room().get_number() + " (" + str(classes[i].get_room().get_seatingCapacity()) +
classes[i].get_instructor().get_name() + " (" + str(classes[i].get_instructor().get_id()) +")",
classes[i].get_meatingTime().get_time() + " (" + str(classes[i].get_meatingTime().get_id()) +")"
])
print(table)
data = Data()
displayMgr = DisplayMgr()
displayMgr.print_available_data()
generationNumber = 0
print("\n> Generation # " + str(generationNumber))
population = Population(POPULATION_SIZE)
population.get_schedules().sort(key=lambda x: x.get_fitness(), reverse=True)
displayMgr.print_generation(population)
displayMgr.print_schedule_as_table(population.get_schedules()[0]) # it will print fittest generation of schedule
geneticAlgorithm = GeneticAlgorithm()
while (population.get_schedules()[0].get_fitness() != 1.0):
generationNumber += 1
print("\n> Generation # " + str(generationNumber))
population = geneticAlgorithm.evolve(population)
population.get_schedules().sort(key=lambda x: x.get_fitness(), reverse=True)
displayMgr.print_generation(population)
displayMgr.print_schedule_as_table(population.get_schedules()[0])
print("\n\n")
def set_room(self, room):
self_room = room
you have missing . in set_room(self,room) function . Change it to self._room=room so that it will set the room value and objectType=None will be solved
Look into your the class DisplayMgr/def print_schedule_as_table
Change classes[i].get_meatingTime().get_time() to meetingTime
I have the following class in python. I want to pass the function get_priority as argument to access the object Task. I obtain the following error when adding the second task to taskManager:
if value == array[int(middle)].acessMethod(): AttributeError: Task
instance has no attribute 'acessMethod'
Task Class
class Task:
def __init__(self,id,name,category="",priority=1):
self.id = id
self.name = name
self.category = category
self.priority = priority
self.concluded = False
self.active_days = 0
print("Beggining Class")
def get_name(self):
return self.name
def get_category(self):
return self.category
def get_priority(self):
return self.priority
def set_name(self,name):
self.name = name
def set_category(self,category):
self.category = category
def set_priority(self,priority):
self.priority = priority
def __str__(self):
return str(self.id) + " | " + self.name + " | " + self.category + " | " + str(self.priority) + " | "
TaskManager Class
from task import Task
class TaskManager(object):
"""docstring forTaskManager."""
def __init__(self):
print("Initing TaskManager")
self.taskArray = []
"""Adding task ordered by priority"""
"""Maibe adding a check for autheticity of the object """
def addTask(self,task):
if len(self.taskArray) == 0 or self.taskArray[0].get_priority() <= task.get_priority():
self.taskArray.insert(0,task)
else:
index = self.__binarySearchIndex(task.get_priority,self.taskArray,'get_priority')
self.taskArray.insert(index,task)
def __binarySearchIndex(self,value,array,acessMethod):
middle = (len(self.taskArray) / 2) if ((len(self.taskArray) % 2) == 0) else (len(self.taskArray) / 2) + 1
if middle == 1:
middle = 0
if value == array[middle].acessMethod():
return middle
elif value < array[middle].acessMethod():
self.__binarySearchIndex(value,array[:middle])
else:
self.__binarySearchIndex(value,array[middle:])
def __str__(self):
taskString = ""
for task in self.taskArray:
taskString = taskString + str(task) + " \n"
return taskString
I've actually went another way instead of calling the method by its name, I simply make a lambda function to extract whatever attribute I want from the Task object.
class Task:
def __init__(self,id,name,category="",priority=1):
self.id = id
self.name = name
self.category = category
self.priority = priority
self.concluded = False
self.active_days = 0
print("Beggining Class")
def get_name(self):
return self.name
def get_category(self):
return self.category
def get_priority(self):
return self.priority
def set_name(self,name):
self.name = name
def set_category(self,category):
self.category = category
def set_priority(self,priority):
self.priority = priority
def __str__(self):
return str(self.id) + " | " + self.name + " | " + self.category + " | " + str(self.priority) + " | "
class TaskManager(object):
"""docstring forTaskManager."""
def __init__(self):
print("Initing TaskManager")
self.taskArray = []
"""Adding task ordered by priority"""
"""Maibe adding a check for autheticity of the object """
def addTask(self,task):
if len(self.taskArray) == 0 or self.taskArray[0].get_priority() <= task.get_priority():
self.taskArray.insert(0,task)
else:
index = self.__binarySearchIndex(task.get_priority(),self.taskArray, lambda task: task.get_priority())
self.taskArray.insert(index,task)
def __binarySearchIndex(self,value,array,accessMethod):
if len(array) == 0:
return 0
middle = (len(self.taskArray) / 2) if ((len(self.taskArray) % 2) == 0) else (len(self.taskArray) // 2) + 1
if middle == 1:
middle = 0
if value == accessMethod(array[middle]):
return middle
elif value < accessMethod(array[middle]):
return middle + self.__binarySearchIndex(value,array[:middle],accessMethod)
else:
return middle - self.__binarySearchIndex(value,array[middle:],accessMethod)
def __str__(self):
taskString = ""
for task in self.taskArray:
taskString = taskString + str(task) + " \n"
return taskString
if __name__ == "__main__":
taskA = Task(1, "taskA", priority=2)
taskB = Task(2, "taskB", priority=1)
taskC = Task(3, "taskC", priority=1)
taskD = Task(4, "taskD", priority=3)
manager = TaskManager()
manager.addTask(taskA)
manager.addTask(taskB)
manager.addTask(taskC)
manager.addTask(taskD)
for task in manager.taskArray:
print(task)
I've also helped debug your program a little. For starters, your recursive calls to the binary search doesn't return values, which is a behavior that you want.
Use getattr to get the function from the string you pass
method_to_call = getattr(Task, accessMethod)
if value == array[middle].method_to_call():
Don't pass a string containing the name at all. Use the methodcaller function.
For example:
from operator import methodcaller
class TaskManager(object):
def __init__(self):
self.taskArray = []
def addTask(self, task):
if (len(self.taskArray) == 0
or self.taskArray[0].get_priority() <= task.get_priority():
self.taskArray.insert(0,task)
else:
index = self.__binarySearchIndex(
task.get_priority(),
self.taskArray,
methodcaller('get_priority')
)
self.taskArray.insert(index, task)
def __binarySearchIndex(self, value, array, accessMethod):
middle = (len(self.taskArray) / 2) if ((len(self.taskArray) % 2) == 0) else (len(self.taskArray) / 2) + 1
if middle == 1:
middle = 0
if value == accessMethod(array[middle]):
return middle
elif value < accessMethod(array[middle]):
self.__binarySearchIndex(value,array[:middle])
else:
self.__binarySearchIndex(value,array[middle:])
...
If you simplify your Task class to get rid of the unnecessary getters and setters:
class Task:
def __init__(self,id,name,category="",priority=1):
self.id = id
self.name = name
self.category = category
self.priority = priority
self.concluded = False
self.active_days = 0
print("Beggining Class")
def __str__(self):
return str(self.id) + " | " + self.name + " | " + self.category + " | " + str(self.priority) + " | "
then you can use attrgetter instead of methodcaller.
from operator import attrgetter
class TaskManager(object):
def __init__(self):
self.taskArray = []
def addTask(self, task):
if (len(self.taskArray) == 0
or self.taskArray[0].get_priority() <= task.get_priority:
self.taskArray.insert(0,task)
else:
index = self.__binarySearchIndex(
task.get_priority,
self.taskArray,
attrgetter('get_priority')
)
self.taskArray.insert(index, task)
def __binarySearchIndex(self, value, array, accessMethod):
middle = (len(self.taskArray) / 2) if ((len(self.taskArray) % 2) == 0) else (len(self.taskArray) / 2) + 1
if middle == 1:
middle = 0
if value == accessMethod(array[middle]):
return middle
elif value < accessMethod(array[middle]):
self.__binarySearchIndex(value,array[:middle])
else:
self.__binarySearchIndex(value,array[middle:])
...
class Unit:
def init(self, _chassisId, _unitNo, _interface):
self.chassisId = _chassisId
self.unitNo = _unitNo
self.interface = _interface
def getInterface(self):
return self.interface
#staticmethod
def parse(elem):
unitList = elem.find(UNIT+LIST)
chassisList = []
for unit in unitList.findall(UNIT):
try:
unitNumber = unit.find(UNIT_NUMBER).text
interface = unit.find(INTERFACE)
interface = ""
chassisIdElem = unit.find(CHASSIS_ID)
chassisId = ""
if chassisIdElem is not None:
chassisId = unit.find(CHASSIS_ID).text
elif unit.find(BURNED_IN_MAC) is not None:
chassisId = unit.find(BURNED_IN_MAC).text
chassisId = chassisId.replace(".", "").replace(":", "").upper()
chassis = Unit(chassisId, interface, unitNumber)
chassisList.append(chassis)
except Exception as e:
print "Unit details not found", e
return chassisList
def getChassisId(self):
return self.chassisId
def __str__(self):
str = "\n"
str += "\nUnit Details:- "
len = str.__len__();
str += "\n"
for i in range(1,len-1):
str += "-"
str += "\nUnit: " + self.unitNo
str += "\nChassis Id: " + self.chassisId
str += "\nInterfaces: " + self.interfaces
return str
def __add__(self, other):
return str(self) + other
def __radd__(self, other):
return other + str(self)
class Interface:
def init(self, _linkState, _interfaceName):
self.linkState = _linkState
self.interfaceName = _interfaceName
#staticmethod
def parse(elem):
prefix = Device.getPrefix(elem.tag)
interfaceList = elem.find(INTERFACE + LIST)
interfaceNameTag = eval(prefix + "_INTERFACE_NAME")
linkStateTag = eval(prefix + "_LINK_STATE")
interfaces = []
for interface in interfaceList.findall(INTERFACE):
try:
interfaceName = interface.find(interfaceNameTag).text
linkStateElem = interface.find(LINK_STATE)
linkState = ""
if linkStateElem is not None:
linkState = interface.find(LINK_STATE).text
elif interface.find(LINE_PROTOCOL) is not None:
linkState = interface.find(LINE_PROTOCOL).text
interface = Interface(linkState, Name)
interfaces.append(interface)
except Exception as e:
print "Interface details not found", e
return interfaces
def getLinkState(self):
return self.linkState
def getInterfaceName(self):
return self.interfaceName
def __str__(self):
str = "\n"
str += "\nInterface Details:- "
len = str.__len__();
str += "\n"
for i in range(1,len-1):
str += "-"
str += "\nLink State: " + self.linkState
str += "\nInterface Name: " + self.interfaceName
return str
def __add__(self, other):
return str(self) + other
def __radd__(self, other):
return other + str(self)
You haven't shown us the call to getInterfaceName() that causes the error, which makes it harder to help you.
However, I'll guess that the call looks something like this:
something = Interface.getInterfaceName()
You can't do it that way. You must create an instance of Interface, and then call its .getInterfaceName() method:
myInterface = Interface()
something = myInterface.getInterfaceName()
I would like to print something inside the method. But the following code does not anything. But if I return the values I am able to print it outside the class. Why is it so? Any guidance would be great !
My code:
import pytest
class Test:
def __init__(self, val_1, val_2):
self.val_1 = val_1
self.val_2 = val_2
self.sum = 0
self.mul = 0
def sum_mul(self):
self.sum = self.val_1 + self.val_2
self.mul = self.val_1 * self.val_2
def ret_val(self):
return self.sum, self.mul
def test_exception(self,exception):
raise exception
return str(exception)
class Assert_Values:
def __init__(self, number, val_1, val_2, exception):
self.number = number
self.val_1 = val_1
self.val_2 = val_2
self.exception = exception
self.test_obj = Test(self.val_1, self.val_2)
def execute_test(self):
if self.number == 1:
self.test_obj.sum_mul()
self.val = self.test_obj.ret_val()
assert self.val == (self.val_1 + self.val_2, self.val_1 * self.val_2)
print (self.val)
elif self.number == 2:
with pytest.raises(self.exception):
self.exception_val = self.test_obj.test_exception(self.exception)
print (self.exception_val)
else:
print ("! Number not valid %d please enter another number" % (self.number))
assert_values = Assert_Values(2,4,5,ValueError)
assert_values.execute_test()
Pytest captures stdout; print() writes to stdout and you'll only see the output if there is a test failure.
Use the -s flag if you want to see stdout output instead:
py.test -s
I'm trying to print a tree recursively in Python. For some reason, the indentation isn't working (perhaps I'm too tired at this point to see an obvious flaw). Here's the structure / class definitions that I'm working with:
class Tree(object):
def __init__(self, data):
self.data = data
self.branches = []
class Branch(object):
def __init__(self, value):
self.label = value
self.node = None
As you see, each tree has Branches, which have a label and point to another Tree (that's the node value you see there). Here's how I'm trying to print out the tree:
def __str__(self):
return self.tree_string(0)
def tree_string(self, indent):
indentation = indent * " "
result = indentation + str(self.data) + "\n";
for branch in self.branches:
result += indentation + branch.label + ": \n" + branch.node.tree_string(indent + 2)
return result
This is giving me:
4
Somewhat:
Yes
Fuller:
3
Correct:
8
Caribbean:
2
Wrong:
Wrong
Correct:
Correct
Italian:
Wrong
Burger:
Correct
Wrong:
Wrong
Nothing:
Wrong
When it should be giving me something like
4
Somewhat:
Correct
Fuller:
3
Correct:
8
Caribbean:
2
Wrong:
Wrong
Correct:
Correct
Italian:
Wrong
Burger:
Correct
Wrong:
Wrong
Nothing:
Wrong
What's causing my code to have those extra newlines and not have the proper indents?
Update
Pretty sure the data is ok. Here's a modified version that shows it's ok:
def tree_string(self, indent):
indentation = indent * " "
result = str(self.data);
if len(self.branches) > 0:
result += "["
for branch in self.branches:
result += branch.label + ":" + branch.node.tree_string(indent + 2) + " "
result += "]"
return result
..which gives the output
4[Somewhat:Correct Fuller:3[Correct:8[Caribbean:2[No:No Correct:Correct ] Italian:Wrong Burger:Correct ] Wrong:Wrong ] Nothing:Wrong ]
However, the indent values are for some reason always 0 or 2.
Looks like it should work to me:
class Tree(object):
def __init__(self, data):
self.data = data
self.branches = []
def __str__(self):
return self.tree_string(0)
def tree_string(self, indent):
indentation = indent * " "
result = indentation + str(self.data) + "\n";
for branch in self.branches:
result += indentation + branch.label + ": \n" + branch.node.tree_string(indent + 2)
return result
class Branch(object):
def __init__(self, value):
self.label = value
self.node = None
tree = Tree(4)
b1 = Branch('Somewhat')
b1.node = Tree('Yes')
b2 = Branch('Fuller')
b2.node = Tree(3)
tree.branches = [b1, b2]
b3 = Branch('Correct')
b3.node = Tree(8)
b2.node.branches = [b3]
print(tree)
yields
4
Somewhat:
Yes
Fuller:
3
Correct:
8