Variables not gaining value in subroutines - python

The total cost wont print or gain value. I've tried running the subroutines separately but that didn't work. It will not print totalcost at all:
#coffee maker program
print("Welcome to the BartSucks Coffee App")
print("We will guide you through the ordering process")
print("And our amazing Barista 'Simpson' will then serve you")
name = input("Please type in your name: ")
print("Would you like small, medium or large?")
size = input("Type s for small\nType m for medium\nType l for large\n")
while size.upper() not in ("S","M","L"):
print("You must enter s, m or l")
size = input("Please try again\n")
print("Would you like zero,one, two or three spoons of sugar?")
sugars = input("Type 0 for none\nType 1 for one\nType 2 for two\nType 3 for three\n")
while sugars not in ("0","1","2","3"):
print("You must enter 0, 1, 2 or 3")
sugars = input("Please try again\n")
print("Would you like no syrup flavouring?")
print ("Or would you like almond, vanilla or butterscotch syrup?")
flavour = input("n = none\na = almond\nv = vanilla\nb = butterscotch\n")
while flavour.upper() not in ("N","A","V","B"):
print("You must enter n, a, v or b")
flavour = input("Please try again\n")
totalcost=0
def CoffeeSize(cs):
cs=cs.upper()
global totalcost
if size =="S" or size=="s":
totalcost+= 2.5
elif size=="M" or size=="m":
totalcost+=3.0
elif size=="L" or size=="l":
totalcost+= 3.5
def SugarAmount(sa):
sa=sa.upper()
global totalcost
if sugars=="0":
totalcost+= 0
elif sugars=="1":
totalcost+= 0.5
elif sugars=="2":
totalcost+= 1.0
elif sugars=="3":
totalcost+= 1.5
def flavour(fl):
fl=fl.upper()
global totalcost
if flavour=="NONE" or flavour=="none":
totalcost+= 0
elif flavour=="BS" or flavour=="bs":
totalcost+= 1.6
elif flavour=="V" or flavour=="v":
totalcost+= 0.75
elif flavour=="A" or flavour=="a":
totalcost+= 1.0
CoffeeSize(cs)
SugarAmount(sa)
flavour(fl)
print(totalcost)

sorry im quite new to this so correct me if im wrong but i think the problem is that you are calling the functions inside a function which isnt being executed?
Also, everything apart from anything under 'if','def'... etc statements should be on the first indentation level
Your code:
totalcost=0
def flavour(fl):
...
...
CoffeeSize(cs)
SugarAmount(sa)
flavour(fl)
print(totalcost)
In Python, indentations are important and define under what statement it runs over.
As you can see, you are calling the functions on the same indentation level as the code underneath the function 'flavour', therefore it wont get executed as there isnt any other place that calls that function. Try and put this at the end of your program instead:
Code:
if __name__ == '__main__':
CoffeeSize(cs)
SugarAmount(sa)
flavour(fl)
print(totalcost)
What this does is checks to see if the program is the main program instead of being imported by something else. If it is the main/'_ main _' program, it will go from the start, ask the users what they want and then check to see if this program is the main one, then executes all the functions that are listed under the if statement.
Sorry if i misinterpreted your problem but i think that's what the problem is from my perspective :)
Thanks!

Related

Changing a local variable in multiple functions in Python?

