I am trying to get the first_name and last_name to combine together into a new dictionary entry. How many depends on how many people buy in the shop. If I buy 50 troops I always receive less than that.
import random, math
first_name = [ "Emily", "Steve" , "Dave" , "Bob" , "James" , "Jim" , "Jenny" , "Will" , "Ryan" ]
last_name = [ "Wright" , "Kalman" , "Meitzen" , "Cole" , "Robins" , "Harrison" , "Saturn" ]
troops = {}
money = 1000
def shop():
loop = 0
global money, first_name, last_name, troops
while loop == 0 :
print("""
Your Money = {}
(Number , Item , cost)
0, Quit ,N/A
1, Troop, 10
""".format(money))
shopq = int( input("What do you want to buy"))
if shopq == 1:
shopq2 = int( input("How many"))
if shopq2 > money :
print(" You cannot by this many")
else:
print("You can buy that many")
money = money - shopq2
troop_number = 0
while troop_number < shopq2 :
s_name = random.choice(first_name) + " " + random.choice(last_name)
troops[s_name] = 100
troop_number = troop_number + 1
print(troops)
print(" Money = {}".format(money))
elif shopq == 0:
break
class dropship:
def create(self, troops):
troop_number = 0
for k in troops :
troop_number = troop_number + 1
print("troops = {}".format(troop_number))
shop()
x = dropship()
x.create(troops)
Output:
Your Money = 1000
(Number , Item , cost)
0, Quit ,N/A
1, Troop, 10
What do you want to buy1
How many50
You can buy that many
{'Ryan Wright': 100, 'Bob Cole': 100, 'Bob Kalman': 100, 'Will Wright': 100, 'Dave Cole': 100, 'Dave Robins': 100, 'Emily Kalman': 100, 'Jenny Kalman': 100, 'Bob Harrison': 100, 'Emily Wright': 100, 'Will Cole': 100, 'Jim Wright': 100, 'Dave Kalman': 100, 'Dave Wright': 100, 'Bob Meitzen': 100, 'Jenny Wright': 100, 'Jenny Harrison': 100, 'Dave Saturn': 100, 'James Robins': 100, 'Bob Robins': 100, 'Dave Meitzen': 100, 'Steve Wright': 100, 'Bob Wright': 100, 'Steve Kalman': 100, 'Ryan Harrison': 100, 'Jim Saturn': 100, 'Steve Robins': 100, 'Ryan Cole': 100, 'Jim Meitzen': 100, 'James Cole': 100, 'Emily Cole': 100, 'Ryan Saturn': 100, 'Steve Harrison': 100}
Money = 950
Your Money = 950
(Number , Item , cost)
0, Quit ,N/A
1, Troop, 10
What do you want to buy0
troops = 33
You are creating random names and some of them will be the same, by chance, so they replace the previous entries in the dictionary (dictionary keys are unique). You'll have to change the way you do that. For instance:
import random
import itertools
random.sample(list(itertools.product(first_name, last_name)), 50)
But you should also get much larger pools of first and last names, otherwise you can only have 63 different full names.
The problem with your dictionary is that dictionary keys must be unique. Since you are using randomly chosen names spliced together as keys, it is very likely that you will generate 'Ryan Wright' (for example) more than once.
Here is what your code is doing that is causing you to come up with a "short" count:
troops['Ryan Wright'] = 100
troops['Bob Cole'] = 100
troops['Ryan Wright'] = 100
The third assignment used the same slot in the dictionary troops because the key is the same. If your code was just those three lines you'd have a dictionary with two entries in it, not the three that you'd hope for. You can see this happen in your code by adding the assert statement:
s_name = random.choice(first_name) + " " + random.choice(last_name)
assert s_name not in troops
troops[s_name] = 100
It won't fix your problem, but it will show you that your keys are colliding.
Related
So I'm very new to Python programming and just testing out some stuff in classes and methods.
Im writing a program for a restaurant that have 4 dictionaries that contains key=food and value=price
The dict's are stored in brunch_items, early_bird_items, dinner_items and kids_items, and then I created a object for each of them to my Menu class.
from main import *
dinner_items = {
'crostini with eggplant caponata': 13.00,
'caesar salad': 16.00,
'pizza with quattro formaggi': 11.00,
'duck ragu': 19.50,
'mushroom ravioli (vegan)': 13.50, 'coffee': 2.00, 'espresso': 3.00,
}
kids_items = {
'chicken nuggets': 6.50,
'fusilli with wild mushrooms': 12.00,
'apple juice': 3.00
}
brunch_menu = Menu("Brunch Menu", brunch_items, 1100, 1600)
early_bird_menu = Menu("Early Bird Menu", early_bird_items, 1500, 1800)
dinner_menu = Menu("Dinner Menu", dinner_items, 1700, 1100)
kids_menu = Menu("Kids Menu", kids_items, 1100, 2100)
print(brunch_menu.calculate_bill(["pancakes", "waffles"]))
In the Menu class have the method that returns the different menus and when they are available.
The next method is calculating the bill and return the price for the items.
Output from printing the bill: 16.5
class Menu:
def __init__(self, name, items, start_time, end_time):
self.name = name
self.items = items
self.start_time = start_time
self.end_time = end_time
self.daily_income = 0
def __repr__(self):
return "{} is available from {} - {}".format(self.name, self.start_time, self.end_time)
def calculate_bill(self, purchased_items):
bill = 0
for purchased_item in purchased_items:
if (purchased_item in self.items):
bill += self.items[purchased_item]
return bill
def total_income(self, purchased_items):
return self.daily_income + purchased_items
I dont know where this is going, but the problem is to define a method that takes the calculated bill and store it to a daily income/profit from the purchased items. The idea is to store the total sum from bills
I tried to make self.daily_income = 0 and eventually return that to a variable that keep tracking the payments
Any suggestions to help out?
There are some modeling choices that you have made that I think you will want to revisit, but with light changes to your code you can get a running total by moving daily_income from an instance variable to a shared variable.
class Menu:
daily_income = 0 # shared between all instances
def __init__(self, name, items, start_time, end_time):
self.name = name
self.items = items
self.start_time = start_time
self.end_time = end_time
def __repr__(self):
return "{} is available from {} - {}".format(self.name, self.start_time, self.end_time)
def calculate_bill(self, purchased_items):
bill = 0
for purchased_item in purchased_items:
if (purchased_item in self.items):
bill += self.items[purchased_item]
Menu.daily_income + bill ## Update the shared total
return bill
dinner_items = {
'crostini with eggplant caponata': 13.00,
'caesar salad': 16.00,
'pizza with quattro formaggi': 11.00,
'duck ragu': 19.50,
'mushroom ravioli (vegan)': 13.50, 'coffee': 2.00, 'espresso': 3.00,
}
kids_items = {
'chicken nuggets': 6.50,
'fusilli with wild mushrooms': 12.00,
'apple juice': 3.00
}
## ---------------------------
## Simulate table A
## ---------------------------
my_bill = Menu("Dinner Menu", dinner_items, 1700, 1100).calculate_bill(["caesar salad", "duck ragu"])
my_bill += Menu("Kids Menu", kids_items, 1100, 2100).calculate_bill(["chicken nuggets"])
Menu.daily_income += my_bill
print(f"Total Table Bill: ${my_bill}. Our revenue so far: ${Menu.daily_income}")
## ---------------------------
## ---------------------------
## Simulate table B
## ---------------------------
my_bill = Menu("Dinner Menu", dinner_items, 1700, 1100).calculate_bill(["pizza with quattro formaggi"])
Menu.daily_income += my_bill
print(f"Total Table Bill: ${my_bill}. Our revenue so far: ${Menu.daily_income}")
## ---------------------------
That should give you:
Total Table Bill: $42.0. Our revenue so far: $42.0
Total Table Bill: $11.0. Our revenue so far: $53.0
I am a beginner in programming and I'm working on the projects in Automate the Boring Stuff with Python, In the book there is a project to create a sandwich, then return the total cost. I want to add to my program by providing an itemized receipt. For example, if I put in an order for 1 sandwich with wheat and chicken and 3 sandwiches with white and turkey, the receipt should show something like this (I will format it better when I figure it out):
1 sandwich ---3.5
wheat, chicken
3 sandwich ---10.5.
white, turkey
Total --- 14.00
My challenge is storing the different sandwich orders into different variables and printing them out at the end.
My code below:
menu = {
'wheat': 1.5, 'white': 1, 'sourdough': 2,
'chicken': 2, 'turkey': 2.5, 'ham': 2, 'tofu': 3,
'cheddar': 0.5, 'mozzarella': 0.25, 'american': 0.5,
'mayo': 0.25, 'mustard': 0.25, 'lettuce': 0.5, 'tomato': 0.5
}
total = 0.0
subtotal = 0.0
while True:
order = {}
print('What bread would you like?')
order['bread'] = pyip.inputChoice(['wheat', 'white', 'sourdough'])
print('How about for your protein?')
order['protein'] = pyip.inputChoice(['chicken', 'turkey', 'ham', 'tofu'])
wantCheese = pyip.inputYesNo('Would you like cheese on the sandwich?')
if wantCheese == 'yes':
order['cheese'] = pyip.inputChoice(['cheddar', 'mozzarella', 'american'])
wantToppings = pyip.inputYesNo('Would you like to add extra toppings?')
if wantToppings == 'yes':
while True:
order['side'] = pyip.inputChoice(['mayo', 'mustard', 'lettuce', 'tomato'])
anotherTopping = pyip.inputYesNo('Would you like another topping?')
if anotherTopping == 'no':
break
orderNumber = pyip.inputInt('How many of those sandwiches would you like? ', min = 1)
for choice in order:
if order[choice] in menu.keys():
subtotal += menu[order[choice]]
total *= orderNumber
total += subtotal
subtotal = 0
anotherOrder = pyip.inputYesNo('Would you like to order another sandwich?')
if anotherOrder == 'no':
break
print(total)
Adjust the following as you see fit. FYI, while coding this up I had "let's get this to work" in mind as opposed to "let's make this as efficient as possible". Moreover, you should format the receipt however you like.
Importantly, I created a list called orders just before the while that will be used to store orders. The form of the elements of orders will be 3-tuples where the first element of the 3-tuple records orderNumber, the third element records the subtotal, and the second element is an order dictionary, just as in your original code, except order["side"] will be a list as this allows for multiple additional toppings to be added. For the sample output below, orders is
[(2, {'bread': 'wheat', 'protein': 'chicken', 'cheese': 'cheddar', 'side': ['mustard', 'lettuce']}, 9.5), (1, {'bread': 'sourdough', 'protein': 'turkey', 'side': []}, 4.5)]
As you can see, there are 2 orders of 'wheat', 'chicken', 'cheddar', 'mustard', 'lettuce' (subtotal 9.5) and 1 order of 'sourdough', 'turkey' (subtotal 4.5).
I hope this helps. Any questions please let me know.
import pyinputplus as pyip
menu = {'wheat': 1.5, 'white': 1, 'sourdough': 2,
'chicken': 2, 'turkey': 2.5, 'ham': 2, 'tofu': 3,
'cheddar': 0.5, 'mozzarella': 0.25, 'american': 0.5,
'mayo': 0.25, 'mustard': 0.25, 'lettuce': 0.5, 'tomato': 0.5
}
orders = []
while True:
order = {}
# choose bread
print("What bread would you like?")
order['bread'] = pyip.inputChoice(['wheat', 'white', 'sourdough'])
# choose protein
print("How about for your protein?")
order['protein'] = pyip.inputChoice(['chicken', 'turkey', 'ham', 'tofu'])
# choose cheese
wantCheese = pyip.inputYesNo("Would you like cheese on the sandwich?")
if wantCheese == 'yes':
order['cheese'] = pyip.inputChoice(['cheddar', 'mozzarella', 'american'])
# choose extra toppings
order["side"] = []
wantToppings = pyip.inputYesNo("Would you like to add extra toppings?")
if wantToppings == 'yes':
while True:
order["side"].append(pyip.inputChoice(
['mayo', 'mustard', 'lettuce', 'tomato']))
anotherTopping = pyip.inputYesNo("Would you like another topping?")
if anotherTopping == 'no':
break
# order number
orderNumber = pyip.inputInt(
"How many of those sandwiches would you like?", min = 1)
# subtotal
subtotal = sum(menu[order[key]] for key in order if key != 'side')
subtotal += sum(menu[j] for j in order['side'])
subtotal *= orderNumber
# add 3-tuple to orders list
orders.append((orderNumber, order, subtotal))
# another order?
anotherOrder = pyip.inputYesNo("Would you like to order another sandwich?")
if anotherOrder == 'no':
break
# add subtotals to form total
total = sum(order[2] for order in orders)
# print orders (for programmer use)
print(f"\nOrders: {orders}")
# print receipt
print(f"\nReceipt\n")
for order in orders:
print(f"{order[0]} sandwich ---{order[2]}")
print(" ", end = "")
for key in order[1]:
if isinstance(order[1][key], list):
for x in order[1][key]:
print(x, end = ", ")
else:
print(order[1][key], end = ", ")
print("\n")
print(f"Total --- {total}")
Sample output:
Receipt
2 sandwich ---9.5
wheat, chicken, cheddar, mustard, lettuce,
1 sandwich ---4.5
sourdough, turkey,
Total --- 14.0
list_A = [['STEVEN', 200], ['SUSAN', 100], ['NICRO', 115], ['MIKE', 320], ['JOHN', 50], ['GIGEE', 270]]
I want to search for name: search_name = "NICRO"
and program will give me: pocket_money = 115
after that I do need to update the values
addition_money = 9000
update_money = pocket_money + addition_money
then put it back to the list
list_A = [['STEVEN', 200], ['SUSAN', 100], ['NICRO', 9115], ['MIKE', 320], ['JOHN', 50], ['GIGEE', 270]]
How to do this code.
New question is if I do need to looking for: search_name = "MJ"
but in list_A doesn't have MJ so I do need to add it to the list
list_A = [['STEVEN', 200], ['SUSAN', 100], ['NICRO', 115], ['MIKE', 320], ['JOHN', 50], ['GIGEE', 270], ['MJ', 9000]]
Search for money:
name = input("Enter name: ")
for i in list_A:
if i[0] == name:
print(i[1])
Update money:
name = "NICRO"
additional_money = 9000
for i in range(len(list_A)): #can't use for i in list_A because need index for reference
if list_A[i][0] == name:
list_A[i][1] += additional_money
break
if i == len(list_A)-1: # only run when all items has been scanned (since there's break)
list_A.append([name, additional_money])
I am wondering if I did correctly. The "Print to screen if show = True", is confusing me a bit on how to implement into my code so the rest of my functions will work properly.
# Display results of scenario
def display_flow(show, # print to screen if show = True`
scen_year,
age,
s_bal,
bal_pv,
inv_gains,
ann_savings,
ss_payment,
major_inc,
major_exp,
tax_rate,
tar_ret_spend,
net_ret_spend,
ret_pre_tax_spend,
taxes,
end_bal
):
""" display_flow() test output
>>> display_flow(show = True,
... scen_year = 0,
... age = 60,
... s_bal = 100000,
... bal_pv = 100000,
... inv_gains = 1000,
... ann_savings = 1000,
... ss_payment = 1000,
... major_inc = 1000,
... major_exp = 1000,
... tax_rate = 0.15,
... tar_ret_spend = 50000,
... net_ret_spend = 40000,
... ret_pre_tax_spend = 60000,
... taxes = 10000,
... end_bal = 120000
... )
Year : 0
Age : 60
Start Bal : 100,000.00
Start Bal PV : 100,000.00
Invest Gains : 1,000.00
Ann Savings : 1,000.00
SS Payment : 1,000.00
Major Inc : 1,000.00
Major Exp : 1,000.00
Tax Rate : 15.00%
Targ Ret Spend : 50,000.00
Net Ret Spend : 40,000.00
Ret Pre-tax Spend: 60,000.00
Taxes : 10,000.00
End Bal : 120,000.00
"""
#==============================================================================================
print(' Year :' , scen_year,
'\n Age :',age,
'\n Start Bal :', (format(s_bal, ',.2f')),
'\n Start Bal PV :', (format(bal_pv, ',.2f')),
'\n Invest Gains :', (format(inv_gains, ',.2f')),
'\n Ann Savings :', (format(ann_savings,',.2f')),
'\n SS Payment :', (format(ss_payment, ',.2f')),
'\n Major Inc :', (format(major_inc, ',.2f')),
'\n Major Exp :', (format(major_exp, ',.2f')),
'\n Tax Rate :', (format(tax_rate, '.2%')),
'\n Targ Ret Spend :', (format(tar_ret_spend, ',.2f')),
'\n Net Ret Spend :', (format(net_ret_spend, ',.2f')),
'\n Ret Pre-tax Spend :', (format(ret_pre_tax_spend, ',.2f')),
'\n Taxes :', (format(taxes, ',.2f')),
'\n End Bal :', (format(end_bal, ',.2f')))
#==============================================================================================
# test function
display_flow(show = True,
scen_year = 0,
age = 60,
s_bal = 100000,
bal_pv = 100000,
inv_gains = 1000,
ann_savings = 1000,
ss_payment = 1000,
major_inc = 1000,
major_exp = 1000,
tax_rate = 0.15,
tar_ret_spend = 50000,
net_ret_spend = 40000,
ret_pre_tax_spend = 60000,
taxes = 10000,
end_bal = 120000
)
The output I receive is exactly what i need. But basically wondering if I need the if show=True. My code is in between the long comment sections of "===".
Everything below it and above it are ways to test my code and parameters I need.
Apologies if made any mistakes on this post, this is my first time posting here asking for help. :(
You do not need show if you always want to print.
If you want to have the option of show then you need an conditional, if else, in your code
If show:
print()
I assume you already know using a print will return a string and not the dictionary you have created. If you need it as dict wrap it in {} and use a return instead of print if you need it like a dictionary
I am making a seating app in Python which takes a list of 10 names and gives every student a seat. The seats are 2 row of 5 seats.
I wrote a simple script to do that, but I am stuck at looping the seats for the students. Here is my code:
from pprint import pprint as pp
C = "ABCDE"
R = range(0, 2)
students= ["rob", "tim", "kaleb", "josh", "victoria", "amy", "fred", "xander", "cody", "dump man"]
seats = [{str(y)+ltr:"EMPTY" for ltr in C} for y in R]
for names in range(10):
for i in range(2):
for letters in C:
for s in range(1):
print(f'{i}{letters}')
seats[i][f"{i}{letters}"]=students[names]
pp(seats)
As you can see, at the loop I am iterating over the letters and numbers of SEATS. However, when coming to iterate of students names, it always gives me 10. Can you please help!
This should work:
C = "ABCDE"
number_of_rows = 2
R = range(number_of_rows)
seats_per_row = 5
students= ["rob", "tim", "kaleb", "josh", "victoria", "amy", "fred", "xander", "cody", "dump man"]
seats = [{str(y)+ltr:"EMPTY" for ltr in C} for y in R]
for row in range(number_of_rows):
for seat in range(seats_per_row):
letter = C[seat]
name = students[row * seats_per_row + seat]
seats[row][f"{row}{letter}"]=name
print(seats)
OUTPUT:
[{'0A': 'rob', '0B': 'tim', '0C': 'kaleb', '0D': 'josh', '0E': 'victoria'}, {'1A': 'amy', '1B': 'fred', '1C': 'xander', '1D': 'cody', '1E': 'dump man'}]