Calling function to new function in Python - python

I have tried this several different ways, I am still fairly new to Python so go easy on me. I am trying to execute a script where the user can choose to import a list from a plaintext file, or input a list manually, and the script will return the median and mode of the data.
The problem I am having is that my median and mode functions are not recognizing the reference to the raw data, and the main function isn't recognizing the median and mode from their respective functions.
I guess it's safe to say I am not calling these functions correctly, but frankly I just dont know how. Any help here would be much appreciated.
def choice():
##Choose user input type
start = input("Please select your input method by typing 'file' or 'manual' in all lower-case letters: ")
# Import File Type
userData = []
if start == "file":
fileName = input("Please enter the file name with the file's extension, e.g. ' numbers.txt': ")
userData = open(fileName).read().splitlines()
return userData
userData.close()
# Manual Entry Type
elif start == "manual":
while True:
data = float(input("Please enter your manual data one item at a time, press enter twice to continue: "))
if data == "":
break
userData = data
return userData
# Error
else:
print("You have entered incorrectly, please restart program")
def median(medianData):
numbers = []
for line in (choice(userData)):
listData = line.split()
for word in listData:
numbers.append(float(word))
# Sort the list and print the number at its midpoint
numbers.sort()
midpoint = len(numbers) // 2
print("The median is", end=" ")
if len(numbers) % 2 == 1:
medianData = (numbers[midpoint])
return medianData
else:
medianData = ((numbers[midpoint] + numbers[midpoint - 1]) / 2)
return medianData
def mode(modeData):
words = []
for line in (choice(userData)):
wordsInLine = line.split()
for word in wordsInLine:
words.append(word.upper())
theDictionary = {}
for word in words:
number = theDictionary.get(word, None)
if number == None:
theDictionary[word] = 1
else:
theDictionary[word] = number + 1
theMaximum = max(theDictionary.values())
for key in theDictionary:
if theDictionary[key] == theMaximum:
theMaximum = modeData
break
return modeData
def main():
print("The median is", (median(medianData)))
print("The mode is", (mode(modeData)))

Welcome! I think you need to read up a bit more on how functions work. The argument when you define a function is a "dummy" local variable whose name matters only in the definition of a function. You need to supply it a variable or constant whose name makes sense where you use it. It is a very good analogy to functions in mathematics which you may have learned about in school. (Note that these points are not specific to python, although the detailed syntax is.)
So when you have def median(medianData) you need to use medianData in the definition of the function, not userData, and when you call median(somevar) you have to make sure that somevar has a value at that point in your program.
As a simpler example:
def doubleMyVariable(x):
return 2*x
How would you use this? You could just put this somewhere in your code:
print(doubleMyVariable(3))
which should print out 6.
Or this:
z = 12
y = doubleMyVariable(z)
print(y)
which will print 12.
You could even do
z = 36
x = doubleMyVariable(z)
which will assign 72 to the variable x. But do you see how I used x there? It has nothing to do with the x in the definition of the function.

Related

Can input exist within a defined function in Python?

