Python Coin Toss - python

I am VERY new to Python and I have to create a game that simulates flipping a coin and ask the user to enter the number of times that a coin should be tossed. Based on that response the program has to choose a random number that is either 0 or 1 (and decide which represents “heads” and which represents “tails”) for that specified number of times. Count the number of “heads” and the number of “tails” produced, and present the following information to the user: a list consisting of the simulated coin tosses, and a summary of the number of heads and the number of tails produced. For example, if a user enters 5, the coin toss simulation may result in [‘heads’, ‘tails’, ‘tails’, ‘heads’, ‘heads’]. The program should print something like the following: “ [‘heads’, ‘tails’, ‘tails’, ‘heads’, ‘heads’]
This is what I have so far, and it isn't working at all...
import random
def coinToss():
number = input("Number of times to flip coin: ")
recordList = []
heads = 0
tails = 0
flip = random.randint(0, 1)
if (flip == 0):
print("Heads")
recordList.append("Heads")
else:
print("Tails")
recordList.append("Tails")
print(str(recordList))
print(str(recordList.count("Heads")) + str(recordList.count("Tails")))

You need a loop to do this. I suggest a for loop:
import random
def coinToss():
number = input("Number of times to flip coin: ")
recordList = []
heads = 0
tails = 0
for amount in range(number):
flip = random.randint(0, 1)
if (flip == 0):
print("Heads")
recordList.append("Heads")
else:
print("Tails")
recordList.append("Tails")
print(str(recordList))
print(str(recordList.count("Heads")) + str(recordList.count("Tails")))
I suggest you read this on for loops.
Also, you could pass number as a parameter to the function:
import random
def coinToss(number):
recordList, heads, tails = [], 0, 0 # multiple assignment
for i in range(number): # do this 'number' amount of times
flip = random.randint(0, 1)
if (flip == 0):
print("Heads")
recordList.append("Heads")
else:
print("Tails")
recordList.append("Tails")
print(str(recordList))
print(str(recordList.count("Heads")) + str(recordList.count("Tails")))
Then, you need to call the function in the end: coinToss().

You are nearly there:
1) You need to call the function:
coinToss()
2) You need to set up a loop to call random.randint() repeatedly.

I'd go with something along the lines of:
from random import randint
num = input('Number of times to flip coin: ')
flips = [randint(0,1) for r in range(num)]
results = []
for object in flips:
if object == 0:
results.append('Heads')
elif object == 1:
results.append('Tails')
print results

This is possibly more pythonic, although not everyone likes list comprehensions.
import random
def tossCoin(numFlips):
flips= ['Heads' if x==1 else 'Tails' for x in [random.randint(0,1) for x in range(numflips)]]
heads=sum([x=='Heads' for x in flips])
tails=numFlips-heads

import random
import time
flips = 0
heads = "Heads"
tails = "Tails"
heads_and_tails = [(heads),
(tails)]
while input("Do you want to coin flip? [y|n]") == 'y':
print(random.choice(heads_and_tails))
time.sleep(.5)
flips += 1
else:
print("You flipped the coin",flips,"times")
print("Good bye")
You could try this, i have it so it asks you if you want to flip the coin then when you say no or n it tells you how many times you flipped the coin. (this is in python 3.5)

Create a list with two elements head and tail, and use choice() from random to get the coin flip result. To get the count of how many times head or tail came, append the count to a list and then use Counter(list_name) from collections. Use uin() to call
##coin flip
import random
import collections
def tos():
a=['head','tail']
return(random.choice(a))
def uin():
y=[]
x=input("how many times you want to flip the coin: ")
for i in range(int(x)):
y.append(tos())
print(collections.Counter(y))

