Coin Flipping/Card picking program not working - python

I was given a task to write a program in a pretty basic python style. The program is supposed to ask the user whether they want to 1. Flip a coin, or 2. Pick a card.
Then uses an IF to check what the user picked. If it was one, it's supposed to randomly generate heads or tails and print what it got.
If the choice was 2, it asks the user to choose a suit, then generates a number between 1 and 13 (ace to king) and prints 'You picked [value] of [suit]'
import random
print('1. Flip a coin')
print('2. Pick a card')
choice = int(input('Enter a coice :'))
if choice == 1:
Hort = ''
HorT == random.randint(0,1)
if HorT == "0":
print('You got Heads')
elif HorT == "1":
print('You got Tails')
elif choice == 2:
print()
print('1. Hearts')
print('2. Clubs')
print('3. Diamonds')
print('4. Spades')
print()
suitno = ''
suitno ==int(input('Choose a suit'))
if suitno == "1":
suit == "Hearts"
elif suitno == '2':
suit == 'Clubs'
elif suitno == '3':
suit == 'Diamonds'
elif suitno == '4':
suit == 'Spades'
value = ''
value == random.randint(1,13)
print()
print('You picked', value, 'of', suit)
as you can see, it's basic but I was asked to follow the pseudo-code as closely as I could. It stops right at the beginning. I enter then number for the choice, and it just ends.
EDIT: I have amended the code to show what I have changed.

You have 2 problems:
choice = int(input('Enter a coice :'))
if choice == '1':
Here you are comparing integer choice and string '1' values.
And the second problem that you have a lot of constructions that looks like:
if a == '1':
some_statement
elif a == '2:
some statement
...
Such switch can be formed in python with dictionaries:
import random
coin_sides = {
'1': 'Heads',
'2': 'Tails'
}
card_suits = {
'1': 'Hearts',
'2': 'Clubs',
'3': 'Diamonds',
'4': 'Spades'
}
print('1. Flip a coin')
print('2. Pick a card')
choice = input('Enter a coice :')
if choice == '1':
side = random.randint(0,1)
print 'You got {0}'.format(coin_sides.get(side))
elif choice == '2':
print()
print('1. Hearts')
print('2. Clubs')
print('3. Diamonds')
print('4. Spades')
print()
suitno = input('Choose a suit')
suit = card_suits.get(suitno)
value = random.randint(1,13)
print()
print('You picked', value, 'of', suit)

Since other answers quite adequately critique your card-picking design, I'll only post the bit I had about your coin flip.
Flip a Coin
The outcome of this program is a statment:
You got {heads|tails}.
Thus, we are only interested in the strings 'heads' or 'tails'. Since explicit is better than implicit:
outcomes = ('heads', 'tails')
print('You got {}.'.format(random.choice(outcomes)))
is all you need.

Common mistakes:
== used for comparison and not for assignment e.g 4 == 4 is True
variable of int type will never be equal to string e.g 4 == '4' is False. This is the reason why your if statements didn't execute.
There's no need in variable initialization before getting input().
It usually better to have else if you have elif.
Dirty, but complete fix:
import random
print('1. Flip a coin')
print('2. Pick a card')
choice = int(input('Enter a coice: '))
if choice == 1:
HorT = random.randint(0,1)
if HorT == 0:
print('You got Heads')
else:
print('You got Tails')
elif choice == 2:
print()
print('1. Hearts')
print('2. Clubs')
print('3. Diamonds')
print('4. Spades')
print()
suitno = int(input('Choose a suit: '))
if suitno == 1:
suit = "Hearts"
elif suitno == 2:
suit = 'Clubs'
elif suitno == 3:
suit = 'Diamonds'
else:
suit = 'Spades'
value = random.randint(1, 13)
print()
print('You picked', value, 'of', suit)
It could be written more concisely, but it is pretty basic python style program :)
#Two-Bit Alchemist - #vaultah version:
import random
print('1. Flip a coin')
print('2. Pick a card')
choice = int(input('Enter a choice: '))
if choice == 1:
outcomes = ('heads', 'tails')
print('You got {}.'.format(random.choice(outcomes)))
else:
suits = ('Hearts', 'Clubs', 'Diamonds', 'Spades')
print()
for index, element in enumerate(suits, start=1):
print('{}. {}'.format(index, element))
suitno = int(input('Choose a suit: '))
value = random.randint(1, 13)
print('\nYou picked', value, 'of', suits[suitno-1])

