Text Based RPG Functioning Error? - python

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

Related

I need assistance for my little program (python lists)

I will give you my python code (it's pretty basic and small) and if you can,tell me where i am wrong.I am noob at coding so your help will be valuable.thanks a lot and don't hate :)
lista=[]
for i in range(100):
a=input("give me a number")
if a%2==0:
a=0
else:
a=1
lista=lista+a
print lista
P.S: I code with python 2 because my school books are written with that in mind.
You need to use append method to add an item to the end of the list.
lista.append(a)
And you need to convert the str returned by input() to int.
The input() function reads a line from input, converts it to a string (stripping a trailing newline), and returns that. When EOF is read, EOFError is raised.
a = int(input("give me a number"))
Try this:
lista=[]
for i in range(2): # Changed from 100 to 2 for my own testing
a = int(input("Give me a number: "))
a = 1 if a%2 else 0
lista.append(a)
print(lista)
Outputs:
[0,1]
EDITED:
So i cant use Lista=lista +a?I thought i could..my book says i can..thanks for your solution,it works!
You can use += operator (similar to extend()) but it requires a list operand. Not an int. So, you need to convert your int to a list. Try this:
lista += [a]
list.append(a) is faster, because it doesn't create a temporary list object. So, better to use append.

Calculating a factorial using loops in Python3

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.

Python code works in 2.7 but not in 3.5

My coursework is to create Tic Tac Toe in Python, my tutor helped me get it working in 2.7 however It needs to be in 3.5.
Firstly in 2.7 the code below prints a 3x3 list, however in 3.5 it just prints the list downwards not 3x3. my tutor said maybe put end = ' ' at the end but that also doesn't work.
def printBoard( board ):
counter = 0
for y in range(3):
for x in range(3):
print (board[counter]),
counter += 1
print
print
second problem is on 2.7 it allows me to continue to input numbers till the board is filled with X or O, on 3.5 it only allows to input once and then the program ends?
value = input("input number between 1 and 9")
value = int(value)
if value == 1:
alist[0] = player1
printBoard( alist )
value = input("input number between 1 and 9")
if value == 2:
alist[1] = player1
printBoard( alist )
value = input("input number between 1 and 9")
etc.
print changed from statement to a function in Python 3.x. To print a statement without newline, you need to pass end=' ' parameter (You can use the print as a function in Python 2.7 if you put from __future__ import print_function at the beginning of the code):
print(board[counter], end=' ')
input returns a string in Python 3.x. (does not evaluate the input string). You need to convert the value into int every where you used input:
value = input("input number between 1 and 9")
value = int(value)
Alternatively, instead of comparing the input with integer literal 1 or 2, compare the input string with strings: '1', '2' without converting the string into integer. (But this requires you to use raw_input in Python 2.7 instead of input)
print should be called: print(). Otherwise, nothing is printed.
I assume board is something like [['*', '*', '*'], ['*', '*', '*'], ['*', '*', '*']]. That means you have an easy way of printing this with a single print() call.
print(*(''.join(row) for row in board), sep='\n')
This joins each row into a new string, producing each row as part of a generator. This generator is unpacked with * and sent to print(), where each row is separated by a newline.
For your second issue, the problem is simple: you cast int() for the first value, but not for the subsequent ones. However, this is the sort of thing you should be doing with a loop. It'll prevent exactly this kind of bug. If you find yourself writing lots of code with Ctrl+V, you're doing something wrong. If each block is slightly different, with an incremented number, you would do that with something like for i in range(n):, which allows you to execute the same code with an incremented number on each iteration.
However, I'd recommend a simple while loop that checks if the game is complete:
while True:
move = request_move()
do_move('X', move)
if game_complete():
break
request_move()
do_move('O', move)
if game_complete():
break
You would then write appropriate functions to request move coordinates, input moves into the board, and check if the game is complete yet.

Running exceptions within a function - Python

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,

I need help wrapping my head around the return statement with Python and its role in this recursive statement

No this isn't homework but it is on our study guide for a test. I need to understand the role the return statement plays and the role recursion plays. I don't understand why the function doesn't break after x = 1.
def thisFunc(x):
print(x)
if x>1:
result=thisFunc(x-1)
print(result)
return x+1
Sorry, I understand how elementary this is but I could really use some help. Probably why I can't find an explanation anywhere...because it's so simple.
edit: Why does it print out what it does and what and why is the value of x at the end? sorry if I'm asking a lot I'm just frustrated
When you enter the function with a value n>1 it prints the current value, and then calls it's self with n-1. When the inner function returns it returns the value n - 1 + 1 which is just n. Hence, the function prints out the value n twice, once before the inner recursion and once after.
If n == 1, which is the base case, the function only prints 1 once and does not call it self again (and hence does not get result back to print). Instead it just returns, hence why 1 is only printed once.
Think of it like an onion.
calling thisFunc(n) will result in
n
# what ever the output (via print) of thisFunc(n-1) is
n
I don't understand why the function doesn't break after x = 1.
But it does:
>>> ================================ RESTART ================================
>>> x = 1
>>> def thisFunc(x):
print("Function called on x-value: ", x)
if x > 1:
result = thisFunc(x-1)
print(result)
return x+1
>>> thisFunc(x)
Function called on x-value: 1
2
>>>
edit: Why does it print out what it does and what and why is the value of x at the end?
Well, it prints it out because you're telling it to. Try following the value of x as you go through the function ("x is one, one is not bigger than 1; return 1+1. Ok. [new case] x is two, two is bigger than 1..." and so on).
return and recursion are part and parcel of programming; return statements designates the end of a function (even if you might have several lines more of code) and they also pass data back to whatever asked them for it. In your case you're asking "what happens when x is 1, given these rules?"; the returned data is your answer.
Recursion is simply the matter of letting the function call itself, should it (you) need to. You simply tell the program that "hey, as long as x is bigger than 1, call this function [that just so happens to be the same function initially called] on it and let it do its thing". To get a better understanding of your function I'd suggest that you add the line "Function called on x-value: " to the first print statement inside the function, or at least something that lets you identify which printed line is x and which is result.
For a more in-depth explanation on recursion, I recommend Recursion explained with the flood fill algorithm and zombies and cats

Categories

Resources