I am trying to shorten the process of making lists through the use of a defined function where the variable is the list name. When run, the code skips the user input.
When I run my code, the section of user input seems to be completely skipped over and as such it just prints an empty list. I've tried messing around with the variable names and defining things at different points in the code. Am I missing a general rule of Python or is there an obvious error in my code I'm missing?
def list_creation(list_name):
list_name = []
num = 0
while num != "end":
return(list_name)
num = input("Input a number: ")
print("To end, type end as number input")
if num != "end":
list_name.append(num)
list_creation(list_Alpha)
print("This is the first list: " + str(list_Alpha))
list_creation(list_Beta)
print("This is the second list: " + str(list_Beta))
I want the two seperate lists to print out the numbers that the user has input. Currently it just prints out two empty lists.
You need to move the return statement to the end of the function, because return always stops function execution.
Also, what you're trying to do (to my knowledge) is not possible or practical. You can't assign a variable by making it an argument in a function, you instead should remove the parameter list_name altogether since you immediately reassign it anyway, and call it like list_alpha = list_creation()
As a side note, the user probably wants to see the whole "To end, type end as number input" bit before they start giving input.
Dynamically defining your variable names is ill advised. With that being said, the following code should do the trick. The problem consisted of a misplaced return statement and confusion of variable name with the variable itself.
def list_creation(list_name):
g[list_name] = []
num = 0
while num != "end":
num = input("Input a number: ")
print("To end, type end as number input")
if num != "end":
g[list_name].append(num)
g = globals()
list_creation('list_Alpha')
print("This is the first list: " + str(list_Alpha))
list_creation('list_Beta')
print("This is the second list: " + str(list_Beta))
There are a couple of fundamental flaws in your code.
You redefine list_name which is what Alpha and Beta lists are using as the return.(list_name = [] disassociates it with Alpha and Beta so your function becomes useless.)
You return from the function right after starting your while loop(so you will never reach the input)
In your function:
list_Alpha = []
list_Beta = []
def list_creation(list_name):
# list_name = [] <-- is no longer Alpha or Beta, get rid of this!
num = 0
...
The return should go at the end of the while loop in order to reach your input:
while num != "end":
num = input("Input a number: ")
print("To end, type end as number input")
if num != "end":
list_name.append(num)
return(list_name)

Calculating average grade using functions and lists in Python 3.6

What I'm trying to do is to make a list of names and grades based on user input, and then to show the list as well as to organize the list in a table, and finally to compute the average grade.
So I want my script to prompt the user to input a name and a grade, and then store them in a list. This prompt will be repeated until the user enter an empty string (just press enter while prompted to enter a name).
I have a problem storing the list, and initiating the printing and calculation when empty string is entered.
Here is what I got so far:
# Importing Python tabulate package
from tabulate import tabulate
# Defining functions
def getRec():
# Get a record from user input, return an empty of the user entered an empty string as input
name = str(input("Enter a name: "))
if name != "":
score = int(input("Enter the grade of " + name +": "))
return name,score
else:
return None
def addList(List,rec):
# Add a rec into the list
List = tuple(rec)
return List,rec
def putRec(List):
# Print a record in a specific format
print(List)
def printTable(List):
# Print a table with a heading
print(tabulate(List,showindex="always",headers=["Index","Name","Grade"]))
def average(List):
# Computes the average score and return the value
total = List[0][1]
avg = total/len(List)
print("Average Grade: ",avg)
# Main function
List = []
rec = []
while True:
rec = list(getRec())
List = addList(List,rec)
if rec == None:
for index in range(len(List)):
print()
putRec(List)
print()
printTable(List)
print()
average(List)
break
When I try to initiate the printing and calculation, there's an error because I returned a 'None' on my first function. But if I return zeros, the list became zeros. I need help trying to initiate my other functions and perhaps fixing how I create my list based on the inputs.
Any help is appreciated. Thanks in advance.
You need to check whether getRec() returns None before adding the record to the list :
# Main function
List = []
rec = []
while True:
result = getRec()
print(result)
if result == None:
for index in range(len(List)):
print()
putRec(List)
print()
printTable(List)
print()
average(List)
break
else:
rec = list(result)
addList(List,rec)
There was also a mistake in your addList function. You must use .append() method to add an item to a list. No return value is needed then.
def addList(List,rec):
# Add a rec into the list
List.append(tuple(rec))
The code should run without any issue with these 2 changes, but the average grade will still be wrong. You need to use a for loop to calculate the sum of all grades :
def average(List):
# Computes the average score and return the value
total = 0
for r in List:
total += r[1]
avg = total/len(List)
print("Average Grade: ",avg)
Hope it helps :)
EDIT :
Not sure why you used a loop to print the whole table. You just don't need it. Here is the code without a loop :
while True:
result = getRec()
print(result)
if result == None:
print()
putRec(List)
print()
printTable(List)
print()
average(List)
break
else:
rec = list(result)
addList(List,rec)

