How to pass a method to timeit in python? - python-2.7

So I am working on comparing the iterative and recursive ways of finding fibonacci numbers. I wanted to pass them both into timeit, but am having trouble formatting my calls to timeit. Good someone give me a little guidance please? Thanks!
import timeit
def it_fib(n):
total = 0
while n > 0:
total += n
n -= 1
return total
def rec_fib(n):
if n == 0:
return 0
else:
return n + rec_fib(n-1)
#print (it_fib(10))
#print (rec_fib(10))
print timeit.timeit("it_fib(n)", number = 1000000)
print timeit.timeit("rec_fib(n)", number = 1000000)

timeit.timeit can take a function or a string. For script use, the function is usually more convenient:
print timeit.timeit(lambda: it_fib(10))
print timeit.timeit(lambda: rec_fib(10))

Related

How To Make raw_input Not A String In python

I want to make this program do the summation of something with their input. My code thus far
def summation():
start = int(raw_input("Start value of n?: "))
end = int(raw_input("End value of n?: "))
eqn = lambda n: raw_input("Equation?: ")
sum = 0
for i in range(start , end + 1):
sum += eqn(i)
return sum
print summation() # start will be 1, end will be 5 , equation will be n + 1. Should print 20
I get the error that I can't add an integer and a string together so is there any way to make the raw_input for equation not a string. Like instead of it being 'n + 1', I want it to be n + 1.
You could use input instead of raw_input, but this isn't really a good idea, since every time eqn is called it will call a input and prompt you for the equation.
A better method is to store the equation beforehand (using raw_input), and then use eval in the lambda function. Something like:
def summation():
start = int(raw_input("Start value of n?: "))
end = int(raw_input("End value of n?: "))
fx = raw_input("Equation: ")
eqn = lambda n: eval(fx)
sum = 0
for i in range(start , end + 1):
sum += eqn(i)
return sum
print summation()
Don't you need to surround your raw_input in your eqn variable with an int()?
I use python 3, but that should fix your problems.

Using Bubble sort and encountering out of range list index

doc = "unsorted.txt"
out_fil = "H:\Grade 11\Intro to Computer Science\sorted.txt" # Used in the Windows variation of the program
out_file = "/Applications/Banter" # Used in the Mac variation of the program
import time
def main():
order = False
blank = []
passcount = 0
starttime = time.time()
numlist = CreateList(doc)
while not order:
passcount = passcount + 1
switch = False
switchcount = 0
print "1" # These are test prints to I used to find problems
for x in range (len(numlist)):
print "2" # These are test prints to I used to find problems
if numlist[x] > numlist[x+1]:
temp = numlist[x+1]
numlist[x+1] = numlist[x]
numlist[x] = temp
switchcount = switchcount + 1
switch = True
print "9" # These are test prints to I used to find problems
elif switch == 0:
order = True
CreateFile(numlist)
endtime = time.time()
print "This list required",endtime-starttime,"seconds to sort."
print "This list required",switchcount,"switches to sort."
print "This list required",passcount,"passes to sort."
def CreateList(doc):
sort = open(doc,"r")
numlist = sort.readlines()
sort.close()
for x in range (len(numlist)):
numlist[x] = int(numlist[x].strip())
return numlist
def CreateFile(numlist):
sort = open(doc,"w")
sort.write(str(numlist)+"\n")
sort.close()
return numlist
def List(numlist):
print numlist
main()
The main purpose of my program is to sort a list of integers from a file in order using the bubble sort method, and then put that list into a new file. I'm also detailing the amount of time it takes to perform this as well as the number of passes and switches within the program that it took to sort it completely.
Now, the problem I'm having is that the list index falls out of range because it's comparing x and x+1 of my numlist. But, I need to compare x+1 in order to sort the two integers beside each others within the list. Is there any way I can fix the program so that it'll compare all the integers in the list and not try to compare the space that isn't in the list because of the x+1?
You could make your loop in this way:
for x in range ( len(numlist) -1 ):
Though stackoverflow is a great resource for answers, giving them up for homework assignments feels like cheating. I'll meet you half way: Make your loop run for one less iteration.

Recursive function without return - Python 2.7

Can this be called a recursive function ? It does reduce in one way but not in a (amount - 1) type of way...
EDIT:
Also how is it possible to write a recursive function without using return?
def wow(amount):
if amount <= 0:
print "Don't be so negative!"
elif amount == 1:
return "Wow!"
else:
return amount * "Wow! \n"
amount = int(raw_input("How many 'Wow!' do you wanna see : "))
print wow(amount)
No, this is not a recursive function. A recursive function has to call itself. This page explains and shows examples of recursive functions.
This would be a recursive function.
def wow(amount):
if amount <= 0:
return
else:
print("Wow! \n")
return wow(amount - 1)
And a full-fledged solution that turns your code into a recursive function would be.
def wow(amount):
if amount <= 0:
return "Don't be so negative!"
elif amount == 1:
return "Wow!"
else:
return inner_wow("", amount)
def inner_wow(wow_str, amount):
if amount == 0:
return
else:
wow_str += "Wow! \n"
return wow(wow_str, amount - 1)
In response to your second question. All functions have to return something. Even if you don't tell them to return something they still returns None.

