Making Python text green and using Spinning cursor - Newbies questions - linux

I want to make my Python script file,when I "announce" something to the user, to be green like this:
How can this be done?I saw a script using this with sys.stdout.write but I dont understand how to use it, Im using a simple "print" commands..
Also, I would like to have the Spinning cursor spin as long as this command runs and only stops when this command stops(finishes):
print('running network scan')
output = subprocesss.check_output('nmap -sL 192.168.1.0/24',shell=True)
print('Done')
Any way to do that (unknown time until task is done)?
Im using a code suggested by nos here:
Spinning Cursor

So, about getting the terminal color to be green, there is a neat package called colorama that generally works great for me. To check whether the process is running or not, I would recommend using Popen instead of check_output, since the latter does not allow you to communicate with the process as far as I know. But you need to since you want to know if your subprocess is still running. Here is a little code example that should get you running:
import subprocess
import shlex
import time
import sys
import colorama
def spinning_cursor():
"""Spinner taken from http://stackoverflow.com/questions/4995733/how-to-create-a-spinning-command-line-cursor-using-python/4995896#4995896."""
while True:
for cursor in '|/-\\':
yield cursor
# Create spinner
spinner = spinning_cursor()
# Print and change color to green
print(colorama.Fore.GREEN + 'running network scan')
# Define command we want to run
cmd = 'your command goes here'
# Split args for POpen
args=shlex.split(cmd)
# Create subprocess
p = subprocess.Popen(args,stdout=subprocess.PIPE)
# Check if process is still running
while p.poll()==None:
# Print spinner
sys.stdout.write(spinner.next())
sys.stdout.flush()
sys.stdout.write('\b')
print('Done')
# Grab output
output=p.communicate()[0]
# Reset color (otherwise your terminal is green)
print(colorama.Style.RESET_ALL)

Related

Pyperclip does not paste until entire code was run

I am trying to use pyperclip (1.8.2) on ubuntu (20), and it seems like the pasting only occurs once all the script has finished being executed. Moreover, pasting into a program seems to freeze that program (chrome for example).
import time
import pyperclip
pyperclip.copy('Hello, world!')
time.sleep(20)
# Paste anywhere, it will only appear after the 20 seconds are over.
What is the reason for this ? Is there a way to make this work (paste anywhere without delay) ?

How to manipulate tkinter GUI from an imported file

I try to create a small GUI with tkinter. To make my code more readable I want to split the code in 2 files. One for the GUI information and one for the process informations. Or is it a bad idea?
So I create a gui.py where I import my process informations from program.py.
gui.py:
import tkinter as tk
from program import *
root = tk.Tk()
btn_Start = tk.Button(text="Start", command=start_loop)
btn_Stop = tk.Button(text="Stop", command=stop_loop, state=tk.DISABLED)
btn_Start.grid(row=1, column=0)
btn_Stop.grid(row=1, column=1)
root.mainloop()
program.py:
def start_loop():
print('disable Start button and enable Stop button')
# what is the code to disable the start button and enable the stop button?
def stop_loop():
print('disable Stop button and enable Start button')
# what is the code to disable the stop button and enable the start button?
How do I tell the button the disable/enable information in my program.py file? I do not understand how I get the information from the gui to the program and back to the gui?
Thanks for your help
For such a small program, it is overkill.
Looking at the tkinter programs I've written, all of them are between 200−300 lines. This is including headers, comments and blank lines. The number of actual code lines is 100−200.
In my opinion that is small enough to comfortably handle in an editor in one file.
Looking over most of my source code repositories, the longest Python files tend to top out at around 230 lines of actual code.
Keeping all the code in one file has significant advantages for a program when you need to install it. Just copy the file and you're done. No need for modules and a setup.py.

Python program stops right away

So I tried to record they keystrokes of my keyboard, when I use the python IDLE and write it in there, it works, but when i run it in the terminal with python3.8.1 it ends right away. That's the code:
import keyboard
def on_key(key):
print(key)
keyboard.on_press(on_key, suppress=False)

Multithreaded Music Playing with Pygame in Terminal

