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

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

Related

Issue With Math Function Called From Another File

I'm currently working on a unit conversion calculator, and wanted to make it smoother by calling the math functions from a different file. Currently, Celsius -> Fahrenheit (CF) is put in 'func.py', like this:
# This file has all the math functions that get called by main.py when needed.
# Also, VARIABLES!
num = 0
typ = 0
def CF():
tota = (num * 9/5) + 32
print("Answer: " + str(tota) + " degrees Fahrenheit")
And the code to call it in main.py looks like this:
if (typ == str('C-F')):
num = int(input("Enter the temperature in Celcius: "))
num = num
CF()
I figure that I imported something wrong, but I've edited the import function several times now. I'm not looking for some type of complete correction, I wish for somebody to tell me what I did wrong, so that I can fix it. I used repl.it, if it helps. Even if someone can tell me that it's possible, it'll help.
I couldn't find anything on websites like GeeksforGeeks, which is my main source on research.
This is very odd:
def CF():
You're relying on num being defined at module scope within its module.
Much better to spell it this way, so you're passing in an argument:
def cf(num):
Over in main.py you're doing this, which isn't helpful:
num = num
Much better to pass it in:
cf(num)
The big concept you've been missing is you have two different modules,
and each one has a num variable.
They are different.
Changing one won't automatically affect the other.
Use function parameters instead.
You need to work with function parameters and returns (see this for a tutorial).
# func.py
def CF(num):
return (num * 9/5) + 32
# main.py
if (typ == str('C-F')):
num = int(input("Enter the temperature in Celcius: "))
tota = CF(num)
print("Answer: " + str(tota) + " degrees Fahrenheit")

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).

Returning multiple valuables and then calling those valuables separately

I'm having issue with allowing a function to call on variables set by another function. I believe I know how to do this with single variables, but my code requires it be done with multiple variables, a challenge I've struggled with for hours. I've read much about ways others seem to have done this but I can't find success in implementing them.
#gathers the user's requests
def ask():
userw = int(input('How wide? '))
userh = int(input('How tall? '))
userc = input('What string to use? ')
userc_len = int(len(userc))
return (userw, userh, userc, userc_len)
#draws the rows of the box. First the top with the topbot function, then the body with body(), then the bottom with topbot again
def draw(w, h, c, c_len):
def topbot(w_, c_):
for x in range(w_):
print (c_, end ='')
print ('\n')
def body(w_, h_, c_, c_len_):
for x in range(h_-2):
print (c_, end = '')
for x in range(w_-2):
print(' ' * c_len_, end = '')
print (c_)
topbot(w, c)
body(w, h, c, c_len)
topbot(w, c)
#begins draw
draw(userw, userh, userc, userc_len)
The problem begins when the draw function tries to begin with the arguments of userw, userh, userc, userc_len, but can't find them:
NameError: name 'userw' is not defined
is returned when I try to run it.
Is it correct to define topbot and body within the draw function and manage the arguments how I did?
How do I return the four variables from ask in a manner such that draw can then use them as arguments?
ask() is a function which will return 4 values. So,
returnValues = ask()
draw = draw(*returnValues)
or simply, draw = draw(*ask())
Also, end = ' ' is not correct. Instead of that you can just use print(c_,'').
Include Validations wherever necessary. Like what if I type "hi" for "How wide?". In this case the program should tell me that this is wrong.
I was able to get draw() to accept the inputs from your ask() function (in Python IDLE) just by changing the last line of your code to this:
draw(*ask())
The * will unpack the variables from the ask() call and pass that along to draw(). The output looks kind of funny, and I'm not sure whether that's what you're looking for or not, but at least it got the variables in there correctly.

Basic Functions Help - Python

