TypeError: __init__() missing 1 required argument: 'id_name' - python-3.x

I am making my first python project which is a grocery store e-commerce page, and Im trying to add a cart section that allows the customer to buy the product, however, whenever I run my code and go to the cart section, I get the error "TypeError: init() missing 1 required argument: 'id_name' at Cart, line 26 called from Base, line 110"
Here is my code:
class Cart(CartTemplate):
def __init__(self, items, **properties):
# Set Form properties and Data Bindings.
self.init_components(**properties)
self.order = []
self.items_1 = items
self.items_2 = items
self.items_3 = items
if not self.items_1:
self.empty_cart_panel.visible = True
self.column_panel_1.visible = False
self.repeating_panel_1.items = self.items_1
self.repeating_panel_2.items = self.items_2
self.repeating_panel_3.items = self.items_3
self.subtotal_1 = sum(dairy['price'] * item['quantity'] for item in self.items_1)
self.subtotal_2 = sum(fruit['price'] * item['quantity'] for item in self.items_2)
self.subtotal_3 = sum(vegetable['price'] * item['quantity'] for item in self.items_3)
self.subtotal = self.subtotal_1 + self.subtotal_2 + self.subtotal_3
self.subtotal_label.text = f"AED {self.subtotal:.02f}"
if self.subtotal >= 40: #free shipping for orders over AED 40
self.shipping_label.text = 'FREE'
else: #add $5 shipping
self.shipping_label.text = "$5.00"
self.subtotal = self.subtotal + 5
self.total_label.text = f"${self.subtotal:.02f}"
def shop_button_click(self, **event_args):
"""This method is called when the button is clicked"""
get_open_form().title_link_click()
def checkout_button_click(self, **event_args):
"""This method is called when the button is clicked"""
for i in self.items:
self.order.append({'name':dairy['name'], 'quantity':i['quantity']})
self.order.append({'name':fruit['name'], 'quantity':i['quantity']})
self.order.append({'name':vegetable['name'], 'quantity':i['quantity']})
try:
charge = stripe.checkout.charge(amount=self.subtotal*100,
currency="AED",
shipping_address=True,
title="Fresh Fields")
except:
return
anvil.server.call('charge_user', token, user["email"])
get_open_form().cart_items = []
get_open_form().cart_link_click()
Notification("Your order has been received!").show()
Called from:
def cart_link_click(self, **event_args):
"""This method is called when the link is clicked"""
self.navigate(self.cart_link, Cart(items=self.cart_items))

Related

loop efficiency and performance impact calling api in python

