I've been learning Python for about 3 weeks now, so what I'm working on is obviously going to be very simple. I've already written a couple programs that return values for certain calculations, and I have successfully used exceptions within functions in those programs. The program that I'm currently working on is only for the purpose of me getting some more practice writing functions, while loops, and exceptions. Here's what I've got so far:
def factorial(n):
while n > 0:
return n * factorial(n-1)
return 1
print factorial(n)
def user():
n = int(raw_input("What number would you like to use?"))
try:
factorial(int(n))
except ValueError:
print "You must choose a number. Please try again."
return user()
if __name__ == '__main__':
user()
I can't figure out why my exception within the user() function doesn't seem to be running. All I get when I run this code is the raw_input "What number would you like to use?". The factorial() function doesn't run, nor do the print or return statements that I've set if there is a ValueError. Can anyone help me figure out why this is (or rather isn't) happening?
Funny enough, all of the code is running! It just isn't showing anything, because the print statement isn't being called! Lets decompose the user function and see what it does.
What the code is doing
n = int(raw_input("What number would you like to use?"))
Convert the string the user types into an integer and store it into the variable (or, if you want to be pythonic-ly correct, the name) n.
try:
factorial(int(n))
Try to convert n into an integer (again) and send said integer to the factorial function. Note that n here is already an integer! So this will always succeed. Just call the function, nothing more.
except ValueError:
print "You must choose a number. Please try again."
return user()
If ValueError is raised, print an error message, then return the value of user.
We don't print anything whether the conversion was successful or not. We just run a single function then exit. What function do we run?
def factorial(n):
while n > 0:
return n * factorial(n-1)
return 1
print factorial(n)
Note that in this function the code says to print a value after returning a value. Once a function returns, nothing after the return statement is run. The print statement will not be executed! So this function correctly computes the factorial (recursively), and returns it. Nothing else!
This is why your program will seem to do nothing. This function is called, computes, and returns the answer. The returned answer is simply ignored!
What does this mean?
There are three key lines in your code that define why it's doing what it's doing.
You convert the input from the user into an integer and store it in n
This will raise ValueError if the user types anything that isn't an integer.
Note that this still happens! if you run the code, type b, then press enter, an exception (ValueError) will be raised.
You convert n into an integer and pass it to factorial.
Although this is in the try block (as it should be), n is already an integer. This is why your exception code will never run.
Your only print statement (after getting valid input from the user) is inside the factorial function, after the return statement. It will never be executed. This is why nothing is printed.
I don't recommend printing the result inside of a recursive function. It can be done, but it is generally better to return the result and print the returned value, outside of the recursive function. (perhaps in the user function, instead of calling factorial(n) printing what it returns would be better!)
I hope that this helped to clarify exactly what is going on with the code, and I hope I was able to answer your question! Happy coding! :D
Here are my comments expanded into an answer.
First, do not print inside the factorial function. Print the value returned from that function:
def factorial(n):
while n > 0:
return n * factorial(n-1)
return 1
>>> factorial(4)
24
Next, wrap the thing that you think will cause the exception in the try part of the block. In this case, the call to int with unknown user input might cause an exception; wrap that in the try -- no more. Finally, do not use recursion for user input. Use a while loop instead:
def user():
n=None
while not n:
user_int=raw_input("What number would you like to use? ")
try:
n=int(user_int)
except ValueError:
print "You must choose a number. Please try again."
print factorial(n)
if __name__ == '__main__':
user()
first of all you have to print the factorial(int(n)) to see the output,
And remove int conversion of your input,
here is my modified code:
def factorial(n):
2 while n > 0:
3 return n *factorial(n-1)
4 return 1
5 print factorial(n)
6
7
8
9
10 def user():
11 n = raw_input("What number would you like to use?")
12
13 try:
14
15 print factorial(int(n))
16 except ValueError:
17 print "You must choose a number. Please try again."
18 return user()
19
20 if __name__ == '__main__':
21 user()
hope this helps,
Related
So I have read tons of solutions to this type of questions, but they all seem to be way too complicated, or I can't find any useful solutions in them.
I have written the first part where I have to ask for an input and validate it to be an integer, but I can't figure out how to write the code for the second part. Efficiency isn't a necessity here, but I think it's better if I learn the most efficient way from the get go. From what I read, using the radicle of the input and checking the divisors is the way to go here, but as I said, I can't figure out how to actually write the code and integrate it into what I already have.
while True:
x = str(input("Please enter an integer: "))
try:
x = int(x)
except ValueError:
print("Please enter a valid integer: ")
continue
break
Any help is greatly appreciated!
It is better to edit multi-line code into your question, rather than post a comment, because then you are not limited to a single line.
Your code appears to be:
def is_prime2(n):
if n == 2 or n == 3:
return True
#endif
if n % 2 == 0 or n < 2:
return False
#endif
for i in range(3, int(n**0.5)+1, 2):
if n % i == 0:
return False
#endif
#endfor
return True
#enddef
print(n)
I have added comments to indicate where I think that various statements end. I may have mistaken the indentation converting from a single line.
Apart from that print(n), which is either not part of the function definition or comes after a return, this appears to work correctly. It will be too slow for very large values of n though it will be fine for smaller values and for testing. For very large values have a look at the Sieve of Eratosthenes.
Write an isPrime(n) function that returns true if n is prime, false otherwise. Then test all the numbers from 2 up to the entered integer to see if they are prime.
We will help you to improve your code, but you have to write it first.
I am currently studying Software Development as a beginner and I have a task in my programming class to calculate and display a factorial using a loop. I've been given the pseudo-code and have to translate it into true code and test it in the REPL to make sure it returns the expected results.
I almost have it but I've run into two issues that I just can't seem to resolve.
1) The function is returning an extra line of "None" after the calculation and
2) The answer is displaying over multiple lines when I want it to display on a single line.
My current code (which does return the correct answer) is as follows:
def calcFactorial(number):
factorial = 1
print(str(number)+"! =", number)
for count in range (1, number):
if number-count > 0:
factorial = factorial*number-count
print("x", str(number-count))
factorial = factorial*number
print("=", factorial)
When I test, using 3 for example, the REPL returns the following:
>>> print(calcFactorial(3))
3! = 3
x 2
x 1
= 12
None
So I have the correct answer but with an extra line of "None" which I would like to remove (I believe it has something to do with the print function?) and I don't know how to format it correctly.
Any help would be much appreciated.
your function calcFactorial(3) prints already, so you shouldn't call it with
print(calcFactorial(3))
just call it with
calcFactorial(3)
without the print function.
you might think about calling the function calc_and_print_factorial() in order to make it clear, that this function does already the printing
Regarding your second question:
Blockquote
2) The answer is displaying over multiple lines when I want it to display on a single line.
You can fix it by using a single print statement:
def calcFactorial(number):
factorial = 1
string = str(number) + "! = " + str(number)
for count in range (1, number):
if number-count > 0:
factorial = factorial*(number-count)
string = string + " x " + str(number-count)
factorial = factorial * number
print(string + " = " + str(factorial))
This will give you:
IN: calcFactorial(3)
OUT: 3! = 3 x 2 x 1 = 6
On a side note: you might want to think of how to implement this recursively. Maybe that comes later in your class but this would be one of the first go-to examples for it.
Adding to the blhsing's answer, you should choose between these built-in ways to print the "returned" value.
First way:
def calcFactorial(number):
... # <- Your function content
return factorial
Then, call your function with a print() to get the explicitly returned value, as you can see in the return factorial line. See this reference for more details:
print(calcFactorial(3))
Second way:
Having the same function definition with its return statement, just call the function with its instance statement:
calcFactorial(8)
By default, python will print the returned value without a print()
Third way:
Just call the function (without the explicit return statement, this will return a "None" (null-like) value by default), using the print() method. Do NOT use print() inside another print().
Your calcFactorial function does not explicitly return a value, so it would return None by default, so print(calcFactorial(3)) would always print None.
You should make the calcFactorial function return factorial as a result at the end:
def calcFactorial(number):
factorial = 1
print(str(number)+"! =", number)
for count in range (1, number):
if number-count > 0:
factorial = factorial*number-count
print("x", str(number-count))
factorial = factorial*number
print("=", factorial)
return factorial
So I have the correct answer but with an extra line of "None" which I would like to remove
You are printing the return value from your function. In this case, you haven't specified a return value with a return statement so the function automatically returns None.
To fix the problem, you should return a value from your function. Note that you don't need to call print() for final answer because the REPL already does this for you.
Note that the REPL will automatically print the return value for you, so you can just type calcFactorial(3) instead of print(calcFactorial(3)).
Additionally, you are not getting the correct answer. You should get 6 instead of 12. It looks like you are trying to count down from number and multiplying each number together. You can get the same result by counting up from 1. This will lead to much simpler code and avoid the error.
If you want to understand why your code isn't doing the correct thing, look closely at factorial = factorial*number-count and think about the order of operations that are used to calculate the result here.
I have the following code:
def is_prime(n):
limit = (n**0.5) + 1
q = 2
p = 1
while p != 0 and q < limit:
p = n % q
q = q + 1
if p == 0 and n != 2:
return 'false'
else:
return 'true'
But when I send in an integer, there is nothing returned. The console simply moves on to a new command line. What's wrong here?
EDIT 1:
The following are screenshots of different scenarios. I would like to make it such that I call the function with a particular number and the function will return 'true' or 'false' depending on the primality of the number sent into the function. I guess I don't really understand the return function very well.
Also, note that when I send in to test 9, it returns true, despite 9 being quite definitely a composite number...should the if/else bits be outside the while loop?
Key to below image:
1: this is the code as it is above and how I call it in the Spyder console
2: adding a print statement outside the function
3: this is a simple factorial function offered by the professor
image here
EDIT 2:
I made a quick change to the structure of the code. I don't really understand why this made it work, but putting the if/else statements outside the while loop made things result in expected true/false outputs
def is_prime(n):
limit = (n**0.5)+1
q=2
p=1
while p!=0 and q<limit:
p = n%q
q = q+1
if p==0 and n!=2:
return 'false'
else:
return 'true'
Also, I call the function in the console using is_prime(int_of_choice)
Thanks for the helpful suggestions
If you want to print something to the console you have to use a print statement. The return keyword means that you can use this value in a piece of code that calls this function. So to print something:
print (x)
For more information about the print statement see: https://en.wikibooks.org/wiki/Python_Programming/Variables_and_Strings
Nothing is wrong, but you have to print out the return of your function.
Like this:
def Test():
if True:
return "Hi"
print(Test())
In this case python will show "Hi" in your console.
I have written the function below. It will work if I pass it an integer or string: If I pass an integer, the program will calculate the factorial, and if I pass a string, it will check the type with isinstance and will print the error message.
But, if I pass a float number or a negative number, the program will print an error... in my second condition. I have said that if n is less than 0, then print that error message, but apparently it won't work, and I don't know why.
def factorial(n):
if not isinstance(n,int):
print('Factorial is only defined for integers.')
return(None)
elif n<0:
print('Factorial is not defined for negative integers.')
return(None)
elif n==0:
return(1)
else:
return(n*factorial(n-1))
How can I change the program so that my conditionals work for float and negative numbers? I don't want to use try and except.
So, I'm hard at work on a text-based RPG game on Python 2.7, but I came across a problem in the character menu. Here's what it looks like:
def raceselect(n):
if n==0:
print "(name) the Human."
if n==1:
print "(name) the Dwarf."
if n==2:
print "(name) the Elf."
if n==3:
print "(name) the Halfling."
n = raw_input
raceselect(n)
0, 1, 2, and 3 are all used as raw_input answers on the previous screen when prompted with the options. However, when the script is run, the options are shown, and the input box shows, however when a number is answered the script simply ends. I can't for the life of me figure out what is causing this, unless it's the fact that I used (name) and raw_input earlier in the script, which I doubt. Please help!
--Crux_Haloine
You need to turn the raw input into a int:
n = int(raw_input())
Also, you need to call the function, so use raw_input() rather than just raw_input
n = raw_input here will bring nothing to you. You should use n = int(raw_input()) according to your need. And I think it is better for you to use a dict or list rather than several if:
def raceselect(n):
races = {0: 'Human', 1: 'Dwarf', 2: 'Elf', 3: 'Halfing'}
if n in races:
print '(name) the %s' % races[n]
else:
print 'wrong input'
First issue is this:
n = raw_input
You never actually call the function. Instead, your are assigning a reference of raw_input to n (as in, n is now the function, not the result of the function).
Also, once you call the function, you have to cast it into an integer, because raw_input returns a string.
Thus, you want:
n = int(raw_input()).