I'm writing a piece of code in Python to create an order system for a PC building shop, and have an 'order' class, which contains a method to print the order. When I reference this (create an order) in one of my functions (to place the order), it works fine. As in:
order1 = order(1,'Luke','p5','16gb','1tb','19in','midi','4usb')
But when I reference it inside my 'main' function, it gives this error when I run the code:
File "program.py", line 103, in main
order1 = order(1,'Luke','p5','16gb','1tb','19in','midi','4usb')
UnboundLocalError: local variable 'order' referenced before assignment
Which makes no sense to me, as it works perfectly well in my other function. The entire code is printed below. You can see in the 'main' function the line where the error is called first on the first and second line of the function, and later when if the text 'test' is entered, it will also return an error, for no apparent reason. I am using Python 3.6.3, on Mac OS X.
#!/usr/bin/env python3
class order(object):
def __init__(self, orderNo, customer, processor, ram, storage, screen, case, usb):
self.orderNo = orderNo
self.customer = customer
self.processor = processor
self.ram = ram
self.storage = storage
self.screen = screen
self.case = case
self.usb = usb
def stockCost(self):
global componentCosts
return componentCosts[self.processor] + componentCosts[self.ram] + componentCosts[self.storage] + componentCosts[self.screen]+ componentCosts[self.case]+ componentCosts[self.usb]
def salePrice(self):
return self.stockCost() * 1.2
def print_order(self):
"""Prints the data of an order in a viewable way for the vendor"""
return 'Order number: {}, for customer: {}.\n'.format(self.orderNo, self.customer) \
+ '{} processor.\n'.format(self.processor) \
+ '{} of ram.\n'.format(self.ram.upper()) \
+ '{} of storage.\n'.format(self.storage.upper()) \
+ '{} screen.\n'.format(self.screen) \
+ '{}{} case.\n'.format(self.case.lower()[0].upper(), self.case.lower()[1:])\
+ '{} {} ports.\n'.format(self.usb[0], self.usb[1:].upper()) \
+ 'Your chosen build will cost ${:0.2f}.\n'.format(self.salePrice())
def user_print_order(self):
"""Prints the data of an order in a viewable way for the customer"""
return '{}, your order number is {}.\n'.format(self.customer, self.orderNo) \
+ 'You have chosen a {} processor.\n'.format(self.processor) \
+ 'You have chosen {} of ram.\n'.format(self.ram.upper()) \
+ 'You have chosen to have {} of storage.\n'.format(self.storage.upper()) \
+ 'You have chosen a {} screen.\n'.format(self.screen) \
+ 'You have chosen a {}{} case.\n'.format(self.case.lower()[0].upper(), self.case.lower()[1:])\
+ 'You have chosen to have {} {} ports.\n'.format(self.usb[0], self.usb[1:].upper()) \
+ 'Your chosen build will cost ${:0.2f}.\n'.format(self.salePrice())
def place_order():
global componentList
global stock
global orders
orderOK = True
componentChoices = {}
print ('Please choose your components, These are your options:\n(please enter the component as they appear on the component list)\n' + componentList)
name = input('Please enter your name: ')
componentChoices['processor'] = input('Please enter what processor you would like: ')
componentChoices['ram'] = input('Please enter how much ram you would like: ')
componentChoices['storage'] = input('Please enter how much storage you would like: ')
componentChoices['screen'] = input('Please enter how big a screen you would like: ')
componentChoices['case'] = input('Please enter what size case you would like: ')
componentChoices['usb'] = input('Please enter whether you would like 4 USB ports or 2 (enter 4USB or 2USB): ')
for part in componentChoices:
choice = componentChoices[part].lower()
if stock[choice] < 1:
print ('Your choice of {} is out of stock, please choose a different option.\n'.format(part) + componentList)
componentChoice[part] = input('Enter your new choice of {}.'.format(part))
if stock[componentChoices[part]] < 1:
print ('Your choice of {} is also out of stock, your order has thus failed to go through. Please try again later.')
orderOK = False
return None
else: stock[componentChoices[part].lower()] -= 1
toBeReturned = order(len(orders)+1, name, componentChoices['processor'], componentChoices['ram'], componentChoices['storage'], componentChoices['screen'], componentChoices['case'], componentChoices['usb'])
print (toBeReturned.user_print_order())
query = input('Is this information correct? Enter "Y" or "N".')
while True:
if query.lower() == 'y':
break
if query.lower == 'n':
print('Your order has not been placed, please re-place the order')
return None
return toBeReturned
componentList = 'Processor: p3, p5 or p7\nRAM: 16GB or 32GB\nStorage: 1TB or 2TB\nScreen: 19in or 23in\nCase Size: Mini or Midi\nNo of Ports: 2USB or 4USB'
componentCosts = {
'p3': 100, 'p5': 120, 'p7': 200, '16gb': 75, '32gb': 150,
'1tb': 50, '2tb': 100, '19in': 65, '23in': 120, 'mini': 40,
'midi': 70, '2usb': 10, '4usb': 20
}
stock = {
'p3': 100, 'p5': 100, 'p7': 100, '16gb': 100, '32gb': 100,
'1tb': 100, '2tb': 100, '19in': 100, '23in': 100, 'mini': 100,
'midi': 100, '2usb': 100, '4usb': 100
}
orders = {}
#~ order1 = order(1,'Luke','p5','16gb','1tb','19in','midi','4usb')
#~ print (order1.print_order())
def main():
order1 = order(1,'Luke','p5','16gb','1tb','19in','midi','4usb')
print (order1.print_order())
global componentList
global stock
global orders
while True:
print ('\nEnter "make" to place an order, "view" to view previous orders, "stock" to view the stock levels, and "quit" to quit the program. Quitting the program will lose records of previous orders, please back them up by copying the output from entering "view".')
command = input().lower()
while True:
if command == 'quit':
return False
if command == 'view':
for order in orders:
print (orders[order].print_order()+'\n')
break
if command == 'make':
#~ globals()["order" + str(len(orders)+1)] = place_order()
order1 = order()
if globals()["order" + str(len(orders)+1)] == None:
break
else:
orders[len(orders)+1] = globals()["order" + str(len(orders)+1)]
break
if command == 'stock':
for i in stock:
print(i + ': ' + str(stock[i]))
if command == 'test':
for i in range(10):
globals()["order" + str(i)] = order(i,'Luke','p5','16gb','1tb','19in','midi','4usb')
orders[len(orders)+1] = globals()["order" + str(i)]
else:
print('Invalid option entered please try again')
break
if __name__ == "__main__":
main()