Fairly New to Python - Global Varibable Issue - python

was wondering if I someone could lend a hand with the issue I am having with my python 3.4 code. I have found it hard to word my problem and searching the web for an answer has been difficult, so I thought it would be easier if I were to show the code and the issue to be resolved.
cola_cost = 2
surcharge = 0
def calc_takeaway(cost):
global surcharge
cost = cost * 1.05
surcharge = surcharge + (cost * 0.05)
cola_place = input("Do you want your cola to go? ")
if cola_place == "yes":
calc_takeaway(cola_cost)
print("$"cola_cost) ## cola cost should be $2.10 but instead prints out $2
print("$"surcharge)
Basically, my cola_cost will not change its global value after being passed into the calc_takeaway function. Sorry if this is too basic I would kist like to get this issue solved. Thank you.
EDIT: I'd also like to mention that I would like to use the function on different cost variables (i.e fanta_cost, water_cost...) as well.

Consider avoiding global in the first place if possible atleast when alternate methods are possible, because they are a bad usage. Instead of global, use simple parameter passing and function return concepts to handle the issue.
cola_cost = 2
surcharge = 0
def calc_takeaway(cost, surcharge):
cost = cost * 1.05
surcharge = surcharge + (cost * 0.05)
return cost, surcharge
cola_place = input("Do you want your cola to go? ")
if cola_place == "yes":
cola_cost, surcharge = calc_takeaway(cola_cost, surcharge)
print("$", cola_cost) # $ 2.10
print("$", surcharge)

Your global variable is sent by value, and so you're not really changing it,
but rather a copy of it. Here is a simpler example based on your code:
cola_cost = 2
def try_to_change_global_variable(cost):
cost = 174
try_to_change_global_variable(cola_cost)
print(cola_cost)
And when you run it you'll get:
$ python cola.py
2

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

I have a question about functions in a simple code [duplicate]

This question already has answers here:
What is the purpose of the return statement? How is it different from printing?
(15 answers)
Closed 1 year ago.
def computepay(h, r):
if h > 40:
pay = 40 * r + (h - 40) * r * 1.5
return pay
else:
pay = h * r
return pay
hrs = input("Enter Hours:")
h = float(hrs)
rph = input("Enter Rate:")
r = float(rph)
computepay(h ,r)
so I wrote this function but it doesn't execute; if I change the last line to
p = computepay(h ,r)
print("pay:", p)
OR if I change the function definition to
def computepay(h, r):
if h > 40:
pay = 40 * r + (h - 40) * r * 1.5
print(pay)
else:
pay = h * r
print(pay)
hrs = input("Enter Hours:")
h = float(hrs)
rph = input("Enter Rate:")
r = float(rph)
computepay(h ,r)
then the fuction works properly.
Can anyone tell me why it happens? I thought in order to execute a function, just to put the function there and then it executes.
Also, what's the difference btw print and return?
Thank you!
I am new to programming. I hope I can be a little helpful with this. I ran both the functions in pycharm with the latest version of both pycharm and python.
So I think you are saying that the first portion of the code you have here does not display the pay at the end after you run it without changing the last two lines.
If this is what you are wondering about, it does indeed execute the code but the issue is you never told it to show you what 'pay' is. Since python is a very literal programming language it actually store the value of 'pay' but doesnt show you what it is because you never asked it to. Sometimes just returning a value might work in some software like Jupyter Notebook but if you want it to work every time you must say print(computepay(h,r)) Otherwise, the computer just does it in the background and keeps the value of 'pay' to its self.
If it still doesnt make sense think of the difference between:
x = 'hello world'
x
versus x = 'hello world' print(x)
the return function is basically the first one. It knows that 'hello world' is stored in variable x but you never told it to print while the second one you did.
Man after writing this post I hope I actually interpreted the question you had right.
So the difference between 'print()' and 'return' is 'return' is that when you return something from a function you are storing the output of the 'def computepay' function in a variable that is functionally the same as "computepay(h, r) = 'pay'".
Cheers and good luck with your coding.
I would recommend this video if you need more help:
https://www.youtube.com/watch?v=_uQrJ0TkZlc&t=16604s&ab_channel=ProgrammingwithMosh

How do I create a financial program where I can continuously input amount and show remaining amount in dollars

