Why time() below 0.25 skips animation in Python? - python

This code works as expected. Output:
Loading
Loading.
Loading..
Loading...
Code:
done = False
count = 0
while not done:
print '{0}\r'.format("Loading"),
time.sleep(0.25)
print '{0}\r'.format("Loading."),
time.sleep(0.25)
print '{0}\r'.format("Loading.."),
time.sleep(0.25)
print '{0}\r'.format("Loading..."),
time.sleep(0.25)
count += 1
if count == 5:
done = True
And this code doesn't. Output:
Loading.
Loading...
Code:
done = False
count = 0
while not done:
print '{0}\r'.format("Loading"),
time.sleep(0.125)
print '{0}\r'.format("Loading."),
time.sleep(0.125)
print '{0}\r'.format("Loading.."),
time.sleep(0.125)
print '{0}\r'.format("Loading..."),
time.sleep(0.125)
count += 1
if count == 5:
done = True
Why does the time function seem to skip every second print statement if it is lower than 0.25?

Reason
Depending on the platform, Python buffers the output to different degrees.
For example, on Mac OSX there is no output at all even for your version with 0.25 seconds sleep.
Flushing manually
Flushing manually should work:
import sys
import time
done = False
count = 0
while not done:
for n in range(4):
print '{0}\r'.format("Loading" + n * '.'),
sys.stdout.flush()
time.sleep(0.125)
print ' ' * 20 + '\r',
count += 1
if count == 5:
done = True
You need to flush the output with sys.stdout.flush(). You also need to print empty spaces to make the dots "going back and forth":
print ' ' * 20 + '\r',
More minimal and cleaned up
This is shortened and a bit more general in terms of the shown text:
import sys
import time
text = 'Loading'
for _ in range(5):
for n in range(4):
print '{0}\r'.format(text + n * '.'),
sys.stdout.flush()
time.sleep(0.25)
nspaces = len(text) + n
print ' ' * nspaces + '\r',
Running unbuffered from the commandline
You can remove the line:
sys.stdout.flush()
if you run your script with the -u option:
python -u script_name.py
Note: This will have an effect on all print statements.

Related

How to optimize? HackerRank: Time limit exceeded Allowed time limit:10 secs Your code did not execute in time. When trying python

How can I optmize this interactions? I'm getting timeout on just a few test cases on HackerRank
import math
#
# Complete the 'nearlySimilarRectangles' function below.
#
# The function is expected to return a LONG_INTEGER.
# The function accepts 2D_LONG_INTEGER_ARRAY sides as parameter.
#
def nearlySimilarRectangles(sides):
# Write your code here
leng = len(sides)
i = 0
rectan = 0
#print('Sides ' + str(sides))
if len(sides)>10**5:
return
while len(sides)>0:
i = sides[0]
sides.remove(i)
#print('Sides Inter ' + str(sides))
for z in sides:
if i[0]/z[0] == i[1]/z[1]:
rectan = rectan +1
print(str(i[0]) +' ' +str(z[0])+ ' '+ str(i[1]) +' ' +str(z[1]))
print('Sum ' + str(rectan))
return(rectan)
And:
def mostActive(customers):
# Write your code here
unique=[]
cont = []
n = len(customers)
for i in customers:
if i not in unique:
unique.append(i)
cont.append([i,1])
else:
sd = unique.index(i)
cont[sd][1]=cont[sd][1]+1
unique.sort()
for i in cont:
if i[1]/n < 0.05:
unique.remove(i[0])
return(unique)
Tried HackerRank test, passed 10/15, the rest were triggered due to:
Time limit exceeded
Allowed time limit:10 secs
Your code did not execute in time. Please optimize your code. For more details on runtime environment, click the “Info” button

Random space at the end of printed outputs