I am attempting to make a text game and add some music to it and maybe sounds too, however, the "Big and Greatest" answer was Pygame. After testing with it, I found that when you use ANY Pygame function, it stops the current terminal session from printing any more output, this stops the game from continuing.
I first tried the usual...
from pygame import *
def some_function():
mixer.load("music.mp3")
mixer.music.play(0)
clock = time.Clock()
clock.tick(10)
while mixer.music.get_busy():
clock.tick(10)
Rest_of_function
And of course this does not work because it is a loop and is doing it in order so I next tried...
from file_with_music import * #added threading to this file
def main():
file_with_music.start()
Rest_of_Function
This however did not work as the annoying "Welcome to pygame" popup blocked terminal output again...
SO the next step was to make a new file and...
from Main import *
from Intro_Sounds import *
if __name__ == '__main__':
Intro_Thread.start() #Intro did not start because pygame popup was somehow called
Music_Thread.start()
Even after putting them both in threads, it still did not work...
As a side note, there is a function built into Main that is meant to execute
Music_Thread.join()
Music_Thread.stop()
After certain input is met.
The expected result is for it to play music in the background while the terminal continues printing out input and accepting input up until the input that would kill the Music thread is input. Of course, it did not work, and I am at a loss...
How can music be played without freezing the terminal.
The pygame.mixer sadly doesn't have this capability (as far as I know). Use winsound instead:
import winsound # only on windows tho...
winsound.PlaySound('sound.wav', winsound.SND_ASYNC) # this will play the sound and...
print('I can still print :D') # this can still print :D
After trying a few things I found...
Pygame is not friendly with sound and terminal output, so it won't work.
WxPython no longer has a functional sound module, making it useless.
Other projects are abandoned or OS specific...
However, I found that PyOpenAL actually works, although it can't understand mp3 files or 32bit float wav. Instead of using multithreading I switched to multiprocessing (making a 2000 line script to properly learn how the module works) and now the sound plays (and loops) while allowing terminal output.
TL:DR
PyOpenAL is the winner.
please try as follow--
from pygame import *
def some_function():
pygame.mixer.music.load("music.mp3")
pygame.mixer.music.play(0)
clock = time.Clock()
clock.tick(10)
while pygame.mixer.music.get_busy():
clock.tick(10)
Rest_of_function

iPython/ Jupyter notebook clear only one line of output

How can I print the status of a Jupyter notebook on the previous line? I think I'm looking for something like clear_output(), but for only a single line.
Sample code:
from IPython.display import clear_output
import time
print('This is important info!')
for i in range(100):
print('Processing BIG data file {}'.format(i))
time.sleep(0.1)
clear_output(wait=True)
if i == 50:
print('Something bad happened on run {}. This needs to be visible at the end!'.format(i))
print('Done.')
When this runs it gives the behavior of over-writing the previous status line, but both of the lines marked as important (with exclamation points and everything!) are lost. When this is finished the display just says:
Done.
What it should say is:
This is important info!
Something bad happened on run 50. This needs to be visible at the end!
Done.
This post suggests using clear_output() and then reprinting everything. This seems impractical because the amount of data I really tend to display is big (lots of graphs, dataframes, ...).
Here's two SO links about clear_output().
Is there a way to make this work that doesn't involve reprinting everything?
I got it woking using the update function of the display handle:
from IPython.display import display
from time import sleep
print('Test 1')
dh = display('Test2',display_id=True)
sleep(1)
dh.update('Test3')
This will do it:
import IPython
IPython.display.display_javascript(r'''
var el = document.querySelector('.output_text:last-of-type > pre');
el.innerHTML = el.innerHTML.replace(/(\n.*$)/gm,""); ''', raw=True)
This simple escape sequence trick can do the job most of the time. \n and \r can do a lot if used properly.
\r: (Carriage Return) (CR) returns the cursor to the beginning of the new line without moving to a new line.
\n:(Line Feed) (LF) moves the cursor to the next line.
import time
print('This is important info!')
for i in range(100):
print("\r"+'Processing BIG data file {}'.format(i),end="")
time.sleep(0.1)
if i == 50:
print("\r"+'Something bad happened on run {}. This needs to be visible at the end!'.format(i))
print("\r"+'Done.')

Resources