background: I'm currently writing a text-based adventure and each enemy has a certain amount of turns you can attack it before it attacks back.
So to handle this the code sets an argument in the function for the fight dictating how many times you can attack.
def fight_sequence(rounds):
while rounds > 0:
attack = input()
if attack == magic:
magic("you teleport away to safety. Congratulations you have stayed alive through your journey and found a few souvenoirs. nice job!", 1, "you muster up all of your energy, chant the spell.... and nothing happens.Cthulu... seems unimpressed", 1, "")
elif attack == sword:
sword(1)
def magic(teleportmessage, teleportsuccess, firemessage, firefail, winmessage):
x = 0
while x == 0:
fightorflight = input("""you open the book to cast a spell
Do you want to try teleporting or use a fireball?""").lower()
if "teleport" in fightorflight:
if teleportsuccess = 1:
print(teleportmessage)
x = 1
else:
choice = input("You can't teleport out of this battle. Would you like to try a fireball?")
if choice == yes:
fightorflight = "fireball"
else:
x = 1
elif "fire" in fightorflight:
print(firemessage)
if firefail == 1:
choice = input("do you want to try to teleport instead?").lower()
if "yes" in choice:
fightorflight = "teleport"
else:
x = 1
else:
print(winmessage)
else:
print("Sorry not sure what you mean")
def sword(attacksuccess):
if attacksuccess == 1:
print("You pull out the sword and swing at the monster damaging it severely.")
else:
print("You pull out the sword and swing at the monster, but its immune to blunt objects.")
fight_sequence(3)
both magic() and sword() need to be able to decrease rounds by 1, originally i just did that before entering the magic or sword function. however some items to attack with allow you to attack more than once if you want so that won't work for them. Such as magic if they also choose to teleport. Is there a way to allow me to change the variable rounds while inside of another function?
I think using a return value might help but I'm not sure how to go about it
You can simply add a new argument to the magic function, and pass the 'rounds' variable through when you call it.
e.g.
def fight_sequence(rounds):
...
magic("some message", false, "fired", false, "you won", rounds)
def magic(teleportmessage, teleportsuccess, firemessage, firefail, winmessage, rounds):
Your passing through the variable (not just the value) so it will change in every context where rounds can be seen.
HTH.
I would recommend using classes to create this game rather than lots of functions, an example of a class in a hero game below.
class Hero:
def __init__(self):
self.health = 10
def eatApple(self):
self.health += 1
def takeDamage(self):
self.health -= 1
init function runs as class is initialized.
player = Hero()
print(player.health) # will print 10
player.takeDamage()
print(player.health) # will print 9
This way you can have global variables for you functions which can be changed in each function and is much more organised.

Program meant to go to a function but instead follows try and except loop

I have decided to make a basic game in Python 3.3 where the a monster and a treasure is generated individually on a number from 1-100, and the user has to choose a number. The program will then inform the user if they are too close or too high or if they have hit something.
I have made a try loop with an except NameError (as I am on Mac, it would be ValueError for Windows). Before I ask anything, I would like to share with you the code that I have so far:
import time, random
def generateValues():
global treasurePos, monsterPos
while treasurePos != monsterPos:
treasurePos = random.randint(1, 100)
monsterPos = random.randint(1, 100)
print(treasurePos)
print(monsterPos)
def mainmenu():
time.sleep(0.5)
print("welcome to this game, press 1 to play or 2 to quit")
time.sleep(0.5)
try:
option = int(input("What would you like to do: "))
if option == (1):
time.sleep(0.5)
generateValues()
elif option == (2):
quit()
except NameError:
time.sleep(0.5)
print("please enter only 1 or 2")
mainmenu()
If I enter 1, my original plan was for the game to continue and generate the positons for the treasure and the monster. What the program does, instead, is loop back to this:
except NameError:
time.sleep(0.5)
print("please enter only 1 or 2")
Which further creates an infinite loop of 'please enter only 1 or 2' - even when I do enter 1.
My question is thus, is there a simple or complex command that I can do to stop this loop from continuing and to allow the program to continue to the 'generateValues' function?
I would appreciate any help or insight that you are willing to share.
Thanks in advance,
Leo
EDIT 1:
Karen Clark pointed out my while loop and I have coded an alternative solution for it below which works:
def generateValues():
global treasurePos, monsterPos
treasurePos = 0
monsterPos = 0
treasurePos = random.randint(1, 3)
monsterPos = random.randint(1, 5)
if treasurePos == monsterPos:
generateValues()
else:
print(treasurePos)
print(monsterPos)
The problem is in the generateValues() function. You need to initizalize both treasurePos and monsterPos to work. Try this:
def generateValues():
global treasurePos, monsterPos
treasurePos = 10
monsterPos = 1
while treasurePos != monsterPos:
treasurePos = random.randint(1, 100)
monsterPos = random.randint(1, 100)
print(treasurePos)
print(monsterPos)
Just make sure to give them different values. If, not the code won't enter the loop.
You have a typo when calling generateCharPosition(). The function definition is correct, but the calls are missing an "i" - generateCharPosition

