cant get random.shuffle to work python random.shuffle() [duplicate] - python

This question already has answers here:
Why does random.shuffle return None?
(5 answers)
Closed 5 years ago.
Right now I am trying to do a piece of code for the Monty Hall problem
I have some code that I am trying to fix and then enhance
This is one thing that I am stuck on:
I am trying to change the way the door at which the prize is chosen by using random.shuffle(), I have to use random.shuffle(), not anything else.
How would I do this?
What I have now does not work for that.
if I put print(random.shuffle(door)), I don't get a new output.
how do I make it return the chosen output
import random
door = ["goat","goat","car"]
choice = int(input("Door 1, 2 or 3? "))
otherDoor = 0
goatDoor = 0
if choice == 1:
if door[1] == "goat":
otherDoor = 3
goatDoor = 2
elif door[2] == "goat":
otherDoor = 2
goatDoor = 3
elif choice == 2:
if door[0] == "goat":
otherDoor = 3
goatDoor = 1
elif door[2] == "goat":
otherDoor = 1
goatDoor = 3
elif choice == 3:
if door[0] == "goat":
otherDoor = 2
goatDoor = 1
elif door[1] == "goat":
otherDoor = 1
goatDoor = 2
switch = input("There is a goat behind door " + str(goatDoor) +\
" switch to door " + str(otherDoor) + "? (y/n) ")
if switch == "y":
choice = otherDoor
if random.shuffle(door) == "car":
print("You won a car!")
else:
print("You won a goat!")
input("Press enter to exit.")

random.shuffle shuffles in place, meaning it will return None if you try and assign a variable to it's non-existent output.
Since you say you have to use shuffle, you can shuffle the list in place with random.shuffle(door), then take an element from this shuffled list eg: door[0]

From the python3 documentation of the random module:
random.shuffle(x[, random])
Shuffle the sequence x in place.
The 'in place' means that the function is replacing the variable x (in your case, 'door') with a different variable that has the same values as before but with their order shuffled. It does not have a return, it simply modifies the variable you gave it, which is why your print statement shows 'None'.
If you must use, random.shuffle, you can simply select an element of the door after you've shuffled it (i.e. random.shuffle(door) then print(door[0])).
However, if other functions were to be an option, then random.sample(door,1) may be simpler instead (documentation for random.sample here).

Related

how to accept multiple answers in 1 variable

im trying to get users to input different strings for Fav_show that can trigger the correct show. i've tried Fav_show = ("game of thrones", "GOT") and Fav_show = ("game of thrones" or "GOT") but my script makes guess != Fav_show if i enter game of thrones/GOT, how would I got about making guess = Fav_show for multiple answers.
Fav_show = ("game of thrones")
guess = ""
guess_count = 0
guess_limit = 0
guess_a_show = False
if raw_input == "whats your favourite tv show":
guess_a_show = input("you have to take a guess, okay? ")
if guess_a_show == "okay":
print("take a guess, you have 5 chances ")
while guess != Fav_show and guess_count < 1:
Sorry I'm new to python, and I've tried looking around for about 30-45 mins, but maybe I'm looking at the wrong places
You could create a list with possible answers of the user:
got_list = ['got', 'Game of Thrones', 'GOT']
Then:
while guess not in got_list and guess_cout < 1
Instead of iterating through the whole list manually and doing the comparison with for x in list... you could also use the in operator:
if x in list return True or even better just return the in comparison straight up return x in list, just keep in mind that for string comparison letter casing does come into play and you should either use 'string'.upper()' or 'string'.lower().

Procedure in if loop not working even though condition is met [duplicate]

