Answer Error, Only outputting Zero - python

I am coding in python and I cannot seem to figure out why when the amount of tickets sold is entered it does not calculate the full price of the tickets that were sold. Any help is appreciated, Thanks.
aLimit=300
bLimit=500
cLimit=100
aPrice=20
bPrice=15
cPrice=10
ticketSold=1
totalIncome=0
def Main():
getTickets(aLimit)
sectionIncome=calcIncome(ticketSold,aPrice)
sectionIncome+=totalIncome
print("The theater generated this much money from section A "+
str(sectionIncome))
getTickets(bLimit)
sectionIncome=calcIncome(ticketSold,bPrice)
sectionIncome+=totalIncome
print("The theater generated this much money from section B "+
str(sectionIncome))
getTickets(cLimit)
sectionIncome=calcIncome(ticketSold,cPrice)
sectionIncome+=totalIncome
print("The theater generated this much money from section C "+
str(sectionIncome))
print("The Theater generated "+str(totalIncome)+" total in ticket sales.")
def getTickets(limit):
ticketSold=int(input("How many tickets were sold? "))
if (ticketsValid(ticketSold,limit)==True):
return ticketSold
else:
getTickets(limit)
def ticketsValid(Sold,limit):
while (Sold>limit or Sold<0):
print("ERROR: There must be tickets less than "+
str(limit)+" and more than 0")
return False
return True
def calcIncome(ticketSold,price):
return ticketSold*price
Main()

How to debug your (small) program
Okay so let's start from the top and go line-by-line. There's a lot of issues here.
aLimit=300
bLimit=500
cLimit=100
aPrice=20
bPrice=15
cPrice=10
ticketSold=1
totalIncome=0
These are all globals since you defined them in the module scope. That's a Bad Thing. Don't do it. If they're constants, use CAPS to mention that, but they should still not be global.
def Main(): # I mentioned in my comment, but Capitals are classes
# by convention, use def main() instead
getTickets(aLimit)
Let's stop and look at getTickets() so we can follow execution
def getTickets(limit): # camelCase is not advised per PEP8, but it's still around
# so I wouldn't worry about this one so much as Capitalized
ticketSold=int(input("How many tickets were sold? "))
# perfect implementation, though be prepared for users who
# will type forty instead of 40!
if (ticketsValid(ticketSold,limit)==True):
return ticketSold
# so any time you write `if ___ == True`, stop and realize that the compare
# is unnecessary. if ticketsValid(ticketSold,limit) works just as well!
else:
getTickets(limit)
# wha-? If the tickets aren't valid, we're RECURSING??! This is an infinite loop.
# are you doing this to prompt for more input if tickets aren't valid? That's Bad
Okay so you invoked ticketsValid in there, so let's look there now...
def ticketsValid(Sold,limit): # another Capital here!
while Sold > limit or Sold < 0: # this should be an if??
print ("...")
return False
return True
# Since you have a set amount, this is MUCH easier written as:
## def ticketsValid(sold,limit):
## return 0 < sold < limit
# but should this be <=?
Alright, back to main--ahem--Main....
def Main():
...
sectionIncome = calcIncome(ticketSold,aPrice)
And hop back to calcIncome
def calcIncome(ticketSold,price):
return ticketSold*price # why not just substitute this???
Main again
def Main():
...
sectionIncome += totalIncome
# this sets sectionIncome equal to the current value of sectionIncome
# plus the current value of totalIncome, which is currently zero.
Then basically the whole thing gets repeated down the function. There's your issue, the += adds zero to sectionIncome instead of adding sectionIncome to totalIncome!
The better way to do this!
Here's the problem. You're trying to use functional programming to do object-oriented tasks. Most of these kind of issues are when new programmers who are interested in video games think that the best task to learn programming is a text adventure. Unfortunately, the best languages for text adventures (those that easily implement a Finite State Machine) are not usually those that beginners start with, so it's hard to implement WELL!
In your case, you should be creating objects to do the workload for you. Python does this elegantly, but it's rarely in beginning tutorials. As an example, I wrote out a bit that does exactly what you did (defines three sections of seating in a theater and sells one ticket per section)
class Section(object):
def __init__(self,price,limit):
self.price = price
self.tickets_sold = 0
self.limit = limit
#property
def sales(self):
return self.price*self.tickets_sold
def sell(self,qty=1):
if not isinstance(qty,int): raise TypeError("Must sell an int of tickets")
if qty < 1: raise ValueError("Must sell positive tickets")
qty = min(qty,self.limit-self.tickets_sold)
self.tickets_sold += qty
# optional print statement for the user
class Theater(object):
def __init__(self,sections):
self.sections = sections
#property
def sales(self):
return sum(section.sales for section in self.sections)
theater = Theater([Section(20,300),
Section(15,500),
Section(10,100)])
for section in theater.sections:
section.sell(1)
print(theater.sales)
The big problem with this is just that you don't know how to do it. Creating an object that will stay constant, then throw several instances of it around with specific attributes is precisely the approach I would favor in this circumstance.