Problems transferring information from one part of a function to another

While working on my program I have run into a problem where the information stored in Menu option 1 is not being transferred to Menu option 2. As you can see it is correctly stored when in menu one. When it returns to go to menu option 2 its like it never went to option 1.
update #1:
some suggestions I've had is to understand scope? from what I can tell the program is not passing the data along to its parent program even though I've typed out return in each of the definitions.
#Must be able to store at least 4 grades
#Each class can have up to 6 tests and 8 hw's
#Weighted 40%*testavg 40% hw average attendance is 20%
#User must be able to input a minimum grade warning
#after each test the your program must calculate the students average and issue warning if necessary
##Define the Modules##
import math
def menu (a): #2nd thing to happen
menuend = 'a'
while menuend not in 'e':
menuend = raw_input("Type anything other then 'e' to continue:\n")
print "What would you like to do ?"
menudo = 0
print "1 - Enter Courses\n2 - Select Course to Edit\n3 - Save File\n4 - Load File\n5 - Exit\n"
menudo = input("Enter Selection:")
if (menudo == 1):
menuchck = 0
menuchck = raw_input("\nYou have entered #1 (y/n)?:\n")
if menuchck in ["Yes","yes","y","Y"]:
x = m1()
else:
print "I'm sorry,",nam,",for the confusion, lets try again\n"
menu()
elif (menudo == 2):
menuchck1 = 0
menuchck1 = raw_input("\nYou have entered #2 (y/n)?:\n")
if menuchck1 in ["Yes","yes","y","Y"]:
x = m2()
else:
print "I'm sorry,",nam,",for the confusion, lets try again\n"
menu()
elif (menudo == 3):
print "Entered 3"
elif (menudo == 4):
print "Entered 4"
else:
print "Anything Else Entered"
def course(): #3rd thing to happen
b = {}
while True:
while True:
print "\n",name,", please enter your courses below ('e' to end):"
coursename = raw_input("Course Name:")
if (coursename == 'e'):
break
will = None
while will not in ('y','n'):
will = raw_input('Ok for this name : %s ? (y/n)' % coursename)
if will=='y':
b[coursename] = {}
print "\n",name,", current course load:\n",b
coursechck = None
while coursechck not in ('y','n'):
coursechck = raw_input("Are your courses correct (y/n)")
if coursechck =='y':
return b
else:
b = {}
print
##Menu Options##
def m1():
a = course()
return a
def m2():
print "Excellent",name,"lets see what courses your enrolled in\n"
print x
return x
###User Input Section###
name = raw_input("Enter Students Name:\n")
a = {}
menu(a)
raw_input("This is the end, my only friend the end")
In your if-elif blocks in the do==1 case, you write m1(), but for the last case, you write x=m1(). You should have the latter everywhere (by typing m1() you only run the function, but do not store the returned x anywhere).
By the way, you can avoid this if-elif confusion using if chck in ["Yes","yes","Y","y"]:

How do I add a number to another everytime a loop repeats

So at school, our teacher asked us to make a program which needs a password to grant access. I have made this however i would like to improve on it by adding a loop count which increase each time it loops round heres what i have so far for the loop count, however it doesn't work.
import time
b=0
a='apple'
def start():
print("enter password")
c=input("-> ")
if c==a:
grant()
else:
delay()
def grant():
end
def delay():
b=b+1
time.sleep(b)
start()
start()
Your problem is inside here:
def delay():
b=b+1
time.sleep(b)
start()
When you do b = b + 1, you're expecting the b variable at the top of the file to increase by 1, right?
You probably haven't learned this yet, but the reason why this doesn't work is because of something called scope.
To fix it, you need to change your delay function to look like this:
def delay():
global b
b=b+1
time.sleep(b)
start()
From looking at your code, I take it you haven't learned how to use while loops yet?
Your solution of repeatedly calling start inside of delay is actually pretty clever. However, if we use a while loop, we can rewrite your program so that it's a little cleaner and more obvious as to what you're trying to do:
import time
password = 'apple'
def start():
counter = 0
user_guess = ''
while user_guess != password:
print("enter password")
user_guess = input("-> ")
if user_guess != password:
counter += + 1 # Same thing as doing `counter = counter + 1`
time.sleep(counter)
grant()
def grant():
print "Access granted!"
start()
Python doesn't recognize b in delay() because it is in global scope.
Try this:
def delay():
global b
b=b+1
time.sleep(b)
start()