I'm quite new to Python, and I'm busy trying to figure out how these pesky functions work... The program I'm making is supposed to be working out the area of a triangle, but I can't actually get it to return the local variables to other functions. Any help would be greatly appreciated!
# Area of a triangle
base = 0
height = 0
area = 0
def inData():
base = float(raw_input("Base:"))
height = float(raw_input("Height:"))
return base
return height
def triangle(b,h):
area = b / 2 * h
return area
if __name__ == '__main__':
inData()
triangle(base, height)
print "The area of a triangle of base", base, "and height" , height, "will be", area
There are many problems and misconceptions I see in your code; Let me see if I can start from scratch and try to convey the proper way to do these functions for you. In the end, we will have a working version of your code. :)
note: You do not have to declare functions ahead of time in Python-- it does that itself! So no need for base, height, area at the top!
Functions
Functions are in short, sets of commands that get run in a bundle. You know this. What you miss though are the concepts of arguments and parameters and return vs print.
Arguments vs Parameters
When you define a function, you are setting up what you want it to do in the future and at your beck and call. Just like any function f(x) in math, you want one equation that will work with whatever input you give it. For f(x), x is your input.
In programming, this is referred to as a parameter. So when you write in Python:
def Function(x):
y = x*x
return y
You have defined x as your parameter. Now, Arguments are the values that you put into a function, where the parameters go. In Algebra, the applicable idea would be defining a variable. Knowing this, when you actually use that function:
Function(2)
You will get back 4, because you said run Function(x) where x = 2.
This is the concept of Arguments vs Parameters. It is very useful, because you don't always want to ask a user for input inside the function. The more direct your function is, the less it can do. Sometimes you want to use that same function to do math in the background, for example. You can't very well have raw_input() if you expect the process to work on its own in the background, can you?
This is the true value of Arguments vs Parameters.
Return vs Print
In the same vein as not using raw_input() because it is too direct, you want to avoid using print and use return instead. I know you didn't use print here, but you've misunderstood the workings of return and I figure the same lesson applies.
Here is an example: You have two functions.
def Function1(x,y):
z = x*y
print z
def Function2(x,y):
z = x*y
return z
Function 1 prints z, which means that no matter what you want it to do, it will always print z to the console, even if you want it to just do the math.
Meanwhile, Function 2 returns z, meaning it hands back the value of z to the program as it was called. It is also worth noting that as soon as a function hits the line return, it stops running the function further. There is no reason to code beyond this, because the function is no longer being run, unless you had a more advanced code that skipped over return (for example, an if statement).
Why is return so conceptually important?
Because in your original code, you run the function inData(), and after that, not only do you run return twice, but in your if statement, you don't even use what inData returns, you just tell the program to run inData().
When a function returns a value, you have to assign it to something. Take, for instance, simple math in any random programming language. The code:
x = sqrt(4)
print x
will output 2, because at the end of the function sqrt(), it returns its answer. Here, we assigned x to be variable that sqrt(4) gives a return to. While it's true that:
sqrt(4)
will also print 2 to the console, this is because of fool-proofing by language developers, where in fact the language assumes you want the code printed. You're not telling it to do that.
So, when you run the lines of code:
inData()
triangle(base, height)
You are basically saying:
run the function inData()
run the function triangle(base, height)
When, because of their returns, you need to be saying:
set <variable1> equal to the return of inData()
set <variable2> equal to the return of triangle(base,height)
(there is more simplification to be done here, but we'll approach it in a moment).
One last thing on return. In programming, it is useless to write:
x = 1+1
return x
When return 1+1 accomplishes the same thing. Thus, no need to define what the area of a triangle will be and then return the area. Just tell the function to return what it calculates the area to be in the same line of code!
Have I lost you? Still with me? Good!
Simplification of your code
Your code has a few structural problems that, while it may work, would baffle any more seasoned programmer that looked at it. While we're here, why don't we see if I can have you understand what a better practice for this would be.
In your code, you have written (in a summarized form)
variables defined that you don't need
def FunctionThatGathersData()
def FunctionThatDoesTheMath(x,y)
if (condition)
FunctionThatGathersData()
FunctionThatDoesTheMath(x,y)
print out the results
The structure of this would confuse a programmer who has more experience. He might ask the following questions:
What?
Why are you returning things this way?
Why are the variables defined?
Why don't you combine FunctionThatGathersData and FunctionThatDoesTheMath?
Some of these reasons are already exposited upon above, but let's get to the last two questions.
Why are the variables defined?: On one hand, Python handles variables during execution. So you never have to define them ahead of time, but you can, and the advantage of this is as follows:
x = 0
def Function()
x = 5
y = 10
Looking at this code, you might wonder why x is defined. The simple answer is that Python will see that you already have an x, and thus, when you run Function(), you want to overwrite it with the work inside the function. y on the other hand, has no previous definition, and thus a new variable will be created.
However, in your function we don't need any of that because your answer, in its best form, won't need to depend on x outside the function.
Why can't we just combine the two functions together, using what we learned about parameters, arguments, and returns? (hint: we can!)
Here is a new snippet of code that you should now be able to read and understand. Clear your head of what you've read for a moment and see if it makes sense. In it, you will:
Define your function DoTheMathAndThenGiveMeTheValueBack
Decide if __name__ == '__main__'
Provide your values (put them in variables)
Pass those variables as arguments into the function
tell the program to print the base and height and then area based on the function's return.
The Code
def CalculateTriangleArea(b,h):
return b / 2 * h
if __name__ == '__main__':
base = float(raw_input("Base:"))
height = float(raw_input("Height:"))
area = CalculateTriangleArea(base,height)
print "The area of a triangle of base", base, "and height", height, "will be", area
If you do not grok this, please, comment and ask me more because I remember struggling with this and know what misunderstandings you are having.
Oh! And I forgot to mention to you what to do about multiple returns.
In the event that you need to return more than one value in a function, you can do so through an array or a tuple. This is just a list of values you have stored. You can access any item in an array or tuple by including the index at the end in the form of [i], where the first item is at [0]. For example:
def Function():
string1 = "nobody"
string2 = "expects"
string3 = "the"
string4 = "spanish"
string5 = "inquisition"
return string1, string2, string3, string4, string5
print Function()[0]
print Function()[1]
print Function()[2]
print Function()[3]
print Function()[4]
print Function() #prints the whole tuple!
Will get you:
nobody
expects
the
spanish
inquisition
('nobody', 'expects', 'the', 'spanish', 'inquisition')
Understand? :)
For more hands-on work in python, try this amazing Python tutorial.
When you do return, the function immediately ends, returning the value. Therefore, your inData function will only return the base, not the height. In addition, you seem to be asking the user to input the base and the height twice -- that's unnecessary, since your inData function already does that
Rather, you want to return two values at the same time by doing something like this. (Note -- I renamed some of your functions for clarity)
# Area of a triangle
def get_user_input():
base = float(raw_input("Base:"))
height = float(raw_input("Height:"))
return base, height
def triangle_area(b, h):
area = b / 2 * h
return area
if __name__ == '__main__':
base, height = get_user_input()
area = triangle_area(base, height)
print "The area of a triangle of base", base, "and height" , height, "will be", area
The problems with your code:
# Area of a triangle
base = 0 # You don't need to initialize these values. Even if you want
height = 0 # to make these global you can simple assign inside the if
area = 0 # __name__ == '__main__' condition
def inData():
base = float(raw_input("Base:"))
height = float(raw_input("Height:"))
return base # return immediately stops the execution of the function
return height # and returns the value
def triangle(b,h):
area = b / 2 * h
return area
if __name__ == '__main__':
inData() # You are not assigning the returned value to any variable
triangle(base, height)
print "The area of a triangle of base", base, "and height" , height, "will be", area
Correct version of your program:
# Area of a triangle
def inData():
base = float(raw_input("Base:"))
height = float(raw_input("Height:"))
return base, height
def triangle(b,h):
area = b / 2 * h
return area
if __name__ == '__main__':
base, height = inData()
area = triangle(base, height)
print "The area of a triangle of base", base, "and height" , height, "will be", area

Categories

Resources