Team:
My concern is on redundancy, efficient use of loops and best approach to get the desired result.
Usecase: get on call user name and create jira ticket with it.
below is my entire code and it runs fine for me. This is my very first OOP project.
Flow: I am calling two APIS (jira and pager api).
First calling pager api and getting who is oncall currently. Here am getting a list of nested dicts as response that am looping on.
Then calling jira api to create ticket with that above oncall user.
i want to learn to calculate Big0 and improve.
since this is my very first time can I get to see if there any problems or inefficiency or divergence from standard practices?
import requests
import json
import os
from jira import JIRA
from pdpyras import APISession
from collections import OrderedDict
JIRA_DICT_KEY = "JIRA"
JIRA_CONFIG = {'server': "https://jirasw.tom.com"}
JIRA_USER = os.environ['JIRA_USER']
JIRA_PW = os.environ['JIRA_PW']
PD_API_KEY = os.environ['PD_API_KEY']
USER_EMAIL = os.environ['USER_EMAIL']
class ZidFinder(object):
def __init__(self):
self.active_zid_errors = dict()
self.team_oncall_dict = dict()
self.onCall = self.duty_oncall()
self.jira = self.init_jira()
def init_jira(self):
jira = JIRA(options=JIRA_CONFIG, auth=(JIRA_USER, JIRA_PW))
return jira
def duty_oncall(self, *args):
session = APISession(PD_API_KEY, default_from=USER_EMAIL)
total = 1 #true or false
limit = 100 # this var is to pull limit records at a time.
teamnm = "Product SRE Team"
team_esp_name = "Product SRE Escalation Policy"
teamid = ""
teamesplcyid = ""
if args:
offset = args[0]
total_teams = args[1]
if offset <= total_teams:
print("\nfunc with args with new offset {} called\n".format(offset))
teams = session.get('/teams?limit={0}&total={1}&offset={2}'.format(limit,total,offset))
else:
print("Reached max teams, no more team records to pull")
return
else:
print("\nPull first set of {} teams as defined by limit var and loop more if team not found..\n".format(limit))
teams = session.get('/teams?limit={0}&total={1}'.format(limit,total))
if not teams.ok:
return
else:
tj = teams.json()
tjd = tj['teams']
print("\n")
for adict in tjd:
if not adict['name'] == teamnm:
continue
elif adict['name'] == teamnm:
teamid = adict['id']
print("Found team..\n",adict['name'], "id: {0}".format(teamid))
esclp = session.get('/escalation_policies?total={0}&team_ids%5B%5D={1}'.format(total,teamid))
if not esclp.ok:
print("Failed pulling Escalation polices for team '{}'".format(teamnm))
return
else:
ep = esclp.json()
epj = esclp.json()['escalation_policies']
if not epj:
print("Escalation polices for team '{}' not defined".format(teamnm))
return
else:
for adict in epj:
if not adict['summary'] == team_esp_name:
continue
else:
teamesplcyid = adict['id']
print("{} id: {}\n".format(team_esp_name, teamesplcyid))
oncalls = session.get('/oncalls?total={0}&escalation_policy_ids%5B%5D={1}'.format(total,teamesplcyid))
if not oncalls.ok:
print("Issue in getting oncalls")
return
else:
ocj = oncalls.json()['oncalls']
for adict in ocj:
if adict['escalation_level'] == 1 or adict['escalation_level'] == 2:
self.team_oncall_dict[adict['schedule']['summary']] = adict['user']['summary']
continue
if self.team_oncall_dict:
if len(self.team_oncall_dict) == 1:
print("\nOnly Primary onCall is defined")
print("\n",self.team_oncall_dict)
else:
print(" Primary and other calls defined")
print("\n",OrderedDict(self.team_oncall_dict),"\n")
return
else:
print("Calling with next offset as team was not found in the records pulled under limit..")
if tj['offset'] <= tj['total'] or tj['more'] == True:
setoffset = limit + tj['offset']
self.onCall(setoffset, tj['total'])
def create_jiras(self):
node = ["node1", "node2"]
zid_label = ["id90"]
labels = [node, zid_label]
print("Creating a ticket for node {} with description: {}".format(node, str(self.active_zid_errors[node])))
if self.msre_oncall_dict:
print("Current onCalls pulled from Duty, use them as assignee in creating jira tickets..")
new_issue = self.jira.create_issue(project='TEST', summary='ZID error on node {}'.format(node),
description=str(self.active_zid_errors[node]), issuetype={'name': 'Bug'}, assignee={'name': self.msre_oncall_dict['Product SRE Primary']},labels=labels)
print("Created a new ticket: ", new_issue.key, new_issue.fields.summary)
self.active_zid_errors[node][JIRA_DICT_KEY] = new_issue.key
else:
print("Current onCalls were not pulled from Duty, create jira with defautl assignee..")
new_issue = self.jira.create_issue(project='TEST', summary='ZID error on node {}'.format(node),
description=str(self.active_zid_errors[node]), issuetype={'name': 'Bug'},labels=labels)
print("Created a new ticket: ", new_issue.key, new_issue.fields.summary)
self.active_zid_errors[node][JIRA_DICT_KEY] = new_issue.key
if __name__== "__main__":
o = ZidFinder()

