I'm trying to unit test purchaseItem when there is no positive amount of given product and find_price_of_given_id methods in my Automat class.
import unittest
from Automat import Automat
from Bank import Bank
from Item import Item
from exceptions.NoItemException import NoItemException
class AutomatTest(unittest.TestCase):
def test_checkPriceOfGivenID(self):
bank = Bank()
automat = Automat(bank)
Cola = Item(2)
automat.add_object(Cola)
self.assertEqual(automat.find_price_of_given_id(30), 2)
def test_checkIfPurchaseItemCanBeProcessedWhenNoProduct(self):
bank = Bank()
automat2 = Automat(bank)
Soda = Item(2, 0)
automat2.add_object(Soda)
self.assertEqual(automat2.purchaseItem(30), "Given amount it too small and " \
"no item with " + str(30) + " in automat!")
if __name__ == '__main__':
unittest.main()
If I run test one by one, both are passed. If I run the whole class then it says thattest_checkPriceOfGivenID is failed :
Testing started at 14:12 ...
C:\Users\Admin\PycharmProjects\vending-machine\venv\Scripts\python.exe "C:\Program Files\JetBrains\PyCharm Community Edition 2018.3.4\helpers\pycharm\_jb_unittest_runner.py" --path C:/Users/Admin/PycharmProjects/vending-machine/AutomatTest.py
Launching unittests with arguments python -m unittest C:/Users/Admin/PycharmProjects/vending-machine/AutomatTest.py in C:\Users\Admin\PycharmProjects\vending-machine
Ran 2 tests in 0.004s
Error
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\lib\unittest\case.py", line 59, in testPartExecutor
yield
File "C:\ProgramData\Anaconda3\lib\unittest\case.py", line 615, in run
testMethod()
File "C:\Users\Admin\PycharmProjects\vending-machine\AutomatTest.py", line 15, in test_checkPriceOfGivenID
self.assertEqual(automat.find_price_of_given_id(30), 2)
File "C:\Users\Admin\PycharmProjects\vending-machine\Automat.py", line 28, in find_price_of_given_id
raise NoItemException
exceptions.NoItemException.NoItemException
FAILED (errors=1)
Process finished with exit code 1
Automat class
from Item import Item
from exceptions.NoItemException import NoItemException
from exceptions.NoProperAmountException import NoProperAmountException
from Coin import Coin
from decimal import *
class Automat:
item_id = 30
def __init__(self, _bank, objects=None):
self.bank = _bank
if objects is None:
objects = {}
self.objects = objects
self.purchaseItemBank = []
def add_object(self, obj: Item):
id_to_assign = Automat.item_id
self.objects.update({id_to_assign: obj})
Automat.item_id = Automat.item_id + 1
return id_to_assign
def find_price_of_given_id(self, item_id):
if self.objects.get(item_id) is not None:
return self.objects.get(item_id).get_price()
else:
raise NoItemException
def find_amount_of_given_id(self, item_id):
if self.objects.get(item_id) is not None:
return self.objects.get(item_id).get_amount()
else:
raise NoItemException
def checkIfAmountIsPositive(self, item_id):
if self.objects.get(item_id) is not None:
var = True if self.objects.get(item_id).get_amount() > 0 else False
return var
else:
raise NoItemException
def withdrawItem(self, item_id):
self.objects.get(item_id).decrease()
def purchaseItem(self, item_id):
sumOfCoins = 0
if 30 <= item_id <= 50:
lista = []
for i in self.purchaseItemBank:
lista.append(i)
sumOfCoins += i.getCoinValue()
priceOfGivenProduct = self.find_price_of_given_id(item_id)
if sumOfCoins < priceOfGivenProduct:
if not self.checkIfAmountIsPositive(item_id):
return "Given amount it too small and " \
"no item with " + str(item_id) + " in automat!"
else:
raise NoProperAmountException
else:
if not self.checkIfAmountIsPositive(item_id):
return "No item with " + str(item_id) + " in automat!"
a = round(abs(Decimal(priceOfGivenProduct) - sumOfCoins), 2)
listaCopy = self.bank.getSortedBankListWithCoins()
if a > 0:
if len(listaCopy) == 0:
return "Nie mozna wydac"
for i, v in enumerate(self.bank.bank):
if a == 0:
break
elif a >= v.getCoinValue():
a = a - v.getCoinValue()
listaCopy.remove(v)
elif a < v.getCoinValue():
continue
if i + 1 == (len(self.bank.bank)):
return "Nie mozna wydac"
if a > 0:
return "Nie mozna wydac"
self.bank.bank = listaCopy.copy()
self.withdrawItem(item_id)
for iterator in lista:
self.bank.addMoney(iterator)
return "Wydano towar"
else:
raise NoItemException
Item class:
class Item:
def __init__(self, price, amount=5):
self.amount = amount
self.price = price
def get_price(self):
return self.price
def get_amount(self):
return self.amount
def decrease(self):
self.amount -= 1
def __str__(self):
return f"{self.amount} # {self.price}"
Bank class:
class Bank:
def __init__(self):
self.bank = []
def addMoney(self, value):
self.bank.append(value)
def getSumBank(self):
return sum(value.getCoinValue() for value in self.bank)
def getSumOfGivenCoins(self, *args):
suma = 0
for i in args:
suma += i.getCoinValue()
return suma
def getSortedBankListWithCoins(self):
self.bank.sort(key=lambda x: x.getCoinValue(), reverse=True)
listaCopy = self.bank.copy()
return listaCopy
Here:
class Automat:
item_id = 30
item_id is a class attribute - it's shared between all instances of Automat, which is probably how the tests are interfering with one another.
Update:
One way to fix the problem would be to reset the item_id in a setUp method.
What you need is to convert item_id to an instance variable:
class Automat:
def __init__(self, _bank, objects=None):
self.item_id = 30
# rest of init here ...
def add_object(self, obj: Item):
id_to_assign = self.item_id
self.objects.update({id_to_assign: obj})
self.item_id += 1
return id_to_assign
Now all ids will start at 30 and your unit tests will be able to find these items.
Related
I try raise exception in pytest when battery run out from device when calculator count 100x times.
class:
class Calculator:
def __init__(self, battery: int = 100, filename=None):
self.battery = battery
self.filename = filename
self.check_battery()
def check_battery(self):
if self.battery <= 0:
raise NoBatteryError("The battery has run out")
def add(self, *args):
self.check_battery()
self.battery -= 1
result_add = 0
for number_to_add in args:
result_add += number_to_add
return result_add
class NoBatteryError(Exception):
pass
Pytest:
def test_battery_by_calculate_100x_times(calc):
# Given
for iteration in range(1, 103):
value = 2
result = calc.add(value, value)
expected_value = value + value
try:
result == expected_value
except NoBatteryError:
assert True
Output:
FAILED test_electronic_device_calculator.py::test_battery_by_calculate_100x_times - electronic_devices.calculator.NoBatteryError: The battery has run out
=========1 failed, 29 passed in 0.20s =======
Simple test like:
def test_check_battery_should_raise_no_battery_error(calc):
calc.battery = 0
with pytest.raises(NoBatteryError):
calc.check_battery()
work for me. I try use also in for loop with pytest.raises(NoBatteryError) - but my function also don't work.
I am not sure that it should looks like that but works:
def test_battery_by_calculate_100x_times(calc):
for iteration in range(0, 102):
value = 2
try:
calc.add(value, value)
except NoBatteryError:
assert True
I want to implements a-star algorithm and the function (from Route_Algorithm.py) extends the nodes to get the next layor of f_value in the tree . The node can be regard as the station. And the self.settings.station_matrix is the numpy.matrix.
def voluation_station(self, successor, dest_location,bus_stations):
'''initilize all the f(g+h) to the specific nodes'''
length = len(self.settings.station_matrix[successor])
for end_element in range(length):
for station in bus_stations:
if int(station.name) == end_element:
station.get_g(self.settings.station_matrix[successor][end_element])
length_station = len(self.settings.station_matrix[end_element])
for element_station in range(length_station):
if element_station == dest_location:
station.get_h(self.settings.station_matrix[end_element][dest_location])
for element in bus_stations:
element.result_f()
return bus_stations
However, when I run the part of code. It reports the error like this:
Traceback (most recent call last):
File "/home/surface/Final-Year-Project/FYP/Main.py", line 4, in <module>
class main():
File "/home/surface/Final-Year-Project/FYP/Main.py", line 13, in main
new_route.busy_route_matrix()
File "/home/surface/Final-Year-Project/FYP/oop_objects/Route.py", line 87, in busy_route_matrix
self.route_algorithm.A_STAR_Algorithm(start_location,dest_location,self.bus_stations)
File "/home/surface/Final-Year-Project/FYP/Util/Route_Algorithm.py", line 40, in A_STAR_Algorithm
self.voluation_station(successor, dest_location,bus_stations)
File "/home/surface/Final-Year-Project/FYP/Util/Route_Algorithm.py", line 73, in voluation_station
station.get_g(self.settings.station_matrix[successor][end_element])
TypeError: 'int' object is not callable
I search the solution in the Internet, I think the problem may be in the end_element, maybe some inherient problem but I'm not sure. Can some one help me! Please!
Additional codes for other classes:
These classes are Util classes, which helps for handle oop_objects!
The class is for the Route_Algorithm:
from Util.Mergesort_algorithm import mergesort_algorithm
class route_algorithm():
'''generate the route to optimise the profiles'''
def __init__(self,settings):
# a* algorithm
self.open_list = []
self.close_list = []
self.route = []
self.settings = settings
self.flag_find = False
self.lines = []
# merge_sort algorithm
self.mergesort_algorithm = mergesort_algorithm()
def A_STAR_Algorithm(self, start_location, dest_location,bus_stations):
'''search the best route for each passenger to the destination'''
#self.clean_f(bus_stations)
# initial the value of f in start_location
for item in bus_stations:
if int(item.name) == start_location:
item.get_g = 0
for key, value in item.adjacent_station.items():
if int(key.name) == dest_location:
item.get_h = value
self.open_list.append(start_location)
#start_location is the name of station
while self.flag_find == False:
successor = self.open_list[0]
self.open_list.remove(successor)
self.route.append(successor)
self.voluation_station(successor, dest_location,bus_stations)
self.a_brain_judge_1(dest_location,bus_stations)
print(self.flag_find)
if self.flag_find == True:
#end the location
self.route.append(dest_location)
#add the line to the self.line
self.print_lines()
self.flag_find = False
self.open_list = []
else:
#continue to search the minimize
list = self.sort(bus_stations)
for item in list:
print(item.name)
print(item.f)
#疑问如果前两个的预估值一样该如何处理
self.open_list.append(int(list[0].name))
def voluation_station(self, successor, dest_location,bus_stations):
'''initilize all the f(g+h) to the specific nodes'''
length = len(self.settings.station_matrix[successor])
for end_element in range(length):
for station in bus_stations:
if int(station.name) == end_element:
station.get_g(self.settings.station_matrix[successor][end_element])
length_station = len(self.settings.station_matrix[end_element])
for element_station in range(length_station):
if element_station == dest_location:
station.get_h(self.settings.station_matrix[end_element][dest_location])
for element in bus_stations:
element.result_f()
return bus_stations
def a_brain_judge_1(self, dest_location,bus_stations):
'''whether the direct_line is the optimize'''
tmp_dest = bus_stations[0]
self.tmp_nodes = []
self.flag_find = True
for element in bus_stations:
if int(element.name) == dest_location:
tmp_dest = element
for element in bus_stations:
if element == tmp_dest:
pass
else:
if element.f < tmp_dest.f:
self.tmp_nodes.append(element)
self.flag_find = False
if self.flag_find == True:
self.route.append(tmp_dest.name)
return None
else:
return self.tmp_nodes
def sort(self,bus_stations):
'''sort all the f in the next stations'''
return self.mergesort_algorithm.Merge_Sort(bus_stations)
def print_lines(self):
#print(len(self.route))
for item in self.route:
print(item)
print("NEXT PASSENGER!---------")
def clean_f(self,stations):
for item in stations:
item.clean_data()
The class is Random_Algorithm, which helps for generate the random passengers.
import random
from Data.Settings import settings
from oop_objects.Bus_Station import bus_station
from oop_objects.Passenger import passenger
class random_algorithm():
'''generate the random bus-stations and passengers'''
def __init__(self):
self.setting = settings()
def random_passenger(self,number):
'''generate random passengers for bus-station,
and assumes there are 6 stations now. Furthermore, the data will be crawled by the creeper'''
passengers = []
for i in range(number):
new_passenger = passenger()
random.seed(self.setting.seed)
new_passenger.Change_Name(random.randint(1,self.setting.bus_station_number))
# generate the start-location
self.setting.seed +=1
end_location = random.randint(1,self.setting.bus_station_number)
# generate the end-location
while new_passenger.name == end_location:
self.setting.seed += 1
end_location = random.randint(1,self.setting.bus_station_number)
#judge whether the start-location same as the end-location
new_passenger.change_end_location(end_location)
passengers.append(new_passenger)
return passengers
def random_station(self,number):
'''generate the name of random stations '''
bus_stations = []
for i in range(number):
new_bus_station = bus_station()
new_bus_station.Name(str(i))
bus_stations.append(new_bus_station)
return bus_stations
def random_edge(self,bus_stations):
'''generate the edge information for the stations'''
for location1 in bus_stations:
#print("The information add in "+location1.name)
for location2 in bus_stations:
if location1 != location2:
#print("the "+location2.name+" was added in the "+location1.name)
if location2 not in location1.adjacent_station and location1 not in location2.adjacent_station:
random.seed(self.setting.seed)
edge = random.randint(1,self.setting.edge_distance)
location1.add_adjacent_station(location2,edge)
#print("the edge is "+str(edge))
self.setting.seed += 1
return bus_stations
The class is the mergesort_algorithm, which compare the f for different stations
class mergesort_algorithm():
def Merge_Sort(self,stations):
length = len(stations)
middle = int(length/2)
if length<=1:
return stations
else:
list1 = self.Merge_Sort(stations[:middle])
list2 = self.Merge_Sort(stations[middle:])
return self.Merge(list1,list2)
def Merge(self,list1,list2):
list3 = []
length1 = len(list1)
length2 = len(list2)
point1 = 0
point2 = 0
while point1<=length1-1 and point2<=length2-1:
if list1[point1].f<list2[point2].f:
list3.append(list1[point1])
point1 += 1
else:
list3.append(list2[point2])
point2 += 1
if point1>=length1:
for i in range(length2):
if i>=point2:
list3.append(list2[point2])
if point2>=length2:
for i in range(length1):
if i>=point1:
list3.append(list1[point1])
return list3
#def print_sort_result(self):
The following class are oop.classes
The class is for the Route:
from Util.Random_Algorithm import random_algorithm
from Data.Settings import settings
from Util.Route_Algorithm import route_algorithm
import numpy as np
class route():
def __init__(self):
self.bus_stations = []
self.passengers = []
self.settings = settings()
#random algorithm
self.random_algorithm = random_algorithm()
#route_algorithm
self.route_algorithm = route_algorithm(self.settings)
def start_route(self):
'''The raw route Information(TEXT) for bus_stations '''
stations = self.random_algorithm.random_station(self.settings.bus_station_number)
finsih_edge_stations = self.random_algorithm.random_edge(stations)
'''
for item in finsih_edge_stations:
print("\nthe information for " + item.name + " is: \t")
for key, value in item.adjacent_station.items():
print("the station is " + key.name)
print(" the distace is " + str(value))
'''
self.bus_stations = finsih_edge_stations
'''The raw route Information(Text) for passengers'''
self.passengers = self.random_algorithm.random_passenger(self.settings.passengers_number)
def bus_stations_matrix(self):
'''trasfer the raw text to the matrix'''
#create zero_matrix
length = len(self.bus_stations)
tmp_matrix = np.zeros(length*length)
station_matrix = tmp_matrix.reshape(length,length)
for item in self.bus_stations:
for key,value in item.adjacent_station.items():
station_matrix[int(item.name)][int(key.name)] = value
station_matrix[int(key.name)][int(item.name)] = value
print(station_matrix)
self.settings.station_matrix = station_matrix
def passengers_matrix(self):
'''trasfer the raw text to the matrix'''
length = len(self.bus_stations)
tmp_matrix = np.zeros(length*length)
passenger_matrix = tmp_matrix.reshape(length,length)
for item in self.passengers:
#print("the start location of passenger is "+str(item.name))
#print("the end location of passenger is "+str(item.end_location))
#print(" ")
passenger_matrix[item.name-1][item.end_location-1]+=1;
print(passenger_matrix)
self.settings.passenger_matrix = passenger_matrix
def busy_route_matrix(self):
'''generate the bus_busy_route matrix'''
#read the requirements of passengers
length = self.settings.bus_station_number
for start_location in range(length):
for dest_location in range(length):
if self.settings.passenger_matrix[start_location][dest_location] == 0:
pass
else:
magnitude = self.settings.passenger_matrix[start_location][dest_location]
#运行a*算法去寻找最短路径/run the a* algorithm to search the path
self.route_algorithm.A_STAR_Algorithm(start_location,dest_location,self.bus_stations)
print("------------------------------------")
def practice(self):
'''practice some programming'''
for element in self.bus_stations:
print((element.f))
The class is for the Passenger
class passenger():
def __init__(self):
self.name = 0
self.end_location = "null"
def Change_Name(self,name):
'''change the name of passenger'''
self.name = name
def change_end_location(self,location):
'''generate the end_location'''
self.end_location = location
The class for the bus_station
class bus_station():
'''the class represents the bus station'''
def __init__(self):
'''the attribute of name means the name of bus-station
the attribute of passenger means the passenger now in the bus-station'''
self.name = "null"
self.passenger = []
self.adjacent_station = {}
#A* algorithm
self.g = 0
self.h = 0
self.f = 0
def Name(self,name):
'''change the name of the station'''
self.name = name
def add_passengers(self,*passenger):
'''add the passenger in the bus-station'''
self.passenger.append(passenger)
def add_adjacent_station(self,station,edge):
'''add the adjacent station in the this station'''
self.adjacent_station[station] = edge
def get_g(self,value):
'''get the value of g (线路值)'''
self.g =self.g+ value
def get_h(self,value):
'''get the value of f (预估值)'''
self.h = value
def result_f(self):
'''print the value of f (实际值)'''
self.f = self.g+self.h
def add_self_cost(self):
self.add_adjacent_station()
The following class is storing the data.
The class is for the setting:
class settings():
def __init__(self):
self.seed = 5
self.bus_station_number = 10
self.passengers_number = 10
self.edge_distance = 50
self.station_matrix = None
self.passenger_matrix = None
And the main class to run the whole project:
from oop_objects.Route import route
class main():
new_route = route()
new_route.start_route()
print("The distance between different bus station :")
new_route.bus_stations_matrix()
print("The location information for passengers :")
new_route.passengers_matrix()
new_route.busy_route_matrix()
#new_route.practice()practice
#new_route.sort()bus_stations
You should avoid the station of successor because you have assigned the value by using the get_g
The result should be:
def voluation_station(self, successor, dest_location,bus_stations):
'''initilize all the f(g+h) to the specific nodes'''
length = len(self.settings.station_matrix[successor])
for end_element in range(length):
if end_element == successor:
pass
else:
for station in bus_stations:
if int(station.name) == end_element:
station.get_g(self.settings.station_matrix[successor][end_element])
length_station = len(self.settings.station_matrix[end_element])
for element_station in range(length_station):
if element_station == dest_location:
station.get_h(self.settings.station_matrix[end_element][dest_location])
for element in bus_stations:
element.result_f()
return bus_stations
I'm trying to create a function that will merge two dictionaries through the use of Classes but I am unable to because I keep getting an AttributeError of 'NoneType.'However, when running the code individually without my entire code the function works, which confuses me.
My entire code is:
prices = {
"apple": 1,
"beets": 1,
"carrots": 1}
cookbook={}
total=20
def handle_commands():
keep_going=True
while keep_going:
choices=input("$ ").strip().lower().split()
command=choices[0]
if command == "loadrecipefile":
recipe_file=choices[1]
loadrecipefile(recipe_file)
elif command == "printrecipes":
printrecipes()
elif command == "printiinventory":
printiinventory()
elif command == "printmoney":
printmoney()
elif command == "preparedish":
recipe_name=choices[1]
preparedish(recipe_name)
elif command == "buyingredient":
name=choices[1]
number=int(choices[2])
buyingredient(name, number)
elif command == "setprices":
apple_price=int(choices[1])
beets_price=int(choices[2])
carrots_price=int(choices[3])
setprices(apple_price, beets_price, carrots_price)
elif command == "mergerecipes":
r1=choices[1]
r2=choices[2]
mergerecipes(r1,r2)
elif command == "quit":
keep_going=False
break
else:
print("Sorry that is not an acceptable command")
return
def loadrecipefile (recipe_file):
infile=open(recipe_file)
Linelist=infile.readlines()
for line in Linelist:
wordList=line.split()
r1=Recipe(wordList[0],int(wordList[1]),int(wordList[2]),int(wordList[3]))
cookbook.addRecipe(r1)
def printrecipes():
for recipe in cookbook.allRecipes():
print(recipe.getName(),int(recipe.getApples()),int(recipe.getBeets()),int(recipe.getCarrots()))
def buyingredient(name, number:int):
global total
if number*prices[name] > total:
print("Not enough cash!")
if iinventory == 'apple':
iinventory.getApples()
elif iinventory == 'beets':
iinventory.getBeets()
elif iinventory == 'carrots':
iinventory.getCarrots()
iinventory[name] += number
total -= number*prices[name]
def printiinventory():
print(int(iinventory.getApples()), int(iinventory.getBeets()), int(iinventory.getCarrots()))
def printmoney():
print(total)
def CanPrepareDish(recipe_name):
recipe = cookbook[recipe_name]
for ingred in recipe:
if ingred not in iinventory:
return False
if iinventory[ingred] < recipe[ingred]:
return False
return True
def preparedish(recipe_name):
if not CanPrepareDish(recipe_name):
print("Not enough ingredients")
else:
recipe = cookbook[recipe_name]
for ingred in recipe:
iinventory[ingred] -= recipe[ingred]
if recipe_name in iinventory:
iinventory[recipe_name] +=1
else:
iinventory[recipe_name] = 1
print("Dish prepared")
#for recipe in cookbook.allRecipes():
#if recipe_name == recipe.getName():
def setprices(apple_price, beets_price, carrots_price):
for name,value in prices.items():
prices["apple"] = apple_price
prices["beets"] = beets_price
prices["carrots"] = carrots_price
def mergerecipes(r1,r2):
dish1 = cookbook.getRecipe(r1)
dish2 = cookbook.getRecipe(r2)
name = dish1.getName() + dish2.getName()
apple_num = dish1.getApples() + dish2.getApples()
beet_num = dish1.getBeets() + dish2.getBeets()
carrot_num = dish1.getCarrots() + dish2.getCarrots()
rnew=Recipe(name,apple_num,beet_num,carrot_num)
class Recipe:
def __init__(self,name,apple_num,beet_num,carrot_num):
self.name=str(name)
self.apple_num=int(apple_num)
self.beet_num=int(beet_num)
self.carrot_num=int(carrot_num)
def getName(self):
return self.name
def getApples(self):
return self.apple_num
def getBeets(self):
return self.beet_num
def getCarrots(self):
return self.carrot_num
class Iinventory:
def __init__(self):
self.apple_num=0
self.beets_num=0
self.carrots_num=0
def getApples(self):
return int(self.apple_num)
def getBeets(self):
return int(self.beets_num)
def getCarrots(self):
return int(self.carrots_num)
iinventory=Iinventory()
class Cookbook:
def __init__(self):
self.Cooklist=[]
def addRecipe(self,Recipe):
self.Cooklist.append(Recipe)
def getRecipe(self,recipe_name):
for recipe in self.Cooklist:
if recipe_name == recipe.getName():
return recipe
def allRecipes(self):
for Recipe in self.Cooklist:
return self.Cooklist
cookbook=Cookbook()
handle_commands()
But with only this portion of the code, the function mergerecipes works. I would like to know why and how to fix the error of fixing my code for that function to work in my entire code.
The snippet of my entire code:
cookbook={}
class Recipe:
def __init__(self,name,apple_num,beet_num,carrot_num):
self.name=str(name)
self.apple_num=int(apple_num)
self.beet_num=int(beet_num)
self.carrot_num=int(carrot_num)
def getName(self):
return self.name
def getApples(self):
return self.apple_num
def getBeets(self):
return self.beet_num
def getCarrots(self):
return self.carrot_num
class Cookbook:
def __init__(self):
self.Cooklist=[]
def addRecipe(self,Recipe):
self.Cooklist.append(Recipe)
def getRecipe(self,recipe_name):
for recipe in self.Cooklist:
if recipe_name==recipe.getName():
return recipe
def allRecipes(self):
for Recipe in self.Cooklist:
return self.Cooklist
cookbook=Cookbook()
def mergerecipes(r1,r2):
dish1 = cookbook.getRecipe(r1)
dish2 = cookbook.getRecipe(r2)
name = dish1.getName() + dish2.getName()
apple_num = dish1.getApples() + dish2.getApples()
beet_num = dish1.getBeets() + dish2.getBeets()
carrot_num = dish1.getCarrots() + dish2.getCarrots()
rnew=Recipe(name,apple_num,beet_num,carrot_num)
cookbook.addRecipe(rnew)
print(rnew.getName(),int(rnew.getApples()),int(rnew.getBeets()),int(rnew.getCarrots()))
def loadrecipefile (recipe_file):
infile=open(recipe_file)
Linelist=infile.readlines()
for line in Linelist:
wordList=line.split()
r1=Recipe(wordList[0],int(wordList[1]),int(wordList[2]),int(wordList[3]))
cookbook.addRecipe(r1)
def printrecipes():
for recipe in cookbook.allRecipes():
print(recipe.getName(),int(recipe.getApples()),int(recipe.getBeets()),int(recipe.getCarrots()))
So when I load a textfile it inputs the "recipes" into the cookbook, which then you can see through printrecipes.
An example of an output would be:
loadrecipefile('recipes.txt')
printrecipes()
Dish1 2 4 1
Dish2 2 2 2
Dish3 1 2 4
Dish4 0 2 1
mergerecipes('Dish1','Dish3')
printrecipes()
Dish1 2 4 1
Dish2 2 2 2
Dish3 1 2 4
Dish4 0 2 1
Dish1Dish3 3 6 5
**IF CONFUSED: I tried running the merge recipes when running my entire code and I get this error:
$ loadrecipefile recipes.txt
$ printrecipes
Dish1 2 4 1
Dish2 2 2 2
Dish3 1 2 4
Dish4 0 2 1
$ mergerecipes Dish1 Dish2
name = dish1.getName() + dish2.getName()
AttributeError: 'NoneType' object has no attribute 'getName'
All help would be appreciated
You're calling lower() on the input, so 'Dish1' becomes 'dish1', which is not found in the list of recipes, and so getRecipe() returns None.
Sorry for all of the code, but for this assignment I am working on, it is necessary due to different references.
This chapter we are working with Binary Trees and Binary Search Trees.
I tested the BinaryTree() and BinarySearchTree() classes with no issue.
My problem is this: we are adding records to a binary search tree as seen in the Student class and the main() function to test the class. According to the assignment:
The Student class has an id and name, getters and setters, a str() function so that you can print a student record, and the operations ==, !=, <=, <, >=, > defined. The comparison operators compare student id's which are intended to be unique. Since we can compare student records, we can now put them into a Binary Search Tree.
My question is, how do I add the records a binary tree if all of the initialized variables are completely different than ones in the BinaryTree() class and the BinarySearchTree() class?
Everytime I run the code, I get errors such as:
AttributeError: 'Student' object has no attribute 'insert'
or
isEmpty() = True
None
isEmpty() = False
None
101(Betty Smith)
101(Betty Smith)
Traceback (most recent call last):
File "/Users/phillipward/Desktop/Lab 10/StudentRecordsTest.py", line 50, in <module>
main()
File "/Users/phillipward/Desktop/Lab 10/StudentRecordsTest.py", line 22, in main
BST.insert(Student(42, "Amy Winchester"))
File "/Users/phillipward/Desktop/Lab 10/BinarySearchTree.py", line 13, in insert
self.getleftChild().insert(data)
File "/Users/phillipward/Desktop/Lab 10/BinarySearchTree.py", line 7, in insert
if(self.isEmpty()):
File "/Users/phillipward/Desktop/Lab 10/binaryTree.py", line 33, in isEmpty
if(self is None or self.data is None):
AttributeError: 'Student' object has no attribute 'data'
I'm stuck on how to tell the program that I the student class is a type of BinarySearchTree.
class BinaryTree():
def __init__(self, data = None, leftChild = None, rightChild = None):
self.data = data
self.leftChild = leftChild
self.rightChild = rightChild
def getData(self):
return self.data
def setData(self, x):
self.data = x
return self.data
def getleftChild(self):
return self.leftChild
def setleftChild(self, x):
self.leftChild = x
return self.leftChild
def getrightChild(self):
return self.rightChild
def setrightChild(self, x):
self.rightChild = x
return self.rightChild
def isEmpty(self):
if(self is None or self.data is None):
return True
else:
return False
def __str__ (self):
return "{0}".format(self.data)
def inOrderTraversal(self):
if (self is None):
return "Empty"
else:
result = ""
if(self.getleftChild() is not None): # When we put payload in, we need equality
result += BinaryTree.inOrderTraversal(self.getleftChild()) + " "
result += str(self.getData())
if (self.getrightChild() is not None):
result += " " + BinaryTree.inOrderTraversal(self.getrightChild()) + " "
return result
def preOrderTraversal(self):
if (self.isEmpty()):
return "Empty"
else:
result = ""
result += str(self.getData())
if (self.getleftChild() is not None):
result += " " + BinaryTree.preOrderTraversal(self.getleftChild()) + " "
if (self.getrightChild() is not None):
result += BinaryTree.preOrderTraversal(self.getrightChild())
return result
def postOrderTraversal(self):
if (self.isEmpty()):
return "Empty"
else:
result = ""
if (self.getleftChild() is not None):
result += BinaryTree.postOrderTraversal(self.getleftChild()) + " "
if (self.getrightChild() is not None):
result += BinaryTree.postOrderTraversal(self.getrightChild()) + " "
result += str(self.getData())
return result
def insert(self, data):
if (self.isEmpty()):
self.setData(data)
elif (data < self.getData()):
if (self.getleftChild() is None):
self.setleftChild(BinarySearchTree(data))
else:
self.getleftChild().insert(data)
else: # data >= self.getData()
if (self.getrightChild() is None):
self.setrightChild(BinarySearchTree(data))
else:
self.getrightChild().insert(data)
def retrieve(self, data):
if self.isEmpty():
return None
elif data == self.getData():
return self.getData()
elif data <= self.getData():
if self.getleftChild() is None:
return None
else:
return self.getleftChild().retrieve(data)
else:
if self.getrightChild() is None:
return None
else:
return self.getrightChild().retrieve(data)
from binaryTree import BinaryTree
class BinarySearchTree(BinaryTree):
def insert(self, data):
if(self.isEmpty()):
self.setData(data)
elif(data < self.getData()):
if(self.getleftChild() is None):
self.setleftChild(data)
else:
self.getleftChild().insert(data)
else: #data >= self.getData()
if(self.getrightChild() is None):
self.setrightChild(data)
else:
self.getrightChild().insert(data)
def retrieve(self, data):
if self.isEmpty():
return None
elif data == self.getData():
return self.getData()
elif data <= self.getData():
if self.getleftChild() is None:
return None
else:
return self.getleftChild().retrieve(data)
else:
if self.getrightChild() is None:
return None
else:
return self.getrightChild().retrieve(data)
def minValue(self):
current = self
while current.leftChild is not None:
current = current.leftChild
return current.data
def maxValue(self):
current = self
while current.rightChild is not None:
current = current.rightChild
return current.data
def isBST(self):
current = self
if current == None:
return True
if current.leftChild.data <= current.data and
current.rightChild.data >= current.data:
return True
else:
return False
class Student():
def __init__(self, id = None, name = ""):
self.__id = id
self.__name = name
def getId(self):
return self.__id
def setId(self, id):
self.__id = id
def getName(self):
return self.__name
def setName(self, name):
self.__id = name
def __str__(self):
if (self is None):
return ""
else:
return str(self.__id) + "(" + self.__name + ")"
def __cmp__(self, other):
if (self is None or other is None):
return 0
else:
return self.__id - other.__id
def __eq__(self, other):
return self.__cmp__(other) == 0
def __ne__(self, other):
return self.__cmp__(other) != 0
def __lt__(self, other):
return self.__cmp__(other) < 0
def __le__(self, other):
return self.__cmp__(other) <= 0
def __gt__(self, other):
return self.__cmp__(other) > 0
def __ge__(self, other):
return self.__cmp__(other) >= 0
from BinarySearchTree import BinarySearchTree
from Student import Student
def main():
BST = BinarySearchTree()
print("isEmpty() = " + str(BST.isEmpty()))
print(BST)
BST.setData(Student(101, "Betty Smith"))
print("isEmpty() = " + str(BST.isEmpty()))
print(BinarySearchTree())
BST.insert(Student(50, "John Adams"))
print(BST)
BST.insert(Student(250, "Mike Jones"))
print(BST)
BST.insert(Student(42, "Amy Winchester"))
print(BST)
BST.insert(Student(31, "Jill Ranger"))
print(BST)
BST.insert(Student(315, "Bob Crachet"))
print(BST)
BST.insert(Student(200, "Karen Wilkins"))
print(BST)
print("\n")
print()
print("Inorder traversal: " + str(BST))
print()
print("Preorder traversal: \n" + BST.preOrderTraversal())
print()
print("Postorder traversal: " + BST.postOrderTraversal())
print()
print("minValue: " + str(BST.minValue()))
print("maxValue: " + str(BST.maxValue()))
print()
print("isBST = " + str(BST.isBST()))
for id in [101, 200, 31, 50, 315, 250, 42]:
print(BST.retrieve(Student(id)))
main()
this is python file im trying to make A*algorithm , but cant get it to work, I need some help , its an awesome code , its been run in latest python version for windows
from queue import PriorityQueue
class State(object):
def _init_(self,value,parent,start = 0,goal = 0):
self.children = []
self.value = value
self.parent = parent
self.dist = 0
if parent:
self.path = parent.path[:]
self.path.append(value)
self.start = parent.start
self.goal = parent.goal
else:
self.path = [value]
self.start = start
self.goal = goal
def GetDist(self):
pass
def CreateChildren(self):
pass
class State_String(State):
def _init_(self,value,parent,start = 0,goal = 0):
super(State_String,self).__init__(value,parent,start,goal)
self.dist = self.GetDist()
def GetDist(self):
if self.value == self.goal:
return 0
dist = 0
for i in range(len(self.goal)):
letter = self.goal[i]
dist += abs(i - self.value.index(letter))
return dist
def CreateChildren(self):
if not self.children:
for i in xrange(len(self.goal)-1):
val = self.value
val = val[:i] + val[i+1] + val[i] + val[i+2:]
child = State_String(val,self)
self.children.append(child)
class AStar_Solver:
def _init_(self,start,goal):
self.path = []
self.visitedQueue = []
self.priorityQueue = PriorityQueue()
self.start = start
self.goal = goal
def Solve(self):
startState = State_String(self.start,0,self.start,self.goal)
count = 0
self.priorityQueue.put((0,count,startState))
while(not self.path and self.priorityQueue.qsize()):
closestChild = self.priorityQueue.get()[2]
closestChild.CreateChildren()
self.visitedQueue.append(closestChild.value)
for child in closestChild.children:
if child.value not in self.visitedQueue:
count +=1
if not child.dist:
self.path = child.path
break
self.priorityQueue.put((child.dist,count,child))
if not self.path:
print "Goal of " + self.goal + " is not possible!"
return self.path
if _name_ == '__main__':
start1 = "hma"
goal1 = "ham"
a = AStar_Solver(start1,goal1)
a.Solve()
for i in xrange(len(a.path)):
print " %d)" %i + a.path[i]
getting these errors:
Traceback (most recent call last):
File "C:/Users/Herby/Desktop/untitled/Astar.py", line 82, in <module>
a.Solve()
File "C:/Users/Herby/Desktop/untitled/Astar.py", line 59, in Solve
startState = State_String(self.start,0,self.start,self.goal)
TypeError: object() takes no parameters
I need to know how it can be fixed
All of your init in your classes are written with single underscore instead of double underscore:
Change all init written as: _init_ to __init__
Also, this line is incorrect as well:
if _name_ == '__main__':
It needs to be double underscore for name as well
if __name__ == '__main__':
If you're interested, here is more information on why this is needed:
https://www.python.org/dev/peps/pep-0008/
In particular look at the description for: "double_leading_and_trailing_underscore"