How do I improve my code for Think Python, Exercise 7.4 eval and loop

The task:
Write a function called eval_loop that iteratively prompts the user, takes the resulting input and evaluates it using eval(), and prints the result.
It should continue until the user enters 'done', and then return the value of the last expression it evaluated.
My code:
import math
def eval_loop(m,n,i):
n = raw_input('I am the calculator and please type: ')
m = raw_input('enter done if you would like to quit! ')
i = 0
while (m!='done' and i>=0):
print eval(n)
eval_loop(m,n,i)
i += 1
break;
eval_loop('','1+2',0)
My code cannot return the value of the last expression it evaluated!
Three comments:
Using recursion for this means that you will eventually hit the system recursion limit, iteration is probably a better approach (and the one you were asked to take!);
If you want to return the result of eval, you will need to assign it; and
I have no idea what i is for in your code, but it doesn't seem to be helping anything.
With those in mind, a brief outline:
def eval_loop():
result = None
while True:
ui = raw_input("Enter a command (or 'done' to quit): ")
if ui.lower() == "done":
break
result = eval(ui)
print result
return result
For a more robust function, consider wrapping eval in a try and dealing with any errors stemming from it sensibly.
import math
def eval_loop():
while True:
x=input('Enter the expression to evaluate: ')
if x=='done':
break
else:
y=eval(x)
print(y)
print(y)
eval_loop()
This is the code I came up with. As a start wrote it using the If,else conditionals to understand the flow of code. Then wrote it using the while loop
import math
#using the eval function
"""eval("") takes a string as a variable and evaluates it
Using (If,else) Conditionals"""
def eval_(n):
m=int(n)
print("\nInput n = ",m)
x=eval('\nmath.pow(m,2)')
print("\nEvaluated value is = ", x)
def run():
n= input("\nEnter the value of n = ")
if n=='done' or n=='Done':
print("\nexiting program")
return
else:
eval_(n)
run() # recalling the function to create a loop
run()
Now Performing the same using a While Loop
"using eval("") function using while loop"
def eval_1():
while True:
n=input("\nenter the value of n = ") #takes a str as input
if n=="done" or n=="Done": #using string to break the loop
break
m=int(n) # Since we're using eval to peform a math function.
print("\n\nInput n = ",m)
x=eval('\nmath.pow(m,2)') #Using m to perform the math
print("\nEvaluated value is " ,x)
eval_1()
This method will run the eval on what a user input first, then adds that input to a new variable called b.
When the word "done" is input by the user, then it will print the newly created variable b - exactly as requested by the exercise.
def eval_loop():
while True:
a = input("enter a:\n")
if a == "done":
print(eval(b)) # if "done" is entered, this line will print variable "b" (see comment below)
break
print(eval(a))
b = a # this adds the last evaluated to a new variable "b"
eval_loop()
import math
b = []
def eval_loop():
a = input('Enter something to eval:')
if a != 'done':
print(eval(a))
b.append(eval(a))
eval_loop()
elif a == 'done':
print(*b)
eval_loop()

Changing global variables within a function