Trying to create a financial calculation program. I know I have to use loop but how do I loop continuously when the user input float value? I believe I'm wayyyyy off but I am quiet curious how this program can be written for myself so I can utilize this.
I would like something like if I input 10000 then ask for another input for expense... This would give me remaining till I stop input. So it would look something like this
10000 #income
3400 # expense
6600 # remaining
600 #transportation
6000 #remaining
100 #utility expense
5900 #remaining
Do I have the concept right?
def financial_plan ():
c = input ("How much income do you have? ")
income = ()
y = input ("expense?")
expense = ()
z = (income - expense)
for income1 in z:
income1 -= y
print(income1)
This seems like a homework, but still you are a bit on right track so I am answering it for you. Note that you need to convert the input to float, other way around doesn't works.
Few points to clarify your doubts:
If you don't know how many times the loop will run, use while loop.
Use the input function to take input, and apply the float on it to get float value of it.
Put the code inside the function it is supposed to be in if you want it work.
Call the function at the end of the program cause Python is not like C like languages with main function which is called by default.
It is a python code.
def financial_plan ():
income = float(input("How much income do you have? "))
while True:
expense = float(input("Expense: "))
if (income >= expense):
income = income - expense
print("You have remainder balance: " + str(income))
else:
print("Insufficient account balance!!")
continue
if (income == 0):
print("Balance Nil!")
print("Program Ended!")
financial_plan()

Self Limiting Repition Function

I'm writing a program that is basically a study guide/ practice test for the current section of my A&P class (it keeps me more engaged than just rereading notes over and over). The test works without any problems, but I have an issue where some of my questions use an "enterbox" input, I can have the question loop if the answer is incorrect, but I can't get it to break without a correct answer.
I figured out a way to make it work by putting the entire function back into the initial "else" tree, so that right or wrong you advance to the next question but it looks incredibly ugly and I can't believe there isn't a better way.
So my "solution" looks like such:
def question82():
x = "which type of metabolism provides the maximum amount of ATP needed for contraction?"
ques82 = enterbox(msg = x, title = version)
#version is a variable defined earlier
if ques82.lower() in ["aerobic"]:
add() #a function that is explained in the example further below
question83()
else:
loss() #again its a housecleaning function shown below
ques82b = enterbox(msg = x, title = version)
if ques82b.lower() in ["aerobic"]:
add()
question83()
else:
loss()
question83()
Okay so it worked, but using a nested if tree for each "enterbox" question looks kinda sloppy. I'm self taught so it may be the only solution but if there is something better I would love to learn about it.
So here is a complete section from my program:
from easygui import *
import sys
version = 'A&P EXAM 3 REVIEW'
points = 0
def add():
global points
msgbox("Correct", title = version)
points = points + 1
def loss():
global points
msgbox("Try Again", title = version)
points = points - 1
def question81():
x = "What chemical is stored by muscle as a source of readily available energy for muscle contractions"
ques81 = enterbox(msg = x, title = version)
if ques81.lower() in ["creatine"]:
add()
question82()
else:
loss()
question81()
It works as is so any errors from what's provided are probably my fault from copy and pasting.
Also I'm running it in python 2.7rc1 if that helps.
Thanks for any help in advance.
I don't know if there is a way to combine "enterbox" that has a button for "skip" as that would also be a solution.
Consider the following approach:
We define a list of question and answer pairs. We do this in one place so it's easy to maintain and we don't have to search all over the file to make changes or re-use this code for a different questionset.
We create an ask_question function that we can call for all of our questions. This way, if we want to make a change about how we implement our question logic, we only have to make it in one spot (and not in each of the questionXX functions).
We compare user input to our answer using == and not in (in will do something else, not what you expect).
We create an object to keep track of our answer results. Here, it's an instance of ResultsStore, but it can be anything really, let's just try to get away from global variables.
Use a loop when prompting for answers. The loop will repeat if the answer given was incorrect (and if retry_on_fail is False).
Allow for the user to enter some "skip" keyword to skip the question.
Display the results once the "test" is complete. Here, we do that by defining and calling the store.display_results() method.
So, what about:
from easygui import enterbox
question_answer_pairs = [
("1 + 1 = ?", "2"),
("2 * 3 = ?", "6"),
("which type of metabolism provides the maximum amount of ATP needed for contraction?", "aerobic")
]
VERSION = 'A&P EXAM 3 REVIEW'
class ResultStore:
def __init__(self):
self.num_correct = 0
self.num_skipped = 0
self.num_wrong = 0
def show_results(self):
print("Results:")
print(" Correct:", self.num_correct)
print(" Skipped:", self.num_skipped)
print(" Wrong: ", self.num_wrong)
def ask_question(q, a, rs, retry_on_fail=True):
while True:
resp = enterbox(msg=q, title=VERSION)
# Force resp to be a string if nothing is entered (so .lower() doesn't throw)
if resp is None: resp = ''
if resp.lower() == a.lower():
rs.num_correct += 1
return True
if resp.lower() == "skip":
rs.num_skipped += 1
return None
# If we get here, we haven't returned (so the answer was neither correct nor
# "skip"). Increment num_wrong and check whether we should repeat.
rs.num_wrong += 1
if retry_on_fail is False:
return False
# Create a ResultsStore object to keep track of how we did
store = ResultStore()
# Ask questions
for (q,a) in question_answer_pairs:
ask_question(q, a, store)
# Display results (calling the .show_results() method on the ResultsStore object)
store.show_results()
Now, the return value currently doesn't do anything, but it could!
RES_MAP = {
True: "Correct!",
None: "(skipped)",
False: "Incorrect" # Will only be shown if retry_on_fail is False
}
for (q,a) in question_answer_pairs:
res = ask_question(q, a, store)
print(RES_MAP[res])
Quick and dirty solution could be using the default value "skip" for the answer:
def question81():
x = "What chemical is stored by muscle as a source of readily available energy for muscle contractions"
ques81 = enterbox(msg = x, title = version, default = "skip")
if ques81.lower() == 'creatine':
add()
question82()
elif ques81 == 'skip':
# Do something
else:
loss()
question81()
But you should really study the answer given by jedwards. There's a lot to learn about
program design. He's not giving you the fish, he's teaching you to fish.

