I have a python script which receives values in realtime. In a green circle that value need to update in real time. In pink cirkle are line from txt file. I have problem becouse actually i use "os.system("cls")" and print all this but that looks bad when value refresh "fastest", i think you know what's happening.
I want "design interface" it will not update but only value who i want to "refresh". Someone have idea?
Example:
https://i.imgur.com/sAEyB7p.png
Perhaps curses. You will need pip install windows-curses. The following snippet is a piece of what I imagine may suit.
import curses
import time
import random
sometext = "User1: xyz\nUser3: xyz\nUser4: xyz\nUser5: xyz\nUser6: xyz\n"
def main(stdscr):
stdscr.clear()
stdscr.addstr(6, 0, sometext)
for _ in range(0, 10):
stdscr.addstr(2, 2, f"Value: {random.random() * 10: .0f}")
stdscr.addstr(3, 2, f"Value2: {random.random() * 100: .0f}")
stdscr.addstr(4, 2, f"Value3: {random.random() * 1000: .0f}")
stdscr.refresh()
time.sleep(0.5)
curses.wrapper(main)
Related
I want to paint some special words while the program is getting them , actually in real-time .
so I've wrote this piece of code which do it quite good but i still have problem with changing the location of the pointer with move keys on keyboard and start typing from where i moved it .
can anyone give me a hint how to do it ?
here is the CODE :
from colorama import init
from colorama import Fore
import sys
import msvcrt
special_words = ['test' , 'foo' , 'bar', 'Ham']
my_text = ''
init( autoreset = True)
while True:
c = msvcrt.getch()
if ord(c) == ord('\r'): # newline, stop
break
elif ord(c) == ord('\b') :
sys.stdout.write('\b')
sys.stdout.write(' ')
my_text = my_text[:-1]
#CURSOR_UP_ONE = '\x1b[1A'
#ERASE_LINE = '\x1b[2K'
#print ERASE_LINE,
elif ord(c) == 224 :
set (-1, 1)
else:
my_text += c
sys.stdout.write("\r") # move to the line beginning
for j, word in enumerate(my_text.split()):
if word in special_words:
sys.stdout.write(Fore.GREEN+ word)
else:
sys.stdout.write(Fore.RESET + word)
if j != len(my_text.split())-1:
sys.stdout.write(' ')
else:
for i in range(0, len(my_text) - my_text.rfind(word) - len(word)):
sys.stdout.write(' ')
sys.stdout.flush()
Doing it the easy way
As you already seem to be using the colorama module, the most easy and portable way to position the cursor should be to use the corresponding ANSI controlsequence (see: http://en.m.wikipedia.org/wiki/ANSI_escape_code)
The one you are looking for should be CUP – Cursor Position (CSI n ; m H)positioning the cursor in row n and column m.
The code would look like this then:
def move (y, x):
print("\033[%d;%dH" % (y, x))
Suffering by doing everything by hand
The long and painful way to make things work even in a windows console, that doesn't know about the above mentioned control sequence would be to use the windows API.
Fortunately the colorama module will do this (hard) work for you, as long as you don't forget a call to colorama.init().
For didactic purposes, I left the code of the most painful approach leaving out the functionality of the colorama module, doing everything by hand.
import ctypes
from ctypes import c_long, c_wchar_p, c_ulong, c_void_p
#==== GLOBAL VARIABLES ======================
gHandle = ctypes.windll.kernel32.GetStdHandle(c_long(-11))
def move (y, x):
"""Move cursor to position indicated by x and y."""
value = x + (y << 16)
ctypes.windll.kernel32.SetConsoleCursorPosition(gHandle, c_ulong(value))
def addstr (string):
"""Write string"""
ctypes.windll.kernel32.WriteConsoleW(gHandle, c_wchar_p(string), c_ulong(len(string)), c_void_p(), None)
As already stated in the comment section this attempt still leaves you with the problem, that your application will only work in the named console, so maybe you will still want to supply a curses version too.
To detect if curses is supported or you will have to use the windows API, you might try something like this.
#==== IMPORTS =================================================================
try:
import curses
HAVE_CURSES = True
except:
HAVE_CURSES = False
pass
I'm running a python script that will display messages on a board. One of the subroutines that I've created is supposed to grab a random line from a small text file, and display that line. It mostly works, except after looping a few times, it gets stuck on the same number, and just displays the same thing over and over.
I am running this in Python 2.7, on a Raspberry Pi in Raspbian. I am using this github as the base for the project, and added lines of my own to it:
https://github.com/CalebKussmaul/Stranger-Things-Integrated
This is part of a halloween display that will be Stranger Things-themed, so the preloaded messages have a reference to the show. I noticed this issue the other day, and have been pouring over the internet to try and figure out what the problem could be. I've tried doing different methods of selecting a randomized number, including some in some similar (but different) threads on this site. All of them produce exactly the same issue.
Below is the subroutine I created:
def preloaded_messages():
print "Preloaded Messages thread is loaded."
global displaying
while True:
if not displaying:
with open('preloaded_messages.txt') as f:
lines = len(f.readlines())
rgn = random.randint(1,lines)
msg = linecache.getline('preloaded_messages.txt', rgn)
print "rng: ", rgn
print "total lines: ", lines
print "line: ", msg
print "displaying from preloaded_messages.txt: ", msg
display(msg)
time.sleep(10)
And here's my preloaded_messages.txt file:
help me
im trapped in the upside down
leggo my eggo
friends dont lie
run /!
hopper is alive
rip barb
demogorgon is coming /!
mouthbreather
When I run it, my output is like this:
rng: 6
total lines: 9
line: hopper is alive
rng: 2
total lines: 9
line: im trapped in the upside down
rng: 9
total lines: 9
line: mouthbreather
...
rng: 9
total lines: 9
line: mouthbreather
the first few times are always random (and the number of times it successfully randomizes varies), but when it gets on 9, it just stays there for as long as I let it run. I am at a loss as to why it works the first few times, but not once it gets to 9.
EDIT: Interestingly, as I've been writing this, I also tried adding a blank line at the end, and while it looked like it'd be stuck again, as it did that one three times in a row, then it finally moved to others. I'm not sure how that changes things. And ideally, I'd rather not have the blank line in there, as it eats up time displaying nothing. So it'd be nice to fix the issue. Anyone have any ideas?
It is reseeding the random generator. See line 49 of stranger.py in the https://github.com/CalebKussmaul/Stranger-Things-Integrated: random.seed(i).
The color_of function should be written as:
def color_of(i):
"""
This function generates a color based on the index of an LED. This will always return the same color for a given
index. This allows the lights to function more like normal christmas lights where the color of one bulb wont change.
:param i: index of LED to get color of
:return: a pseudorandom color based on the index of the light
"""
_random = random.Random(i)
rgb = colorsys.hsv_to_rgb(_random.random(), 1, 1)
return int(rgb[0] * 255), int(rgb[1] * 255), int(rgb[2] * 255)
To create its own Random instance with the given seed rather than reseeding the Random instance that is a singleton in the random module.
This appears to work for me. Note that I'm seeding the RNG.
import time
import random
from datetime import datetime
def preloaded_messages():
print("Preloaded Messages thread is loaded.")
displaying = False
while True:
if not displaying:
with open('preloaded_messages.txt') as f:
random.seed(datetime.utcnow())
text = f.read().splitlines()
msg = random.choice(text)
print("line: ", msg)
# print("displaying from preloaded_messages.txt: ", msg)
time.sleep(10)
if __name__ == "__main__":
preloaded_messages()
I would like to understand how to reprint multiple lines in Python 3.5.
This is an example of a script where I would like to refresh the printed statement in place.
import random
import time
a = 0
while True:
statement = """
Line {}
Line {}
Line {}
Value = {}
""".format(random.random(), random.random(), random.random(), a)
print(statement, end='\r')
time.sleep(1)
a += 1
What I am trying to do is have:
Line 1
Line 2
Line 3
Value = 1
Write on top of / update / refresh:
Line 1
Line 2
Line 3
Value = 0
The values of each line will change each time. This is effectively giving me a status update of each Line.
I saw another question from 5 years ago however with the addition of the end argument in Python 3+ print function, I am hoping that there is a much simpler solution.
If you want to clear the screen each time you call print(), so that it appears the print is overwritten each time, you can use clear in unix or cls in windows, for example:
import subprocess
a = 0
while True:
print(a)
a += 1
subprocess.call("clear")
If I've understood correctly you're looking for this type of solution:
import random
import time
import os
def clear_screen():
os.system('cls' if os.name == 'nt' else 'clear')
a = 0
while True:
clear_screen()
statement = """
Line {}
Line {}
Line {}
Value = {}
""".format(random.random(), random.random(), random.random(), a)
print(statement, end='\r')
time.sleep(1)
a += 1
This solution won't work with some software like IDLE, Sublime Text, Eclipse... The problem with running it within this type of software is that clear/cls uses ANSI escape sequences to clear the screen. These commands write a string such as "\033[[80;j" to the output buffer. The native command prompt is able to interpret this as a command to clear the screen but these pseudo-terminals don't know how to interpret it, so they just end up printing small square as if printing an unknown character.
If you're using this type of software, one hack around could be doing print('\n' * 100), it won't be the optimal solution but it's better than nothing.
You could use curses for this.
#!/usr/bin/python3
import curses
from time import sleep
from random import random
statement = """
Line {}
Line {}
Line {}
Value = {}"""
screen = curses.initscr()
n = 0
while n < 20:
screen.clear()
screen.addstr(0, 0, statement.format(random(), random(), random(), n))
screen.refresh()
n += 1
sleep(0.5)
curses.endwin()
My code generates random outcomes of the list "outcomes". I am running batches of 10,000+, and I need a way to count the batches and total them at the bottom. How would I do this?
Here is my code:
import random
import time
from time import sleep
outcomes = ['TT','Tt','Tt','tt']
for x in range (0, 5):
b = "LOADING OUTCOMES" + "." * x
print (b, end="\r")
time.sleep(0.5)
print("4 Possible Genetic Outcomes Will Be Shown. . . ") ; sleep(1)
for x in range (0, 10000):
print(random.choice(outcomes))
time.sleep(0.001)
x=input("Done determining outcomes!! Press enter to close")
from collections import Counter
from random import choice
outcomes = ["TT", "Tt", "Tt", "tt"]
totals = Counter(choice(outcomes) for _ in range(10000))
which gives something like
Counter({'TT': 2528, 'Tt': 4914, 'tt': 2558})
This is using the code you provided in the screen shot. Here is how I would go about it. Check if this solution works for you. Next time please put the code inside the question itself and not as an image. It will attract more people to help you since they can just copy paste your code and help you out quicker instead of typing out your code themselves.
How I solved it:
have a dictionary already predefined with the possible choices from the list. Each time a choice appears, just increment the counter by 1. At the end print all the possibilities. You can use a loop to do this, but since there are only 3 elements I decided to just print them out.
import random
import time
from time import sleep
outcomes = ["TT", "Tt", "Tt", "tt"]
outcomesCount = {"TT":0, "Tt":0, "tt":0}
for x in range(0,5):
b = "LOADING OUTCOMES" + "." * x
print(b, end="\r")
time.sleep(0.5)
print("4 Possible Genetic Outcomes Will Be Shown. . . ")
sleep(1)
for x in range(0,10000):
choice = (random.choice(outcomes))
time.sleep(0.001)
outcomesCount[choice] += 1
print(choice) #This is something you were doing in original code. I would not do this because there are too many print statements, and will cause the program to run for a while.
print("The number of times each outcome appeared was: ")
print("TT : %s" %(outcomesCount["TT"]))
print("Tt : %s" %(outcomesCount["Tt"]))
print("tt : %s" %(outcomesCount["tt"]))
x = input("Done determining outcomes!! Press enter to close")
The output of running the above program was note this is only the last print statements:
The number of times each outcome appeared was:
TT : 2484
Tt : 4946
tt : 2570
Done determining outcomes!! Press enter to close
improvements:
1. get rid of the sleep because you are just delaying the program execution. You don't need it there. If you want the user to see the loading message for a second of two, you can just add 1 pause at the end.
The sleep in the second for loop is not needed at all. This is a computer and is capable of doing amazing things. This is nothing compared to what it can handle.
dont print all the outcomes, as it is going to be printing 10000 different rows.
Good luck and hope this helped.
I am very new in Python and I decided to make a game.
I want a value to be output like this:
Heat: x #x would always be changing
For that I have the following block of code:
while True:
print("Heat: {}".format(Heat))
but all it does is spam "Heat: xHeat: xHeat: x"
When it should be only one Heat bar
What should I do?
In that code 'Heat' in the loop and it will be printed all the time:
Heat = 0
while True:
Heat +=1
print ('Heat: {heat}'.format(heat=Heat))
In that code 'Heat' out of the loop and it will be printed once:
Heat = 0
print ('Heat:')
while True:
Heat +=1
print ('{heat}'.format(heat=Heat))
if you want more newlines use '\n' char (strictly depends on OS).
You can use carriage return to send the cursor to the start of the line.
import sys
while True:
sys.stdout.write("\rHeat: {}".format(Heat))
sys.stdout.flush()
But this approach doesn't sound like you will be able to extend it into any sort of game.
You should look up the python curses library for complete control over the console output.
Also if the number of digits in your output changes then you might want to right-align the output so that you don't get any left-overs. This code demonstrates what happens if you go from a 2 digit number to a 1 digit number:
import sys
import time
for heat in reversed(range(5, 12)):
time.sleep(0.5)
sys.stdout.write("\rHeat: {:>5}".format(heat))
sys.stdout.flush()