How do I make random.randint refresh while program is running? - python

I'm making a small program that shoots out math problems and requires an answer to pass. It works fine, but all the randint values I generate stay static for as long as the progran is running. I figured if I change:
Tehtävä = random.choice(Laskut)
Into a function it should refresh with the loop. Problem is I can't for the life of me figure out how to do that. Would it even work for what I'm trying? The randint values are determined in a seperate list. Heres the rest of the code:
Peli = 1
while Peli != 2:
pulma = 1
refresh = 1
Tehtävä = random.choice(Laskut)
while pulma == 1:
ratkaisu = float(input(Tehtävä.problem + "\n:"))
if ratkaisu == Tehtävä.answer:
pulma += 1
refresh += 1
print("oikein")
elif ratkaisu == "loppu":
pulma += 1
refresh += 1
Peli += 1
else:
print("väärin")
Here are the values I used:
import random
class Algebra:
def __init__(self, problem, answer):
self.problem = problem
self.answer = answer
#Muuttujat
#erotus ja summa
a = random.randint(1,99)
b = random.randint(1,99)
c = random.randint(1,99)
d = random.randint(1,99)
#jako ja kerto
e = random.randint(1,10)
f = e*random.randint(1,10)
g = random.randint(1,10)
#Kysymykset
Kysymys_M = [str(a) + "+" + str(b) + "-x=" + str(c),
str(a) + "-" + str(b) + "-x=" + str(a),
str(a) + "-" + str(b) + "-" + str(c) + "-x=" + str(d),
str(e) + "*x=" + str(f),
str(f) + ":x=" + str(e),
"x:" + str(e) + "=" + str(g)]
#Vastaukset
Vastaus_M = [a+b-c,
-b,
a-b-c-d,
f/e,
f/e,
e*g]
Laskut = [
Algebra(Kysymys_M[0], Vastaus_M[0]),
Algebra(Kysymys_M[1], Vastaus_M[1]),
Algebra(Kysymys_M[2], Vastaus_M[2]),
Algebra(Kysymys_M[3], Vastaus_M[3]),
Algebra(Kysymys_M[4], Vastaus_M[4]),
Algebra(Kysymys_M[5], Vastaus_M[5]),]
(If I have packed too much information please let me know.)

Related

Implementing a match counter into a lotto number guesser

im rather new to python and found someones lottery simulation in github. After playing around with it for a while i wanted to add a counter, that counts the number of matches of your Number out of the total draws.
I don't know if it is because i did not write the code myself, but i can't seem to make it happen. I've tried some of pythons counter modules bu that did'nt seem to be the right thing.
Heres my code:
import random
import time
### TODO - Refactor GetDrawNumbers (add timers)
### TODO - Refactor CheckNumbers
def GetDrawNumbers():
drawNumbers = []
for i in range(6):
x = None
while (x == None or x in drawNumbers):
x = random.randint(1, 49)
drawNumbers.append(x)
return drawNumbers
def CheckNumbers(myTicket, actualNumbers):
numbersMatched = 0
for number in myTicket:
if number in actualNumbers:
numbersMatched += 1
return numbersMatched
### Script starts here
startTime = time.perf_counter()
myNumbers = [4, 8, 15, 16, 23, 42]
for draw in range(2000):
drawNumber = draw + 1
thisWeeksDraw = GetDrawNumbers()
numbersMatched = CheckNumbers(myNumbers, thisWeeksDraw)
##print("Week " + str(drawNumber) + " numbers : " + str(thisWeeksDraw) + " (" + str(numbersMatched) + " matched)")
if numbersMatched == 4:
print("Week " + str(drawNumber) + " numbers : " + str(thisWeeksDraw) + " (" + str(numbersMatched) + " matched)")
count = numbersMatched
print("Total matches: " + str(count))
endTime = time.perf_counter()
elapsedTime = endTime - startTime
print("Completed in " + str(elapsedTime) + " seconds!")
If anyone knows a way to implement a counter, that counts the number of times this the program gets 3,4,5 or 6 correct matches i would be super relieved! It's not that this project would be super important but solving the problem would be a milestone for me and my learning process!
Thanks in advance and best wishes!
How about this where I have added a check of the numbersMatched value and increment a counter whenever it is 3 or more
import random
import time
### TODO - Refactor GetDrawNumbers (add timers)
### TODO - Refactor CheckNumbers
def GetDrawNumbers():
drawNumbers = []
for i in range(6):
x = None
while (x == None or x in drawNumbers):
x = random.randint(1, 49)
drawNumbers.append(x)
return drawNumbers
def CheckNumbers(myTicket, actualNumbers):
numbersMatched = 0
for number in myTicket:
if number in actualNumbers:
numbersMatched += 1
return numbersMatched
### Script starts here
startTime = time.perf_counter()
myNumbers = [4, 8, 15, 16, 23, 42]
countOfThreeOrMoreMatched = 0
for draw in range(2000):
drawNumber = draw + 1
thisWeeksDraw = GetDrawNumbers()
numbersMatched = CheckNumbers(myNumbers, thisWeeksDraw)
##print("Week " + str(drawNumber) + " numbers : " + str(thisWeeksDraw) + " (" + str(numbersMatched) + " matched)")
if numbersMatched >= 3:
countOfThreeOrMoreMatched += 1
if numbersMatched == 4:
print("Week " + str(drawNumber) + " numbers : " + str(thisWeeksDraw) + " (" + str(numbersMatched) + " matched)")
print(f"Count with 3 or more matches {countOfThreeOrMoreMatched}")
count = numbersMatched
print("Total matches: " + str(count))
endTime = time.perf_counter()
elapsedTime = endTime - startTime
print("Completed in " + str(elapsedTime) + " seconds!")