Here's another restructured version:
from random import choice
COINS = ["Heads", "Tails"]
FACES = ["Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"]
SUITS = ["Hearts", "Clubs", "Diamonds", "Spades"]
def get_int(prompt, lo=None, hi=None):
while True:
try:
value = int(input(prompt))
if (lo is None or lo <= value) and (hi is None or value <= hi):
return value
except ValueError:
pass
def do_menu(prompt, options):
print("")
for i,option in enumerate(options, 1):
print("{:>3}. {}".format(i, option))
return get_int(prompt, 1, len(options)) - 1
def main():
while True:
option = do_menu("> ", ["Flip a coin", "Pick a card", "Quit"])
if option == 0:
print("\nYou flipped {}.".format(choice(COINS)))
elif option == 1:
suit = SUITS[do_menu("Pick a suit: ", SUITS)]
print("\nYou picked {} of {}".format(choice(FACES), suit))
else:
print("\nGoodbye!")
break
if __name__=="__main__":
main()

Related

Getting an error for using break command in Python

So I'm trying to use a break in my code for a choice to quit the program, but when I run it, I get "break outside Loop". Is there a way to fix it? I've tried the return command or other commands from other questions similar to this one, but I had no luck with them. Here's the piece of code I'm referring to:
v1 = []
v2 = []
while True:
print('Welcome to vector arithmetic! Below is a list of available operations.')
print('1. Enter values for your vectors')
print('2. Print vectors')
print('3. Vector dimensionality')
print('4. Add vectors')
print('5. Compute dot product of vectors')
print('6. Compute magnitude of vectors')
print('7. Quit')
choice = int(input('Enter the number corresponding to your choice: '))
if choice == 7:
break
elif choice == 1:
pass
elif choice == 2:
pass
elif choice == 3:
pass
elif choice == 4:
pass
elif choice == 5:
pass
elif choice == 6:
pass
else:
print('Invalid choice, try again')
In python, the indentation and white space matters. As the comment above mentions, I just moved that whole block below your while statement into the correct indentation and works as you expect.
v1 = []
v2 = []
while True:
print('Welcome to vector arithmetic! Below is a list of available operations.')
print('1. Enter values for your vectors')
print('2. Print vectors')
print('3. Vector dimensionality')
print('4. Add vectors')
print('5. Compute dot product of vectors')
print('6. Compute magnitude of vectors')
print('7. Quit')
choice = int(input('Enter the number corresponding to your choice: '))
if choice == 7:
break
elif choice == 1:
pass
elif choice == 2:
pass
elif choice == 3:
pass
elif choice == 4:
pass
elif choice == 5:
pass
elif choice == 6:
pass
else:
print('Invalid choice, try again')
Your code is not properly indented:
v1 = []
v2 = []
while True:
print('Welcome to vector arithmetic! Below is a list of available operations.')
print('1. Enter values for your vectors')
print('2. Print vectors')
print('3. Vector dimensionality')
print('4. Add vectors')
print('5. Compute dot product of vectors')
print('6. Compute magnitude of vectors')
print('7. Quit')
choice = int(input('Enter the number corresponding to your choice: '))
if choice == 7:
break
elif choice == 1:
pass
elif choice == 2:
pass
elif choice == 3:
pass
elif choice == 4:
pass
elif choice == 5:
pass
elif choice == 6:
pass
else:
print('Invalid choice, try again')
As you can see, indentation in python is very important.
Seems to me that you are having an indentation error, in that case you need to make sure that while you enter anything in a loop, function, or class that it is properly indented.
v1 = []
v2 = []
while True:
print('Welcome to vector arithmetic! Below is a list of available operations.')
print('1. Enter values for your vectors')
print('2. Print vectors')
print('3. Vector dimensionality')
print('4. Add vectors')
print('5. Compute dot product of vectors')
print('6. Compute magnitude of vectors')
print('7. Quit')
choice = int(input('Enter the number corresponding to your choice: '))
if choice == 7:
break
elif choice == 1:
pass
elif choice == 2:
pass
elif choice == 3:
pass
elif choice == 4:
pass
elif choice == 5:
pass
elif choice == 6:
pass
else:
print('Invalid choice, try again')
Also, I do not recommend that you use break in loops as they can be problematic if they are not implemented properly. Instead, try using quit

