I'm new to python and am trying to make a simple paper, rock, scissors game. no matter what I do inside my "lame" function the value of local variable "y" will not be assigned to global variable "var1" or "var2". I have tried using return but cannot get anything to work.
#get input (paper, rock scissors from players)
play1 = input("player 1:")
play2 = input("player 2:")
#set value of players score to 0
val1 = 0
val2 = 0
def lame(x, y):
#set value of p, r, s choice, to 1, 2 or 3
if x in("p","P"):
y = y + 1
elif x in("r","R"):
y = y + 2
elif x in("s","S"):
y = y + 3
else:
print("your value was not p, r or s")
#run function "lame" and pass in "play1" choice and
#retrieve "val1" for that choice
lame(play1, val1)
lame(play2, val2)
def win(x, y):
#subtracts value of players choices to find winner
dif = x - y
if dif == 0:
print("tie game")
elif dif % 3 == 1:
print("player 2 wins")
elif dif % 3 == 2:
print("player 1 wins")
else:
print("logic error")
#call function "win" and pass in results of their choices
win(val1, val2)
The wrong way to do this:
val1 = 0
...
def lame(x):
global val1
val1 = result_of_some_calculations_to_do_with(x)
The right way to do this:
def lame(x):
return result_of_some_calculations_to_do_with(x)
val1 = lame(x)
Contrary to what L3viathan said in the comments, Python DOES pass variables by reference, but does not ASSIGN variables by reference. In other words:
x = 3 # x is 3
y = x # x is 3, y is 3, x is y
y = 4 # x is 3, y is 4, y is REASSIGNED so y is not x
That's basically what you were trying to do, passing val1 to your lame function and rebinding it as y.
val1 = 0 # val1 is 0
def lame(x, y):
# y is val1
y = some_calculations_to_do_with(x)
# y has been REASSIGNED so y is not val1
This is important when you pass objects like lists that are mutable (e.g. they can be changed, as opposed to immutable objects line int and str in Python).
val1 = list() # val1 is an empty list
def lame(x,y):
y.append(x) # append x to y, DO NOT REASSIGN y TO ANYTHING ELSE
lame(1, val1) # val1 is [1]
Right after I posted this question I figured it out, and can confirm what Adam Smith has said.
Here is the code I changed to get it working properly:
def lame(x):
#set value of p, r, s choice to 1, 2 or 3
if x in("p","P"):
return 1
elif x in("r","R"):
return 2
elif x in("s","S"):
return 3
else:
print("your value was not p, r or s")
#run function "lame" and pass in play1 choice and
#retrive val1 for that choice
val1 = lame(play1)
val2 = lame(play2)
Related
I´m trying to make a snake game without graphics to train with lists. Game pretty much works but I need to find a way how to make the snake longer when he eats food. Well I know how to do it manually, write the same thing 100 times with different numbers and use if, but how to automate it? I know there is some better way to code this game, but is it possible to do it with this and just change something? I tried to do it with for x in range, but didn´t work out, maybe I did it wrong I don´t know.
def snake():
y = 5 #starting point on Y axis
x = 9 #starting point on X axis
length = 10 #length of the map
width = 10 #width of the map
food = [(2, 3), (4, 5)] #coordinates of food
coordinates = [(y, x)] #where head of the snake currently is
food2 = [(y, x)] #current position + position of food
fcount = 0 #number of ate food
erase = 0
way = 1
while way != "stop":
way = input("Choose your way, use wasd: ")
if way == "s":
y = y + 1
elif way == "w":
y = y - 1
elif way == "d":
x = x + 1
elif way == "a":
x = x - 1
coordinates.append([(y, x)])
food2.append((y, x))
if y < 0:
raise ValueError("This doesn´t work")
elif x < 0:
raise ValueError("This doesnt´t work")
if food2[-1] in food:
fcount = fcount + 1
for g in range(length):
for z in range(width):
position = (g, z)
if position in coordinates[-1]:
print("x", end = " ")
elif position in coordinates[-2]: #I need to make something like this for all the food therecould be
if fcount > 0:
print("x", end = " ")
erase = erase + 1
else:
print(".", end = " ")
elif position in food:
print("?", end = " ")
else:
print(".", end = " ")
while erase == 1:
if fcount == 1:
food.remove(food2[-1])
erase = erase + 1
break
break
print()
print(fcount)
print(snake())
There are some other problems that I see, but if you only want to find a way to grow a snake in, as you say, 'auotomatic' mode, you can try calling print('x') when position in coordinates[-1-fcount:].
I have slightly modified your code to show how this can be done. However, as I said, I see other problems, and when someone tries to solve them, it may turn out that the way to grow a snake can be done differently.
def snake():
y = 5 #starting point on Y axis
x = 9 #starting point on X axis
length = 10 #length of the map
width = 10 #width of the map
food = [(2, 3), (4, 5)] #coordinates of food
coordinates = [(y, x)] #where head of the snake currently is
fcount = 0 #number of ate food
way = 1
while way != "stop":
way = input("Choose your way, use wasd: ")
if way == "s":
y = y + 1
elif way == "w":
y = y - 1
elif way == "d":
x = x + 1
elif way == "a":
x = x - 1
coordinates.append((y, x))
if (y,x) in food:
fcount = fcount + 1
food.remove((y,x))
for g in range(length):
for z in range(width):
position = (g, z)
if position in coordinates[-1-fcount:]:
print("x", end = " ")
elif position in food:
print("?", end = " ")
else:
print(".", end = " ")
print()
snake()
I am trying to catch an Index out of range error with the following try and except block.
def getStepList(r, h, d):
x = len(r)-1
y = len(h)-1
list = []
while True:
try:
if x == 0 and y == 0:
break
elif x >= 1 and y >= 1 and d[x][y] == d[x-1][y-1] and r[x-1] == h[y-1]:
x = x - 1
y = y - 1
elif y >= 1 and d[x][y] == d[x][y-1]+1:
#insertion
x = x
y = y - 1
list.append(h[y])
print('insertion')
elif x >= 1 and y >= 1 and d[x][y] == d[x-1][y-1]+1:
#substitution
x = x - 1
y = y - 1
list.append(r[x])
print('substitution')
else:
#deletion
x = x - 1
y = y
list.append(r[x])
print('deletion')
except IndexError:
print('index error')
return list[::-1]
but it gets stuck in a infinite loop. I want it to ignore it and proceed appending the next instances. (For reference its a piece of code that uses a metric of another function to determine which words were inserted, substituted or deleted at each operation).
I feel like I should know this, but in all honesty I am stuck.
Don't do a while True. Change your while condition to:
while(not (x == 0 and y == 0)):
Inside your exception also add a break
except IndexError:
print('index error')
break
You could also add some checks to see what the specific Index Error might be:
d_len = len(d)
r_len = len(r)
h_len = len(h)
d_x_of_y_len = len(d[x][y])
if(x > d_len):
print("x is too big")
if(y > d_x_of_y_len):
print("y is too big")
I managed to sort of complete the first part of this question. But I have no idea on how to finish the second part. I managed to complete the input for x and y.
Exercise 1
The function takes in input a number x and a list of numbers y, and returns a value as
follows:
• If x is odd, fun_exercise_1 subtract 1 from all the elements of y and then returns
its sum.
• If x is even, fun_exercise_1 multiplies each element of y by 2 and then returns its
sum.
• If x is zero, fun_exercise_1 returns the sum of all the elements in y
def fun_exercise_1(x,y):
print ("enter value for x")
x = float (input ("x:"))
y = []
print ("Enter 4 numbers for a list. Use a negative number to finish")
yy = float(input ("Enter Number:"))
while yy >=0.0 :
y.append(yy)
yy = float(input("Next number:"))
This is one way to do it. Although it doesn't validate if the first argument is an integer or if the second argument is a list. It just expects those in order to run correctly.
def test(x, y):
if x == 0:
sum = 0
for i in y:
sum += i + sum
return sum
elif x % 2 == 0:
sum = 0
for i in y:
sum += i * 2
return sum
else:
sum = 0
for i in y:
sum += i - 1
return sum
This would be tested by passing an integer and a list as arguments when calling test().
Here is what you wanna do:
def fun_exercise_1(x, y):
if x ==0:
return sum(y)
elif x % 2 == 0:
y = [(val*2) for val in y]
return sum(y)
else:
y = [(val -1) for val in y]
return sum(y)
print(fun_exercise_1(3,[4,5,6,7]))
Output:
18
This function (playCraps()) is supposed to choose two random integers between 1 and 6, sum them up, and return a True or False value held in x.
For some reason, each time I run the program, it always returns True with either 7 or 11.
import random
wins = [7, 11]
losses = [2, 3, 12]
def playCraps():
x = 0
while x == 0:
sumDice = random.randint(1,6) + random.randrange(1,6)
if sumDice in wins:
x = True
elif sumDice in losses:
x = False
else:
sumDice = 0
print("The sum of the dice was " + str(sumDice))
print("So the boolean value is " + str(x))
Why does this happen? And how can this be fixed?
You always get True because your while loop will execute even if x is False. 0 is a falsy value in Python. Example:
>>> x = False
>>> if x == 0:
print 'x == 0 is falsy'
x == 0 is falsy
So your loop will eventually give True no matter what. A possible solution will be to define:
x = False
while not x:
...
You won't exit the while x == 0: loop until x is equal to True.
Because 0 == x
I am trying to make a dungeon based game and was in the process of making a theoretical path finder, but whenever I run the program, it just prints the same coordinates(theoretical) that I entered in the 1st place. I'm a bit "new" to programming in general so I got stuck
import winsound
def main():
snd = winsound.Beep
a = input("Enter the x value for the entrance: ")
b = input("Enter the y value for the entrance: ")
entrance = [a, b]
x = input("Enter the x value for the exit: ")
y = input("Enter the y value for the exit: ")
a = float(a)
b = float(b)
x = float(x)
y = float(y)
exut = [x, y] #deliberatly placed exit misspelling as exit is a command
done = False
while done == False:
if b > a:
b = b - 1
elif b < a:
b = b + 1
else:
if a > x:
a = a - 1
elif a < x:
a = a + 1
else:
done = True
done2 = False
while done2 == False:
if b > y:
b = b - 1
elif b < y:
b = b + 1
else:
snd(494, 250)
snd(659, 400)
print("done!")
print(entrance)
print(exut)
entrance = [a, b]
exut = [a, b]
done2 = True
when I run it and put lets say 1 for x value of entrance, 2 for y value of entrance, 3 for x value of exut and 4 for y value of exut I get this result;
>>> main()
Enter the x value for the entrance: 1
Enter the y value for the entrance: 2
Enter the x value for the exit: 3
Enter the y value for the exit: 4
done!
['1', '2']
[3.0, 4.0]
>>>
I don't know why it does that so please can you help, it would be much appreciated, thanks.
Firstly, you don't need to convert to float since you only move in steps of one, so get rid of this code:
a = float(a)
b = float(b)
x = float(x)
y = float(y)
It's inconsistent because you are assigning a and b to entrance before converting to float, but assigning x and y to exut after converting. However you should add code to make sure that only integer values can be entered for entrance and exut.
In your first loop, you are comparing b to a, when it should be compared to y (because y is the target value of b):
while done == False:
if b > y: # changed a to y here
b = b - 1
elif b < y: # changed a to y here too
b = b + 1
else:
if a > x:
a = a - 1
elif a < x:
a = a + 1
else:
done = True
Also, you don't need the second loop because after the first loop finishes, a and b will already be set to x and y. So you can just print out your values.
You are printing out entrance and exut, but you aren't printing out the final values of a and b:
print("done!")
print(entrance)
print(exut)
print(a, b) # print out a and b. they should be equal to exut
If you want to see the progress of your pathfinder you can add print(a, b) to your pathfinding loop:
while done == False:
print(a, b)
if b > y: # changed a to y here
b = b - 1
elif b < y: # changed a to y here too
b = b + 1
else:
if a > x:
a = a - 1
elif a < x:
a = a + 1
else:
done = True