Convert from decimal to binary - python

I'm having an issue with this piece of code I wrote. I'm trying to convert an integer input and print an output with its equivalent in binary base. For example for 5 it should drop an output of '101' however it just prints '10' like if it doesn't take into account the last digit. Please any comments would be greatly appreciated
T = raw_input()
for i in range(0, int(T)):
n = raw_input()
dec_num = int(n)
cnv_bin = ''
while dec_num//2 > 0:
if dec_num%2 == 0:
cnv_bin += '0'
else:
cnv_bin += '1'
dec_num = dec_num//2
print cnv_bin[::-1]
while dec_num//2 > 0:
should be:
while dec_num > 0:
The first time through the loop, 5//2==2, so it continues.
The second time through the loop, 2//2==1, so it continues.
The third time, 1//2==0 and the loop quits without handling the last bit.
Also, you can just do the following to display a number in binary:
print format(dec_num,'b')
Format string version:
print '{0} decimal is {0:b} binary.'.format(5)
Why not use the build-in function bin()?
eg:
bin(5)
output
0b101
If you don't want the prefix(0b), you can exclude it.
bin(5)[2:]
hope to be helpful!
import math
def roundup(n):
return math.ceil(n)
D = eval(input("Enter The Decimal Value: "))
n = roundup(math.log2(D+1))-1
bi = 0
di = D
qi = 0
i = n
print("Binary Value:",end = " ")
while(i>=0):
qi = math.trunc(di/2**i)
bi = qi
print(bi,end = "")
di = di - bi*(2**i)
i = i-1

Python 2.7 : How to reduce time to get data percentage of a file?

I'm writting a python code to get percentage of each bytes contained in a file. Then check if percentage is less than a given limit and display the byte value (as hex) + percentage if over.
My code works great but it is very time consuming. It take approx 1 minute for a 190KB file.
import time
def string2bytes(data):
return "".join("{:02x}".format(ord(c)) for c in data)
startTime = time.time()
# get datas from file
f = open("myfile.bin","rb")
filedata = f.read()
size = f.tell()
f.close
# count each data, check percentage and store to a dictionnary if upper than 0.50%
ChkResult = True
r = {}
for data in filedata:
c = float(filedata.count(data)) / size * 100
if c > 0.50:
ChkResult = False
tag = string2bytes(data).upper()
r[tag] = c
# print result
if ChkResult:
print "OK"
else:
print "DANGER!"
print "Any bytes be less than 0.50%%."
for x in sorted(r.keys()):
print " 0x%s is %.2f%%"%((x), r[x])
print "Done in %.2f seconds."%(time.time() - startTime)
Do you have any idea to reduce this time with same result? Staying with python 2.7.x (for many reasons).
Many thanks.
Use Counter[docs] to prevent O(n^2) time:
You are calling count n times. count is O(n).
import time
from collections import Counter
def string2bytes(data):
return "".join("{:02x}".format(ord(c)) for c in data)
startTime = time.time()
# get datas from file
f = open("myfile.bin","rb")
filedata = f.read()
size = f.tell()
f.close
# count each data, check percentage and store to a dictionnary if upper than 0.50%
ChkResult = True
r = {}
for k,v in Counter(filedata).items():
c = float(v) / size * 100
if c > 0.50:
ChkResult = False
tag = string2bytes(k).upper()
r[tag] = c
# print result
if ChkResult:
print "OK"
else:
for x in sorted(r.keys()):
print " 0x%s is %.2f%%"%((x), r[x])
print "Done in %.2f seconds."%(time.time() - startTime)
or slightly more succinctly:
import time
from collections import Counter
def fmt(data):
return "".join("{:02x}".format(ord(c)) for c in data).upper()
def pct(v, size):
return float(v) / size * 100
startTime = time.time()
with open("myfile.bin","rb") as f:
counts = Counter(f.read())
size = f.tell()
threshold = size * 0.005
err = {fmt(k):pct(v, size) for k,v in counts.items() if v > threshold }
if not err:
print "OK"
else:
for k,v in sorted(err.items()):
print " 0x{} is {:.2f}%".format(k, v)
print "Done in %.2f seconds."%(time.time() - startTime)
If there is a need for speed:
I was curious so I tried a homespun version of counter. I actually thought it would Not be faster but I am getting better performance than collections.Counter.
import collections
def counter(s):
'''counts the (hashable) things in s
returns a collections.defaultdict -> {thing:count}
'''
a = collections.defaultdict(int)
for c in s:
a[c] += 1
return a
This could be substituted into #DTing s solution - I wouldn't change any of that.
Guess it wasn't homespun at all, it is listed in the defaultdict examples in the docs.