List failing on second run

I am currently trying to program a mathematical card trick, which asks the user what pile their random card is in. However, the second time it runs (the 'trick phase' has to occur 3 times for the trick to work) the list index becomes out of range. I am unsure where exactly the problem lies and will attach the current version so you can try to run it to see clearer. Thanks!
import random
def makedeck():
listy = []
cardsindeck = 0
while cardsindeck != 21:
suit = random.randint(1,4)
if suit == 1:
suit = "D"
elif suit == 2:
suit = "H"
elif suit == 3:
suit = "S"
else:
suit = "C"
cardtype = random.randint(1,13)
if cardtype == 1:
card = "A"
elif cardtype == 2:
card = "2"
elif cardtype == 3:
card = "3"
elif cardtype == 4:
card = "4"
elif cardtype == 5:
card = "5"
elif cardtype == 6:
card = "6"
elif cardtype == 7:
card = "7"
elif cardtype == 8:
card = "8"
elif cardtype == 9:
card = "9"
elif cardtype == 10:
card = "10"
elif cardtype == 11:
card = "J"
elif cardtype == 12:
card = "Q"
else:
card = "K"
cardandsuit = (card + suit)
if cardandsuit not in listy:
listy.append(cardandsuit)
cardsindeck = cardsindeck + 1
return listy
def dealdeck(listy):
list1 = []
list2 = []
list3 = []
for i in range(len(listy)):
if i % 3 == 0:
list1.append(listy[i])
elif i % 3 == 1:
list2.append(listy[i])
else:
list3.append(listy[i])
return[list1, list2, list3]
def makepiles(pile1,pile2,pile3):
print("Pile 1\t\tPile 2\t\t Pile 3\t\t")
for i in range(7):
print(pile1[i],"\t\t",pile2[i],"\t\t",pile3[i],"\t\t")
def usercardpile():
userinput = input("What pile is your card in?")
if userinput == "1" or userinput.title() == "One":
return 1
elif userinput == "2" or userinput.title() == "Two":
return 2
elif userinput == "3" or userinput.title() == "Three":
return 3
else:
print("Please only write 1, 2 or 3")
return usercardpile()
listy = makedeck()
pile1, pile2, pile3 = dealdeck(listy)
for i in range(1,4):
newlisty = makepiles(pile1,pile2,pile3)
userspile = usercardpile()
if userspile == 1:
newlisty = (pile2,pile1,pile3)
elif userspile == 2:
newlisty = (pile1,pile2,pile3)
else:
newlisty = (pile1,pile3,pile2)
pile1, pile2, pile3 = dealdeck(newlisty)
print("Your card is",newlisty[10])
One issue is with this line of code:
newlisty = makepiles(pile1, pile2, pile3)
You're expecting makepiles to return 3 lists, whereas it returns None (no explicit item returned).
I imagine if you were to return the piles from that function, it'd work.
The other thing is, You are doing this:
newlisty = (pileX, pileY, pileZ)
This will create a tuple of lists, and you will iterate over the entire lists rather than the individual cards. I believe you want
newlisty = pile1 + pile3 + pile2`
This'll create a composite list of 21 elements by linearly combining the smaller piles.
Other comments:
Consider storing your decktype and card type in dicts. That way, you can quickly lookup and generate your piles without having to write a long set of if statements. Example:
You can reduce
cardtype = random.randint(1,13)
if cardtype == 1:
card = "A"
elif cardtype == 2:
card = "2"
elif cardtype == 3:
card = "3"
elif cardtype == 4:
card = "4"
elif cardtype == 5:
card = "5"
elif cardtype == 6:
card = "6"
elif cardtype == 7:
card = "7"
elif cardtype == 8:
card = "8"
elif cardtype == 9:
card = "9"
elif cardtype == 10:
card = "10"
elif cardtype == 11:
card = "J"
elif cardtype == 12:
card = "Q"
else:
card = "K"
To...
cardtype_lookup = { 1 : 'A', 2 : '2', 3 : '3', .... 12 : 'K' }
card = cardtype_lookup[random.randint(1, 13)]
...And so on.
I think you are hitting a few issues with your code beyond just the final iterations. Below are some suggestions along with comments that I believe accomplishes your purpose.
from random import shuffle
# Function for generating 21 random cards
def makedeck():
# Create 52 cards by suit and cardtype
listy = [card + suit for card in ['A','2','3','4','5','6','7','8','9','10','J','Q','K'] for suit in ['D','H','S','C']]
# Shuffle the list
shuffle(listy)
# Choose only the first 21 items of that list
listy = listy[:21]
return listy
# Function for dividing 21-card deck into 3 equally-sized piles
def dealdeck(listy):
# Iterate over listy, stepping by 3, starting with the first, second, and third item
list1 = listy[::3]
list2 = listy[1::3]
list3 = listy[2::3]
# Return the three lists as three items to correspond to the three piles of the call
return list1, list2, list3
# This works
def makepiles(pile1,pile2,pile3):
print("Pile 1\t\tPile 2\t\t Pile 3\t\t")
for i in range(7):
print(pile1[i],"\t\t",pile2[i],"\t\t",pile3[i],"\t\t")
# This works
def usercardpile():
userinput = input("What pile is your card in?")
if userinput == "1" or userinput.title() == "One":
return 1
elif userinput == "2" or userinput.title() == "Two":
return 2
elif userinput == "3" or userinput.title() == "Three":
return 3
else:
print("Please only write 1, 2 or 3")
return usercardpile()
listy = makedeck()
pile1, pile2, pile3 = dealdeck(listy)
for i in range(1,4):
# Because this function does not return anything, it should be run on its own, and not assigned to a variable
makepiles(pile1,pile2,pile3)
userspile = usercardpile()
# Now you want to re-order the piles based on user input. Because these are lists, you can simply add them together in a new order to create a newly arranged list
if userspile == 1:
newlisty = pile2 + pile1 + pile3
elif userspile == 2:
newlisty = pile1 + pile2 + pile3
else:
newlisty = pile1 + pile3 + pile2
# Now you create new piles based on the re-sorted list and re-iterate
pile1, pile2, pile3 = dealdeck(newlisty)
# Uses .format method instead
print("Your card is {}".format(newlisty[10]))

Why this conversion program does not work?

I am trying to figure out what is wrong in here. Any help is very appreciated. I think one of the problem is the declaration of the variable that is inside the method. Can I make a global variable from the method?
def cycle():
choice = None
while not choice:
newcalc = input('Do you want to make a new calculation? \n \t (Y/N)')
if newcalc.lower() in ["no", "n"]:
choice = "no"
if newcalc.lower() in ["yes", "y"]:
choice = "yes"
else:
print('This is not the right answer')
continue
return choice
def counting_M(data):
while True:
concersion_1 = input('Do you want to convert from M to uM? (Y/N)')
if concersion_1.lower() in ["y", "yes"]:
print('This is the result of the conversion {} uM'.format(str(data/1000)))
else:
print('Not converting')
while True:
mw = input('What is the Molecular Weight of your compound, please in g/M?')
try:
mw = float(mw)
break
except ValueError:
print("Not a valid float!")
print('Your coumpound weights ug/ml', str((data/1000) / (mw / 1000)))
def measure():
while True :
data = input('Please, provide the absolute amount of compound you have, without units \n \t')
try:
data = float(data)
break
except ValueError:
print("Not a valid float value!")
units = input('Please, indicate the measure unit you have \n A)M, B)mM, C)uM '
'\n 1A)g/liter, 2A)mg/ml, 3A)ug/ml \n \t')
if units.lower() == "a":
print('Ok so you have M')
counting_M(data)
choice = cycle()
print(choice)
elif units.lower() == "b":
print('Ok so you have mM')
counting_M(data)
choice = cycle()
print(choice)
elif units.lower() == "c":
print('Ok so you have uM which it the right concentration')
cycle()
elif units.lower() == "1a":
print('Ok so you have g/liter you have now mg/ml')
counting_M(data)
choice = cycle()
print(choice)
elif units.lower() == "2a":
print('Ok so you have mg/ml')
counting_M(data)
choice = cycle()
print(choice)
elif units.lower() == "3a":
print('Ok so you have ug/ml, hence nothing to do')
cycle()
else:
print('You have to select one of the options above')
counting_M(data)
choice = cycle()
print(choice)
Thank you for your help

Data being Stored in wrong Object

SORRY FOR THE MESSY AND INEFFICIENT CODE
Let me start with the basic rules for the code. A bag is stored under a mattress and each bag can only contain coins. Individually they can only contain a single type of coin. So the pennies bag cannot contain dimes or any other coin, only pennies.
Ok so, the Issue I have here is that when I deposit money it doesn't matter what "Bag" I deposit into, the coins automatically go to the Dime bag and I can't find where in the code this is happening. From my viewpoint, the code makes sense(Which it would to me but not the computer). I really think I just need a second set of eyes looking at it. I'm also not a python programmer which doesn't really help
import os
class Bags:
def __init__(self, nOC, n, v):
self.name = n
self.numOfCoins = nOC
self.value = v
self.SetBal()
# Setters
def SetBal(self):
self.amount = self.numOfCoins * self.value
def SetCoin(self, coin):
self.numOfCoins += coin
self.SetBal()
# Getters
def GetBal(self):
return self.amount
class Mattress:
def __init__(self):
self.pBag = Bags(0, "Pennies", 0.01)
self.dBag = Bags(0, "Dimes", 0.05)
self.nBag = Bags(0, "Nickles", 0.10)
self.qBag = Bags(0, "Quarters", 0.25)
self.boBag = Bags(0, "Bug-Out-Bag", 0.00)
# Setters
# Getters
def GetBalances(self):
pen = self.pBag.GetBal()
print("Balance of pennies : $%.2f. %d pennies" % (pen, self.pBag.numOfCoins))
print("Balance of dimes : $%.2f. %d dimes" % (self.dBag.GetBal(), self.dBag.numOfCoins))
print("Balance of nickles : $%.2f" % self.nBag.GetBal())
print("Balance of quarters: $%.2f" % self.qBag.GetBal())
total = self.pBag.GetBal() + self.qBag.GetBal() + self.dBag.GetBal() + self.nBag.GetBal()
print("Total : $%.2f" % total)
def main ():
# Check laod or what not for what you have to do and all that good stuff
userMain = Mattress()
mainLoop = True
menu = '''What would you like to do?
D. Deposit Money
W. Withdraw Money
T. Transfer Funds
S. Show Balances
E. Exit'''
diffBags = '''
P. Pennies
D. Dimes
N. Nickles
Q. Quarters
C. Cancel'''
while(mainLoop):
print(menu)
action = input("Select an option: ")
if action == 'D' or action == 'd' :
depositMenu = "What bag would you like to deposit into? " + diffBags
depLoop = True
while(depLoop):
print(depositMenu)
depAction = input("Select an option: ")
depAmt = "How much would you like to deposit? "
if depAction == 'P' or action == 'p':
while True:
try:
depCoin = int(input(depAmt))
if depCoin < 1:
print("Invalid. Please enter a positive number")
continue
break
except ValueError:
print("Invalid. Please enter a positive number")
userMain.pBag.SetCoin(depCoin)
depLoop = False
elif depAction == 'D' or action == 'd':
while True:
try:
depCoin = int(input(depAmt))
if depCoin < 1:
print("Invalid. Please enter a positive number")
continue
break
except ValueError:
print("Invalid. Please enter a positive number")
userMain.dBag.SetCoin(depCoin)
depLoop = False
elif depAction == 'N' or action == 'n':
while True:
try:
depCoin = int(input(depAmt))
if depCoin < 1:
print("Invalid. Please enter a positive number")
continue
break
except ValueError:
print("Invalid. Please enter a positive number")
userMain.nBag.SetCoin(depCoin)
depLoop = False
elif depAction == 'Q' or action == 'q':
while True:
try:
depCoin = int(input(depAmt))
if depCoin < 1:
print("Invalid. Please enter a positive number")
continue
break
except ValueError:
print("Invalid. Please enter a positive number")
userMain.qBag.SetCoin(depCoin)
depLoop = False
elif depAction == 'C' or action == 'c':
depLoop = False
elif action == 'W' or action == 'w':
print ("working on it")
elif action == 'T' or action == 't':
print ("working on it")
elif action == 'S' or action == action == 's':
userMain.GetBalances()
elif action == 'E' or action == 'e':
print("Have a great day")
mainLoop = False
else:
print ("Incorrect value")
if __name__ == "__main__":
main()
I found your problem.
Let me explain to you how I found your problem, so next time you can find it.
I added a line to your code
print("Q")
userMain.qBag.SetCoin(depCoin)
Given what your program was trying to do I expected that to be printed when I tried to add quarters. But it was never printed, indicating that something had gone before that point.
Next I added another line:
depAction = input("Select an option: ")
print("GOT", depAction)
Then I ran the program again, and it printed.
Now I know the problem is somewhere between the two print statements. Given that the program ends up adding it to the dimes, it makes it look like somehow we ended up running the dimes-adding code even though I had entered q. I look at the code which checked for entry into the dimes section and saw the problem.
I see the problem, but the for sake of a didactic exercise I think you should find it yourself.

if, elif not working as expected

I am new to Python and I do not know why but the if, elif in the following code is not working as I expect it to. However,
It works perfectly when I type 1 to 7
it works perfectly when I type 0 8 or 9 (it says "Try again")
It does not work if I type 10 to 69, 100 to any number
When I say it does not work I mean it prints
my_shape_num = h_m.how_many()
But I do not know why. It has to stop if choice is not between 1 and 7
def main(): # Display the main menu
while True:
print
print " Draw a Shape"
print " ============"
print
print " 1 - Draw a triangle"
print " 2 - Draw a square"
print " 3 - Draw a rectangle"
print " 4 - Draw a pentagon"
print " 5 - Draw a hexagon"
print " 6 - Draw an octagon"
print " 7 - Draw a circle"
print
print " X - Exit"
print
choice = raw_input(' Enter your choice: ')
if (choice == 'x') or (choice == 'X'):
break
elif (choice >= '1' and choice <= '7'):
my_shape_num = h_m.how_many()
if ( my_shape_num is None):
continue
d_s.start_point() # start point on screen
if choice == '1':
d_s.draw_triangle(my_shape_num)
elif choice == '2':
d_s.draw_square(my_shape_num)
elif choice == '3':
d_s.draw_rectangle(my_shape_num)
elif choice == '4':
d_s.draw_pentagon(my_shape_num)
elif choice == '5':
d_s.draw_hexagon(my_shape_num)
elif choice == '6':
d_s.draw_octagon(my_shape_num)
elif choice == '7':
d_s.draw_circle(my_shape_num)
else:
print
print ' Try again'
print
Edit: Ok, sorted:
choice = raw_input(' Enter your choice: ')
if (choice == 'x') or (choice == 'X'):
break
try:
choice = int(choice)
if (1 <= choice <= 7):
my_shape_num = h_m.how_many()
if ( my_shape_num is None):
continue
d_s.start_point() # start point on screen
if choice == 1:
d_s.draw_triangle(my_shape_num)
elif choice == 2:
d_s.draw_square(my_shape_num)
elif choice == 3:
d_s.draw_rectangle(my_shape_num)
elif choice == 4:
d_s.draw_pentagon(my_shape_num)
elif choice == 5:
d_s.draw_hexagon(my_shape_num)
elif choice == 6:
d_s.draw_octagon(my_shape_num)
elif choice == 7:
d_s.draw_circle(my_shape_num)
else:
print
print ' Number must be from 1 to 7!'
print
except ValueError:
print
print ' Try again'
print
Strings are compared lexicographically: '10' is greater than '1' but less than '7'. Now consider this code:
elif (choice >= '1' and choice <= '7'):
In addition to accepting '7', this will accept any string beginning with 1, 2, 3, 4, 5 or 6.
To fix, convert choice to integer as soon as you've tested for 'x', and use integer comparisons thereafter.
'43' < '7' # True
43 < 7 # False
int('43') < int('7') # False
You're comparing strings (text), so the order is like a dictionary. You need to convert them into integers (numbers), so that comparisons put them in counting order.
Then, course, you also need to be prepared for people typing things that aren't numbers:
int('hi') # ValueError
I think it's because you are using string for comparing... try
choice = int(choice)
before if, elif block and change their comparisons to
if choice == 1:
(without quotes)

Categories

Resources