read up on the += operator. totalIncome is only ever set to 0.

You need to replace sectionIncome+=totalIncome with totalIncome+=sectionIncome
Code
aLimit=300
bLimit=500
cLimit=100
aPrice=20
bPrice=15
cPrice=10
ticketSold=1
totalIncome=0
def Main():
getTickets(aLimit)
sectionIncome=calcIncome(ticketSold,aPrice)
totalIncome=sectionIncome
print("The theater generated this much money from section A "+str(sectionIncome))
getTickets(bLimit)
sectionIncome=calcIncome(ticketSold,bPrice)
totalIncome+=sectionIncome
print("The theater generated this much money from section B "+str(sectionIncome))
getTickets(cLimit)
sectionIncome=calcIncome(ticketSold,cPrice)
totalIncome+=sectionIncome
print("The theater generated this much money from section C "+str(sectionIncome))
print("The Theater generated "+str(totalIncome)+" total in ticket sales.")
def getTickets(limit):
ticketSold=int(input("How many tickets were sold? "))
if (ticketsValid(ticketSold,limit)==True):
return ticketSold
else:
getTickets(limit)
def ticketsValid(Sold,limit):
while (Sold>limit or Sold<0):
print ("ERROR: There must be tickets less than "+str(limit)+" and more than 0")
return False
return True
def calcIncome(ticketSold,price):
return ticketSold*price
Main()