bad performance for loop with instance and bulk create

I need to use bulk_create to create a lot of "detalle"(details), the problem is i have to iterate trough a json to get the arguments, and i got 4 fk so django ask to me for the instance, not the id. but to have id i have to do a .get(), so i got a bad performance, because its 4 gets by each iteration.
its there a way to get all objects instances and put in a list or something to perform load then the instance without using get every time?
class DetalleFichaAllViewSet(viewsets.ModelViewSet):
serializer_class = DetalleFichaUpdateAllSerializer
def create(self, request, *args, **kwargs):
user = self.request.user
data = request.data
try:
ficha = Ficha.objects.get(autor=user.id)
DetalleFicha.objects.filter(ficha=ficha.id).delete()
except Http404:
pass
# Create Ficha
now = datetime.now()
date_time = now.strftime("%Y-%m-%d %H:%M")
print("AAAAAA DATA:", data)
Ficha.objects.filter(autor=user.id).update(fecha_creacion=date_time, autor=user,
nombre=data["nombreFicha"], descripcion=data["descripcionFicha"])
ficha = Ficha.objects.filter(autor=user.id).last()
recintos = Recinto.objects.all()
productos = Producto.objects.all()
estandar_productos = EstandarProducto.objects.all()
cotizaciones = Cotizacion.objects.all()
detalles_ficha = []
for detalle in data["detalles"]:
recinto = recintos.get(id=detalle[1])
producto = productos.get(id=detalle[10])
estandar_producto = estandar_productos.get(id=detalle[9])
try:
cotizacion = cotizaciones.get(id=detalle[4])
except ObjectDoesNotExist:
cotizacion = None
print("Fecha: ", detalle[8])
detalle = DetalleFicha(carreras=detalle[0],
recinto=recinto, nombre=detalle[2],
cantidad_a_comprar=detalle[3], cotizacion=cotizacion,
valor_unitario=detalle[5], valor_total=detalle[6],
documento=detalle[7], fecha_cotizacion=detalle[8],
estandar_producto=estandar_producto, producto=producto,
ficha=ficha)
detalles_ficha.append(detalle)
DetalleFicha.objects.bulk_create(detalles_ficha)
print("Array convertida", detalles_ficha)
print(detalles_ficha[0])
return Response(status=status.HTTP_200_OK)

Taking info from file and creating a dictionary