Python custom modules - error with example code

I am reading the book "Python Programming for the Absolute Beginner (3rd edition)". I am in the chapter introducing custom modules and I believe this may be an error in the coding in the book, because I have checked it 5 or 6 times and matched it exactly.
First we have a custom module games.py
class Player(object):
""" A player for a game. """
def __init__(self, name, score = 0):
self.name = name
self.score = score
def __str__(self):
rep = self.name + ":\t" + str(self.score)
return rep
def ask_yes_no(question):
""" Ask a yes or no question. """
response = None
while response not in ("y", "n"):
response = input(question).lower()
return response
def ask_number(question, low, high):
""" Ask for a number within a range """
response = None
while response not in range (low, high):
response = int(input(question))
return response
if __name__ == "__main__":
print("You ran this module directly (and did not 'import' it).")
input("\n\nPress the enter key to exit.")
And now the SimpleGame.py
import games, random
print("Welcome to the world's simplest game!\n")
again = None
while again != "n":
players = []
num = games.ask_number(question = "How many players? (2 - 5): ", low = 2, high = 5)
for i in range(num):
name = input("Player name: ")
score = random.randrange(100) + 1
player = games.Player(name, score)
players.append(player)
print("\nHere are the game results:")
for player in players:
print(player)
again = games.ask_yes_no("\nDo you want to play again? (y/n): ")
input("\n\nPress the enter key to exit.")
So this is exactly how the code appears in the book. When I run the program I get the error IndentationError at for i in range(num):. I expected this would happen so I changed it and removed 1 tab or 4 spaces in front of each line from for i in range(num) to again = games.ask_yes_no("\nDo you want to play again? (y/n): ").
After this the output is "Welcome to the world's simplest game!" and that's it.
I was wondering if someone could let me know why this is happening?
Also, the import games module, is recognized in Eclipse after I added the path to PYTHONPATH.
I actually have this book myself. And yes, it is a typo. Here is how to fix it:
# SimpleGame.py
import games, random
print("Welcome to the world's simplest game!\n")
again = None
while again != "n":
players = []
num = games.ask_number(question = "How many players? (2 - 5): ", low = 2, high = 5)
for i in range(num):
name = input("Player name: ")
score = random.randrange(100) + 1
player = games.Player(name, score)
players.append(player)
print("\nHere are the game results:")
for player in players:
print(player)
again = games.ask_yes_no("\nDo you want to play again? (y/n): ")
input("\n\nPress the enter key to exit.")
All I did was indent num 4 spaces and lined it up with the first for-loop.
You have an infinite loop here:
again = None
while again != "n":
players = []
If this is exactly the way it's printed in the book, the book does have an error.
You've got these two lines:
num = games.ask_number(question = "How many players? (2 - 5): ", low = 2, high = 5)
for i in range(num):
The second one is more indented than the first. That's only legal if the first one is a block-introducer like a for or while or if. Since it's not, this is an IndentationError. And that's exactly what Python is telling you.
(It's possible that you've copied things wrong. It's also possible that you're mixing tabs and spaces, so it actually looks right in your editor, but it looks wrong to Python. But if neither of those is true, the book is wrong.)
So, you attempted to fix it by dedenting everything from that for loop on.
But when you do that, only one line is still left under the while loop:
while again != "n":
players = []
There's nothing that can possibly change again to "n", so this will just spin forever, doing nothing, and not moving on to the rest of the program.
So, what you probably want to do is to indent the num = … line to the same level as the for i… line, so both of them (and all the stuff after) ends up inside the while loop.

Categories