sectionIncome+=totalIncome
This is the wrong way around. To add to totalIncome the value of sectionIncome, the syntax is
totalIncome+=sectionIncome
You will allso need to add global totalIncome to the beginning of Main -- or, better yet, do away with the global variables completely, like you have often been told before.
Finally, your getTickets function returns a calculated value, but the code which calls it doesn't store that result anywhere. Instead, you simply set ticketSold=1 in the global initialization, then use that as the multiplier instead of the actual number of tickets input by the user.
As a general observation, you have a lot of repetitive code, while the functions you do have are not very useful (they do not encapsulate complex behavior, nor repeated functionality). If you are a beginner, concentrate on a straightforward flow, then factor out complex repeating operations to loops or functions. Perhaps something like this:
def income ():
total = 0
for ticket_type, limit, price in [('A', 300, 20),
('B', 500, 15),
('C', 100, 10)]:
print "How many %s tickets sold? (Max %d):" % (ticket_type, limit),
sold = -1
while sold < 0 or sold > limit:
if sold != -1:
print "Sorry. Try again:",
sold = raw_input()
try:
sold = int(sold)
except:
pass
total += sold*price
print "total %d" % total
income()
Please also note the user-friendly gesture of indicating the maximum allowed for each category in the input prompt (-:
The loop driver is a bit of a wart; a slicker way to do that would be to declare a class TicketCategory and have three instances A, B, and C with methods to report back their name, price, and available amounts, but that's for later.

Related

Coffee Machine - invalid syntax and End of Statement expected in new function

So I'm trying to create a coffee machine program (you choose a drink, the machine checks the ingredients, the resources and the money you insert, then it dispenses the drink.) and it went okay until I got to the part where the program processes the coins and, if sufficient, adds them to the amount of money in the machine.
I'm not really good with return statements and global vs local scopes, so I assume they are the issue. I tried googling, but nothing came up that actually solves the specific problem I have.
This is the code for the function in question:
def process_coins(order, money):
print("Please insert coins.")
quarters = float(input("Quarters: ")) * quarters_value
dimes = float(input("Dimes: ")) * dimes_value
nickles = float(input("Nickles: ")) * nickles_value
pennies = float(input("Pennies: ")) * pennies_value
total = quarters + dimes + nickles + pennies
if total < MENU[order]["cost"]:
total = 0
return print("Sorry, that's not enough money. Money refunded.")
else:
return money += total
PyCharm tells me "End of Statement expected" and "invalid Syntax" for the last line.
When I remove "return" it runs but doesn't actually add the total to the money in the machine. I also tried putting brackets around money += total, which turns both problems into "unexpected expression syntax".
I honestly don't understand why this doesn't work. I just want pycharm to add "total" (local scope) to "money"(global scope) and to return it so I can use it in the rest of the code.
I also don't understand why this function wasn't able to work with the variable "money" before I added it as an argument in the brackets, but it was able to work with the variables "dimes_value" etc. just fine, even though those are mentioned just one line before "money" at the start of the code and aren't part of the arguments in the bracket of the function.
What am I missing?
The problem is that return can only return expressions, but an augmented assignment is a statement. This is why you get a syntax error.
For Python >= 3.8, you can use an assignment expression to overcome this:
return (money := money + total)
* Note the necessary parenthesis.
This will both assign to money and return the value assigned to it.
But this will create a new problem: money will now be considered a local variable (because you assign to it inside the function) and you'll get a different error.
To overcome this, you will need to declare
global money
At the start of the function.
But really the best solution here is not to use global variables at all, simply return money + total, and assign the returned value in the global scope, where you call the function.
if total < MENU[order]["cost"]:
total = 0
return print("Sorry, that's not enough money. Money refunded.")
else:
money += total
return money

How do I subtract a number with an if-statement?

This is my code:
import sys
import click
def Seats():
global seats
seats = 168
print("\nThe current seating capacity is {}\n".format(seats))
def Restart():
while True:
restart = click.confirm('\nWould you like to subtract 1 from seats?',
default=True)
if restart == True:
x = seats - 1
Seats()
elif restart == False:
print("\nOk, see you next time!\n")
sys.exit()
Seats()
Restart()
I want to ask the user "Would you like to subtract 1 from seats?" and then subtract one from seats variable and then repeat until the users inputs no.
As pointed in the comments, the main problem in your code is here:
def Seats():
global seats
seats = 168
print("\nThe current seating capacity is {}\n".format(seats))
Whenever and wherever you call the function Seats in your code, the value of seats is redefined because seats = 168 gets executed.
With the problem pointed out, I tried to edit your code maintaining the same structure in order to try to show you how to fix the problem, but changed my mind. The code, despite small, has an unnecessarily complex logic and a far from clean syntax. You are a beginner, so there is no problem with that! It is just that, because of that, I thought that showing you another way to implement this algorithm would be more valuable. Here it goes:
import click
seats = 168
while seats > 0:
subtract_seat = click.confirm('\nWould you like to subtract 1 from seats?', default = True)
if subtract_seat:
seats -= 1
print("\nThe current seating capacity is {}\n".format(seats))
else:
break
print("\nOk, see you next time!\n")
Do not need to import the sys library. You are not using it
while seats > 0 avoids subtracting seats when there are no more seats left and is also the main loop used to interact with the user
The else clause will automatically take care if the first condition is not met
There is absolutely no need for functions or global variables in your code. They might be needed if you insert this code in a bigger context, but keep simplicity in mind
#AshidoBestGirl
To get things to work you have to declare seats to be a global variable in the Restart() function and stop resetting it in the Seats() function. It doesn't have to be declared in the version of the Seats() function below because it no longer tries to set or change its value.
To subtract a number from a variable and store the result back into the variable, you need to either do variable = variable - number or use the more succinct variable -= number statement.
Also, when you want to terminate the while loop in Restart() and let it "fall of the end" and return, all you need to do is break out of the while True loop.
Here's your code with those changes:
import click
seats = 168 # Initialize global variable.
def Seats():
print("\nThe current seating capacity is {}\n".format(seats))
def Restart():
global seats
while True:
restart = click.confirm('\nWould you like to subtract 1 from seats?',
default=True)
if restart:
seats -= 1
Seats()
else:
print("\nOk, see you next time!\n")
break
Seats()
Restart()

How can I create a program that count votes that are being put by the user

I need to make 3 political parties like in an election. The program should ask "for which will you vote?" (showing the 3 political options), after 10 the user randomly inserts 10 votes, the program should count the votes and print the results.
I'm new to programming, I really don't know what I'm doing
print("today is election day! for who will u vote?")
polls=print("PLD","PRM","PRD")
1) In your question, you stated "after 10...", after 10 what?
Im assuming that if was just a typo.
Here's the code for the program. All you need to do is figure out how to stop asking once it the vote count is greater than or equal to 10. You learn and retain information best when you struggle, trust me.
If you have any questions about the syntax used, feel free to drop a comment.
parties = ['PLD', 'PRM', 'PRD']
max_votes = 10
num_votes = 0
print('~'*40)
print(f'\n~ Today is election day!\n~ You have {vote_count} votes to use\n~ Use them wisely!\n')
print('~'*40)
print(f' Polical Parties: {parties[:]}')
print('~'*40,'\n')
"""
As declared above, "num_votes" is the variable that is being used to keep
track of how many votes the user has used so far.
The += operator adds the value of the variable on the right to the existing
value of the variable on the left. It would be the same as saying:
>>> num_votes = num_votes + PLD_votes
So, its just saving the number of votes used to the varible "num_votes".
"""
PLD_votes = int(input(f'\nHow many votes for "{parties[0]}": '))
num_votes += PLD_votes
num_votes = input(f'\nHow many votes for "{parties[1]}": ')
num_votes += PRM_votes
PRD_votes = input(f'\nHow many votes for "{parties[2]}": ')
vote_count += PRD_votes
print('Here are the results...\n')
print(f'{parties[0]}: {PLD_votes}\n{parties[1]}: {PRM_votes}\n{parties[2]}: {PLD_votes}')
"""
The use of "f" and "{}" within strings is a way of formating the string to return letters with variables in them.
Example: print(f'Number of votes: {num_votes}') *mind the 'f'*
Here, typing 'f' before the quotations tells the program that you are going to be using "{}" within the string. What goes inside of the curlies "{}" are variables that you want to print along with the string. I prefer this
There are many different ways of accomplishing this:
Concatenation:
>>> print('Number of votes' + num_votes)
Using %d ('d' for numbers; for variable which contain strings you would use '%s'):
>>> print('Number of votes %d')
There are more ways of doing it, I just prefer using {} because to me it seems more straightforward to read.
"""