The goal of mine is to create a dictionary called 'sum_of_department' contains the department as the key and the total annual salary of all employees combined as a value. So far this is what I have but I'm a bit lost on how to add all the department names along with a sum of all of the employees salary in that dictionary. The current dictionary i tried displays only the amount of the salary and how many times its seen in the file. this is where i need the help.
import requests
# endpoint
endpoint = "https://data.cityofchicago.org/resource/xzkq-xp2w.json"
# optional parameters
parameters = {"$limit":20,}
# make request
response = requests.get(endpoint, params=parameters)
# Get the response data as a python object.
data = response.json()
count_by_department = {}
sum_by_department = {}
#loop through the data
for i in data:
if ('department' and 'salary_or_hourly' and 'annual_salary' in i):
department = i['department']
pay_type = i['salary_or_hourly']
anual_salary = i['annual_salary']
# print(i['annual_salary'])
else:
# handle case where there is no department property in that record
department = 'undefined'
pay_type = 'n/a'
anual_salary = 'n/a'
# print(department,"," ,pay_type)
# exclude the cases where the pay type is Hourly
if(pay_type != 'Salary' ):
pay_type = 0
# print(department,"," ,pay_type)
# update the sum_by_department and count_by_department dictionaries
if (department in count_by_department):
count_by_department[department] += 1
else:
count_by_department[department] = 1
if (anual_salary in sum_by_department):
sum_by_department[anual_salary] +=1
else:
sum_by_department[anual_salary] = 1
# print(count_by_department)
# print(sum_by_department)
You should add each person's annual_salary to the sum_by_department array while looping. Also, do not forget to convert your annual_salary variable to the float type, because adding them together as strings won't work.
Example script:
import requests
# endpoint
endpoint = "https://data.cityofchicago.org/resource/xzkq-xp2w.json"
# optional parameters
parameters = {"$limit":20,}
# make request
response = requests.get(endpoint, params=parameters)
# Get the response data as a python object.
data = response.json()
count_by_department = {}
sum_by_department = {}
#loop through the data
for i in data:
if ('department' and 'salary_or_hourly' and 'annual_salary' in i):
department = i['department']
pay_type = i['salary_or_hourly']
annual_salary = float(i['annual_salary'])
# print(i['annual_salary'])
else:
# handle case where there is no department property in that record
department = 'undefined'
pay_type = 'n/a'
annual_salary = 0
# print(department,"," ,pay_type)
# exclude the cases where the pay type is Hourly
if(pay_type != 'Salary' ):
pay_type = 0
# print(department,"," ,pay_type)
# update the sum_by_department and count_by_department dictionaries
if (department in count_by_department):
count_by_department[department] += 1
sum_by_department[department] += annual_salary
else:
count_by_department[department] = 1
sum_by_department[department] = annual_salary
#import pdb; pdb.set_trace();
print('count_by_department = ', count_by_department)
print('sum_by_department = ', sum_by_department)
Tip:
Uncomment the pdb line to debug interactively. The Python Debugger (pdb for short) halts the program while it's still running (i.e. in memory), so you can interact with it and inspect all variables.

Dictionary with functions versus dictionary with class