I'm new to programming, and I'm looking for some advice on what to do. The program I'm trying to write will need several numbers from the user.
I want to use a function to test if the user input a number or not for each of the values entered. If the input isn't a number, I want the function to keep asking for a number until one is entered. I want to know if there is a better way to pass the value into a global variable other than explicitly declaring each variable in the function as global. I'm unsure if there is a better way to do this...
rowNum = None
def numTest(c, d):
x = False
while x is not True:
try:
c = raw_input(d)
c = float(c)
x = True
except:
print "The value you entered isn't a valid number, please try again."
global rowNum
rowNum = c
numTest(rowNum, "Enter number of rows: ")
print rowNum
# I want to use the numTest function on several variables...
# e.g.
# numTest(contourLevel, "Enter number of contour levels: ")
# numTest(cellSize, "Enter cell size: ")
# numTest(labelSize, "Enter label size: ")
Just make it a function, that returns something instead of manipulating a global, much easier to maintain!
def get_num(msg):
while True:
try:
return int(raw_input(msg)) # number of rows should be int
except ValueError:
print "The value you entered isn't a valid number, please try again."
num_rows = get_num("Enter number of rows: ")
print num_rows
Instead of something like numTest(cellSize, "Enter cell size: ") which you mentioned,
you should be doing cellSize = get_num("Enter cell size: "). It's better practice to return values.
You could make this function more general for int and float like so:
def get_num(msg, type_=int):
while True:
try:
return type_(raw_input(msg))
except ValueError:
print "The value you entered isn't a valid number, please try again."
now you can also have:
x = get_num("test") # normal int
x = get_num("foo", float)
I don't have enough rep so I can't comment but:
#Schack,
think of return as kind of an internal print statement (you can't see what is returned, but the Python interpreter can read and use/store/manipulate that value.)
The print statement shows the output on the screen (for humans) although does nothing to your program calculations/running, and the return statement sends the output to the python interpreter(for the program) although shows nothing on your screen for humans to read.
if a function returns a string for example, you could store that output as a variable by stating:
variable1 = function1(args)
which will store whatever string function1 returns (based on an input of args) as variable1.
This is incredibly useful for organising code and means you don't have to fiddle with global variables.
An important thing to note is that once a function returns a value, no other code executes.
So for example:
def example(a, b):
for n in range(1, 30):
if a**n == b**4:
return
break
else:
return False
The break and else statement are redundant because after the function executes the return statement, no other code will execute. A better way to write this would be:
def example(a, b):
for n in range(1, 30):
if a**n == b**4:
return n
return False
I hope I haven't confused you at all as I did get a little sidetracked with my answer, just trying to help, as I'm new myself and found this type of explanation useful when I learnt these topics

How to parse an inputted string to extract individual numbers

Going to feel dumb once I figure this out.
The program I'm writing prompts for an operation (e.g. 9+3) and then prints the result.
Example run:
>>>Enter an operation: 9+3
>>>Result: 12
I'll have four separate functions for the operators +,-,*,/ and another function to receive the user input and print the result after the appropriate function return.
This is my code so far (I'm including only one operator function):
def add(n, y):
result = ""
result = n + y
return result
def main():
op = input("Enter an operation: ")
for i in range(1,len(op)):
n = n[0]
y = y[2]
if (i == "+"):
result = add(n, y)
print("Result: ", result)
print("Bye")
My error in the shell states n and y are not assigned so I'm not parsing them from the input correctly.
Because they are not assigned in the body of the function and not available in the global scope:
def main():
op = input("Enter an operation: ")
for i in range(1,len(op)):
n = n[0] # no n here yet so n[0] won't work
y = y[2] # no y here yet so y[2] won't work
I think you aim to parse the input, and then use those values to perform addition, something like that:
def main():
op = input("Enter an operation: ")
i = op[1]
n = int(op[0])
y = int(op[2])
if i == "+":
result = add(n, y)
print("Result: ", result)
print("Bye")
But it will work only for one digit arguments, so you might think about some proper parsing using regex, but that's for another question.
There are problems with your code:
In main, at n = n[0], you don't have any n defined. So you will get an error. Same for y = y[2].
In add you are adding strings. So you will get '93' as the answer.
For the proper parsing use regex
Or if you want quick to work, less coding version (not recommended if you are learning)
Try this:
def main():
while True:
# just a variable used to check for errors.
not_ok = False
inp = input("Enter an operation: ")
inp = inp.replace('\t',' ')
for char in inp:
if char not in '\n1234567890/\\+-*().': # for eval, check if the
print 'invalid input'
not_ok = True # there is a problem
break
if not_ok: # the problem is caught
continue # Go back to start
# the eval
try:
print 'Result: {}'.format(eval(inp)) # prints output for correct input.
except Exception:
print 'invalid input'
else:
break # end loop
Some regex links: 1 2

Categories