How to use def *insert name here* (): functions?

I'm new to python and had a question about to to use more functions in a code besides def main():
My code below works, but I am trying to add new def's to their respective areas.
So like a new def called (def calcPay():), to where the hours enter are calculated (regPay, overtimePay, and total) as 3 separate items.
&
Also add a new def called (def displayOutput():), the function would receive all three of the values from (overtimePay, regPay, and totalPay) and print the message below.
If someone could explain to me how to use new functions besides main, that would be greatly appreciated.
Thanks, here is my code:
def main():
try:
hoursWorked = float(input("How many hours did you work? "))
if hoursWorked > 40:
overtimePay = (hoursWorked - 40) * 15
regPay = 40 *10
totalPay =( overtimePay + regPay)
else:
regPay = hoursWorked * 10
overtimePay = 0
totalPay = (regPay + overtimePay)
print("You earned",'${:,.2f}'.format(regPay),"in regular pay",'${:,.2f}'.format(overtimePay),
"in overtime for a total of",'${:,.2f}'.format(totalPay))
except:
print("Sorry, that wasn't a valid number. Ending program")
main()
You can declare your functions outside of the main function declaration and then use them in the main function (or inside of other functions in the main function).
So you could do something like:
def calcPay(hours):
# Does logic
return [400, 30, 430]
def displayOutput(regPay, overtimePay, totalPay):
# Prints formatted string
def main():
hoursWorked = float(input("How many hours did you work? "))
pay = calcPay(hoursWorked)
displayOutput(pay[0], pay[1], pay[2])
main()
Have a look at these similar questions:
What does it mean to call a function?
How to correctly define a function?
Basic explanation of Python functions?
There's nothing special about the function named main. You can name functions whatever you want.
When you "call" a function you're just jumping from one block of code to another. When the function returns it goes back to the line that called it.
def something():
print('something')
def other():
print('else')
def a_value():
return 100
something()
other()
x = a_value()
print(x)
# ~~~~~ output
something
else
100
In your example a good use of a function would be to calculate the employee's pay.
def total_pay(hours_worked, hourly_rate, overtime_after=40):
base_pay = min(overtime_after, hours_worked) * hourly_rate
overtime_pay = max(0, hours_worked - overtime_after) * (hourly_rate * 1.5)
return base_pay + overtime_pay
This function allows us to define the three things that determine a worker's pay. The base_pay will be, at most, the number of hours before overtime is applied. The overtime_pay will be from 0 to "some other limit" that's not defined here. Overtime is given time and a half (1.5).

Categories

Resources