I'm trying to use a timer to see how fast each function is. My codes work but after running it many times I get slightly different results and wonder if I'm implementing function correctly. I am only going to the 10th Fibonacci number which is 55 for testing. Each time I run the "A" option the clockTime() function returns a slightly larger number than before. Any thoughts would be appreciated.
import math
import time
#create a time variable
start_time = time.time()
#create the golden Ratio formula
golden_ratio = (1 + math.sqrt(5)) / 2
#the runtime function
def clockTime():
print("\nrun time: " + str(time.time()-start_time))
#the golden ration function
def fibGen(num):
for number in range(0,num+1):
val = (golden_ratio**number - (1 - golden_ratio)**number) / math.sqrt(5)
print('{i:3}: {v:3}'.format(i=number, v=round(val)))
#the find element < Max number function
def elemFib(num):
for number in range(0,num+1):
val = (golden_ratio**number - (1 - golden_ratio)**number) / math.sqrt(5)
if val < num:
print('Fib({}): {}'.format(number, round(val)))
#Pythonic way
def pythonic():
a, b = 0,1
while a < 57:
print(a, sep=" ", end="\n")
a, b = b, a+b
#display the Main Menu
def dispMenu():
print('---------------------Fibonacci Series ------------------\n')
print('(A) Print Fibonacci numbers to the nth term')
print('(B) Print Fibonacci numbers until element is less than Max number')
print('(C) pythonic print')
print('(Q) Quit the program\n')
def main():
# set boolean control variable for loop
loop = True
#Create while loop for menu
while loop:
#Display the menu
dispMenu()
#Get user's input
choice = (input('Please make a selection: '))
#Perform the selected action
if choice.upper() == 'A':
num = int(input("How many Fibonacci numbers should I print? "))
fibGen(num)
clockTime()
elif choice.upper() == 'B':
num = int(input("the element should be less than? "))
elemFib(num)
clockTime()
elif choice.upper() =='C':
pythonic()
clockTime()
elif choice.upper() == 'Q':
print('\nExiting program, Thank you and Goodbye')
loop = False
else:
print('\nInvalid selection, try again\n')
main()
The problem is you initialized start_time at the start of the program rather than right before you ran the function to be timed. You were adding in the times of previous runs as well as the time the user took to read the instructions and make a decision, etc. Here's a rework of your code that should do what you want:
import math
import time
# create the golden Ratio formula
golden_ratio = (1 + math.sqrt(5)) / 2
# the runtime function
def clockTime(start_time):
print("\nrun time:", time.time() - start_time)
# the golden ration function
def fibGen(num):
for number in range(num+1):
val = (golden_ratio**number - (1 - golden_ratio)**number) / math.sqrt(5)
print('{i:3}: {v:3}'.format(i=number, v=round(val)))
# the find element < Max number function
def elemFib(num):
for number in range(num + 1):
val = (golden_ratio**number - (1 - golden_ratio)**number) / math.sqrt(5)
if val < num:
print('Fib({}): {}'.format(number, round(val)))
# Pythonic way
def pythonic():
a, b = 0, 1
while a < 57:
print(a, sep=" ", end="\n")
a, b = b, a + b
# display the Main Menu
def dispMenu():
print('---------------------Fibonacci Series ------------------\n')
print('(A) Print Fibonacci numbers to the nth term')
print('(B) Print Fibonacci numbers until element is less than Max number')
print('(C) pythonic print')
print('(Q) Quit the program\n')
def main():
# set boolean control variable for loop
loop = True
# Create while loop for menu
while loop:
# Display the menu
dispMenu()
# Get user's input
choice = input('Please make a selection: ').upper()
# Perform the selected action
if choice == 'A':
num = int(input("How many Fibonacci numbers should I print? "))
start_time = time.time()
fibGen(num)
clockTime(start_time)
elif choice == 'B':
num = int(input("the element should be less than? "))
start_time = time.time()
elemFib(num)
clockTime(start_time)
elif choice == 'C':
start_time = time.time()
pythonic()
clockTime(start_time)
elif choice == 'Q':
print('\nExiting program, Thank you and Goodbye')
loop = False
else:
print('\nInvalid selection, try again\n')
main()
Related
Basically, I'm trying to build a code to get the largest number from the user's inputs. This is my 1st time using a for loop and I'm pretty new to python. This is my code:
session_live = True
numbers = []
a = 0
def largest_num(arr, n):
#Create a variable to hold the max number
max = arr[0]
#Using for loop for 1st time to check for largest number
for i in range(1, n):
if arr[i] > max:
max = arr[i]
#Returning max's value using return
return max
while session_live:
print("Tell us a number")
num = int(input())
numbers.insert(a, num)
a += 1
print("Continue? (Y/N)")
confirm = input()
if confirm == "Y":
pass
elif confirm == "N":
session_live = False
#Now I'm running the function
arr = numbers
n = len(arr)
ans = largest_num(arr, n)
print("Largest number is", ans)
else:
print(":/")
session_live = False
When I try running my code this is what happens:
Tell us a number
9
Continue? (Y/N)
Y
Tell us a number
8
Continue? (Y/N)
Y
Tell us a number
10
Continue? (Y/N)
N
Largest number is 9
Any fixes?
The error in your largest_num function is that it returns in the first iteration -- hence it will only return the larger of the first two numbers.
Using the builtin max() function makes life quite a bit easier; any time you reimplement a function that already exists, you're creating work for yourself and (as you've just discovered) it's another place for bugs to creep into your program.
Here's the same program using max() instead of largest_num(), and removing a few unnecessary variables:
numbers = []
while True:
print("Tell us a number")
numbers.append(int(input()))
print("Continue? (Y/N)")
confirm = input()
if confirm == "Y":
continue
if confirm == "N":
print(f"Largest number is {max(numbers)}")
else:
print(":/")
break
So, first things first,
the use of max can be avoided, as it is a reserved keyword in python
And coming to your fix, you are comparing it with the value only once in the loop, and you are returning the number, the indentation is the key here. You will have to wait for the loop to complete its job then return the value.
There are many inbuilt methods to do the job, Here is your implementation (a bit modified)
session_live = True
numbers = []
a = 0
def largest_num(arr, n):
#Create a variable to hold the max number
max_number = arr[0]
#Using for loop for 1st time to check for largest number
for i in range(1, n):
if arr[i] > max_number:
max_number = arr[i]
# --- The indentation matters
#Returning max's value using return
return max_number
while session_live:
print("Tell us a number")
num = int(input())
numbers.insert(a, num)
a += 1
print("Continue? (Y/N)")
confirm = input()
if confirm == "Y":
pass
elif confirm == "N":
session_live = False
#Now I'm running the function
arr = numbers
n = len(arr)
ans = largest_num(arr, n)
print("Largest number is", ans)
else:
print(":/")
session_live = False
I made it without using the built-in function 'max'.
It is a way to update the 'maxNum' variable with the largest number by comparing through the for statement.
numbers = []
while True:
print("Tell us a number")
numbers.append(int(input()))
print("Continue? (Y/N)")
confirm = input()
if confirm == "Y":
continue
if confirm == "N":
maxNum = numbers[0]
for i in numbers:
if i > maxNum:
maxNum = i
print("Largest number is", maxNum)
else:
print(":/")
break
I've just started learning python and have just finished writing a program that allows a user to find the nth term of the Fibonacci sequence. I have tested it and it appears to work as intended. My question is how can I make my code more concise or more pythonic. Any advice or tips would be greatly appreciated.
values = [0,1]
n1 = 2
while True: # input and loop to limit the input range.
try:
n = int(input('Please enter position of fibonacci sequence you wish to know.'))
break
except:
print('That\'s not a valid input')
if n < 3: #calculation block
print (n)
else:
while n1 != n:
n2 = values[0] + values[1]
values[0] = values[1]
values[1] = n2
n1 +=1
print (n2)
Using functions would make your code more "pythonic" - Conciseness may not be your first priority:
def get_user_input():
while True: # input and loop to limit the input range.
try:
n = int(input('Please enter position of fibonacci sequence you wish to know.'))
return n
except:
print('That\'s not a valid input')
def get_nth_fib_number(nth):
values = [0, 1]
current_fib = 2
while current_fib <= nth:
values.append(values[-2] + values[-1])
current_fib += 1
return values[nth]
get_nth_fib_number(get_user_input())
i have no idea why this is broken. Also dont tell me to use python's built in function because this is designed for some practice not to actually be used. It is binary to decimal that is broken. It has a index error with the variable 'index'
print('Please choose from the list below:')
print('')
print('1) Convert from decimal/denary to binary; ')
print('2) Covert from binary to denary/decimal; ') #Main Menu
print('3) Infomation and settings (coming soon);')
print('4) Exit. ')
print('')
menu_choice = str(input('Enter your choice here: ')) #User inputs choice here
if menu_choice == '1':
dec_binary()
elif menu_choice == '2':
binary_dec()
elif menu_choice == '3':
print('By Callum Suttle')
else:
return 'Thank You'
def dec_binary(): #Module 1: decimal to binary
dec = int(input('Enter a number in decimal up to 255: ')) #Checks The number is an ok size, could be made bigger
while dec > 255:
dec = int(input('Enter a number up to 255, no more: '))
power = int(7) #change 7 to make bigger by 1 digit
convert = []
while power > -1: #until power goes below zero
if dec - pow(2, power) >= 0: #if entered number subtract 2 to the power of var-pow returns posotive number
convert.append(1)
power -=1 # add a 1
dec = dec - pow(2, power) >= 0
else:
convert.append(0)#if not add a zero
power -=1
print('')
print(convert) # print completed number
print('')
binary_decimal_converter() #back to main menu
def binary_dec():
anwser = 0
l_bi = str(input('Enter a number in binary up to 7 digits: '))
while len(l_bi) != 7: #checks for correct length
l_bi = str(input('Enter a number in binary up to 7 digits, you may add zeros before: '))
power = 7 #size can be increased by using this
index = 0
while index > 6: #until every power has been checked (in reverse order)
if l_bi[index] == '1': #if the digit is equal to 1
anwser += pow(2, power) #add that amount
power -= 1 #take the power to check next #why is this broken
index += 1 # add another index to check previous
else:
power -= 1 #as above
index += 1 #/\
print('')
print(anwser) #prints result
print('')
binary_decimal_converter() #main menu
this doesn't seem right
index = 0
while index > 6: #until every power has been checked (in reverse order)
...
you never enter this loop, do you?
a better loop would be something like
for i, bit in enumerate(l_bi):
answer += int(bit) * pow(2, 7-i)
also, since you're just practicing, you should find a better way to jump from menu to functions and back. you're doing recursive calls, which is a waste of stack, i.e. your functions actually never finish but just call more and more functions.
Some fixes:
def binary_dec():
anwser = 0
l_bi = str(input('Enter a number in binary up to 7 digits: '))
while len(l_bi) > 7: # LOOP UNTIL LENGTH IS LESS THAN 7
l_bi = str(input('Enter... : '))
power = len(l_bi) - 1 # directly set the power based on length
index = 0
while index < len(l_bi): # CORRECT LOOP CONDITION
I'm trying to generate 20 random numbers in python and say whether they are odd or even, this is what I have so far:
import random
def main():
i = 0
num = 0
#while loop
while i<20:
#user enters input
num = random.randint(input("enter lowest number:\t"))
i = random.randint(input("enter highest number:\t"))
#if else
if num>=0 and num<=100:
num = num+i
i = i +1
print(num)
else:
print("error")
#for loop
for i in range(num):
main()
would someone be able to help me finish it as I'm completely lost
here is the question:
Write a program which generates 20 random integers and indicates whether each number is odd or even. The program should begin by asking the user to input two integers which will act as the range for the generation of 20 random integers.
use list comprehension
import random
lower = int(raw_input("enter lowest number:\t"))
greater = int(raw_input("enter highest number:\t"))
print [random.randint(lower, greater) for a in range(100)]
I would rather rewrite that function completely
import random
def main():
lower = int(raw_input("enter lowest number: "))
upper = int(raw_input("enter highest number: "))
for i in range(20):
num = random.randint(lower, upper)
print(num)
main()
I think you will be able to easily modify it to suite your needs :)
EDIT: As suggested, I rewrote the function so it wouldnt ask for lower and upper bound every step of for loop, but only once before entering the for loop. Which is much less annoying and probably the thing you wanted to do.
def odd_or_even(num):
if num % 2 == 0:
print(num, 'is even')
else:
print(num, 'is not even')
lst = [random.randint(lower, upper) for x in range(20)]
for num in lst:
print(even_or_odd(num))
Here is a working program but if you couldn't be bothered to figure this out I doubt you are going to enjoy this class very much as it's only going to get more difficult.
import random
import time
start = time.time()
for i in range(10000):
random.choice([i for i in range(1000)])
print 'random.choice()', time.time() - start
start = time.time()
for i in range(10000):
random.randint(0,1000)
print 'random.randint()', time.time() - start
start = time.time()
for i in range(10000):
int(random.random() * 1000)
print 'random.random()', time.time() - start
[out]:
random.choice() 0.849874973297
random.randint() 0.015105009079
random.random() 0.00372695922852
First ask the user the top and bottom numbers,
Then use a generator to get the numbers.
import random
def randnums(number, startnum=0, endnum=100):
for i in range(1, number + 1):
yield random.randint(startnum, endnum)
def getparams():
return int(input('Lowest number: ')), int(input('Highest number: '))
def main():
bottom, top = getparams()
nums = list(randnums(20, startnum=bottom, endnum=top))
for number in nums:
print(number, ',', sep='')
if __name__ == '__main__':
main()
I am coding a program that lets you type in the three angles or sides of a triangle, and it tells if it's equilateral, isosceles etc. I am not worrying about the rest for now, but I'm stuck on the equilateral part of it. Here is my code:
def idtri():
print("\nDo you have all three sides, or al three angles?")
print("(1) Sides")
print("(2) Angles")
choice = input()
if choice == 1:
print("\nType in the lengths of all of the sides.")
t1 = input("1: ")
t2 = input("2: ")
t3 = input("3: ")
print("Your triangle is an equalateral triangle.")
menu()
elif choice == 2:
pass
idtri()
The first thing to note is that, for identifying the triangle as scalene, isoceles, or equilateral, it doesn't matter whether the three values you have are the angles or the side lengths, the process is:
If all three values are the same, the triangle is equilateral;
otherwise, if any two values are the same, the triangle is isoceles;
otherwise, the triangle is scalene.
So you can write a simple function to return the type based on the number of equal values provided:
id_triangle = lambda a, b, c: {0: 'scalene', 1: 'isoceles', 3: 'equilateral'}\
[(a == b) + (a == c) + (b == c)]
and then call that from your interactive script, like:
print('Your triangle is %s.' % id_triangle(t1, t2, t3))
You can also use the counter from the Python collections:
from collections import Counter
def idtri():
cnt = Counter()
side1 = input('Enter length of first side: ')
cnt[side1] += 1
side2 = input('Enter length of second side: ')
cnt[side2] += 1
side3 = input('Enter length of third side: ')
cnt[side3] += 1
if 3 in cnt.values():
print('Equilateral Triangle')
elif 2 in cnt.values():
print('Isosceles Triangle')
else:
print('Scalene Triangle')
if __name__ == "__main__":
idtri()