Change two lines dyanmically on Python - python

Let's say I have a counter that counts from 0 to 100000. I don't want all the numbers showed, I just want to see the number we are at end the % of completion.
I know that if I want to rewrite over the line, I must add \r at the beginning. However, if I want to do this on two lines, how am I supposed to do that ?
1
0.001%
then
2
0.002%
Also, let's say I want to add new lines for the numbers, but always keep the percentage at the bottom like this:
1
2
3
4
5
6
7
8
0.008%
Do you have any idea on how to achieve that?
Here is my code so far (doesn't work, obviously):
from sys import stdout
for i in range(100000):
stdout.write(str(i) + '\r\n')
stdout.write('%.2f' % (i / 100000 * 100) + '%\r')
stdout.flush()
stdout.write('\n')
Thank you !

you can use curses module:
import curses
import time
stdscr = curses.initscr()
curses.noecho()
curses.cbreak()
n = 100000
num_lines = 10
lst = list(range(n))
for t in [lst[i:i + num_lines] for i in range(0, len(lst), num_lines)]:
final_line = f'{t[-1] / n * 100:.4f}%'
out = '\n'.join(map(str, [*t, final_line]))
stdscr.addstr(0, 0, out)
stdscr.refresh()
time.sleep(0.005) # you can comment but will be too fast
curses.echo()
curses.nocbreak()
curses.endwin()

Related

How can I use stdout.write in python 2.7 to display multiple lines at the same time? [duplicate]

This question already has answers here:
Rewrite multiple lines in the console
(7 answers)
Closed 5 years ago.
I have a question regarding the python programming, let's say i have a loop, so within the loop, i want to stdout.write 3 variables in different lines.
For example:
while (True):
a += 0
b += 5
c += 10
sys.stdout.write("\routput1 = %d" % a)
sys.stdout.write("\routput2 = %d" % b)
sys.stdout.write("\routput3 = %d" % c)
So in the terminal should be like:
output1 = .........
output2 = .........
output3 = .........
Each output just remain in their lines and keep refreshing. Thank you!
For multiple line printing, each console window on Windows is a number of lines, with number of columns... usually 25 lines and 80 columns as an old standard.
You can move a cursor to an (y, x) position, and print a string on screen.
y = line
x = column
Example code:
import ctypes
from ctypes import c_long, c_wchar_p, c_ulong, c_void_p
handle = ctypes.windll.kernel32.GetStdHandle(c_long(-11))
def move_console_cursor(y, x):
value = (x + (y << 16))
ctypes.windll.kernel32.SetConsoleCursorPosition(handle, c_ulong(value))
def print_string_at_cursor(string):
ctypes.windll.kernel32.WriteConsoleW (handle, c_wchar_p(string), c_ulong(len(string)), c_void_p(), None)
You then can print multiple lines over eachother by moving the cursor to the appropriate position and then print a string with the functions given.
A 3 line example: Easy would be to do a os.system('CLS') to clear the screen, and then you can move cursor to 1,1 2,1 3,1 and repeat until you have done all your processing. At the end, don't forget to move your cursor to 4,1. You can of course pick any location of your console window.
For single line on Windows you can do a sys.stdout.write() and then write cursor movements '\b' to move the cursor back to the beginning of the line.
Example of a copy file function with % progress indicator on the same line, using this method:
import os
import sys
def copy_progress(source_file, dest):
source_size = os.stat(source_file).st_size
copied = 0
source = open(source_file, 'rb')
target = open(dest, 'wb')
print ('Copy Source: ' + source_file)
print ('Copy Target: ' + dest)
print ('Progress:')
while True:
chunk = source.read(512)
if not chunk:
break
target.write(chunk)
copied += len(chunk)
progress = round(copied * 100 / source_size)
my_progress = str(progress).ljust(5)
sys.stdout.write (my_progress + '%\b\b\b\b\b\b')
sys.stdout.flush()
sys.stdout.flush()
source.close()
target.close()

Itertools writes some letters which are not in the list - Python

import time, itertools, win32com.client
print("Ctrl+C to start...")
while True:
try:
time.sleep(0.01)
except KeyboardInterrupt:
print("BruteForcing will start after 3 seconds...")
time.sleep(3)
break
shell = win32com.client.Dispatch('WScript.Shell')
msgs = 0
#here we go!
chrs = '0123456789'
min_length, max_length = 6, 6
file = open('data.di', 'a')
for n in range(min_length, max_length+1):
for xs in itertools.product(chrs, repeat=n):
x = ''.join(xs)
for m in range(0, len(x)):
shell.SendKeys(x[m])
shell.SendKeys("{ENTER}")
well, this programe gonna make a random number (Lenth = 6 digits) x and write them in a box and then press enter (As a bot). it works in the 1st fine but for some reasons, it starts giving random symboles and numbers later.
Example:
13&&
001
2121521
7-011
à'&é-é2
I would like to know if there are any bugs in the script and why this is happening. Thanks
Use random.choice(seq):
import random
for n in range(min_length, max_length+1):
for _ in range(n):
shell.SendKeys(random.choice(chrs))
shell.SendKeys("{ENTER}")
Sends 6 random digits followed by enter.

Python Indentation bug?

I have the this code:
import numpy
import random
import pylab
from ps3b import *
def AvgWithDrug(numViruses, maxPop, maxBirthProb, clearProb, resistances, mutProb, numTrials, delay):
viruses = []
timeSteps = delay + 300
print 'timeSteps = ', timeSteps
for i in range(numViruses):
viruses += [ResistantVirus(maxBirthProb, clearProb, resistances, mutProb)]
avg = [0] * timeSteps
print 'len avg[] =', len(avg)
hola = []
last = 0
for j in range(numTrials):
patient = TreatedPatient(viruses, maxPop)
for i in range(timeSteps):
if i == 150:
patient.addPrescription('guttagonol')
if i == 150 + delay:
patient.addPrescription('grimpex')
avg[i] += patient.update()
new = avg[timeSteps - 1]
print new - last
hola += [new - last]
last = new
for i in range(timeSteps):
avg[i] = avg[i]/ float(numTrials)
print avg[i]
print 'len avg[] =', len(avg)
Of course you cannot run it without knowing how to attach my class definitions.
But the issue when I run it is that last statement is like it is inside the above for loop. print avg[i] should be executed timeSteps times, and last print 'len avg[] =', len(avg) should be executed once.
It doesn't happen; the output shows me print avg[i], print 'len avg[] =', len(avg) over and over again through the timeSteps.
You've mixed tabs and spaces. Most of your code is indented with spaces, but a few lines have tabs, including the line that seems to be indented too far. Python treats a tab like Notepad does, as enough spaces to reach the next 8-space indentation level. Run your code with the -tt option to get Python to notify you of things like this, turn on "show whitespace" in your editor if it has that option, and change those tabs to spaces.

Delay between for loop iteration (python)

Is this possible in Python? I wrote a great loop/script in Python and I’d like to add this delay to it if at all possible.
map(firefox.open, ['http://www.bing.com/search?q=' + str(i) for i in range(x))], [2] * x)
Where shall I put the sleep(6) in this?
You can do that using time.sleep(some_seconds).
from time import sleep
for i in range(10):
print i
sleep(0.5) #in seconds
Implementation
Here is a cool little implementation of that: (Paste it in a .py file and run it)
from time import sleep
for i in range(101):
print '\r'+str(i)+'% completed',
time.sleep(0.1)
map(firefox.open, ['http://www.bing.com/search?q=' + str(i) for i in range(x))], [2] * x)
Or if you want it to start on one and emulate a stopwatch:
import time
def count_to(number):
for i in range(number):
time.sleep(1)
i += 1
if i >= number:
print('Time is up')
break
print(i)
Yes it is possible in python you should use 'time' module:
>>> import time
>>> list1=[1,2,3,4,5,6,7,8,9,10]
>>> for i in list1:
time.sleep(1)#sleep for 1 second
print i
output :
1
2
3
4
5
6
7
8
9
10

