I have to set the total_cost variable to be equal to the subtotal variable or the from the product class. However, when I try to derive the value from the class. It gives me an attribute error of AttributeError: 'Product' object has no attribute '_Product__total_price'. I am implementing where you apply the promo code then it will deduct the total price from the cart.
This is init.py and functions used.
#app.route('/applyPromo/<string:id>/', methods=['GET','POST'])
def apply_promo(id):
promotions_dict = {}
db = shelve.open('promotions.db','w')
promotions_dict = db['Promotions']
total_cost = 100
hidden = True
applied = True
click = True
get_from_class = False
print(promotions_dict)
promotions = promotions_dict.get(UUID(id))
db = shelve.open('storage.db', 'r')
product_dict = db['products']
for key in product_dict:
product = product_dict[key]
total_cost = product.get_total_price()
print(total_cost)
#when user apply promo, promo will get deleted from the list/dictionary of promos they have.
if promotions["type"] == 1:
total_cost = total_cost - 10
hidden = False
print(f"Total Cost : {total_cost}")
promotions_dict.pop(UUID(id))
elif promotions["type"] == 2:
total_cost = total_cost - 5
hidden = False
print(f"Total Cost : {total_cost}")
promotions_dict.pop(UUID(id))
elif promotions["type"] == 3:
total_cost = (70/100)*total_cost
hidden = False
print(f"Total Cost : {total_cost}")
promotions_dict.pop(UUID(id))
elif promotions["type"] == 4:
total_cost = (80/100)*total_cost
hidden = False
print(f"Total Cost : {total_cost}")
promotions_dict.pop(UUID(id))
elif promotions["type"] == 5:
total_cost = (85/100)*total_cost
hidden = False
print(f"Total Cost : {total_cost}")
promotions_dict.pop(UUID(id))
else:
total_cost = (90/100)*total_cost
hidden = False
print(f"Total Cost : {total_cost}")
promotions_dict.pop(UUID(id))
db['Promotions'] = promotions_dict
db.close()
db.close()
print(promotions_dict)
session['promotion_applied'] = promotions["id"]
return render_template("generatePromo.html", total_cost=total_cost,applied=applied, promotions_dict=promotions_dict,hidden=hidden,promotions=promotions,get_from_class=get_from_class, click=click)
#app.route('/shopping_cart')
def shopping_cart():
# session.clear()
error = None
cart_items = []
quantity_list = []
subtotal = 0
db = shelve.open('storage.db', 'r')
product_dict = db['products']
db.close()
for products in session:
item = product_dict.get(products)
cart_items.append(item)
if None in cart_items:
cart_items.remove(None)
quantity_list.append(session[products])
if products in quantity_list:
quantity_list.remove(products)
for i in range(len(cart_items)):
cart_items[i].set_purchased_quantity(quantity_list[i])
# set total price for single item
item_total = int(cart_items[i].get_price()) * int(cart_items[i].get_purchased_quantity())
cart_items[i].set_total_price(item_total)
# set total price of all items in cart
subtotal += item_total
print('QTY LIST', quantity_list)
print('CART', cart_items)
if not cart_items:
error = "Cart Is Empty"
return render_template('shoppingcart.html', products_list=cart_items, error=error, subtotal=subtotal)
This is the product class.
from uuid import uuid4
class Product:
def __init__(self, name, price, quantity, color, vase, remarks):
self.__product__id = str(uuid4())
self.__name = name
self.__price = price
self.__quantity = quantity
self.__color = color
self.__vase = vase
self.__remarks = remarks
self.__purchased_quantity = 0
self.__total_price = 0
def get_product_id(self):
return self.__product__id
def get_name(self):
return self.__name
def get_price(self):
return self.__price
def get_quantity(self):
return self.__quantity
def get_color(self):
return self.__color
def get_vase(self):
return self.__vase
def get_remarks(self):
return self.__remarks
def get_image(self):
return self.__image
def get_purchased_quantity(self):
return self.__purchased_quantity
def get_total_price(self):
return self.__total_price
def set_name(self, name):
self.__name = name
def set_price(self, price):
self.__price = price
def set_quantity(self, quantity):
self.__quantity = quantity
def set_color(self, color):
self.__color = color
def set_vase(self, vase):
self.__vase = vase
def set_remarks(self, remarks):
self.__remarks = remarks
def set_image(self, image):
self.__image = image
def set_purchased_quantity(self, purchased_quantity):
self.__purchased_quantity = purchased_quantity
def set_total_price(self, total_price):
self.__total_price = total_price
This is the traceback for the error.
Traceback
Leading double underscores should not be used as you are using them to define attributes of your class - single underscores is conventional. The problem with using leading double underscores is that the interpreter "mangles" the names of those attributes to avoid a subtle problem with inheritance, but leading to the problem, I believe, you are seeing. Here is a good read on the subject.
Related
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
The Product class seems to work fine but I'm trying to figure out how to get the Inventory class to separate each product into there specific categories. I feel like I'm close but whenever I try and print out the inventory it just shows where it's stored in memory and doesn't actually print anything out. The output i receive when running is at the bottom. I want it to print out the actual products and data, not the instance of it stored in memory.
class Product:
def __init__(self, pid, price, quantity):
self.pid = pid
self.price = price
self.quantity = quantity
def __str__(self):
#Return the strinf representing the product
return "Product ID: {}\t Price: {}\t Quantity: {}\n".format(self.pid, self.price, self.quantity)
def get_id(self):
#returns id
return self.pid
def get_price(self):
#returns price
return self.price
def get_quantity(self):
#returns quantity
return self.quantity
def increase_quantity(self):
self.quantity += 1
def decrease_quantity(self):
self.quantity -= 1
def get_value(self):
value = self.quantity * self.price
return 'value is {}'.format(value)
product_1 = Product('fishing', 20, 10)
product_2 = Product('apparel', 35, 20)
class Inventory:
def __init__(self, products):
self.products = products
self.fishing_list = []
self.apparel_list = []
self.value = 0
def __repr__(self):
return "Inventory(products: {}, fishing_list: {}, apparel_list: {}, value: {})".format(self.products, self.fishing_list, self.apparel_list, self.value)
def add_fishing(self):
for product in self.products:
if product.get_id() == 'fishing':
self.fishing_list.append(product)
return '{} is in the fishing section'.format(self.fishing_list)
def add_apparel(self):
for product in self.products:
if product.get_id() == 'apparel':
self.apparel_list.append(product)
return '{} is in the apparel section'.format(self.apparel_list)
inventory_1 = Inventory([product_1, product_2])
inventory_1.add_fishing()
print(inventory_1)
OUTPUT = Inventory(products: [<main.Product instance at 0x10dbc8248>, <main.Product instance at 0x10dbc8290>], fishing_list: [<main.Product instance at 0x10dbc8248>], apparel_list: [], value: 0)
You need to specify how an object of the class Inventory should be printed.
To do this you need to implement at least one of the following functions in your class.
__repr__
__str__
This answer helps, which of both you should use: https://stackoverflow.com/a/2626364/8411228
An implementation could look something like this:
class Inventory:
# your code ...
def __repr__(self):
return str(self.products) + str(self.fishing_list) + str(self.apparel_list) + str(self.value)
# or even better with formatting
def __repr__(self):
return f"Inventory(products: {self.products}, fishing_list: {self.fishing_list}, apparel_list: {self.apparel_list}, value: {self.value})
Note that I used in the second example f strings, to format the output string.
I'm working on a big page with different product statistics. I use there multiple charts, tables etc. It takes for example 5 seconds to load the page.
This is a very simplified models.py
EDIT
For example, OccurencesTable contains this row:
last_scan_time = tables.columns.TemplateColumn("""{{ record.get_last_scan.datetime }}""",accessor='get_last_scan.datetime', verbose_name='Last scan time')
So for each row, there must be executed query to the database which calls last scan. Better approach would be to preload all Scan objects.
PRODUCT
class Product(models.Model):
user = models.ForeignKey(User, null=False, blank=False, related_name='products')
name = models.CharField(max_length=200)
def get_occurences(self):
return self.occurences.prefetch_related("scans__price__currency")
def get_occurences_count(self):
return self.occurences.all().count()
def get_all_scans(self):
return [item for sublist in [x.scans.all() for x in self.get_occurences()] for item in sublist]
def get_all_valid_scans(self):
return [item for sublist in [x.get_valid_scans() for x in self.get_occurences()] for item in sublist]
def get_last_scans(self):
scans = []
for occ in self.get_occurences():
scan = occ.get_last_scan()
if scan:
scans.append(scan)
return scans
# #property
#def last_scan_time(self):
#scans = sorted([x for x in self.get_last_scans() if x.datetime],key = lambda x: x.datetime, reverse=True)
#Scan.objects.filter(occurence__product=self,price__amount__isnull=False)
#return str(scans[0].datetime)
def get_last_min_scan(self):
sorted_last_scans = [x for x in self.get_last_scans() if x.valid]
sorted_last_scans.sort(key=lambda x: x.price.eur_price)
return sorted_last_scans[0] if sorted_last_scans else None
def get_last_min_price(self):
last_scan = self.get_last_min_scan()
if last_scan:
return last_scan.price.eur_price
return None
def get_active_occurences(self):
return self.get_occurences().filter(active=True)
OCCURENCE
class Occurence(models.Model):
product = models.ForeignKey(Product, related_name='occurences', on_delete=models.CASCADE)
_last_scan = models.OneToOneField('Scan',null=True,blank=True,related_name='+')
currency = models.ForeignKey('Currency',related_name='occurences')
def get_last_scan(self):
try:
last = self.scans.select_related("price__amount").order_by('datetime').last()
except:
last = None
return last
def get_last_valid_scan(self):
try:
last = self.scans.exclude(price__isnull=True).order_by('-datetime').first()
except:
last = None
return last
def get_second_last_valid_scan(self):
scans = self.scans.exclude(price__isnull=True).order_by('-datetime').select_related("price")
if scans.count()>=2:
return scans[1]
return None
def get_valid_scans(self):
return self.scans.all().exclude(price__isnull=True)
def get_min_scan(self):
scan = self.get_valid_scans().order_by('price__amount').first()
if scan:
return scan
return None
""" STATS METHODS """
def stats_get_difference_for_two_last_scans(self):
second_last_valid_scan = self.get_second_last_valid_scan()
if second_last_valid_scan:
difference_in_percent = math_ops.round_eur(decimal.Decimal(-1 * (100 - self.get_last_valid_scan().price.eur_price / second_last_valid_scan.price.eur_price * 100), 2))
else:
difference_in_percent = decimal.Decimal(0)
return {'percent':difference_in_percent,
'xml_tag':'<two_last_scans_difference_in_percent>',
'xml_close_tag':'</two_last_scans_difference_in_percent>',
'label':'Last scans diff'}
def stats_get_min_price(self):
scan = self.get_min_scan()
if scan:
price = scan.price.eur_price
else:
price = None
return {'price': price,
'xml_tag': '<min_price>',
'xml_close_tag': '</min_price>',
'label': 'Min'}
def stats_get_avg_price(self):
prices = [x.price for x in self.scans.all() if x.price]
if prices:
price = math_ops.round_eur(decimal.Decimal(sum([x.eur_price for x in prices]) / len(prices), 2))
else:
price = None
preferred_currency = self.product.user.userprofile.preferred_currency
if preferred_currency:
if preferred_currency.shortcut == 'czk':
amount = Exchange.eur_to_czk(price)
pref_currency_string = '{} CZK'.format(amount)
pref_currency_amount = amount
else:
amount = price
pref_currency_string = u'{} €'.format(amount)
pref_currency_amount = amount
else:
if self.currency.shortcut == 'czk':
amount = Exchange.eur_to_czk(price)
pref_currency_string = '{} CZK'.format(amount)
pref_currency_amount = amount
else:
amount = price
pref_currency_string = u'{} €'.format(amount)
pref_currency_amount = amount
return {'price': price,
'pref_currency_string':pref_currency_string,
'pref_currency_amount':pref_currency_amount,
'xml_tag': '<average_price>',
'xml_close_tag': '</average_price>',
'label': 'AVG'}
PRICE
class Price(models.Model):
currency = models.ForeignKey('Currency',related_name='prices')
amount = models.DecimalField(max_digits=10,decimal_places=2)
def __unicode__(self):
return u'{} {}'.format(self.amount,self.currency)
def to_eur(self):
if self.currency.shortcut=='eur':
return self.amount
elif self.currency.shortcut=='czk':
return Exchange.objects.first().czk_to_eur(self.amount)
def to_czk(self):
if self.currency.shortcut == 'czk':
return self.amount
elif self.currency.shortcut == 'eur':
return Exchange.objects.first().eur_to_czk(self.amount)
#property
def eur_price(self):
if self.currency.shortcut=='eur':
return self.amount
elif self.currency.shortcut=='czk':
return self.to_eur()
#property
def czk_price(self):
cents = decimal.Decimal('01')
if self.currency.shortcut == 'czk':
return (self.amount).quantize(cents, decimal.ROUND_HALF_UP)
elif self.currency.shortcut == 'eur':
return self.to_czk()
#property
def pref_currency_amount(self):
pref_currency = self.scan.occurence.product.user.userprofile.preferred_currency
if pref_currency:
if pref_currency.shortcut == 'czk':
return self.czk_price
else: return self.eur_price
return self.amount
#property
def pref_currency_string(self):
pref_currency = self.scan.occurence.product.user.userprofile.preferred_currency
# return pref_currency.shortcut
if pref_currency:
if pref_currency.shortcut.lower() == 'czk':
return u'{} {}'.format(self.czk_price, pref_currency.shortcut)
else:
return u'{} {}'.format(self.eur_price, pref_currency.special_sign)
return u'{} {}'.format(self.amount,self.currency.special_sign)
def get_price(self,currency):
if currency=='eur':
return self.eur_price
elif currency=='czk':
return self.czk_price
def get_exchanged_price_string(self):
if self.currency.shortcut=='czk':
return u'{} {}'.format(Exchange.czk_to_eur(self.amount),u'€')
else:
return u'{} {}'.format(Exchange.eur_to_czk(self.amount),'CZK')
def get_original_price_string(self):
if self.currency.shortcut=='czk':
return u'{} {}'.format(self.amount,u'€')
else:
return u'{} {}'.format(Exchange.eur_to_czk(self.amount),'CZK')
For example rendering table occurences takes almost 2 seconds according to django-debug-toolbar. I'm trying to optimize it using select_related and prefetch_related but its still slow.
It's because of different methods I call has the same queries and those queries are called multiple times.
class OccurencesTable(tables.Table):
site = tables.columns.TemplateColumn("""{{ record.site.name }}""",accessor='site.name', verbose_name=u'Site')
avg_price = tables.columns.TemplateColumn("""{{ record.stats_get_avg_price.pref_currency_string }}""",accessor='stats_get_avg_price.price', verbose_name='AVG price')
last_scan_price = tables.columns.TemplateColumn("""{{ record.get_last_scan.price.pref_currency_string }} """,accessor='get_last_scan.price.amount', verbose_name='Last scan price')
last_scan_time = tables.columns.TemplateColumn("""{{ record.get_last_scan.datetime }}""",accessor='get_last_scan.datetime', verbose_name='Last scan time')
difference = tables.columns.TemplateColumn("""{% load static %}{% with diff=record.stats_get_difference_for_two_last_scans.percent %}
{% if diff > 0 %}+{% endif %}{{ diff }} % <img style="height: 15px" src="{% if diff < 0 %}{% static "img/icons/arrow-trend-minus.png" %}{% elif diff == 0 %}{% static "img/icons/arrow-trend-normal.png" %}{% else %}{% static "img/icons/arrow-trend-plus.png" %}{% endif %}">
{% endwith %}""",verbose_name='Difference')
class Meta:
model = Occurence
fields = ('id', 'site', 'last_scan_time','last_scan_price', 'difference', 'avg_price')
attrs = {'id': 'id_occurences_table',
'class': 'table', }
Can't figure out how to optimize methods of models Occurence and Product. Do you have any ideas?
With code like this, you should be thrilled with the timing that you get
#property
def last_scan_time(self):
scans = sorted([x for x in self.get_last_scans() if x.datetime],key = lambda x: x.datetime, reverse=True)
Scan.objects.filter(occurence__product=self,price__amount__isnull=False)
return str(scans[0].datetime)
This code is retrieving an entire table by the call to get_last_scans() then you are sorting that result inside python code! Databases have very fast built in sort functionality. Please use it.
There are plenty of other functions like this in this code. You will have to fix each of them. Do the filtering and sorting in the database. Not in your python code.
I keep getting this error:
<__main__.product object at 0x0231A7B0>
from the code:
def prnt(self):
print("\n**********************************************************")
print(self.prntlist())
print("Grand total\t\t\t\t$", self.setprice())
print("**********************************************************\n")
def prntlist(self):
x = ''
for i in self.cartlist:
x = i, "/n"
return x
instead of executing the function prntlist it displays that error
full code:
class product(object):
name = ''
price = 0
def __init__(self, name, price):
self.name = name
self.price = price
def prnt(self):
print("\n**********************************************************")
print("Item\t\t\t Price")
print(self.name,"............ $", self.price)
print("\n**********************************************************")
def prntline(self):
x = self.name + ".........." + self.price
return x
class cart(object):
totalprice = 0
cartlist = []
def __init__(self):
self.totalprice = totalprice
self.cartlist = []
def setprice(self):
totprice = self.totalprice
for i in self.cartlist:
self.totalprice += i.price
return totprice
def prnt(self):
print("\n**********************************************************")
print(self.prntlist())
print("Grand total\t\t\t\t$", self.setprice())
print("**********************************************************\n")
def prntlinecart(self):
print("You have purchased: ", self.prntlist())
def prntlist(self):
x = ''
for i in self.cartlist:
x = i, "/n"
return x
def additem(self, item):
self.cartlist.append(item)
print("Ah, fresh out. But we can have it shipped to your house next week")
Ok, I made your example work for me, just to see what is happening:
class product(object):
name = ''
price = 0
def __init__(self, name, price):
self.name = name
self.price = price
def prnt(self):
print("\n**********************************************************")
print("Item\t\t\t Price")
print(self.name,"............ $", self.price)
print("\n**********************************************************")
def prntline(self):
x = self.name + ".........." + self.price
return x
class cart(object):
totalprice = 0
cartlist = []
def __init__(self):
self.totalprice = 0
self.cartlist = []
def setprice(self):
totprice = self.totalprice
for i in self.cartlist:
self.totalprice += i.price
return totprice
def prnt(self):
print("\n**********************************************************")
print(self.prntlist())
print("Grand total\t\t\t\t$", self.setprice())
print("**********************************************************\n")
def prntlinecart(self):
print("You have purchased: ", self.prntlist())
def prntlist(self):
x = ''
print('fff')
for i in self.cartlist:
x = i, "/n"
return x
def additem(self, item):
self.cartlist.append(item)
print("Ah, fresh out. But we can have it shipped to your house next week")
mycart = cart()
RL = product("Red Leicester", 13.99)
RL.prnt()
mycart.additem(RL)
mycart.prnt()
The output is:
**********************************************************
Item Price
Red Leicester ............ $ 13.99
**********************************************************
Ah, fresh out. But we can have it shipped to your house next week
**********************************************************
fff
(<__main__.product object at 0x7ffbe52609e8>, '/n')
Grand total $ 0
**********************************************************
It seems that you ask about this: <__main__.product object at 0x7ffbe52609e8>. As I wrote in the first comment, this is because you are making tuple, not a string when with the following line x = i, "/n".
I am studying for my final and this was a quiz question I missed. I need most of the help on the getTotal method. I need to loop through the list, find the price of each item, add the price to the total and return the total. I struggle with loops and I am not sure how to pull the second item out of a list.. [1] ?? I have tried many ways and am getting frustrated.
If there is anyone up that is willing to help me that would be great. I am still learning and am new at this so go easy on me, but I really want to learn it. It's probably not as hard as I make it out to be, but Ill be waiting for some input. Thank you!
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 Cart:
def __init__(self, list):
self.list = []
def addItem(self, item):
self.list.append(self.list)
def getTotal(self):
total = 0
for item in self.list:
name, price = item # or price = item[1]
total = total + price
def getNumItems(self):
count = 0
for c in range(self.list):
count = self.list + 1
return count
def removeItem(self, item)
#removes the item from the cart's item list
def main():
item1 = Item("Banana", .69)
item2 = Item("Eggs", 2.39)
item3 = Item("Donut", .99)
c = Cart()
c.addItem(item1)
c.addItem(item2)
c.addItem(item3)
print "You have %i items in your cart for a total of $%.02f" %(c.getNumItems(), c.getTotal())
c.removeItem(item3)
print "You have %i items in your cart for a total of $%.02f" % (c.getNumItems(), c.getTotal())
main()
Here gives the time and I changed the code and now it is fully functional shopping cart
class Item(object):
def __init__(self, unq_id, name, price, qty):
self.unq_id = unq_id
self.product_name = name
self.price = price
self.qty = qty
class Cart(object):
def __init__(self):
self.content = dict()
def update(self, item):
if item.unq_id not in self.content:
self.content.update({item.unq_id: item})
return
for k, v in self.content.get(item.unq_id).iteritems():
if k == 'unq_id':
continue
elif k == 'qty':
total_qty = v.qty + item.qty
if total_qty:
v.qty = total_qty
continue
self.remove_item(k)
else:
v[k] = item[k]
def get_total(self):
return sum([v.price * v.qty for _, v in self.content.iteritems()])
def get_num_items(self):
return sum([v.qty for _, v in self.content.iteritems()])
def remove_item(self, key):
self.content.pop(key)
if __name__ == '__main__':
item1 = Item(1, "Banana", 1., 1)
item2 = Item(2, "Eggs", 1., 2)
item3 = Item(3, "Donut", 1., 5)
cart = Cart()
cart.update(item1)
cart.update(item2)
cart.update(item3)
print "You have %i items in your cart for a total of $%.02f" % (cart.get_num_items(), cart.get_total())
cart.remove_item(1)
print "You have %i items in your cart for a total of $%.02f" % (cart.get_num_items(), cart.get_total())
And a output is:
You have 8 items in your cart for a total of $8.00
You have 7 items in your cart for a total of $7.00
for getTotal:
def getTotal(self):
total = 0
for item in self.list:
name, price = item # or price = item[1]
total = total + price
BTW, Your addItem and getNumItems method are also wrong. Since it is final, you should try to understand what you are working on.