How to round float down to 3 decimal places? - python

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.")

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 do I make random.randint refresh while program is running?

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.)

How would I work around this invalid literal for int() with base 10 error?

import math
# The standard gravitational parameter for the sun
mu = 1.327 * math.pow(10, 20)
class Planet:
def __init__(self, name, radius, moons, orbital_radius):
self.name = name
self.radius = radius
self.moons = moons
self.orbital_radius = orbital_radius
def collide(self):
self.moons = self.moons + 1
return self.moons
def volume(Planet):
v = (4 / 3) * math.pi * math.pow(Planet.radius, 3)
return str(v)
def surface(Planet):
area = 4 * math.pi * math.pow(Planet.radius, 2)
return str(area)
def physical(Planet):
if Planet.moons == 1:
Planet.moons = str(Planet.moons) + " moon"
else:
Planet.moons = str(Planet.moons) + " moons"
return (Planet.name + " has a volume of " + volume(Planet) + " cubic km, a surface area of " + surface(Planet) + " sq. km, and " + Planet.moons)
def dynamic(Planet):
period = 2 * math.pi * Planet.orbital_radius * math.sqrt(Planet.orbital_radius / mu)
return (Planet.name + " has a year of approximately " + str(period // (60 * 60 * 24)) + " days")
Earth = Planet('Earth', 6371, 1, 1.496 * math.pow(10, 11))
Jupiter = Planet('Jupiter', 69911, 79, 7.786 * math.pow(10, 11))
print(physical(Earth))
print(physical(Jupiter))
print(dynamic(Earth))
print(dynamic(Jupiter))
print(Earth.collide())
I understand that self.moons is turned into a string due to the physical function but how would I go about in turning into an integer again. It doesn't seem possible as an integer and string is stored as its value that's why I'm getting the error message ValueError: invalid literal for int() with base 10: '1 moon' when I attempt to print(Earth.collide())
Just partition the string on a space and take the first part:
int(self.moon.partition(" ")[0])
You can also use str.split() but partition is a little faster for the 'only need to split once' case.
The better approach is to not set the .moons attribute to a string. Keep it an integer, there is no need to replace it just to format a nice string with information:
def physical(Planet):
if Planet.moons == 1:
moons = str(Planet.moons) + " moon"
else:
moons = str(Planet.moons) + " moons"
return (Planet.name + " has a volume of " + volume(Planet) + " cubic km, a surface area of " + surface(Planet) + " sq. km, and " + moons)
You may want to look at formatted string literals or the format string syntax:
def physical(Planet):
moons = f"{Planet.moons} moon"
if Planet.moons != 1:
moons += 's'
return (
f"{Planet.name} has a volume of {volume(Planet)} cubic km, a surface "
f"area of {surface(Planet)} sq. km, and {moons}"
)
Either way, by using a local variable moons to contain the formatted number of moons value, you don't alter the Planet.moons value so don't have to worry about how to go back to it being an integer again.
I would recommend, to stick with a local/private variable in def physical(Planet), because it is not used anywhere else and just a format to a value.
def physical(Planet):
if Planet.moons == 1:
_planet_moons = str(Planet.moons) + " moon"
else:
_planet_moons = str(Planet.moons) + " moons"
return (Planet.name + " has a volume of " + volume(Planet) + " cubic km, a surface area of " + surface(Planet) + " sq. km, and " + _planet_moons)
This prevents you from convering the value forth and back.

function doesnt show up when its supposed to

At school we have to write a program to use the pythagorean theory. Im writing it in python 3 but when I return cber the program just ends. bber on the other hand works fine. Can someone please help? Thanks already:)
Edit: Thanks for helping me, this is not everything with the function kiezen the user can choose two numbers and the j and the n are to decide which lines they are in the triangle, thats in the function kiezen too. This is all in one function called cijfers, I dont know if that makes a difference. I used return because that way I could let the user choose the numbers again if he/she entered something unvalid. And I forgot to remove the ifs in cber before posting it. I’ll try to
improve my program sometime soon. Thanks for all your feedback:)
def bber():
if (c >= a):
print(str(a) + "^2 + b^2 = " + str(c) + "^2")
print("b^2 = " + str(c) + "^2 - " + str(a) + "^2")
print("b = V(" + str(c**2) + " - " + str(a**2) + ")")
print("b = V" + str((c**2) - (a**2)) + " = " + str(math.sqrt((c**2) - (a**2))))
if (a >= c):
print("De rechthoekzijde kan niet langer zijn dan de schuine zijde.")
cijfers()
def cber():
if (a >= b):
print(str(a) + "^2 + " + str(b) + "^2 = c^2")
print("c^2 = " + str(a) + "^2 + " + str(b) + "^2")
print("c = V(" + str(a**2) + " + " + str(b**2) + ")")
print("c = V" + str((a**2) + (b**2)) + " = " + str(math.sqrt((a**2) + (b**2))))
if (b >= a):
print(str(a) + "^2 + " + str(b) + "^2 = c^2")
print("c^2 = " + str(a) + "^2 + " + str(b) + "^2")
print("c = V(" + str(a**2) + " + " + str(b**2) + ")")
print("c = V" + str((a**2) + (b**2)) + " = " + str(math.sqrt((a**2) + (b**2))))
def kiezen():
x = int(input("Wat is de lengte van de eerste zijde?"))
xz = input("Is deze zijde een rechthoekzijde (J/N)?")
print(" ")
y = int(input("Wat is de lengte van de tweede zijde?"))
yz = input("Is deze zijde een schuine zijde (J/N)?")
print(" ")
return kiezen()
if xz == "j" or "J":
if yz == "n" or "N":
b = y
a = x
return cber()
if yz == "j" or "J":
c = y
a = x
return bber()
There are a few problems going on.
You need to import modules.
In your code, you are using math.sqrt, so the first line required is to actually import the math module at the beginning of your file:
import math
You are not getting access to your variables inside your functions. To pass them to your function, you have to specify them as function parameters:
def bber(a, c):
On the positive side, your function bber reports the right answer inside your statement if (c >= a). However, the following conditional statement, if (a >= c), calls the function cijfers(), which doesn't actually exist. In that case, every time a is greater than or equal to c, the program will print a NameError.
The function cber works, but you don't actually need to have if statements, because you get the variable c no matter if b is greater than a or if a is greater than b. You might want to consider checking for other types of input (like text, negative numbers, floats, etc.), though.
Here is how you could simplify your cber function, also having to pass in actual parameters:
def cber(a, b):
print(str(a) + "^2 + " + str(b) + "^2 = c^2")
print("c^2 = " + str(a) + "^2 + " + str(b) + "^2")
print("c = V(" + str(a**2) + " + " + str(b**2) + ")")
print("c = V" + str((a**2) + (b**2)) + " = " + str(math.sqrt((a**2) + (b**2))))
The function kiezen isn't actually doing anything in your code. It is defined, but you don't use it anywhere, apparently.
Variables defined inside functions are local to that function while variables defined outside a function (i.e. no indentation) are global variables. When you need to use a global variable inside a function, you have to pass it as a function parameter. For more information on this topic, you can read about the concepts of "scope", "global scope" and "local scope". You can also find examples in the official Python documentation, here.
For now, so you can see how to use variables that are defined globally, I will use your incomplete kiezen function without actually making it a function, so the code is directly executed in your program.
One other problem here is that you can use the keyword return only inside a function, because that is what it is meant for: to return the result of a function.
This means that you have to change your code return cber() and return bber() by removing the return keyword.
You are missing a space at the end of your questions with input. When you type your answer, it will appear right next to the last character in your string.
When you want to check for multiple options (as you did with XZ == "j" or "J"), you can use a list instead and the keyword in.
Here are some modifications needed to make your program work in the end. Comments are present on lines with the # symbol.
# To use a function provided by the math module, you have to import it first
import math
# You have to get "a" and "c" from somewhere, so you pass them as parameters
def bber(a, c):
if (c >= a):
print(str(a) + "^2 + b^2 = " + str(c) + "^2")
print("b^2 = " + str(c) + "^2 - " + str(a) + "^2")
print("b = V(" + str(c**2) + " - " + str(a**2) + ")")
print("b = V" + str((c**2) - (a**2)) + " = " + str(math.sqrt((c**2) - (a**2))))
if (a >= c):
print("De rechthoekzijde kan niet langer zijn dan de schuine zijde.")
# Same scenario here: "a" and "b" must be defined somehow
# Note that the "if" statements were unnecessary
def cber(a, b):
print(str(a) + "^2 + " + str(b) + "^2 = c^2")
print("c^2 = " + str(a) + "^2 + " + str(b) + "^2")
print("c = V(" + str(a**2) + " + " + str(b**2) + ")")
print("c = V" + str((a**2) + (b**2)) + " = " + str(math.sqrt((a**2) + (b**2))))
# Note that a space has been added at the end of each string
# where you use "input".
X = int(input("Wat is de lengte van de eerste zijde? "))
XZ = input("Is deze zijde een rechthoekzijde (J/N)? ")
print(" ")
Y = int(input("Wat is de lengte van de tweede zijde? "))
YZ = input("Is deze zijde een schuine zijde (J/N)? ")
print(" ")
if XZ in ["j", "J"]:
if YZ in ["n", "N"]:
b = Y
a = X
# You have to remove the word "return", this is not a function
cber(a, b)
if YZ in ["j", "J"]:
c = Y
a = X
# You have to remove the word "return", this is not a function
bber(a, c)
As I mentioned earlier, this is not perfect because you would need to manage errors. For example, it will not work if you enter text instead of numbers, but that is a topic for another discussion.
Also, for the purpose of this exercise, you do not actually "need" to use the return keyword in your functions if your goal is just to print the output, but keep in mind that if you need to reuse the result of a function, you will have to return a value for it.
A quick example of that concept would be the following:
def my_function():
return 12
# my_variable will have a value of 12
my_variable = my_function()

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