Instead of all that, you can do like this:
import random
options = ['Heads' , 'Tails']
number = int(input('no.of times to flip a coin : ')
for amount in range(number):
heads_or_tails = random.choice(options)
print(f" it's {heads_or_tails}")
print()
print('end')

I did it like this. Probably not the best and most efficient way, but hey now you have different options to choose from. I did the loop 10000 times because that was stated in the exercise.
#Coinflip program
import random
numberOfStreaks = 0
emptyArray = []
for experimentNumber in range(100):
#Code here that creates a list of 100 heads or tails values
headsCount = 0
tailsCount = 0
#print(experimentNumber)
for i in range(100):
if random.randint(0, 1) == 0:
emptyArray.append('H')
headsCount +=1
else:
emptyArray.append('T')
tailsCount += 1
#Code here that checks if the list contains a streak of either heads or tails of 6 in a row
heads = 0
tails = 0
headsStreakOfSix = 0
tailsStreakofSix = 0
for i in emptyArray:
if i == 'H':
heads +=1
tails = 0
if heads == 6:
headsStreakOfSix += 1
numberOfStreaks +=1
if i == 'T':
tails +=1
heads = 0
if tails == 6:
tailsStreakofSix += 1
numberOfStreaks +=1
#print('\n' + str(headsStreakOfSix))
#print('\n' + str(tailsStreakofSix))
#print('\n' + str(numberOfStreaks))
print('\nChance of streak: %s%%' % (numberOfStreaks / 10000))

#program to toss the coin as per user wish and count number of heads and tails
import random
toss=int(input("Enter number of times you want to toss the coin"))
tail=0
head=0
for i in range(toss):
val=random.randint(0,1)
if(val==0):
print("Tails")
tail=tail+1
else:
print("Heads")
head=head+1
print("The total number of tails is {} and head is {} while tossing the coin {} times".format(tail,head,toss))

Fixing the immediate issues
The highest voted answer doesn't actually run, because it passes a string into range() (as opposed to an int).
Here's a solution which fixes two issues: the range() issue just mentioned, and the fact that the calls to str() in the print() statements on the last two lines can be made redundant. This snippet was written to modify the original code as little as possible.
def coinToss():
number = int(input("Number of times to flip coin: "))
recordList = []
heads = 0
tails = 0
for _ in range(number):
flip = random.randint(0, 1)
if (flip == 0):
recordList.append("Heads")
else:
recordList.append("Tails")
print(recordList)
print(recordList.count("Tails"), recordList.count("Heads"))
A more concise approach
However, if you're looking for a more concise solution, you can use a list comprehension. There's only one other answer that has a list comprehension, but you can embed the mapping from {0, 1} to {"Heads", "Tails"} using one, rather than two, list comprehensions:
def coinToss():
number = int(input("Number of times to flip coin: "))
recordList = ["Heads" if random.randint(0, 1) else "Tails" for _ in range(number)]
print(recordList)
print(recordList.count("Tails"), recordList.count("Heads"))

import random
def coinToss(number):
heads = 0
tails = 0
for flip in range(number):
coinFlip = random.choice([1, 2])
if coinFlip == 1:
print("Heads")
recordList.append("Heads")
else:
print("Tails")
recordList.append("Tails")
number = input("Number of times to flip coin: ")
recordList = []
if type(number) == str and len(number)>0:
coinToss(int(number))
print("Heads:", str(recordList.count("Heads")) , "Tails:",str(recordList.count("Tails")))

All Possibilities in Coin Toss for N number of Coins
def Possible(n, a):
if n >= 1:
Possible(n // 2, a)
z = n % 2
z = "H" if z == 0 else "T"
a.append(z)
return a
def Comb(val):
for b in range(2 ** N):
A = Possible(b, [])
R = N - len(A)
c = []
for x in range(R):
c.append("H")
Temp = (c + A)
if len(Temp) > N:
val.append(Temp[abs(R):])
else:
val.append(Temp)
return val
N = int(input())
for c in Comb([]):
print(c)

heads = 1
tails = 0
input("choose 'heads' or 'tails'. ").upper()
random_side = random.randint(0, 1)
if random_side == 1:
print("heads you win")
else:
print("sorry you lose ")

Related

My python program freezes when I input a much larger list length

So I'm trying to write a program that guesses automatically a random number that I generate. And then store the number of guesses on a list.
My inputs are : the maximum number that the random number should not exceed; and the size of the list I want to store the number of guesses on after each guess.
My method to guess the number very quickly is to use half segmentation or dichotomy.
import random
import math
import numpy as np
Max_Number = input()
Size_Liste = input()
if Max_Number.isdigit() > 0 and Size_Liste.isdigit() > 0:
Max_Number = int(Max_Number)
Size_Liste = int(Size_Liste)
else:
print("Please Enter A Positif Integer. Goodbye!")
quit()
NG = [] #This list will store the number of guesses to find the random number
while len(NG) != Size_Liste:
Random_Number = random.randint(0 , Max_Number)
#print(Random_Number)
t1 = 0
t2 = Max_Number
Num_Guesses = 0
while True:
Y = int(abs(0.5 * (t2 - t1))) + t1
Num_Guesses += 1
if Y == Random_Number:
break
elif Y > Random_Number:
t2 = Y
continue
else:
t1 = Y
continue
NG.append(Num_Guesses)
continue
print(NG)
The program works fine when I demand 100 round of guesses (Size_List = 100), but it froze each time I demand a higher size.
Thank you
Your problem is that your binary search doesn't reach up to the max number that could be randomly generated.
If you do this:
Random_Number = random.randint(0 , Max_Number - 1)
then if Random_Number is assigned to Max_Number - 1, then this line:
Y = int(abs(0.5 * (t2 - t1))) + t1
will reach it.
The problem was never to do with the input of Size_Liste.

I want there to be a message printed when all the values are either 0 or 1

the message "all heads" is printed every time 0 appears whilst the message "all tails" doesn't appear at all
what should happen is when every value is 0 "all heads" gets printed but if all the values are 1 the message "all tails"
i tried writing that if all a equals 0 an n amount of time the message will print but if a equals 1 an n amount of times a different message will be printed
the code
import random
n = int(input("enter the number of coin flips "))
a = []
for q in range(n):
a = (random.randint(0,1))
print(a)
if a == 0*n:
print("all heads")
if a ==1*n:
print("all tails")
You were overwriting your list and nesting conditions that need not be nested. Here is an implementation for your consideration.
import random
def flip(n: int) -> list[int]:
return [random.randint(0, 1) for _ in range(n)]
if __name__ == "__main__":
flips = flip(int(input("how many? ")))
print(flips)
if all(f == 0 for f in flips):
print("all 0")
if all(f == 1 for f in flips):
print("all 1")
With a = random.randint(0, 1) you are overwriting your list.
Use this:
coin_flip = random.randint(0, 1)
a.append(coin_flip)
print(coin_flip)

Finding a more concise way to add values to empty list Python

I am new to Python and while my task is deemed correct, I know there is a more efficient way to write the code and am looking for advice.
My goal is to count the number of scores (between 1-6) of a dice roll and assign each number to a list. In this case I know the value of the dice roll 'N' - 1 will be the index at which it is added to the list but I am unsure as to how to go about writing it.
import random
dice = [0]*6
for roll in range(1001):
N = random.randint(1,6)
if N == 1:
dice[0] = dice[0] + 1
if N == 2:
dice[1] = dice[1] + 1
if N == 3:
dice[2] = dice[2] + 1
if N == 4:
dice[3] = dice[3] + 1
if N == 5:
dice[4] = dice[4] + 1
if N == 6:
dice[5] = dice[5] + 1
print(f' the number of times the dice rolled 1-6 is as follows {dice}')
You can use N-1 for the index of the list.
dice[N-1] += 1
When dealing with lists of random values, I recommend numpy:
import numpy as np
_, counts = np.unique(np.random.randint(1,7, 1000), return_counts=True)
Here you go:
dice = [0]*6
for roll in range(1001):
dice[random.randint(0, 5)] += 1
print(f' the number of times the dice rolled 1-6 is as follows {dice}')
The list is being indexed with N-1.
import random
a = random.sample(range(1, 1001), 6)
print(a)
This could brief a lot more what you are looking for
https://pynative.com/python-random-sample/

players roll 2 dice till one reaches 100

Each player roll two dice in a row on one turn. The amount of dice obtained is
added to the player's total points. The game ends when one of the players
the first has achieved at least 100 points.
from random import randint
dicesum2 = 0
dicesum1 = 0
while (dicesum1 < 100):
dice1 = [randint(1, 6) for i in range(2)]
dicesum1 += sum(dice1)
print('player 1',dice1,'|',dicesum1)
dice2 = [randint(1, 6) for i in range(2)]
dicesum2 += sum(dice2)
print('player 2',dice2,'|',dicesum2)
i need it to end when one reaches 100. how do i check both?
if a player throws exactly one single, he loses the points obtained in the turn;
how do i check when one of the generated numbers is 1?
I need it to end when one reaches 100. how do i check both?
Learn about what the or logical operator does:
dicesum1 < 100 or dicesum2 < 100
how do i check when one of the generated numbers is 1?
Learn what the in operator does:
if 1 in dice1:
# Apply penalty.
Take a look at this and see if it helps out
from random import randint
def roll():
return [randint(1, 6) for i in range(2)]
def check_for_one(rolls):
for roll in rolls:
# this could be simplified to "if 1 in rolls", this was just my preference
if roll == 1:
return True
return False
dicesum2 = 0
dicesum1 = 0
while True:
d1 = roll()
dicesum1 += sum(d1)
if check_for_one(d1):
print(f"Player 1 rolled a 1 in batch: {d1}")
print(f"Player 1 roll: {d1} | {dicesum1}")
d2 = roll()
dicesum2 += sum(d2)
if check_for_one(d2):
print(f"Player 2 rolled a 1 in batch: {d2}")
print(f"Player 2 roll: {d2} | {dicesum2}")
if dicesum1 >= 100:
print(f"Player 1 won with: {dicesum1}")
break
elif dicesum2 >= 100:
print(f"Player 2 won with: {dicesum2}")
break
So in this example, we shove the roll out to a function and check_for_one which iterates the list you are making checking for ones and returning a boolean.
I changed the loop to while True so the loop wasn't responsible for the more complex condition which can be limiting.
For each player, it performs the roll, sums, checks and reports if a 1 is in the batch, reports the roll.
Finally it checks for the winner and breaks if one is at or over 100, reporting their win.
You can change the while condition as follow :
while (dicesum1 < 100 and dicesum2 < 100):
Alternatively, you can also use break :
...
if dicesum1 >= 100:
break
...
if dicesum2 >= 100:
break

Using for loops over while loops

How would one produce some code that counts up using a for loop as opposed to a while loop? My code is as follows;
def square():
count = 1
number = input("How far?")
number = int(number)
if number < 1:
print ("broken")
elif number >= 1:
while count <= number:
square = count*count
print ("{0}*{0}={1}".format(count, square))
count = count+1
square()
You can do it like that:
def square():
number = input("How far?")
number = int(number)
if number < 1:
print ("broken")
elif number >= 1:
for count in range(1,number+1):
square = count*count
print ("{0}*{0}={1}".format(count, square))
square()
Using the line
for count in range(1,number+1):
counts iterates over the values 1,2,...,number.
U can do it with list comprehensions like:
def square():
number = int(input("How far?"))
# range will be from 1 to number +1, and will proceed square for all
return [val ** 2 for val in range (1, number+1)]
squares = square()
if not squares:
print('broken')
# u can iterate over result even if list is empty(if u pass broken number)
for val in squares:
print ("{0}*{0}={1}".format(count, square))

Categories

Resources