My code says its missing a new line after it is submitted
Here is my code
import math
r = math.pow(2,1/12)
f0 = float(input(''))
print('{:.2f}'.format(f0), end = " ")
for n in range(1,5):
fn = f0 * math.pow(r,n)
print('{:.2f}'.format(fn), end = ' ')
print ()
It is showing that there is an extra space at the end.
this one :
import math
r = math.pow(2,1/12)
f0 = float(input(''))
print('{:.2f}'.format(f0), end='') # < remove space
for n in range(1,5):
fn = f0 * math.pow(r,n)
print(' ',end='') # < put space there
print('{:.2f}'.format(fn), end='')
print ()
outs:
% python3 1.py
10
10.00 10.59 11.22 11.89 12.60
there are no space after 12.60

Calculating the amount of time left until completion

I am wondering how to calculate the amount of time it would take to example:
Complete a brute force word list.
I know how to use the time function and measure in time,
but the problem is i need to find out how long it would take in the program itself...
Here is the code i made this yesterday
import itertools, math
import os
Alphabet = ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890") # Add or remove whatevs you think will be in the password you're cracking (example, [symbols])
counter = 1
CharLength = 1
range_num = int(raw_input("Enter range: "))
stopper = range_num + 1
filename = "bruteforce_%r.txt" % (range_num)
f = open(filename, 'a')
#n_1 = len(Alphabet)
#n_2 = n_1 - 1 # <-- total useless peice of garbage that could of been great in vurtual life
#n_3 = '0' * n_2
#n = '1' + n_3
x = range_num
y = len(Alphabet)
amount = math.pow(y, x)
total_items = math.pow(y, x)
for CharLength in range(range_num, stopper):
passwords = (itertools.product(Alphabet, repeat = CharLength))
for i in passwords:
counter += 1
percentage = (counter / total_items) * 100
amount -= 1
i = str(i)
i = i.replace("[", "")
i = i.replace("]", "")
i = i.replace("'", "")
i = i.replace(" ", "")
i = i.replace(",", "")
i = i.replace("(", "")
i = i.replace(")", "")
f.write(i)
f.write('\n')
print "Password: %r\tPercentage: %r/100\tAmount left: %r" % (i, int(percentage), amount)
if i == '0'* range_num:
print "*Done"
f.close()
exit(0)
else:
pass
This is my timer function i managed to make
#import winsound # Comment this out if your using linux
import os
import time
from sys import exit
print "This is the timer\nHit CTRL-C to stop the timer\nOtherwise just let it rip untill the time's up"
hours = int(raw_input('Enter the hours.\n>>> '))
os.system('clear') # Linux
#os.system('cls') # Windows
minutes = int(raw_input('Enter the minutes.\n>>> '))
os.system('clear') # linux
#os.system('cls') # Windows
seconds = int(raw_input('Enter the seconds.\n>>> '))
os.system('clear') # Linux
#os.system('cls') # Windows
stop_time = '%r:%r:%r' % (hours, minutes, seconds)
t_hours = 00
t_minutes = 00
t_seconds = 00
while t_seconds <= 60:
try:
os.system('clear') # Linux
#os.system('cls') # Windows
current_time = '%r:%r:%r' % (t_hours, t_minutes, t_seconds)
print current_time
time.sleep(1)
t_seconds+=1
if current_time == stop_time:
print "// Done"
#winsound.Beep(500,1000)
#winsound.Beep(400,1000)
break
elif t_seconds == 60:
t_minutes+=1
t_seconds=0
elif t_minutes == 60:
t_hours+=1
t_minutes = 00
except KeyboardInterrupt:
print "Stopped at: %r:%r:%r" % (t_hours, t_minutes, t_seconds)
raw_input("Hit enter to continue\nHit CTRL-C to end")
try:
pass
except KeyboardInterrupt:
exit(0)
Now i just cant figure out how to make this again but to calculate how long it will take rather than how long it is taking...
You cannot predict the time a script is going to take.
Firstly because two machines wouldn't run the script in the same time, and secondly, because the execution time on one machine can vary from on take to another.
What you can do, however, is compute the percentage of execution.
You need to figure out, for example, how many iterations your main loop will do, and calculate at each iteration the ratio current iteration count / total number of iterations.
Here is a minimalist example of what you can do:
n = 10000
for i in range(n):
print("Processing file {} ({}%)".format(i, 100*i//n))
process_file(i)
You can take it further and add the time as an additional info:
n = 10000
t0 = time.time()
for i in range(n):
t1 = time.time()
print("Processing file {} ({}%)".format(i, 100*i//n), end="")
process_file(i)
t2 = time.time()
print(" {}s (total: {}s)".format(t2-t1, t2-t0))
The output will look like this:
...
Processing file 2597 (25%) 0.2s (total: 519.4s)
Processing file 2598 (25%) 0.3s (total: 519.7s)
Processing file 2599 (25%) 0.1s (total: 519.8s)
Processing file 2600 (25%)
This is my implementation, which returns time elapsed, time left, and finish time in H:M:S format.
def calcProcessTime(starttime, cur_iter, max_iter):
telapsed = time.time() - starttime
testimated = (telapsed/cur_iter)*(max_iter)
finishtime = starttime + testimated
finishtime = dt.datetime.fromtimestamp(finishtime).strftime("%H:%M:%S") # in time
lefttime = testimated-telapsed # in seconds
return (int(telapsed), int(lefttime), finishtime)
Example:
import time
import datetime as dt
start = time.time()
cur_iter = 0
max_iter = 10
for i in range(max_iter):
time.sleep(5)
cur_iter += 1
prstime = calcProcessTime(start,cur_iter ,max_iter)
print("time elapsed: %s(s), time left: %s(s), estimated finish time: %s"%prstime)
Output:
time elapsed: 5(s), time left: 45(s), estimated finish time: 14:28:18
time elapsed: 10(s), time left: 40(s), estimated finish time: 14:28:18
time elapsed: 15(s), time left: 35(s), estimated finish time: 14:28:18
....
You will never ever be able to know exactly how long it is going to take to finish. The best you can do is calculate was percentage of the work you have finished and how long that has taken you and then project that out.
For example if you are doing some work on the range of numbers from 1 to 100 you could do something such as
start_time = get the current time
for i in range(1, 101):
# Do some work
current_time = get the current time
elapsed_time = current_time - start_time
time_left = 100 * elapsed_time / i - elapsed_time
print(time_left)
Please understand that the above is largely pseudo-code
The following function will calculate the remaining time:
last_times = []
def get_remaining_time(i, total, time):
last_times.append(time)
len_last_t = len(last_times)
if len_last_t > 5:
last_times.pop(0)
mean_t = sum(last_times) // len_last_t
remain_s_tot = mean_t * (total - i + 1)
remain_m = remain_s_tot // 60
remain_s = remain_s_tot % 60
return f"{remain_m}m{remain_s}s"
The parameters are:
i : The current iteration
total : the total number of iterations
time : the duration of the last iteration
It uses the average time taken by the last 5 iterations to calculate the remaining time. You can the use it in your code as follows:
last_t = 0
iterations = range(1,1000)
for i in iterations:
t = time.time()
# Do your task here
last_t = time.time() - t
get_remaining_time(i, len(iterations), last_t)

Python code reading serial inputs on Beaglebone

I am trying to read the data from my Geiger Counter on my Beaglebone, but when I print the result, doesn't include my counter code:
import Adafruit_BBIO.UART as UART
import serial
import time
UART.setup("UART4")
ser = serial.Serial(port = "/dev/ttyO4", baudrate=9600)
r = 0
d = 0
z = 0
minutes = 0
while True:
timeout = time.time() + 60
while True:
x = ser.read()
if ser.isOpen():
print "Serial is open!"
r = r +1
print r
print x
elif x is '0':
d=d+1
#print '.'
elif x is '1':
d=d+1
#print '.'
time.sleep(1)
z=z+d
print "CPM %f " % d
print "total %f" % z
print "minutes %f" % minutes
My output came out as:
Serial is open!
1
1
Serial is open!
2
1
Serial is open!
3
0
There is no break in your inner while loop, so it will loop infinitely. Assuming counter code means the print statements at the end of your code sample, they will never be reached.

Python - pdsend datastream

First of all some context:
Four MPR121 Breakout Boards (https://www.sparkfun.com/products/9695) connected via i2C to a Raspberry Pi 2. A python script reads the data from the four boards and sends it to pure data with pdsend.
At the moment I have managed to get all the data I need to print nicely on the terminal. However, I am not sure how to get the same in pure data as I am getting text messages only (something like "print: .join(map(str print: diff3))")
I am pretty sure I need to change the os.system line to accomodate for the variables but I can't find how to do this.
Thank you very much in advance.
def send2Pd (message=' '):
os.system("echo '" + message + "' | pdsend 3000");
while True:
diff1 = [cap1.baseline_data(i)-cap1.filtered_data(i) for i in range(12)]
print 'Diff1:', '\t'.join(map(str, diff1))
send2Pd ('.join(map(str, diff1));')
diff2 = [cap2.baseline_data(i)-cap2.filtered_data(i) for i in range(12)]
print 'Diff2:', '\t'.join(map(str, diff2))
send2Pd ('.join(map(str, diff2));')
diff3 = [cap3.baseline_data(i)-cap3.filtered_data(i) for i in range(12)]
send2Pd ('.join(map(str, diff3));')
print 'Diff3:', '\t'.join(map(str, diff3))
diff4 = [cap4.baseline_data(i)-cap4.filtered_data(i) for i in range(12)]
print 'Diff4:', '\t'.join(map(str, diff4))
send2Pd ('.join(map(str, diff4));')
time.sleep(0.1)
If I understand correctly, you just need to remove the quotes from the arguments you pass to send2Pd, does something like send2Pd('\t'.join(map(str, diff1))) work?
OK sorted.
This code gives me one line for each cap in pure data.
However, it does seem very resource hungry (the usage monitor marks around 50%) and that is without running the pd patch. Is there a simple way of making this more efficient?
Thank you!
import os
import sys
import time
import captouch as MPR121
# Create MPR121 instances
cap1 = MPR121.MPR121()
cap2 = MPR121.MPR121()
cap3 = MPR121.MPR121()
cap4 = MPR121.MPR121()
# Initialize communication with all 4 MPR121s
cap1.begin( 0x5a )
cap2.begin( 0x5b )
cap3.begin( 0x5d )
cap4.begin( 0x5c )
# Define send2Pd function
def send2Pd (message=' '):
os.system("echo '" + message + "' | pdsend 3000");
# Start loop
while True:
# Filtered and baseline data are commented out
# filtered = [cap1.filtered_data(i) for i in range(12)]
# print 'Filt:', '\t'.join(map(str, filtered))
# base = [cap1.baseline_data(i) for i in range(12)]
# print 'Base:', '\t'.join(map(str, base))
# Difference for all 4 boards are calculated, printed in terminal and sent to Pure Data
diff1 = [cap1.baseline_data(i)-cap1.filtered_data(i) for i in range(12)]
print 'Diff1:', '\t'.join(map(str, diff1))
send2Pd ('diff1: ' + '\t'.join(map(str, diff1)) + ';')
diff2 = [cap2.baseline_data(i)-cap2.filtered_data(i) for i in range(12)]
print 'Diff2:', '\t'.join(map(str, diff2))
send2Pd ('diff2: ' + '\t'.join(map(str, diff2)) + ';')
diff3 = [cap3.baseline_data(i)-cap3.filtered_data(i) for i in range(12)]
print 'Diff3:', '\t'.join(map(str, diff3))
send2Pd ('diff3: ' + '\t'.join(map(str, diff3)) + ';')
diff4 = [cap4.baseline_data(i)-cap4.filtered_data(i) for i in range(12)]
print 'Diff4:', '\t'.join(map(str, diff4))
send2Pd ('diff4: ' + '\t'.join(map(str, diff4)) + ';')
# Short pause before repeating loop
time.sleep(0.1)

Categories

Resources