Decided to make a simple mp3 player for terminal. But while I was doing animation I had a problem - it blinks when the frame changes. Heres a video of it: https://youtu.be/in4VLPOfzHw. And the code:
import time, os, glob, eyed3, math, sys
from colorama import init
from mutagen.mp3 import MP3
mpts = glob.glob('*.mp3')
dark_grey = '\033[1;30;40m'
light_grey = '\033[0;37;40m'
white = '\033[1;37;40m'
lime = '\033[1;32;40m'
red = '\033[0;31;40m'
i = 0
song_list = []
for mpt in mpts:
song = MP3(mpt)
duration = math.ceil(song.info.length)
m_duration = duration // 60
s_duration = duration % 60
song = eyed3.load(mpt)
name = song.tag.title
song_list.append([name, [m_duration, s_duration]])
init()
# draw
while True:
# cassette
res = ''
i += 1
res += light_grey + ' ■̅̅̅̅̅̅̅̅̅̅̅̅■ \n'
res += dark_grey + ' |'
res += light_grey + '|############|'
res += dark_grey + '| \n'
res += dark_grey + ' |'
res += light_grey + '|'
if i % 4 == 0:
res += white + ' (/)====(/) '
elif i % 4 == 1:
res += white + ' (-)====(-) '
elif i % 4 == 2:
res += white + ' (\\)====(\\) '
elif i % 4 == 3:
res += white + ' (|)====(|) '
res += light_grey + '|'
res += dark_grey + '| \n'
res += dark_grey + ' |'
res += light_grey + '|############|'
res += dark_grey + '|\n'
res += light_grey + ' ■____________■ \n'
# green line
res += lime + ' ___________________________________\n\n'
# song list
res += red + ' # NAME TIME\n'
for i1 in range(len(song_list)):
res += dark_grey + ' ' + str(i1+1) + '.'
res += white + ' ' + song_list[i1][0] + ' '*(28 - len(song_list[i1][0])) + f'{song_list[i1][1][0]}:{song_list[i1][1][1]}\n'
os.system('cls')
sys.stdout.write(res)
sys.stdout.flush()
time.sleep(0.4)
Can it be fixed or sould I try to make in some other language instead of python?
It's the shelling out to cls that's doing it. Since you're already using ANSI codes for other stuff, try something like:
clear = '\033c'
...
while True:
...
print(clear)
Note that you'll never be able to completely get rid of the screen flicker using the "clear the screen then redraw it" technique, but this will shave several milliseconds from every loop and should decrease the flickering.
The idea is to avoid cleaning the whole screen (os.system('cls')). We could simply move the cursor to top and reprint everything. However moving cursor to top is almost impossible. One workaround I found is to print a lot of special characters that move cursor up one line until all the way to the top.
Reference:
cmd console game; reduction of blinking
The first solution of using \b does not work for me on a windows machine. So I go for the ender_scythe's solution. You have to print an empty line on first run to avoid the issue he/she mentioned. Here is the sample code that does not blink at all:
import time
import os
i = 0
dark_grey = '\033[1;30;40m'
light_grey = '\033[0;37;40m'
white = '\033[1;37;40m'
lime = '\033[1;32;40m'
red = '\033[0;31;40m'
def my_cls(nrow = 0):
if nrow == 0:
os.system('cls')
else:
print('\033[F'*nrow)
def my_display(chars):
print(''.join(chars))
return len(chars)
nrow = 0
while True:
my_cls(nrow)
# cassette
res = []
i+=1
if i == 1:
res.append('\n')
res.append(light_grey + ' ■̅̅̅̅̅̅̅̅̅̅̅̅■ \n')
res.append(dark_grey + ' |')
res.append(light_grey + '|###########|')
res.append(dark_grey + '| \n')
res.append(dark_grey + ' |')
res.append(light_grey + '|')
if i % 4 == 0:
res.append(white + ' (/)====(/) ')
elif i % 4 == 1:
res.append(white + ' (-)====(-) ')
elif i % 4 == 2:
res.append(white + ' (\\)====(\\) ')
elif i % 4 == 3:
res.append(white + ' (|)====(|) ')
res.append(light_grey + '|')
res.append(dark_grey + '| \n')
res.append(dark_grey + ' |')
res.append(light_grey + '|############|')
res.append(dark_grey + '|\n')
res.append(light_grey + ' ■____________■ \n')
# green line
res.append(lime + ' ___________________________________\n\n')
# song list
res.append(red + ' # NAME TIME\n')
nrow = my_display(res)
time.sleep(0.4)
Related
I have made a python program that recreates an image in excel by filling cells with different shades of red, green and blue. I have made this method to convert a number to a x coordinate in excel:
alph = [i for i in string.ascii_uppercase]
alph.insert(0,'')
def numToExcel(x):
stri = ''
row = x
rdiv26 = row//26
rdiv676 = row//676
stri += alph[(rdiv676)-((rdiv676)//676)*676]
stri += alph[(rdiv26)-((rdiv26)//26)*26]
stri += alph[1+(row%26)]
return stri
I added an empty space at the beginning so the program prints, for example, B3 instead of AAB3. However this means it does not reach for the letter Z. If i do x // 27 the image comes out wavy and it does not fix the issue.
This is my entire program:
import string
import time
import math
import openpyxl
from PIL import Image
from openpyxl import Workbook
from openpyxl.styles import Color, PatternFill, Font, Border
alph = [i for i in string.ascii_uppercase]
alph.insert(0,'')
def rgb_to_hex(r, g, b):
return '%02x%02x%02x' % (r,g,b)
def numToExcel(x):
stri = ''
row = x
rdiv26 = row//26
rdiv676 = row//676
stri += alph[(rdiv676)-((rdiv676)//676)*676]
stri += alph[(rdiv26)-((rdiv26)//26)*26]
stri += alph[1+(row%26)]
return stri
wb = Workbook()
ws = wb.active
im = Image.open('input.jpg')
pix = im.load()
x,y=im.size
start_time = time.time()
ct=0
for j in range(1,y-1):
i = 0
while i < 3*(x-1):
#Debug shi: print("["+"#"*math.floor(20*(ct/(x*3*y)))+"-"*(20-math.floor(20*ct/(x*3*y)))+"] " + str(math.floor(ct/(x*3*y)*100))+"% "+ str(ct) + "/" + str(x*y))
#Debug Shi: print("["+"#"*math.floor(20*(ct/(x*3*y)))+"-"*(20-math.floor(20*ct/(x*3*y)))+"] " + str(math.floor(ct/(x*3*y)*100))+"% "+ str(ct) + "/" + str(x*y*3) + " | (" + numToExcel(i) + "," + str(j) + ") -> (" + numToExcel(i+2) + "," + str(j) +") | " + str(pix[i/3,j][0])+','+str(pix[i/3,j][1])+','+str(pix[i/3,j][2]))
ws[numToExcel(i)+str(j)].fill = PatternFill("solid", fgColor=rgb_to_hex(pix[i/3,j][0],0,0))
ws[numToExcel(i+1)+str(j)].fill = PatternFill("solid", fgColor=rgb_to_hex(0,pix[i/3,j][1],0))
ws[numToExcel(i+2)+str(j)].fill = PatternFill("solid", fgColor=rgb_to_hex(0,0,pix[i/3,j][2]))
i += 3
ct += 3
#Progress Bar and stuff
print("\n"*100)
print("["+"#"*math.floor(20*(ct/(x*3*y)))+"-"*(20-math.floor(20*ct/(x*3*y)))+"] " + str(math.floor(ct/(x*3*y)*100))+"% "+ str(ct) + "/" + str(x*y*3) + " | Row " + str(j))
wb.save("sample2.xlsx")
print("--- Complete! ---\n--- %s seconds ---" % (time.time() - start_time))
And here is the output:
Please ignore any shitty code/math lol. I do not want to use any if statements because I am scared it would slow down the program.
This question already has answers here:
How do I terminate a script?
(14 answers)
Closed 4 months ago.
I want to print out an error code "DAT_GRESKA" or "GRESKA" in other input and then make the code do nothing but in my case it is taking me back and asking me to redo the input because its false. How do I make it to stop but without using exit() or quit().
import csv
def unos_csv():
ucsv = input("Unesi CSV datoteku: ")
if ucsv == 'raspored1.csv' or ucsv == 'raspored2.csv':
ucsv = str(ucsv)
return ucsv
else:
print('DAT_GRESKA')
return main()
def ime_predmeta():
subname = input("Unesi kod predmeta: ")
if subname.isupper():
return subname
else:
print("GRESKA")
return main()
def obrada():
file = open(unos_csv(), "r")
reader = csv.reader(file, delimiter=',')
predmet = ime_predmeta()
with open(predmet + '.txt', 'a')as a:
for row in reader:
danu_nedelji = int(row[0])
dejan = row[3].split('[')[1].split(']')[0]
if predmet in row[3]:
t1 = row[1]
t2 = row[2]
h1, m1 = t1.split(':')
h2, m2 = t2.split(':')
t11 = int(h1) * 60 + int(m1)
t22 = int(h2) * 60 + int(m2)
tkon = t22 - t11
tkon = str(tkon)
if danu_nedelji == 0:
a.write("Monday" + ' ' + row[1] + ' ' + row[2] + ' ' + tkon + ' ' + dejan + '\n')
elif danu_nedelji == 1:
a.write("Tuesday" + ' ' + row[1] + ' ' + row[2] + ' ' + tkon + ' ' + dejan + '\n')
elif danu_nedelji == 2:
a.write("Wednesday" + ' ' + row[1] + ' ' + row[2] + ' ' + tkon + ' ' + dejan + '\n')
elif danu_nedelji == 3:
a.write("Thursday" + ' ' + row[1] + ' ' + row[2] + ' ' + tkon + ' ' + dejan + '\n')
elif danu_nedelji == 4:
a.write("Friday" + ' ' + row[1] + ' ' + row[2] + ' ' + tkon + ' ' + dejan + '\n')
a.close()
def main():
obrada()
if __name__ == '__main__':
main()
I think you misunderstand how the return statement works.
The reason that your program "continues" ... it doesn't continue -- you specifically invoke your main program another time. If you simply want to go back to the calling location and continue, use
return
You used
return main()
which is a command to invoke main again, wait until it's done, and send that value back to whatever called the function.
How can I make the program print the CTRL+C to go BACK once down?[Look pictures][Picture][1]
while h < math.inf:
time2 = time.strftime("[%H" + ":%M" + ":%S]")
console = colorama.Fore.WHITE + time2 + '' + defaultname
file = open("Accounts/Failed.txt", "a+")
file2 = open("Accounts/Success.txt", "a+")
x = random.randrange(0, 100)
f = generator()
if x <= 97:
print(console + colorama.Fore.RED + "[FAILED] " + "0x" + f + ' ETH Wallet' + colorama.Fore.WHITE + ' CTRL+C to go BACK')
file.write(str(j) + ":0x" + f + "\n")
time.sleep(0.15)
j += 1
file.close()
elif x >= 97:
print(console + colorama.Fore.GREEN + "[SUCCESS] " + "0x" + f + ' ETH Wallet' + colorama.Fore.WHITE + ' CTRL+C to go BACK')
file2.write(str(h) + ":0x" + f + "\n")
time.sleep(0.15)
h += 1
file2.close()```
[1]: https://i.stack.imgur.com/Qa7Bw.png
So to print CTRL+C to go BACK only on the last loop iteration, you have too check if h + 1 is going to break the loop condition. To do so, you could check the condition h + 1 >= math.inf.
if h + 1 >= math.inf:
print("CTRL+C to go BACK")
This way you'll have to remove the CTRL+C to go BACK in your infos print functions
This small scripts makes exactly what I need.
#!/usr/bin/python
import os
import fileinput
import sys
import shutil
import glob
import time
def replaceAll1(files,searchExp,replaceExp):
for line in fileinput.input(files, inplace=1):
if searchExp in line:
line = line.replace(searchExp,replaceExp)
sys.stdout.write(line)
param1 = [1,2,3]
param2 = [1,2,3]
param3 = [1,2,3]
for i in xrange(len(param1)):
for ii in xrange(len(param2)):
for iii in xrange(len(param3)):
os.system("cp -a cold.in input.in")
old_param1 = "param1 = 1"
old_param2 = "param2 = 1"
old_param3 = "param3 = 1"
new_param1 = "param1 = " + str(param1[i])
new_param2 = "param2 = " + str(param2[ii])
new_param3 = "param3 = " + str(param3[iii])
replaceAll1('input.in',old_param1,new_param1)
replaceAll1('input.in',old_param2,new_param2)
replaceAll1('input.in',old_param3,new_param3)
time.sleep(4)
It enters in a configuration file and replaces sequentially the input parameters according to the lists that are accessed by the loop indexes. It is simple a combination of all the three parameters between each other.
# Input file
param1 = 1 # --- Should be [1,2,3]
param2 = 1 # --- Should be [1,2,3]
param3 = 1 # --- Should be [1,2,3]
The problem is that his big brother is not behaving like it. When it loops through the lists, it gets lost in scheme = 2 and puts dissp_scheme = 2 (freezed) when it should be dissp_scheme = 1. I printed out every single variable that goes inside the function replaceAll marked with comments but when I turn on the other calls it mess up everything. Here is the script.
#!/usr/bin/python
import os
import fileinput
import sys
import shutil
import glob
import time
os.chdir(os.getcwd())
# Replaces the input file parameters
def replaceAll(files,searchExp,replaceExp):
for line in fileinput.input(files, inplace=1):
if searchExp in line:
line = line.replace(searchExp,replaceExp)
sys.stdout.write(line)
# Gets a number inside my input file.
def get_parameter(variable,file_name):
f = open(file_name,'r').readlines()
for i in xrange(len(f)):
index = f[i].find(variable)
if index != -1:
pre_found = f[i].split('=')[1]
return pre_found
# Gets the discretization scheme name.
def get_sheme(number):
if number == 1:
return "Simple Centered Scheme"
elif number == 2:
return "Lax-Wendroff Scheme"
elif number == 3:
return "MacCormack Scheme"
elif number == 4:
return "Beam-Warming Scheme"
elif number == 5:
return "Steger-Warming 1st Order Scheme"
elif number == 6:
return "Steger-Warming 2nd Order Scheme"
elif number == 7:
return "Van Leer 1st Order Scheme"
elif number == 8:
return "Van Leer 2nd Order Scheme"
elif number == 9:
return "Roe Scheme"
elif number == 10:
return "AUSM Scheme"
# Gets the dissipation scheme name.
def get_dissip(number):
if number == 1:
return "Pullian Non-Linear dissipation"
elif number == 2:
return "Second difference dissipation"
elif number == 3:
return "Fourth difference dissipation"
elif number == 4:
return "B&W dissipation"
# Generates the density gnuplot scripts.
def gnuplot(variable,pressure_ratio,scheme,dissip_scheme):
#gnuplot('Density',10,get_sheme(3),'Pullian')
# Building name of the output file.
outFileName = variable.lower() + '_ratio' + str(int(pressure_ratio)) + '_' + scheme.replace(" ","") + '_dissp' + dissip_scheme.replace(" ","") + '.tex'
gnuFileName = variable.lower() + '_ratio' + str(int(pressure_ratio)) + '_' + scheme.replace(" ","") + '_dissp' + dissip_scheme.replace(" ","") + '.gnu'
# Build title of the plot
title = 'Analytical vs Numerical | ' + scheme
f = open(gnuFileName,'w')
f.write("set term cairolatex monochrome size 15.0cm, 8cm\n")
f.write('set output "' + outFileName + '"\n')
f.write("set grid\n")
f.write('set xtics font "Times-Roman, 10\n')
f.write('set ytics font "Times-Roman, 10\n')
f.write('set xlabel "x position" center\n')
f.write('set ylabel "' + variable + '" center\n')
f.write('set title "Analytical vs Numerical Results | ' + variable + '" \n')
f.write('set pointsize 0.5\n')
f.write('set key font ",10"\n')
fortran_out_analytical = 'a' + variable.lower() + '.out'
fortran_out_numerical = variable.lower() + 'Output.out'
f.write('plot "' + fortran_out_analytical +'" u 1:2 with linespoints lt -1 lw 1 pt 4 title "Analytical",\\\n')
f.write( '"' + fortran_out_numerical + '" u 1:2 with lines lw 5 title "Numerical"\n')
f.close()
# Generate latex code.
def generate_latex(text_image_file,caption):
latex.write("\\begin{figure}[H]\n")
latex.write(" \centering\n")
latex.write(" \input{" + text_image_file + "}\n")
latex.write(" \caption{"+ caption +"}\n")
latex.write(" \label{fig:digraph}\n")
latex.write("\\end{figure}\n")
latex.write("\n\n")
# -----------------------------------------------------------------------
# Main loop.
# -----------------------------------------------------------------------
pressure_ratios = [5.0]
schemes = [1,2,3]
dissips = [1,2,3]
# Define replace lines for replace all.
scheme_line = "scheme = "
dissip_line = "dissp_scheme = "
# Open Latex export file.
latex = open("bizu.txt",'w')
i = 0
# ratios.
for i in xrange(len(pressure_ratios)):
print "----------------------------------------"
print " + Configuring File for pressure ratio: " + str(pressure_ratios[i])
print "----------------------------------------\n"
# Schemes
for jj in xrange(len(schemes)):
print " + Configuring file for scheme: " + get_sheme(schemes[jj]) + "\n"
for kkk in xrange(len(dissips)):
print " + Configuring file for dissip: " + get_dissip(dissips[kkk])
# We always work with a brand new file.
os.system("rm input.in")
os.system("cp -a cold.in input.in")
# Replace pressures.
p1_line_old = 'p1 = 5.0d0'
rho1_line_old = 'rho1 = 5.0d0'
p1_line_new = 'p1 = ' + str(pressure_ratios[i]) + 'd0'
rho1_line_new = 'rho1 = ' + str(pressure_ratios[i]) + 'd0'
replaceAll('input.in',p1_line_old,p1_line_new)
replaceAll('input.in',rho1_line_old,rho1_line_new)
# Replace discretization scheme.
old_scheme = scheme_line + "1"
new_scheme = scheme_line + str(schemes[jj])
#==========================================================
# This call is messing everything up when scheme turns to 2
#==========================================================
replaceAll('input.in',old_scheme,new_scheme)
# Replace dissipation scheme.
old_dissp_scheme = dissip_line + "1"
new_dissp_scheme = dissip_line + str(dissips[kkk])
print p1_line_old
print new_scheme
print new_dissp_scheme
replaceAll('input.in',old_dissp_scheme, new_dissp_scheme)
time.sleep(3)
# ### Calling program
# os.system("./sod")
#
latex.close()
And the input file that the it works on is:
&PAR_physical
p1 = 5.0d0
p4 = 1.0d0
rho1 = 5.0d0
rho4 = 1.0d0
fgamma = 1.4d0
R_const = 287.0d0
F_Cp = 1004.5
F_Cv = 717.5
/
&PAR_geometry
total_mesh_points = 1001
start_mesh_point = -5.0d0
final_mesh_point = 5.0d0
print_step = 100
/
&PAR_numeric
scheme = 3
iterations = 10000
time_step = 0.0001d0
/
&PAR_dissip
dissp_scheme = 3
dissip_omega = 0.5d0
/
Thank you all !
Trying to get a self updating speedometer and clock working for my truck using gps. So far I have been able to get the read out that I want using easygui and msgbox but it is not self updating which will not help much on either application. Below is the code. Any help would be much appreciated, I know this is pretty ugly and probably not correct but I am new to python.
import gps
from easygui import *
import sys
# Listen on port 2947 (gpsd) of localhost
session = gps.gps("localhost", "2947")
session.stream(gps.WATCH_ENABLE | gps.WATCH_NEWSTYLE)
while True:
try:
report = session.next()
if report['class'] == 'TPV':
if hasattr(report, 'time'):
hour = int(report.time[11:13])
hourfix = hour - 7
if hourfix < 12:
time = 'Current Time Is: ' + report.time[5:7] + '/' + report.time[8:10] + '/' + report.time[0:4] + ' ' + str(hourfix) + report.time[13:19] + ' am'
else:
hourfix = hourfix - 12
time = 'Current Time Is: ' + report.time[5:7] + '/' + report.time[8:10] + '/' + report.time[0:4] + ' ' + str(hourfix) + report.time[13:19] + ' pm'
if report['class'] == 'TPV':
if hasattr(report, 'speed'):
speed = int(report.speed * gps.MPS_TO_MPH)
strspeed = str(speed)
currentspeed = 'Current Speed Is: ' + strspeed + ' MPH'
msgbox(time + "\n" + currentspeed, "SPEEDO by Jono")
except KeyError:
pass
except KeyboardInterrupt:
quit()
except StopIteration:
session = None
print "GPSD has terminated"