I'm creating a game where i have the data imported from a database, but i have a little problem...
Currently i get a copy of the data as a dictionary, which i need to pass as argument to my GUI, however i also need to process some data, like in this example:
I get the data as a dict (I've created the UseDatabase context manager and is working):
def get_user(name: str, passwd: str):
user = {}
user['name'] = name
user['passwd'] = passwd
with UseDatabase() as cursor:
_SQL = "SELECT id, cash, ruby FROM user WHERE name='Admin' AND password='adminpass'"
cursor.execute(_SQL)
res = cursor.fetchall()
if res:
user['id'] = res[0][0]
user['cash'] = res[0][1]
user['ruby'] = res[0][2]
return user
return res
.
.
.
def get_activities():
with UseDatabase() as cursor:
_SQL = "SELECT * FROM activities WHERE user_id='2'"
cursor.execute(_SQL)
res = cursor.fetchall()
if res:
ids = [i[0] for i in res]
activities = {}
for i in res:
activities[i[0]] = {'title':i[1],'unlock':i[2],'usr_progress':i[3]}
return (ids, activities)
return res
Need it as a dict in my GUI ("content" argument):
class SideBar:
def __init__(self, screen: 'pygame.display.set_mode()', box_width: int, box_height: int, content: dict, font: 'font = pygame.font.Font()'):
#content dict: {id: {'title':'','unlock':'','usr_progress':''},...}
self.box_width = box_width
self.box_height = box_height
self.box_per_screen = screen.get_height() // box_height
self.content = content
self.current_box = 1
self.screen = screen
self.font = font
self.generate_bar()
def generate_bar (self):
active = [i for i in self.content.keys() if i in range(self.current_box, self.current_box+self.box_per_screen)]
for i in range(self.box_per_screen):
gfxdraw.box(self.screen,pygame.Rect((0,i*self.box_height),(self.screen.get_width()/3,self.screen.get_height()/3)),(249,0,0,170))
self.screen.blit(self.font.render(str(active[i]) + ' - ' + self.content[active[i]]['title'], True, (255,255,255)),(10,i*self.box_height+4))
for i in range(self.box_per_screen):
pygame.draw.rect(self.screen,(50,0,0),pygame.Rect((0,i*self.box_height),(self.screen.get_width()/3,self.screen.get_height()/3)),2)
But still need to make some changes in the data:
def unlock_act(act_id):
if user['cash'] >= activities[act_id]['unlock'] and activities[act_id]['usr_progress'] == 0:
user['cash'] -= activities[act_id]['unlock']
activities[act_id]['usr_progress'] = 1
So the question is: in this situation should i keep a copy of the data as dict, and create a class with it plus the methods i need or use functions to edit the data inside the dict?

Global Name "msg" not defined

I'm currently writing a class called SMS_store(). In it, I have a method called delete.
Delete is simply supposed to make sure the user has given me a valid integer. If so, it's supposed to pop an item from the list.
class SMS_store():
def __init__(self):
self.__inbox = []
def delete(self, i):
if i >= len(self.__inbox):
return None
else:
self.__inbox.pop[i]
Whenever I run the code in my test program, I run into two errors at my delete stage:
1) if I type myInbox.delete(2) when there's only 2 items in the list, I get "list index out of range" and I though I was protected from that error. myInbox.delete(3) gives me None.
2) If I type myInbox.delete(1) when there's a valid index 1 in my list, it says global name 'msg' not defined. I don't get why I'm seeing that error.
Here's my full class code.
#SMS_store class
"""
Pre-condition: SMS_store class is instantiated in client code.
Post-condition: SMS_store class is instantiated.
"""
class SMS_store():
#Object instantiation
"""
Pre-conditon: SMS_store class is instantiated in client code.
Post-condition: Object creates an empty list.
"""
def __init__(self):
self.__inbox = []
#add_new_arrival method
"""
Pre-condition: Class method is handed a valid phone number of 11, 10, or 7
digits as a string with no hyphens or letters, a string containing a time,
and a string containing the text of a message.
Post-condition: Method will append a tuple containing False for an
undread message, the phone number, the time arrived and the text of the
message to the class created list.
"""
def add_new_arrival(self, from_number, time_arrived, text_of_SMS):
number = from_number
#Check for valid phone number and add hyphens based on number length
if len(number) == 11:
number = number[0] + "-" + number[1:4] + "-" + number[4:7] + "-"\
+ number[7:]
elif len(number) == 7:
number = number[:3] + "-" + number[3:]
elif len(number) == 10:
number = "1-" + number[:3] + "-" + number[3:6] + "-" + number[6:]
elif number.isalpha():
number = "Invalid number"
else:
number = "Invalid number"
time = time_arrived
text = text_of_SMS
message = (False, number, time, text)
self.__inbox.append(message)
#message_count method
"""
Post-condition: method returns the number of tuples in class created list.
Returns None if list is empty.
"""
def message_count(self):
count = len(self.__inbox)
if count == 0:
return None
else:
return count
#get_unread_indexes method
"""
Post-condition: method creates an empty list,checks for any tuples with
"False" at index 0. If "False" is found, it appends the index for the
tuple in the list. Method returns list of indexes.
"""
def get_unread_indexes(self):
unread = []
for message in self.__inbox:
if message[0] == False:
unread.append(self.__inbox.index(message))
return unread
#get_message method
"""
Pre-condition: Method is passed an integer.
Post-condition: Method checks for a valid index number. If valid, the
method will then check if indexed tuple contains "True" or "False" at index
0. If True, message is returned in new tuple containing items from indexes
1, 2, and 3. If False, a new tuple is created containing "True"
indicating the message is now read, plus indexes 1, 2, and 3 from the
original called tuple.
"""
def get_message(self, i):
#check for valid index number
if i >= len(self.__inbox):
return None
else:
msg = self.__inbox[i]
if msg[0] == True:
return (msg[1], msg[2], msg[3])
#create new tuple with True, and index 1-3 from original tuple
else:
self.__inbox.pop(i)
newMsg = (True, msg[1], msg[2], msg[3])
self.__inbox.insert(i, newMsg)
return newMsg[1:]
#delete method
"""
Pre-condition: Method is passed an integer.
Post-condition: Method checks that the integer is a valid index number. If
valid, method pops index from class created list.
"""
def delete(self, i):
if i >= len(self.__inbox):
return None
else:
self.__inbox.pop(i)
#Clear method
"""
Post-condition: method resets the inbox to an empty list.
"""
def clear(self):
self.__inbox = []
Here's how I am using the code in my test program:
#Test instantiation
naomisInbox = SMS_store()
martisInbox = SMS_store()
#Test add_new_arrival
naomisInbox.add_new_arrival("12345678912", "10:38PM", "Yay! Sorry, been")
martisInbox.add_new_arrival("23456789123", "10:37PM", "Hey I finally hit 90")
martisInbox.add_new_arrival("12345678912", "10:40PM", "Now I sleep :)")
naomisInbox.add_new_arrival("23456789123", "10:40PM", "Night")
#Test message_count
count = naomisInbox.message_count()
print("Naomi has", count, "messages in her inbox.")
count = martisInbox.message_count()
print("Marti has", count, "messages in his inbox.\n")
#Test get_unread_indexes
numUnread = naomisInbox.get_unread_indexes()
print("Naomi has unread messages at indexes: ", numUnread)
numUnread = martisInbox.get_unread_indexes()
print("Marti has unread messages at indexes: ", numUnread,"\n")
#Test get_message
msg = naomisInbox.get_message(9)
print("Getting message from Naomi's inbox at index [9]: ")
if msg == None:
print("No message at that index.")
else:
for item in msg:
print(item)
print("\n")
numUnread = naomisInbox.get_unread_indexes()
print("Naomi now has unread messages at indexes: ", numUnread, "\n")
msg = martisInbox.get_message(1)
print("Getting message from Marti's inbox at index [1]:")
for item in msg:
print(item)
print("\n")
numUnread = martisInbox.get_unread_indexes()
print("Marti now has unread messages at indexes: ", numUnread, "\n")
#Test delete
remove = naomisInbox.delete(0)
if remove == None:
print("Invalid index.")
count = naomisInbox.message_count()
numUnread = naomisInbox.get_unread_indexes()
print("Naomi now has", count, "messages with unread messages at index: ",\
numUnread)
#Test clear
print("\nAfter clearing: ")
naomisInbox.clear()
count = naomisInbox.message_count()
print("Naomi now has", count, "messages in her inbox.")
martisInbox.clear()
count = martisInbox.message_count()
print("Marti now has", count, "messages in his inbox.")
Error
Error:
Traceback (most recent call last):
File "/home/theriddler/Documents/CSIS153/Assignments/Nansen3/Nansen3.py", line 56, in <module>
remove = naomisInbox.delete(0)
File "/home/theriddler/Documents/CSIS153/Assignments/Nansen3/modSMS.py", line 125, in delete
NameError: global name 'msg' is not defined
Any help is appreciated. Sorry if it's a repeated question. Thanks, Blackwell.
for your first problem.
1)if there are only two items in the list then you cannot delete the 2nd item by passing 2 as index it should be 1.
2)your second problem tells that you are using same msg variable in SMS_store class within different functions without defining it as self variable for the class. However cant find any thing for now. You should probably check it again as it works well on my machine.
Now a little more light on your delete method:
def delete(self, i):
if i >= len(self.__inbox):
return None
else:
self.__inbox.pop(i)
Here if you want to delete the last message always then just use self.__ibox.pop() without passing any index but in case you want to delete an indexed message then u should do self.__ibox.pop(i-1)
because in case i is last element of the list then it will always be equal to length of the list and else will never be executed.
Also your delete method returns None only in if condition but if else runs then again None is returned by default so
remove = naomisInbox.delete(0)
if remove == None:
print("Invalid index.")
This will always print 'invalid index' as message even if the message gets deleted.

Resources