How to round float down to 3 decimal places?

I wrote a function to return the energy of a given wavelength. When I run the function the print statement returns the float E, but returns 20+ decimals and I cannot figure out how to round it down.
def FindWaveEnergy(color, lam):
c = 3.0E8
V = c/lam
h = 6.626E-34
E = h*V
print("The energy of the " + color.lower() + " wave is " + str(E) + "J.")
FindWaveEnergy("red", 6.60E-7)
I tried doing this:
def FindWaveEnergy(color, lam):
c = 3.0E8
V = c/lam
h = 6.626E-34
E = h*V
print("The energy of the " + color.lower() + " wave is " + str('{:.2f}'.format(E)) + "J.")
FindWaveEnergy("red", 6.60E-7)
But that returned 0.000000J.
How can I fix my program to return 3 decimal places?
The program returns an E value. i.e. 3.10118181818181815e-19J.
I want it to return something like 3.1012e-19J with fewer decimal places.
You are actually nearly there.
I found this Question
So all you have to do is change
str('{:.2f}'.format(E))
to
str('{:.3g}'.format(E))
Try this:
def FindWaveEnergy(color, lam):
c = 3.0E8
V = c/lam
h = 6.626E-34
E = str(h*V).split("e")
print("The energy of the " + color.lower() + " wave is " + E[0][:4] + "e" + E[-1] + "J.")
FindWaveEnergy("red", 6.60E-7)
or you can :
print("The energy of the " + color.lower() + " wave is " + str('{:.2e}'.format(E)) + "J.")

Python: How can I make my elif loop work?

I just started making a game like thing, and for some reason, the elif loop isn't doing anything when "upgrade" is entered.
choclate = 0
multiplier = 1
multipliercost = 10
x = 1
while x == 1:
if input() == (("choclate") + str(choclate+multiplier)):
choclate = choclate+multiplier
print("\nYou now have " + str(choclate) + " choclate.\nMultiplier Upgrade Cost: " + str(multipliercost) + " choclate\n")
elif input() == "upgrade":
multiplier = multiplier*2
choclate = choclate-multipliercost
multipliercost = multipliercost*2.5
print("You have upgraded your multiplier to " + str(multiplier))
I am very new to coding, so I don't really know what to call this problem.
If you call input() twice, then the user needs to key in twice in each round.
if you expect the user to key in only once, then you also need to call input() once in each round, and store it into a variable.
Here is the fix.
choclate = 0
multiplier = 1
multipliercost = 10
x = 1
while x == 1:
# save the input into variable
key_in = input()
print(("choclate") + str(choclate+multiplier))
if key_in == (("choclate") + str(choclate+multiplier)):
choclate = choclate+multiplier
print("\nYou now have " + str(choclate) + " choclate.\nMultiplier Upgrade Cost: " + str(multipliercost) + " choclate\n")
elif key_in == "upgrade":
multiplier = multiplier*2
choclate = choclate-multipliercost
multipliercost = multipliercost*2.5
print("You have upgraded your multiplier to " + str(multiplier))