Turbo sort - Time Limit Exceeded

Am trying to solve a Codechef problem (Turbo Sort). The problem is
Given the list of numbers, you are to sort them in non decreasing
order.
Input
t – the number of numbers in list, then t lines follow [t <= 10^6].
Each line contains one integer: N [0 <= N <= 10^6]
Output
Output given numbers in non decreasing order.
Example
Input:
5 5 3 6 7 1
Output:
1 3 5 6 7
My Solution is :
l = []
t = input()
MAX = 10**6
while t <= MAX and t != 0:
n = input()
l.append(n)
t = t - 1
st = sorted(l)
for x in st:
print x
The challenge is this program should run in 5 sec. When i submit the file, codechef says it is exceeding the time and needs optimization.
Can some one help, how to optimize it ?
My accepted solutions:
import sys
from itertools import imap
T = int(raw_input())
lines = sys.stdin.readlines()
lis = imap(str, sorted(imap(int, lines)))
print "\n".join(lis)
A readable version(accepted solution) :
import sys
T = raw_input()
lines = sys.stdin.readlines() #fetch all lines from the STDIN
lines.sort(key=int) #sort the list in-place(faster than sorted)
print "\n".join(lines) #use `str.join` instead of a for-loop
Things like readlines should be supported. I've just made an attempt and got this as an accepted solution:
import sys
print '\n'.join(map(str, sorted(map(int, sys.stdin.read().split()[1:]))))
Not pretty but functional. Took me a bit before I figured out you had to skip the first number, debugging is a bit annoying with this system ;)

Categories

Resources