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
Related
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.
I want to use just one try\except for many variables. I want to find out which part is causing the error so I could print it to the user under the except part.
try:
i = int(i)
j = int(j)
k = int(k)
l = int(l)
m = int(m)
n = int(n)
n+1 = int(n+1)
...
..
.
except ValueError:
print('Please enter an integer as {}'.format(# whether i, j, k, l, or ...))
I want to find out which int(x) is causing the error so I can print it to the user? Is there any way to do it? I don't want to try for each part because my variables are nearly infinite ;)
How about something like this:
def parse_int(num, name='var'):
try:
return int(num)
except ValueError:
print(f"Please enter an integer for {name}")
i = parse_int(i, name='i')
You can call the parse_int method for other variables as you see fit.
PS: you can't assign to an expression like n+1 - that last line before the except in your code will not work
I think that #rdas has a better answer, but since you didn't like it, you can do something like this as well, it just looks a little hacky and not that much better than doing try/except on every line.
try:
last = 'i'
i = int('10')
last = 'j'
j = int('ten')
except ValueError:
print(f'Please enter an integer as {last}')
If all of them are integers, and if they are related in some way, then you can use a list to store them. The reason for another list with variable names is so you can use the same index to say which variable was error in.
my_list=[]
my_list_variables=["a","b","c"]
i=0
while True:
try:
x=int(input("Please input "+my_list_variables[i]+" : "))
my_list.append(x)
i=i+1
#Just make sure to add a if statement to quit out of the loop
#Like if that is end of the amount of input you are asking.
break
except ValueError:
#index i doesn't change so you can tell the user which variable they
#entered a wrong input for.
print("Error: input "+my_list_variables[i]+" have to be a number")
Just have another list stored of name variables.
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)
I have a function below which is part of my big main function, what I want this function to do is that whenever called, I want the function to check if the user input is
a number or not. If it is a number it will return the number and break.
But if it is not a number I want it to loop again and again.when I try to
run it, it gives me unexpected an error:
unexpected eof while parsing
can any body help me what I am missing or how I should rearrange my code? thank you!
def getnumber():
keepgoing==True
while keepgoing:
number = input("input number: ")
result1 = number.isdigit()
if result1 == 1:
return number
break
elif keepgoing==True:
A neater and clearer what to do what you are already doing:
def getnumber():
while True:
number = input("Input number: ")
if number.isdigit():
return number
That's all you need, the extra variables are superfluous and the elif at the end makes no sense. You don't need to check booleans with == True or == 1, you just do if condition:. And nothing happens after return, your break will never be reached.
You don't need the last line:
elif keepgoing==True:
It's waiting for the rest of the file after the :.
Side note, it should be a single = in the first part, and can just be written simpler as well.
def getnumber():
while True:
number = input("input number: ")
result1 = number.isdigit()
if result1:
return number
Since you're inside the while loop, it'll keep executing. Using return will end the while loop, as will breaking and exiting the program. It will wait for input as well each time, though.
While assigning you have used keepgoing == True, I think it should be keepgoing=True
The following solution works on my machine, although I am running Python 2.7
def get_num():
while True: #Loop forever
number_str = raw_input("> Input a number: ") #Get the user input
if number_str.isdigit(): #They entered a number!
return int(number_str) #Cast the string to an integer and return it
I used raw_input rather than input, because raw_input gives you the exact string the user entered, rather than trying to evaluate the text, like input does. (If you pass the 12 to input, you'll get the number 12, but if you pass "12", you'll get the string '12'. And, if you pass my_var, you'll get whatever value was in my_var).
Anyway, you should also know that isdigit() returns whether or not the string has only digits in it and at least one character - that is not the same thing as isNumber(). For instance, "123".isdigit() is True, but "123.0".isdigit() is False. I also simplified your loop logic a bit.
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()