Python Local Variable As Counter

Using Python 3.7.
Is there any way to use a local variable as a counter?
I tried and received error:
UnboundLocalError
I did find a recommendation to use a glbal variable which is working, but if possible I would prefer to use a local variable.
Thanks,
-w
Working code using global variable for counter:
count = 0
def my_collatz(number):
global count
count +=1
if int(number)%2 == 0:
r = int((number)//2)
else:
r = int(((number * 3) + 1))
print('Attempt : ' + str(count) + ',' + str(r))
if r != 1:
return my_collatz(int(r))
print('Please enter a number : ')
number=input()
my_collatz(int(number))
It is a very strange function indeed. Anyway, you can avoid using a global variable by converting it into an input parameter:
count = 0
def my_collatz(number, count):
count +=1
if int(number)%2 == 0:
r = int((number)//2)
else:
r = int(((number * 3) + 1))
print('Attempt : ' + str(count) + ',' + str(r))
if r != 1:
return my_collatz(int(r), count=count)
print('Please enter a number : ')
number=input()
my_collatz(int(number),count)
One possible solution is to move the count variable as parameter to the function and increment it each call:
def my_collatz(number, count=1):
if number % 2 == 0:
r = number // 2
else:
r = (number * 3) + 1
print('Attempt : ' + str(count) + ',' + str(r))
if r != 1:
return my_collatz(r, count + 1)
print('Please enter a number : ')
number=input()
my_collatz(int(number))
Prints:
Please enter a number :
6
Attempt : 1,3
Attempt : 2,10
Attempt : 3,5
Attempt : 4,16
Attempt : 5,8
Attempt : 6,4
Attempt : 7,2
Attempt : 8,1
Other solution is to not use count at all, and instead make the function a generator (using yield). Then you can use enumerate() to obtain your number of steps:
def my_collatz(number):
if number % 2 == 0:
r = number // 2
else:
r = (number * 3) + 1
yield r
if r != 1:
yield from my_collatz(r)
print('Please enter a number : ')
number=input()
for count, r in enumerate(my_collatz(int(number)), 1):
print('Attempt : ' + str(count) + ',' + str(r))

Conditional statement printing values twice python

So I am testing my script in which i am passing two values to compare. It goes through two conditional statements. I have carried out some debugging and it prints out the same expression twice which is "Current value is in range". It first prints it out from the first loop and then from the second loop. I am not sure why my code is doing that. It should only print that out once and get out of the else statement and not go in to the second else statement which it is currently doing. What is that I am doing wrong to stop this.
def compare_sizes(previous_size, current_size):
subtract_f1_f2 = int(current_size - previous_size)
range_num = 0.4
range_previous_day = int(previous_size * range_num)
if subtract_f1_f2 > 0 and range_previous_day > 0 and subtract_f1_f2 >= range_previous_day:
whole_percent = subtract_f1_f2 / previous_size * 100
print (human_bytes(previous_size) +" -> " + human_bytes(current_size) + " " +
"+" + str(whole_percent) + " % bigger" + "\n")
return
else:
print("Current Value Is In Range")
if subtract_f1_f2 <0 and subtract_f1_f2 <= range_previous_day:
whole_percent = abs(subtract_f1_f2 / previous_size * 100)
print (human_bytes(previous_size) + " -> " + human_bytes(current_size) + " " + str(
whole_percent) + " % smaller" + "\n")
else:
print("Current Value Is In Range")
result = compare_sizes(1000,1400)# 40% Bigger
result = compare_sizes(1000,1399)# In Range
# result = compare_sizes(1000,599)

Categories