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
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)
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:])
...
Following Code From the book deep learning and the game of go
Not Sure Why I am getting this error
full error:
Traceback (most recent call last): File "bot_v_bot.py", line 25, in
main() File "bot_v_bot.py", line 20, in main
bot_move = bots[game.next_player].select_move(game) File "C:\Users\Max\Desktop\books\pdf\code\Go ML\dlgo\agent\naive.py", line
14, in select_move
if game_state.is_valid_move(Move.play(canidate)) and not is_point_an_eye(game_state.board, canidate, game_state.next_player):
File "C:\Users\Max\Desktop\books\pdf\code\Go
ML\dlgo\agent\helpers.py", line 20, in is_point_an_eye
if board.is_on_grid(corners): File "C:\Users\Max\Desktop\books\pdf\code\Go ML\dlgo\goboard_slow.py", line
71, in is_on_grid
return 1 <= point.row <= self.num_rows and 1 <= point.col <=
self.num_cols AttributeError: 'list' object has no attribute 'row'
My Directory looks like
GO ML
-bot_v_bot.py
-dlgo
---__pychache__
---agent
----__init__.py
----base.py
----helpers.py
----naive.py
---__init__.py
---goboard_slow.py
---gotypes.py
---utils.py
Bot_V_Bot code
from dlgo.agent import naive
from dlgo import goboard_slow
from dlgo import gotypes
from dlgo.utils import print_board, print_move
import time
def main():
board_size = 9
game = goboard_slow.GameState.new_game(board_size)
bots = {
gotypes.Player.black: naive.RandomBot(),
gotypes.Player.white: naive.RandomBot(),
}
while not game.is_over():
time.sleep(0.3)
print(chr(27) + "[2j")
print_board(game.board)
bot_move = bots[game.next_player].select_move(game)
print_move(game.next_player, bot_move)
game = game.apply_move(bot_move)
if __name__ == '__main__':
main()
goboard_slow code
import copy
from dlgo.gotypes import Player
from dlgo.gotypes import Point
class GoString():
def __init__(self, color, stones, liberties):
self.color = color
self.stones = set(stones)
self.liberties = set(liberties)
def remove_liberty(self, point):
self.liberties.remove(point)
def add_liberty(self, point):
self.liberties.add(point)
def merged_with(self, go_string):
assert go_string.color == self.color
combined_stones = self.stones | go_string.stones
return GoString(
self.color,
combined_stones,
(self.liberties | go_string.liberties) - combined_stones)
#property
def num_liberties(self):
return len(self.liberties)
def __eq__(self, other):
return isinstance(other, GoString) and \
self.color == other.color and \
self.stones == other.stones and \
self.liberties == other.liberties
class Board():
def __init__(self, num_rows, num_cols):
self.num_rows = num_rows
self.num_cols = num_cols
self._grid = {}
def place_stone(self, player, point):
assert self.is_on_grid(point)
assert self._grid.get(point) is None
adjacent_same_color = []
adjacent_opposite_color = []
liberties = []
for neighbor in point.neighbors():
if not self.is_on_grid(neighbor):
continue
neighbor_string = self._grid.get(neighbor)
if neighbor_string is None:
liberties.append(neighbor)
elif neighbor_string.color == player:
if neighbor_string not in adjacent_same_color:
adjacent_same_color.append(neighbor_string)
else:
if neighbor_string not in adjacent_opposite_color:
adjacent_opposite_color.append(neighbor_string)
new_string = GoString(player, [point], liberties)
for same_color_string in adjacent_same_color:
new_string = new_string.merged_with(same_color_string)
for new_string_point in new_string.stones:
self._grid[new_string_point] = new_string
for other_color_string in adjacent_opposite_color:
other_color_string.remove_liberty(point)
for other_color_string in adjacent_same_color:
if other_color_string.num_liberties == 0:
self._remove_string(other_color_string)
def is_on_grid(self, point):
return 1 <= point.row <= self.num_rows and 1 <= point.col <= self.num_cols
def get(self, point):
string = self._grid.get(point)
if string is None:
return None
return string.color
def get_go_string(self, point):
string = self._grid.get(point)
if string is None:
return None
return string
def _remove_string(self, string):
for point in string.stones:
for neighbor in point.neighbors():
neighbor_string = self._grid.get(neighbor)
if neighbor_string is None:
continue
if neighbor_string is not string:
neighbor_string.add_liberty(point)
self._grid[point] = None
class Move():
def __init__(self, point=None, is_pass=False, is_resign=False):
assert (point is not None) ^ is_pass ^ is_resign
self.point = point
self.is_play = (self.point is not None)
self.is_pass = is_pass
self.is_resign = is_resign
#classmethod
def play(cls, point):
return Move(point=point)
#classmethod
def pass_turn(cls):
return Move(is_pass=True)
#classmethod
def resign(cls):
return Move(is_resign=True)
class GameState():
def __init__(self, board, next_player, previous, move):
self.board = board
self.next_player = next_player
self.previous_state = previous
self.last_move = move
def apply_move(self, move):
if move.is_play:
next_board = copy.deepcopy(self.board)
next_board.place_stone(self.next_player, move.point)
else:
next_board = self.board
return GameState(next_board, self.next_player.other, self, move)
#classmethod
def new_game(cls, board_size):
if isinstance(board_size, int):
board_size = (board_size, board_size)
board = Board(*board_size)
return GameState(board, Player.black, None, None)
def is_over(self):
if self.last_move is None:
return False
if self.last_move.is_resign:
return True
second_last_move = self.previous_state.last_move
if second_last_move is None:
return False
return self.last_move.is_pass and second_last_move.is_pass
def is_move_self_capture(self, Player, move):
if not move.is_play:
return False
next_board = copy.deepcopy(self.board)
next_board.place_stone(Player, move.point)
new_string = next_board.get_go_string(move.point)
return new_string.num_liberties == 0
#property
def situation(self):
return (self.next_player, self.board)
def does_move_validate_ko(self, player, move):
if not move.is_play:
return False
next_board = copy.deepcopy(self.board)
next_board.place_stone(player, move.point)
next_situation = (Player.other, next_board)
past_state = self.previous_state
while past_state is not None:
if past_state.situation == next_situation:
return True
past_state = past_state.previous_state
return False
def is_valid_move(self, move):
if self.is_over():
return False
if move.is_pass or move.is_resign:
return True
return (
self.board.get(move.point) is None and
not self.is_move_self_capture(self.next_player, move) and
not self.does_move_validate_ko(self.next_player, move))
gotypes code
import enum
from collections import namedtuple
class Player(enum.Enum):
black = 1
white = 2
#property
def other(self):
return Player.black if self == Player.white else Player.white
class Point(namedtuple('Point', 'row col')):
def neighbors(self):
return [
Point(self.row - 1, self.col),
Point(self.row + 1, self.col),
Point(self.row, self.col - 1),
Point(self.row, self.col + 1),
]
utils code
import random
from dlgo.agent.base import Agent
from dlgo.agent.helpers import is_point_an_eye
from dlgo.goboard_slow import Move
from dlgo.gotypes import Point
class RandomBot(Agent):
def select_move(self, game_state):
""""Choose a random valid move that preserves our own eyes."""
canidates = []
for r in range(1, game_state.board.num_rows + 1):
for c in range(1, game_state.board.num_cols +1):
canidate = Point(row=r, col=c)
if game_state.is_valid_move(Move.play(canidate)) and not is_point_an_eye(game_state.board, canidate, game_state.next_player):
canidates.append(canidate)
if not canidates:
return Move.pass_turn()
return Move.play(random.choice(canidates))
from dlgo import gotypes
COLS = 'ABCDEFGHIJKLMNOPQRST'
STONE_TO_CHAR = {
None: ' . ',
gotypes.Player.black: ' x ',
gotypes.Player.white: ' o ',
}
def print_move(player, move):
if move.is_pass:
move_str = 'passes'
elif move.is_resign:
move_str = 'resigns'
else:
move_str = '%s%d' % (COLS[move.point.col - 1], move.point.row)
print('%s %s' % (player, move_str))
def print_board(board):
for row in range(board.num_rows, 0, -1):
bump = " " if row <= 9 else ""
line = []
for col in range(1, board.num_cols + 1):
stone = board.get(gotypes.Point(row = row, col = col))
line.append(STONE_TO_CHAR[stone])
print('%s%d %s' % (bump, row, ''.join(line)))
print(' ' + ' '.join(COLS[:board.num_cols]))
Helpers Code
from dlgo.gotypes import Point
def is_point_an_eye(board, point, color):
if board.get(point) is not None:
return False
for neighbor in point.neighbors():
if board.is_on_grid(neighbor):
neighbor_color= board.get(neighbor)
if neighbor_color != color:
return False
friendly_corners = 0
off_board_corners = 0
corners = [
Point(point.row - 1, point.col - 1),
Point(point.row - 1, point.col + 1),
Point(point.row + 1, point.col - 1),
Point(point.row + 1, point.col + 1),
]
for corner in corners:
if board.is_on_grid(corners):
corner_color = board.get(corner)
if corner_color == olor:
friendly_corners += 1
else:
off_board_corners += 1
if off_board_corners > 0:
return off_board_corners + friendly_corners == 4
return friendly_corners >= 3
Base Code
class Agent:
def __init(self):
pass
def selec_move(self, game_state):
raise NotImplementedError()
Both Inits are empty
corners is the list of all corner points, corner is
the current element in the for loop.
Barmar
I think it's just a typo: board.is_on_grid(corners)
should be board.is_on_grid(corner)
Barmar
These worked and fixed it
Here is the whole program. I'm not sure why but the error says this but I am using a seperate .py program to test all the functions within this class and I ran into this error that I can't seem to find a solution to.
File "C:\Python\PythonLab\PythonLab.py\classes.py", line 73, in
printEmployeeNames
Supervisor.printName(worker) File "C:\Python\PythonLab\PythonLab.py\classes.py", line 56, in printName
print(str(self.name) + "'" + str(self.department)) AttributeError: 'str' object has no attribute 'name'
class Employee:
def __init__(self, fullname, datestart, monthstart, yearstart):
self.fullname = fullname
self.datestart = datestart
self.monthstart = monthstart
self.yearstart = yearstart
def getService(self):
from datetime import date
current_date = date.today()
date1 = date(self.yearstart, self.monthstart, 1)
date_now = date(current_date.year, current_date.month, 1)
serviceTime = date_now - date1
day_format = serviceTime.days
years = int((day_format/365))
months = int(((day_format % 365)/30))
if day_format < 0:
return('Still In Service')
if day_format == 1:
return("Last Service Time was Yesterday")
if day_format < 365:
return("Last Service Time was " + str(months) + " months ago.")
if day_format > 365:
return('Last Service Time was ' + str(years) + "-" + str(months) + " ago.")
def printName(self):
print(self.fullname)
def setName(self, name):
self.fullname = name
class Supervisor(Employee):
def __init__(self, name, datestart, department):
Employee.__init__(self, name, int(datestart[0:2]), int(datestart[2:4]), int(datestart[5:8]))
self.employees = {}
self.contact_info = {}
self.department = department
self.name = Employee.__name__
def getName(self):
return self.fullname
def printName(self):
print(str(self.name) + "'" + str(self.department))
def setName(self, name, department):
self.name = name
self.department = department
def addEmployee(self, Employee):
self.employees[str(Supervisor.getName(self))] = Employee
def isManager(self):
if self.employees:
return True
else:
return False
def printEmployeeNames(self):
for worker in self.employees:
Supervisor.printName(worker)
def removeEmployee(self, employeename):
for worker in self.employees:
if employeename in self.employees:
del self.employees[employeename]
def getContactInfo(self):
return self.employees
def setContactInfo(self, phone, fax, email):
self.contact_info["phone"] = phone
self.contact_info["fax"] = fax
self.contact_info["email"] = email
def getPhone(self):
return self.contact_info["phone"]
def getFax(self):
return self.contact_info["fax"]
def getEmail(self):
return self.contact_info["email"]
self.employees is a dict. Iterating it means iterating its keys. Thus, in this code
for worker in self.employees:
Supervisor.printName(worker)
worker is a string. Change it to:
for worker in self.employees:
Supervisor.printName(self.employees[worker])
Or, even more to the point:
for name, worker in self.employees.items(): # iterates key-value pairs
Supervisor.printName(worker)
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.