I'm trying to create a function where it takes in a list I give it of my predicted out come of the race and my bet. So for example, i could predict the outcome [1,3,4,2] where horse 1 would be in 1st, horse 3, in 2nd etc... This prediction would be compared to a randomized/ shuffled list a. I have set up a couple of if statements to try and compare both items in each list to each other but it ends up giving me all my placements were correct even if they were not. I am stuck!!!
def horseRace(gList,bet):
import random
a = [1,2,3,4]
random.shuffle(a,random.random)
i = 0
x = 0
while i < len(gList):
if gList[i] == a[0]:
x = x + 1
if gList[i] == a[1]:
x = x + 1
if gList[i] == a[2]:
x = x + 1
if gList[i] == a[3]:
x = x + 1
else:
x = x
i = i + 1
print(x)
print(a)
print(gList)
if x == 4:
money = bet*2
print("You guessed 4 position(s) correctly and won $ %d !"%money)
if x == 0:
money = 0.00
print("You guessed no position(s) correctly and won $ %d !"%money)
if x == 1:
money = bet
print("You guessed 1 position(s) correctly and won $ %d !"%money)
if x == 2:
money = bet
print("You guessed 2 position(s) correctly and won $ %d !"%money)
if x == 3:
money = bet
print("You guessed 3 position(s) correctly and won $ %d !"%money)
your while loop should look more like this
while i < len(gList):
if gList[i] == a[i]:
x = x + 1
else:
x = x
i = i + 1
That way, you're comparing the value in cell position i in gList to the value in the same cell position in a. Right now, your code essentially says to add one to x as long as the value gList[i] is equal to any of:
a[1], a[2], a[3], a[4]
which of course it wil be
Consider using a for loop to count the number of correct guess. Assuming gList and a are the same size:
for (gList_i, a_i) in zip(gList, a):
if g_List_i == a_i:
x += 1
Also, maybe a function for the message, that would take the number of positions guessed correctly as an input.
def win_message(nwins):
if nwins == 0:
money = 0
elif nwins == 4:
money = 2*bet
else: # For nwins equals 2 or 3
money = bet
if nwins > 1:
plural = "s"
else:
plural = ""
print("You guessed %d position%s correctly and won $ %d !" % (nwins, plural, money))
You can do it in more Pythonic way, and count the number of correct guess in one line:
nCorrect = len(filter(lambda x: x[0]==x[1], zip(randomized,gList)))
Here is the full code, I'll explain in the bottom:
import random
def horseRace(gList,bet):
randomized = [1,2,3,4]
random.shuffle(randomized,random.random)
nCorrect = len(filter(lambda x: x[0]==x[1], zip(randomized,gList)))
def getResult(bet,nCorrect):
if nCorrect==0:
return 0
elif nCorrect==4:
return 2*bet
else:
return bet
outcome = getResult(bet,nCorrect)
print 'Randomized order: ' + randomized
print 'Your guess: ' + bet
print 'You guessed %d position(s) correctly and won $%d!' % (nCorrect,outcome)
You should change the getResult method depending on how you want to calculate your outcome.
I'll explain this line:
nCorrect = len(filter(lambda x: x[0]==x[1], zip(randomized,gList)))
So, first, it'll combine the randomized and gList into a list of tuples:
gList = [1,2,3,4]
randomized = [1,3,2,4]
print zip(randomized,gList)
[(1,1), (2,3), (3,2), (4,4)]
Then the filter will take only elements that match the condition. In this case the condition is that the first element of the tuple equals the second element of the tuple (x[0]==x[1])
print filter(lambda x: x[0]==x[1], zip(randomized,gList))
[(1,1), (4,4)]
Then we return the length of the array, which is the number of correct guess.
Related
Today my professor asked us to do a binary converter using python, and I did it quickly with my friend assigning a variable to the length and decreasing it by 1 in the for loop. And then we decided to do it the opposite way.
We tried to do it converting the number into a list, reversing the list, using the index position to match the required exponent number. But we found 2 main problems with that code:
1.The exponent will never be able to be bigger than 1, because it's not in the list.
2.The number 1 and 0 are going to repeat a lot of times in the list, so there's gonna be a problem when we try to access the index value.
Is there any way to fix it or we should just stick to the other method? Here's the code so you can take a look:
num = input ('Insert the binary number: ')
res = [int(x) for x in num]
res.reverse()
length = len(res) + 1
counter = 0
for x in range (0, length):
if res[x] == 1:
counter += res[x]**res.index(x)
elif res[x] == 0:
pass
else:
print ('The number is not binary')
break
print (f'Your number in decimal is : {counter}')
Your method is fine. Two errors in your code:
Do not add 1 to the length as it is already the correct value. If you have a, say, 8 digit binary number the range should be from 0 to 7.
You should simply add 2**x to the counter when the digit is 1. I don't know why you tried to use the .index()
Here is a working version:
num = input ('Insert the binary number: ')
res = [int(x) for x in num]
res.reverse()
length = len(res)
counter = 0
for x in range(length):
if res[x] == 1:
counter += 2 ** x
elif res[x] == 0:
pass
else:
print ('The number is not binary')
break
print (f'Your number in binary is : {counter}')
...or a one-liner just for some Python fun:
print(sum(int(x) * 2**i for i, x in enumerate(reversed(num))))
For determining the correct value of the exponent you can use enumerated. Also, there is no point in converting the each digit to an integer, you can just compare the string.
num = input('Insert the binary number: ')
result = 0
for i, digit in enumerate(reversed(num)):
if digit == "1":
result += 2 ** i
elif digit != "0":
print('The number is not binary')
break
else:
print(f'Your number in decimal is : {result}')
Just a little fix and your program will work. Modified length = len(res), added enumerate to find index, and changed the counter formula.
num = input ('Insert the binary number: ')
res = [int(x) for x in num]
res.reverse()
length = len(res)
counter = 0
for index,x in enumerate(range(length)):
if res[x] == 1:
counter += res[x]* 2**index
elif res[x] == 0:
pass
else:
print ('The number is not binary')
break
print (f'Your number in decimal is : {counter}')
I would like to find dynamically the correct ordinal number root for instance:
111 = 111st
112 = 112nd
113 = 113rd ...
I tried other solutions but I can't find a good one.
This is my code:
for number in range(1, 114):
print(number)
ex1 = 11
ex2 = 12
ex3 = 13
if number == ex1:
print("is the " + str(number) + "th number.")
elif number % 10 == 1 or not ex1:
print("is the " + str(number) + "st number.")
elif number == ex2:
print("is the " + str(number) + "nd number.")
elif number % 10 == 2 or not ex2:
print("is the " + str(number) + "nd number.")
elif number == ex3:
print("is the " + str(number) + "rd number.")
elif number % 10 == 3 or not ex3:
print("is the " + str(number) + "rd number")
else:
print("is the " + str(number) + "th number.")
Note that 11, 12 and 13 have th suffix.
Also note you can change the end of the line in print function (default \n):
print('text', end=' ')
print('another text')
Then, I suggest you to use formatted string using f"{data} constant text" or "{} constant text".format(data).
Here is my solution to your problem:
def getSuffix(n):
if n < 0: raise Exception("Ordinal negative numbers are not allowed")
if n % 100 in [11, 12, 13]: return 'th'
if n % 10 == 1: return 'st'
if n % 10 == 2: return 'nd'
if n % 10 == 3: return 'rd'
return 'th'
for number in range(1, 114):
print(f"{number} is the {number}{getSuffix(number)} number")
I hope I was helpful.
So, the problem is that 111 gets displayed as 111st instead of 111th.
You have 11 as ex1, I assume short for "exception 1", but your condition:
if number == ex1:
Clearly doesn't match 111.
Instead you could do:
if number % 100 == ex1:
Which will be true for 11, 111, 211 etc.
On a side note:
elif number % 10 == 1 or not ex1:
Clearly isn't what you intended. This is interpreted as:
elif (number % 10 == 1) or (not ex1):
not ex1 does not depend on number and will always evaluate the same way (False). But since you're already checking ex1 separately, it would be redundant to do it correctly here.
If you wanted to correct that, so that you don't need to check ex1 twice, you'd do this:
if number % 10 == 1 and number % 100 != 11:
I think in this case using != is clearer than not and I don't think there is any benefit from assigning a variable to 11.
This is a pretty good solution:
ordinal = lambda n: "%d%s" % (n, "tsnrhtdd"[(n // 10 % 10 != 1) * (n % 10 < 4) * n % 10::4])
for number in range(1, 114):
print(f'the {ordinal(number)} number. :) ')
EDIT For Human Beings
NOTE: Variables name aren't meant to be used in a production environment, I tried to make it more explicit what each step on the lambda function does!
def get_ordinal(n):
hacking_string = "tsnrhtdd" # 1)
is_num_divisible_by_ten = (n // 10 % 10 != 1) # 2)
is_num_reminder_0_3= (n % 10 < 4) # 3)
are_both_false_or_both_true= is_num_divisible_by_ten * is_num_between_0_3 # 4)
get_index = are_both_false_or_both_true* n % 10 # 5)
return f'{number}{hacking_string[get_index::4]}' #6) ---> starts at t | s | n | r
for number in range(1, 114):
print(f'the {get_ordinal(number)} number. :) ')
Considerations
The solution found is very Hacky and smart and I probably would never come up my self, is using some clever math tricks to find the off sets of the number.
As requested I however simplified the function and added some explanation to it.
Step 1. This string is better seen it as this "tsnr" "htdd" | On the left side you heve the "root" of the string, on the right the end. (more explanation below)
Step 2. is_num_divisible_by_ten --> using a floor division the result is True or False.
Step 3. is_num_reminder_0_3 If checking if the reminder of N and 10 is between 0 & 3, returns a True / False Flag.
Step 4. are_both_false_or_both_true is multiplying 2 bool value, in Python True is a 1 and False is a 0, so is like do --> 1 * 0. The Variable is True only if both values are True or both are False, otherwise is always False.
Step 5. get_index - > Returns either 0 or 1 or 2 or 3.
Step 6. Here the hacky part, with the received index from get_index, is laverage the hacking_string variable with indexing-and-slicing:
The get_index value is always one of these: "tsnr" and the steps taken (4) any of these "rhtdd" hence the possible combination are:
get_index = 0 = "th"
get_index = 1 = "st"
get_index = 2 = "nd"
get_index = 3 = "rd"
Finally
The exact mathematics that goes behind it may be better asked on math.stackexchange or if someone knows it would be good to either add a comment or edit my answer!
References (It wasn't my solution)
Ordinal numbers replacement
outputting ordinal numbers 1st,2nd,3rd
Guides
python-lambda
python-string-formatting
python-booleans-as-numbers
You can do it like that:
for number in range(1, 114):
printedString = str(number)+' is the '+str(number)
if str(number) == '1' or (str(number)[-1] == '1' and str(number)[-2] != '1'):
printedString += 'st'
elif str(number) == '2' or (str(number)[-1] == '2' and str(number)[-2] != '1'):
printedString += 'nd'
elif str(number) == '3' or (str(number)[-1] == '3' and str(number)[-2] != '1'):
printedString += 'rd'
else:
printedString += 'th'
print(printedString+' number.')
I've got an assignment which requires me to use a Python recursive function to output the factors of a user inputted number in the form of below:
Enter an integer: 6 <-- user input
The factors of 6 are:
1
2
3
6
I feel like a bit lost now and have tried doing everything myself for the past 2 hours but simply cannot get there. I'd rather be pushed in the right direction if possible than shown where my code needs to be changed as I'd like to learn
Below is my code:
def NumFactors(x):
for i in range(1, x + 1):
if x == 1:
return 1
if x % i == 0:
return i
return NumFactors(x-1)
x = int(input('Enter an integer: '))
print('The factors of', x, 'are: ', NumFactors(x))
In your code the problem is the for loop inside the method. The loop starts from one and goes to the first if condition and everything terminates there. That is why it only prints 1 as the output this is a slightly modified version of your own code. This should help. If you have any queries feel free to ask.
def factors(x):
if x == 1:
print(1 ,end =" ")
elif num % x == 0:
factors(x-1)
print(x, end =" ")
else:
factors(x-1)
x = num = int(input('Enter an integer: '))
print('The factors of', x, 'are: ',end =" ")
factors(x)
Since this question is almost 3 years old, I'll just give the answer rather than the requested push in the right direction:
def factors (x,c=1):
if c == x: return x
else:
if x%c == 0: print(c)
return factors(x,c+1)
Your recursion is passing down x-1 which will not give you the right value. For example: the number of factors in 6 cannot be obtained from the number of factors in 5.
I'm assuming that you are not looking for the number of prime factors but only the factors that correspond to the multiplication of two numbers.
This would not normally require recursion so you can decide on any F(n) = F(n-1) pattern. For example, you could use the current factor as a starting point for finding the next one:
def NumFactors(N,F=1):
count = 1 if N%F == 0 else 0
if F == N : return count
return count + NumFactors(N,F+1)
You could also optimize this to count two factors at a time up to the square root of N and greatly reduce the number of recursions:
def NumFactors(N,F=1):
count = 1 if N%F == 0 else 0
if N != F : count = count * 2
if F*F >= N : return count
return count + NumFactors(N,F+1)
My objective was to use the index of a list to do addition/subtraction with. Where by I turned the even index positive, and the odd index negative.
EX1: 1234508 Should be answered by a 0: 1-2+3-4+5-0+8 = 11, then the while loops it again and I get 1-2+1 = 0
Ex2: 12345 Should be answered by a 3: 1-2+3-5 = 3, so it shouldn't go through the loop again.
Ex3: 121 Should be answered by a 0: 1-2+1 = 0, so it shouldn't go throught he loop again.
def main():
print()
print("Program to determine if a number is evenly\ndivisible by 11")
print()
indexed = input("Enter a number: ",)
total = 0
num = 0
while num >= 10:
for item in indexed:
if num %2 == 0:
total = total + int(item)
else:
total = total - int(item)
num = num + 1
print(total)
main()
Note that this print statement above is a place holder for a if statement which is inactive on my code, but was printing as large bold print here.
Let's say you have a string st whose characters are all digits, and that you want to have the sum of these digits. You then define the following function
def sd(st):
return sum(int(d) for d in st)
that we can test in the interpreter
In [30]: sd('10101010101010101010')
Out[30]: 10
In [31]: sd('101010101010101010101')
Out[31]: 11
What you really want is to sum the odd digits and subtract the even ones, but this is equivalent to sum the odds, sum separately the evens and then take the difference, isn't it? so what you want is
step_1 = sd(odds(st)) - sd(evens(st))
How can you separate the odd digits from the even ones? Ah! no need for a function, we can use slices
step_2 = sd(st[::2]) - sd(st[1::2])
Now we want to test the slices in the interpreter
In [32]: '101010101010101010101'[::2]
Out[32]: '11111111111'
In [33]: '101010101010101010101'[1::2]
Out[33]: '0000000000'
But step_2 could be a negative number, that I don't want to manage... I'd rather use the abs builtin
step_3 = abs(sd(st[::2]) - sd(st[1::2]))
and this is exactly what you were looking for.
Eventually we can put all the above together, but we may need to iterate until the difference is less than 11 --- we'll use an infinite loop and a break statement to exit the loop when we'll have found the answer
def sd(st):
return sum(int(d) for d in st)
number = input('Give me a number: ')
trial = number
while True:
n = abs(sd(trial[::2]) - sd(trial[1::2]))
if n < 11: break
trial = str(n)
if n > 0:
...
else:
...
what exactly do you want to do with this?
evenindex = evenindex int(item)
"list" is a type, means the list type in python, so it cannot be the name of a variable. Furthermore, you have not defined this variable in your code.
I have figured out the answer to the question I asked above. As such, my answer here is in the event anyone stumbles upon my above question.
def main():
indexed = input("Enter a number: ",)
total = 0
num = 0
while num <= 10:
for item in indexed:
if num %2 == 0:
total = abs(total + int(item))
else:
total = abs(total - int(item))
num = num + 1
if total == 0:
print(indexed, "is evenly divisible by 11 \ncheck since", indexed, "modulus 11 is", int(indexed) % 11)
else:
print(indexed, "is not evenly divisible by 11 \ncheck since", indexed, "modulus 11 is", int(indexed) % 11)
input()
main()
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 ")