This question already has answers here:
How can I read inputs as numbers?
(10 answers)
Closed 5 years ago.
I have made this code to emulate a rock paper scissors game. I have a procedure which has the main game, and when I run this by itself without the if loop at the end, it works. However, when I try to validate whether or not the user entry is numerical, it does not print the correct message. Here is the full code:
import random
def game(choice):
number = random.randint(1,3)
if choice == 1 and number == 2:
print("You lose.")
if choice == 1 and number ==3:
print("You win.")
if choice == 1 and number == 1:
print("It is a draw")
if choice == 2 and number == 3:
print("You lose.")
if choice == 2 and number ==1:
print("You win.")
if choice == 2 and number == 2:
print("It is a draw")
if choice == 3 and number == 1:
print("You lose.")
if choice == 3 and number ==2:
print("You win.")
if choice == 3 and number == 3:
print("It is a draw")
x = input("Choose 1 (rock), 2 (paper) or 3 (scissors).")
digit = x.isdigit()
if digit == True:
game(x)
By the way, there is no error message, the procedure just does not work!
First of all, there are a few issues with your code. If you wish to ignore, skip to Error Handling for answer to your question. You will find it in there.
Naming Variables
Your variables do not tell a person reading your code what they are. If you showed someone the word number, they would not know that it is what the computer chooses in rock paper scissors. Same with choice (who's choice?) and even more so x. So why don't we name them computer_choice, user_choice and choice respectively. I know these are a bit longer to type, but it is worth sacrificing a few extra keystrokes for a bit more clarity. Also notice that I used snake_case name formatting as per usual Python standards.
Repetitiveness/ game()
Your game function could do with a bit of re-doing. All you need is a general 'formula' for winning and losing. In this case, losing is when (thanks to #Brett Beatty) if computer_choice == (user_choice + 1) % 3, drawing is when computer_choice == user_choice and winning is everything else. Also, when your code is being played, the user only knows if they have won or lost, and not what the computer chose, so to add a bit more clarity, I added a list and another print() line. This feature is also useful to test code. Additionally, use zero-based variable values, such as in the computer_choice and user_choice variables. This is useful when converting values to list indexes. Below is a revised version of your code that i have made which includes all points above (I have also made it a function, as you will see below - I just think it looks better):
import random
def game(user_choice):
user_choice -= 1
rps = ["Rock", "Paper", "Scissors"]
computer_choice = random.randint(0, 2)
print("You: {} Computer: {}".format(rps[user_choice], rps[computer_choice]))
if user_choice == computer_choice:
return 0
elif computer_choice == (user_choice + 1) % 3:
return -1
else:
return 1
Error Handling
To make sure the user enters an integer, you would have to add int() around the input statement. However, this alone would return ValueError if the value entered by the user is not an integer, and this is a problem. However, there is a way to fix this using try: except: else: blocks, as you will see below. This is what you would need to decide if the value is an integer, it also prints the correct message when it is not. I also think this is what you wanted for if digit == True(FYI you would only need if digit if you were to do it that way).
def main():
while True:
try:
value = int(input("Choose 1 (rock), 2 (paper) or 3 (scissors):"))
except ValueError: # If any part of the code in the try block raises a ValueError
print("Not an integer")
else: # If error is not raised
if not 1 <= value <= 3: # If value is not between 1 and 3
print("Must be between 1 and 3")
else:
result = game(value) # sets result to return value from game()
break
if result == 1:
print("You Win")
elif result == -1:
print("You Lose")
else:
print("It's a Draw")
And Finally, the 'if loop'?
Let me just make this clear. There is no such thing as an if loop!!! An if statement runs code **ONCE** if a certain condition is True. I think what you want is a while loop. This runs code **REPEATEDLY** as long as a certain condition is True. In the code below, I created a while True loop, which runs the code each time the user types in "y", and breaks from the loop if not.
Also, use if __name__ == '__main__'. It exists in Python so that Python files can act as either reusable modules, or as standalone programs. It also looks more complex, if you want to look smart.
if __name__ == '__main__':
while True:
main()
if input("Again? Yes(y) No(Anything else): ").lower() != 'y':
break
Example Output (ignore colours):
Choose 1 (rock), 2 (paper) or 3 (scissors):1
You: Rock Computer: Scissors
You Win
Again? Yes(y) No(Anything else): y
Choose 1 (rock), 2 (paper) or 3 (scissors):3
You: Scissors Computer: Scissors
It's a Draw
Again? Yes(y) No(Anything else): y
Choose 1 (rock), 2 (paper) or 3 (scissors):2
You: Paper Computer: Paper
It's a Draw
Again? Yes(y) No(Anything else): n
Process finished with exit code 0
Also, for the OP, if you haven't already, I would recommend downloading Pycharm. It is completely free, and makes coding a lot easier. It also improves presentation too. It picks up on some of the things mentioned above, as well as keeping your code in line with PEP guidelines.

"List indices must be integers or slices, not tuple" error

I am a beginner at coding and I'm currently making an rpg. When I run the code, it gives me the above error. The part that is giving me the error is print("You are on " + floors[currentRoom] + ". You find " + floorsFeature[currentRoom]). My guess is that there must be something wrong with floors, floorsFeature, and currentRooms. Because I'm a beginner, I'm not sure what the error means. Can someone please explain in simple terms?
print("You are finally a Pokemon trainer! Today, you have gotten your very first Pokemon, a Bulbasaur!")
name = input("What will you name your Bulbasaur? ")
print("Unfortunately, " + name + " doesn't seem to obey or like you...")
print("You try to be friendly to " + name + ", but it just won't listen...")
print("As " + name + " was busy ignoring you, something seems to catch its attention and it runs off!")
print("You chase after " + name + ", but it's too fast! You see it running into an abandoned Pokeball Factory.")
print("You must explore the abandoned Pokeball Factory and find " + name + " before something happens to it!")
print()
print("You may input 'help' to display the commands.")
print()
gamePlay = True
floors = [['floor 1 room 1', 'floor 1 room 2', 'floor 1 room 3', 'floor 1 room 4'],['floor 2 room 1', 'floor 2 room 2', 'floor 2 room 3', 'floor 2 room 4', 'floor 2 room 5'],['floor 3 room 1,' 'floor 3 room 2', 'floor 3 room 3'],['floor 4 room 1', 'floor 4 room 2']]
floorsFeature = [['nothing here.', 'nothing here.', 'stairs going up.', 'a Squirtle.'],['stairs going up and a pokeball.', 'a Charmander.', 'a FIRE!!!', 'stairs going down.', 'a pokeball.'],['stairs going down.', 'a door covered in vines.', '2 pokeballs!'],['your Bulbasaur!!!', 'an Eevee with a key tied around its neck.']]
currentRoom = [0][1]
pokemonGot = []
count = 0
bagItems = []
countItems = 0
while gamePlay == True:
print("You are on " + floors[currentRoom] + ". You find " + floorsFeature[currentRoom])
move = input("What would you like to do? ")
while foo(move) == False:
move = input("There's a time and place for everything, but not now! What would you like to do? ")
if move.lower() == 'left':
if currentRoom > 0:
currentRoom = currentRoom - 1
print("Moved to " + floors[currentRoom] + ".")
else:
print("*Bumping noise* Looks like you can't go that way...")
elif move.lower() == 'right':
if currentRoom < len(floors) - 1:
currentRoom = currentRoom + 1
print("Moved to " + floors[currentRoom] + ".")
else:
print("*Bumping noise* Looks like you can't go that way...")
elif move.lower() == 'help':
print("Input 'right' to move right. Input 'left' to move left. Input 'pokemon' to see what Pokemon are on your team. Input 'bag' to see the items you are carrying. Input 'help' to see the commands again.")
elif move.lower() == 'pokemon':
if count == 0:
print("There are no Pokemon on your team.")
else:
print("The Pokemon on your team are: " + ", ".join(pokemonGot) + ".")
elif move.lower() == 'bag':
if countItems == 0:
print("There are no items in your bag.")
else:
print("The items in your bag are: " + ", ".join(bagItems) + ".")
print()
Lets go by parts:
Provide all the needed code:
We do not know what the foo() function does. It seems to be a validating function but we are missing that part of the code. Please always provide a piece of code we can run to check your errors.
foo() replacement:
To check a choice against a valid set of options you can do it in a single line:
1 in [1, 2, 3] # Output: True
4 in {1, 2, 3} # Output: False
4 not in {1, 2, 3} # Output: True
"b" in ("a", "b", "c") # Output: True
"abc" in ("a", "b", "c") # Output: False
"a" in "abc" # Output: True
As you can see I've used different values (int and str) and different containers (list, set, tuple, str, ...) and I could use even more. Using not in gives you the opposite answer as expected. In your case you could use:
commands = {'help', 'pokemons', 'bag', 'left', 'right'}
while move not in commands:
...
String formating:
There are multiple ways of formatting strings to include variables values inside them, but the most pythonic way is using str.format(). You can check the documentation on how the formatting string works here, but the most simple example would be:
print("Unfortunately, {} doesn't seem to obey or like you...".format(name))
Basically you use placehodlers delimited by {} and then call the .format() function with the arguments you want to place there. Inside the {} you can place different additional strings to format the output as for example determining the number of decimals of a float number.
lists and tuples:
Both lists and tuples in Python are sequence containers. The main difference in that the list is mutable and the tuple isn't. They are both accessed with the var[position] notation starting from 0. So if you are not going to ever change the content of a sequence, you should use a tuple instead of a list to enforce it to the interpreter and to be more memory efficient. You use parenthesis instead of square brackets for tuples.
dicts
dicts are a great way of holding state:
player = {
'floor': 1,
'room': 2,
'pokemons': [],
'bag': [],
}
You don't have to store the length of an array:
In some languages you always keep the ammount of items inside an array stored. Python's containers can determine at runtime their size by calling len(container). You have used it at some parts of the code but you are keeping a count and countItems variables that are not needed.
Multi dimensional lists (a.k.a. matrixes):
You seem to be having some problems dealing with matrixes, use the following notation: matrix[i][j] to access the j+1th element (as it starts in 0) of the i+1th list.
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]
print(matrix[1][2]) # Output: 6
To know the number of lists, in your case floors, use len(matrix). To know the number of elements of the n-th list use len(matrix[n-1]).
The final code:
commands = {'help', 'pokemons', 'bag', 'left', 'right', 'exit'}
gamePlay = True
features = (
['nothing here.' , 'nothing here.' , 'stairs going up.', 'a Squirtle.' ],
['stairs going up and a pokeball.', 'a Charmander.' , 'a FIRE!!!' , 'stairs going down.', 'a pokeball.'],
['stairs going down.' , 'a door covered in vines.' , '2 pokeballs!'],
['your Bulbasaur!!!' , 'an Eevee with a key tied around its neck.'],
)
player = {
'floor': 1,
'room': 2,
'pokemons': [],
'bag': [],
}
def positionString(player):
return "floor {p[floor]} room {p[room]}".format(p=player)
def featureString(player):
return features[player['floor']-1][player['room']-1]
print("You are finally a Pokemon trainer! Today, you have gotten your very first Pokemon, a Bulbasaur!")
name = input("What will you name your Bulbasaur? ")
print("Unfortunately, {} doesn't seem to obey or like you...".format(name))
print("You try to be friendly to {}, but it just won't listen...".format(name))
print("As {} was busy ignoring you, something seems to catch its attention and it runs off!".format(name))
print("You chase after {}, but it's too fast! You see it running into an abandoned Pokeball Factory.".format(name))
print("You must explore the abandoned Pokeball Factory and find {} before something happens to it!".format(name))
print()
print("You may input 'help' to display the commands.")
print()
while gamePlay == True:
print("You are on {}. You find {}".format(positionString(player), featureString(player)))
move = input("What would you like to do? ").lower()
while move not in commands:
move = input("There's a time and place for everything, but not now! What would you like to do? ").lower()
if move == 'left':
if player['room'] > 1:
player['room'] -= 1
print("Moved to {}.".format(positionString(player)))
else:
print("*Bumping noise* Looks like you can't go that way...")
elif move == 'right':
if player['room'] < len(features[player['floor']-1]):
player['room'] += 1
print("Moved to {}.".format(positionString(player)))
else:
print("*Bumping noise* Looks like you can't go that way...")
elif move == 'help':
print("Input 'right' to move right. Input 'left' to move left. Input 'pokemons' to see what Pokemon are on your team. Input 'bag' to see the items you are carrying. Input 'help' to see the commands again.")
elif move == 'pokemons':
if len(player['pokemons']) == 0:
print("There are no Pokemon on your team.")
else:
print("The Pokemon on your team are: {}.".format(", ".join(player['pokemons'])))
elif move == 'bag':
if len(player['bag']) == 0:
print("There are no items in your bag.")
else:
print("The items in your bag are: {}.".format(", ".join(player['bag'])))
elif move == 'exit':
gamePlay = False
print()
As you can see I've made two functions to get the name of the room and the feature of the room from the state vector so that I do not have to duplicate that part of the code anywhere. One of the function is generating the string itself as they all had the same scheme: floor X room Y. Holding them on a matrix makes no sense unless you wnat to give them names such as 'lobby', I let you the task of modifying the function if thats the case, it should be easy as it would be very similar to the second one. I've also added an 'exit' command to get out of the loop.
I was not able to replicate your error with the code provided as it threw another error (list index out of range)
I suspect the issue is here
currentRoom = [0][1]
What this means is that you are trying to set the value of currentRoom to the index 1 of [0], which does not exist.
[0] here is a list containing one item.
If you are confused about this, fire up python3, and try this
currentRoom = [0,2][1]
print(currentRoom)
Based on your sample, you are using a nested list for your floor list.
floor[0] = floor 1, floor [0] = floor 2, etc.
within floor 1, you have another list, where each index determines your current room.
How about using two integers to hold the current position instead?
currentRoom = 0 // room 1
currentFloor = 0 //floor 1
print (You are on floors[currentFloor][currentRoom], you find floorsFeature[currentFloor][currentRoom])
....
..... // user entered move left
if currentRoom >0:
currentRoom -= 1
print (Moved to floors[currentFloor][currentRoom])
.... //user went up by one floor
if ....
currentFloor += 1
print (Moved to floors[currentFloor][currentRoom])
You can't define currentRoom = [0][1]:
>>> currentRoom = [0][1]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
[0][1] is not an integer, a string or another type. You can use a list or a tuple to keep floor and room info:
#To get floor 3, room 2
currentRoom = [2,1] # Or you can use currentRoom = (2,1)
print(floors[currentRoom[0]][currentRoom[1]]) # It refers print(floors[2][1])
Output:
floor 3 room 2
The error in the header can occur when you do:
>>> currentRoom = (2,1)
>>> print(floors[currentRoom])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: list indices must be integers or slices, not tuple
Use the solution above:
print(floors[currentRoom[0]][currentRoom[1]])

Python ignores input for raw_input and continues to repeat function [duplicate]

This question already has answers here:
How to test multiple variables for equality against a single value?
(31 answers)
Closed 8 years ago.
This is a small experiment I am trying in learning Python. Its meant to be a text based slot machine, where 3 slots are 'rolled' and 1 of the 4 possible choices is chosen for each
If the 2 numbers match, 5 points are given. If all 3 match, 10 are given.
After running this function the game prints their current score asks if the user wants to play again. At this portion of the code:
def ask():
play_again = raw_input ("Do you want to play again? (Yes or No):")
if play_again == "yes" or "Yes":
run_machine()
elif play_again == "No" or "no":
print "Bye!"
sys.exit(1)
else:
print "I don't know what that means"
ask()
Where run_machine() is the main function. However regardless of the input, the program repeats. I am new to python so this might be something simple but I wanted to see what so far might be the problem.
If it isn't something in this block then here is the full program:
import random
slot_1 = [1,2,3,4]
slot_2 = [1,2,3,4]
slot_3 = [1,2,3,4]
points = 0
def role(slot):
return (random.choice(slot))
def run_machine():
print "ROLLING!"
first = role(slot_1)
second = role(slot_2)
third = role(slot_3)
global points
if (first == second) or (first == third) or (second == third):
if (first == second) and (second == third):
print "You got 10 points! Full matches!"
points = points + 10
else:
print "You got 5 points, 2 matched!"
points = points + 5
else:
print "Sorry try again!"
print "You now have %s points" % points
ask()
def ask():
play_again = raw_input ("Do you want to play again? (Yes or No):")
if play_again == "yes" or "Yes":
run_machine()
elif play_again == "No" or "no":
print "Bye!"
else:
print "I don't know what that means"
ask()
run_machine()
This does not do what you think it does.
if play_again == "yes" or "Yes":
The correct way to say this would be the following (I added parentheses for emphasis)
if (play_again == "yes") or (play_again == "Yes"):
The way you originally wrote it means the following in pseudo-code
if (play_again == "yes")
or
if ("Yes") # this always evaluates to True

Python dicerolling program skipping the roll

I have been trying to create a program that will simulate a dice roll, with the option to choose between a 4, 6, or 12 sided die. At the moment the problem I am having is that the program skips the rolling entirely no matter what option I choose and immediately asks me if I want to roll again. Im using Portable Python 3.2.1.1 to create the code. This is what I have so far:
#!/usr/bin/env python
import random
def fourdie():
min = 1
max = 4
print (random.randint(min, max));
return;
def sixdie():
min = 1
max = 6
print (random.randint(min, max));
return;
def twelvedie():
min = 1
max = 12
print (random.randint(min, max));
return;
roll = "yes"
y = 1
while roll == "yes" or roll == "y":
x = raw_input("What die do you want to roll? 4, 6 or 12?");
if x == 4:
print (fourdie());
elif x == 6:
print (sixdie());
elif x == 12:
print (twelvedie());
else:
print = "Sorry, I dont appear to have that dice type";
roll = raw_input("Do you want to roll again?");
Any help would be appreciated.
Thank you for your time!
input function returns a string.
You can convert this string to int and then compare it to 4, 6, or 12:
x = int(input("What die do you want to roll? 4, 6 or 12?"))
if x == 4:
// whatever
elif x == 6:
// whatever
Or you can compare x directly to a string:
x = input("... whatever ...")
if x == "4":
// whatever
elif x == "6":
// whatever
And one other thing: there is no need to end lines with the semicolon in python. Makes Guido van Rossum happy.
Your basic problem is typing, as solved by Nigel Tufnel
I just, because it strikes my fancy, thought I'd mention you could make your code far more generic:
while roll in ["yes", "y"]:
x = int(raw_input("Number of sides on the die you want to roll?"))
print random.randint(1,x)
roll = raw_input("Do you want to roll again?")

Categories

Resources