How to match input with elements in list/dictionary in Python3

I'm very new at coding, and I'm trying to create a shop list with items and prices on it.
That is, once typed in all the items, the function should calculate the sum and stop the moment you exceed the budget.
So I wrote something like:
def shoplist():
list={"apple":30, "orange":20, "milk":60......}
buy=str(input("What do you want to purchase?")
If buy in list:
While sum<=budget:
sum=sum+??
shoplist ()
I really don't know how to match the input of an item with the price in the list...
My first thought is to use 'if', but it's kinda impractical when you have more than 10 items on the list and random inputs.
I'm in desperate need of help....So any suggestions would be nice!! (or if you have a better solution and think me writing it this way is complete garbage... PLEASE let me know what those better solutions are😭😭😭
The code you post will not run in python. list is a builtin and should not be used for a variable name, and is doubly confusing since it refers to a dict object here. input() already returns a str so the cast has no effect. if and while should be lowercase, and there is no indentation, so we have no way of knowing the limits of those statements.
There are so many things wrong, take a look at this:
def shoplist(budget):
prices = {"apple":30, "orange":20, "milk":60}
# Initialise sum
sum = 0
while sum <= budget:
buy = input("What do you want to purchase?")
# Break out of the loop if the user hts <RETURN>
if not buy: break
if buy in prices:
sum += prices[buy] # This gets the price
else:
print("Invalid item", buy)
shoplist(142)
So what have I changed? The budget has to come from somewhere, so I pass it in as a parameter (142, I made that up). I initialise the sum to zero, and I moved the while loop to the outside.
Notice as well lots of whitespace - it makes the code easier to read and has no effect on performance.
Lots of improvements to make. The user should be shown a list of possible items and prices and also how much budget there is left for each purchase. Note as well that it is possible to go over budget since we might only have 30 in the budget but we can still buy milk (which is 60) - we need another check (if statement) in there!
I'll leave the improvements to you. Have fun!
Take a look at this as an example:
# this is a dictionary not a list
# be careful not using python reserved names as variable names
groceries = {
"apple":30,
"orange":20,
"milk":60
}
expenses = 0
budget = 100
cart = []
# while statements, as well as if statements are in lower letter
while expenses < budget:
# input always returns str, no need to cast
user_input = input("What do you want to purchase?")
if user_input not in groceries.keys():
print(f'{user_input} is not available!')
continue
if groceries[user_input] > budget - expenses:
print('You do not have enough budget to buy this')
user_input = input("Are you done shopping?Type 'y' if you are.")
if user_input == 'y':
break
continue
cart.append(user_input)
# this is how you add a number to anotherone
expenses += groceries[user_input]
print("Shopping cart full. You bought {} items and have {} left in your budget.".format(len(cart), budget-expenses))
I've made some changes to your code to make it work, with explanation including using comments indicated by the # symbol.
The two most important things are that all parentheses need to be closed:
fun((x, y) # broken
fun((x, y)) # not broken
and keywords in Python are all lowercase:
if, while, for, not # will work
If, While, For, Not # won't work
You might be confused by True and False, which probably should be lowercase. They've been that way so long that it's too late to change them now.
budget = 100 # You need to initialize variables before using them.
def shoplist():
prices = { # I re-named the price list from list to prices
'apple' : 30, # because list is a reserved keyword. You should only
'orange' : 20, # use the list keyword to initialize list objects.
'milk' : 60, # This type of object is called a dictionary.
} # The dots .... would have caused an error.
# In most programming languages, you need to close all braces ().
# I've renamed buy to item to make it clearer what that variable represents.
item = input('What do you want to purchase? ')
# Also, you don't need to cast the value of input to str;
# it's already a str.
if item in prices:
# If you need an int, you do have to cast from string to int.
count = int(input('How many? '))
cost = count*prices[item] # Access dictionary items using [].
if cost > budget:
print('You can\'t afford that many!')
else:
# You can put data into strings using the % symbol like so:
print('That\'ll be %i.' % cost) # Here %i indicates an int.
else:
print('We don\'t have %s in stock.' % item) # Here %s means str.
shoplist()
A lot of beginners post broken code on StackOverflow without saying that they're getting errors or what those errors are. It's always helpful to post the error messages. Let me know if you have more questions.

I/O python: Handling output and variable

Good day :)
So during the day, I decided to make a gambling simulation. I'm testing a fail gambling strategy (So mine you if you try to tried my method)
Let me show my code, then the whole thing what happened.
from random import randint
winningNumber=0
bankroll=5000
testCase=1
betLevel=0
bettingLevel=[1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987]
town=[]
bet=0
#----------------------------
my_file= open("output.txt","w")
my_file.write(" # Bet Number Outcome bankroll "+"\n")
def startTheSimulation():
print "OK"
for i in range(100):
if bankroll==0:
break
global betLevel
if bankroll < bettingLevel[betLevel]:
betLevel=0
bet= bettingLevel[betLevel]
print "betlevel",betLevel
print "bet",bet
winningNumber= randint(0,36)
print "winningnumber",winningNumber
if winningNumber== 4:
win(bet)
else:
lose(bet)
def win(inbox):
global bankroll
cow= inbox*35
bankroll+=cow
print "OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO"
print "bankroll",bankroll
town=[testCase,bet,winningNumber,"WIN",bankroll]
print town
betLevel=0
writing()
def lose(inbox):
global bankroll
global betLevel
wow= inbox
bankroll-=wow
town=[testCase,bet,winningNumber,"LOSE",bankroll]
betLevel+=1
if betLevel==16:
betLevel=15
writing()
def writing():
global testCase
testCase+=1
print "Hey!"
my_file.write(" ".join(town)+"\n")
startTheSimulation()
my_file.write("On all betting, player bet single bet on one number, which is number 4. How money money bet on number for is indicated.")
my_file.close()
My betting system is a weird one. It works like martingale betting system, but instead of doubling my bet, my next bet is based on Fibonacci sequence.
The parameter betLevel is used to decide how many should I bet. The bettingLevel shows the list of the Fibonnaci sequence.
Here comes trouble
Trouble #1:
My output contains blank line
The desired output file is this
& Bet Number Outcome bankroll
# 100 lines of information
On all betting, player bet single bet on one number, which is number 4. How money money bet on number for is indicated.
However, I in turn got this
& Bet Number Outcome bankroll
# 100 BLANK LINES
On all betting, player bet single bet on one number, which is number 4. How money money bet on number for is indicated.
My debugging process:
I actually print the list town. The list if filled (not empty). No other improvement.
Trouble #2: (Solved by using function with arguments.)
My bank roll doesn't update.
My debugging process:
I figured out the problem.
Notice the win function. When I print (int(35)*int(bet)). It turns out to return 0, causing the bankroll not moving.
HOWEVER
When I print "bet",bet in the startTheSimulation() function, it prints the right number. I'm stucked here.
That's my 2 biggest problem. Any help is appreciated.
PS: I use global to avoid UnBoundLocalError
PPS: I use Python 2.7.6
Your logic seems quite convoluted for a fairly simple process. Also, you write things like int(35), that tell me you just came to Python from another language (IDL, perhaps?).
If you are using this as an exercise to learn, I can give you a few hints on how to solve it:
First of all, global variables are almost always a bad idea. If you need to use one, you are probably doing something wrong. The proper way of sharing this information is creating a class. Something like this (very incomplete)
class Simulation(object):
def __init__(self, bankroll):
self.betlevel = 0
self.betting = [1, 1, 2, 3, 5] # You should actually generate this on the fly
self.bankroll = bankroll
self.outputfile = open('filename.txt', 'w')
def do_bet(self):
self.bet = self.betting[self.betlevel]
luckynumber = random.randint()
mynumber = random.randint()
if mynumber == luckynumber:
self.win()
def win(self):
self.bankroll -= self.bet
self.outputfile.write('I won:' + str(self.bet))
The idea is that the class methods have access to the class attributes, so you totally avoid global variables, and reduce the possibility of mistake.
Try to complete the implementation. Once you have it, you can post it again and we can see if there are improvements.
Trouble #1:
you didn't set town as global, so this will print correctly:
town=[testCase,bet,winningNumber,"WIN",bankroll]
print town
, but in writing() method town is empty, and that's why you get 100 empty lines
here is example:
#global town #uncomment if you want to change "town" in "one()"
town = ["not", "changed", "town"]
def one():
#global town #uncomment if you want to change "town" here
town = [1,"local", "town", True]
print "local -> ", town
def two():
# you don't need "global town" here because you do not change it, you only use it
print town
one()
two()
this is output:
local -> [1, 'local', 'town', True]
['not', 'changed', 'town']
Trouble #2:
similar as trouble #1, in startTheSimulation(): you need to write global bet , otherwise bet is local variable and never gets changed, that's why it's 0 in your win() method.
Those are solutions for your problems , but consider creating a class, like #davidmh said...global variables are almost always a bad idea

Categories

Resources