Python deleting input line - python-3.x

I would like to have an input loop in python 3 where the information which gets typed in gets deleted from terminal automatically (f.eks. after 3 seconds)
I know the function with \r to go back in line, but struggle with the automatic new line after input.
while True:
inputStr = (input("Add the hidden word: ")).lower()
processingTheInput(inputStr) #some sort of function using the input word

Ansi escape codes will not work the same on all terminals but this might suit your needs. The ‘\033’ is the escape character. The ‘[1A’ says go up one line and the ‘[K’ says erase to the end of this line.
prompt = 'Add the hidden word: '
inputStr = input(prompt).lower()
print ('\033[1A' + prompt + '\033[K')

You want to clear the terminal with a function
# import only system from os
from os import system, name
# import sleep to show output for some time period
from time import sleep
# define our clear function
def clear():
# for windows
if name == 'nt':
_ = system('cls')
# for mac and linux(here, os.name is 'posix')
else:
_ = system('clear')
Now you need to have a function that adds your word into a list then runs the clear function, then finally can pick a word at the end

Related

Is there a function from terminal that removes repetition and concatenates the output on the same line?

With this input
x 1
x 2
x 3
y 1
y 2
y 3
I'd like to have this output
x 1;2;3
y 1;2;3
Thank you in advance,
Simone
If by terminal you mean something natively built in you might not be in much luck, however you could run a python file from the terminal which could do want you want and more. If having a standalone file isn't possible then you can always run python in REPL mode for purely terminal usage.
If you have python installed all you would need to do to access REPL would be "py" and you could manually setup a processor. If you can use a file then something like this below should be able to take any input text and output the formatted text to the terminal.
file = open("data.txt","r")
lines = file.readlines()
same_starts = {}
#parse each line in the file and get the starting and trailing data for sorting
for line in lines:
#remove trailing/leading whitesapce and newlines
line_norm = line.strip()#.replace('\n','')
#splits data by the first space in the line
#formatting errors make the line get skipped
try:
data_split = line_norm.split(' ')
start = data_split[0]
end = data_split[1]
except:
continue
#check if dictionary same_starts already has this start
if same_starts.get(start):
same_starts[start].append(end)
else:
#add new list with first element being this ending
same_starts[start] = [end]
#print(same_starts)
#format the final data into the needed output
final_output = ""
for key in same_starts:
text = key + ' '
for element in same_starts[key]:
text += element + ";"
final_output += text + '\n'
print(final_output)
NOTE: final_output is the text in the final formatting
assuming you have python installed then this file would only need to be run with the current directory being the folder where it is stored along with a text file called "data.txt" in the same folder which contains the starting values you want processed. Then you would do "py FILE_NAME.ex" ensuring you replace FILE_NAME.ex with the exact same name as the python file, extension included.

Writing strings to a text file in python

I am generating some random strings in python using the following code:
import string
import random
import os
passphrases = []
pass_file = open("Passphrases2.txt","w")
os.chmod("Passphrases2.txt",0o777)
for _ in range(100):
st = "".join(random.choice(string.ascii_lowercase + string.ascii_uppercase + string.digits) for i in range(random.randint(8,16)))
passphrases.append(st)
print(st)
for p in passphrases:
pass_file.write("\n"%p)
I want these strings to be stored in a text file in the same directory as the python code.
When I execute this code, a file named Passphrases2.txt gets created but it is empty in the first execution.
When I execute the same code for the second time, the file gets updated with the strings that were generated during the first execution, then on running the third time, it gets updated with the strings generated in the second execution and so on. I am unable to figure out why this is happening.
You need to .close() file or use with statement.
This is including some optimizations:
import os
from random import choice, randint
import string
alphabet = string.ascii_lowercase + string.ascii_uppercase + string.digits
with open("Passphrases2.txt", "w") as pass_file:
for _ in range(1000):
st = "".join(choice(alphabet) for i in range(randint(8, 16)))
print(st)
pass_file.write(f"{st}\n")
os.chmod("Passphrases2.txt", 0o777)
import string
import random
import os
passphrases = []
for _ in range(100):
st = "".join(random.choice(string.ascii_lowercase + string.ascii_uppercase + string.digits) for i in range(random.randint(8,16)))
passphrases.append(st)
print(st)
with open("Passphrases2.txt","w") as pass_file:
for p in passphrases:
pass_file.write("%s\n" %p)
It's because you are missing pass_file.close() at the end to properly close the file handle after finishing to write. Without properly closing, the write to file was not fully flushed and saved. It's like you are typing something in Notepad but have not yet hit the save button.
Then on the 2nd run, pass_file = open("Passphrases2.txt","w"), reopening the file handle will close the previous handle; this will act like pass_file.close() for the previous run and thus you are seeing previous data on 2nd run and so on.
You may add pass_file.close() after the last for loop or use the Python with statement to ensure file handle open is being closed properly after it is done.
You need to close the file in the end 😀

How do I change the key to confirm/submit the input() function?

I am making a typeracer sort of game as a final assignment for school and I want to have it so that every time the user presses "space" the input() function would be submitted.
For example, if I were to regularly use the input() function I would need to press "enter" for the input to submit. However, I want it so that if I were to press space instead of enter the function would still submit.
If anyone knows a way around this please help.
I used the getch module to do this.
def takeInput():
word = ''
userInp = ''
# this loop ends when the user presses space indicating a new word
while userInp != " ":
if userInp == backSpace(): # I created a whole new backspace function for this
word = word[:-1]
print('\r' + ' '*25)
print('\033[F\r'+ word, end="") # goes up one line then proceeds
else:
word += userInp
word = word.strip()
userInp = g.getche()
# erases final output
print("\r", end="")
sys.stdout.write("\033[K")
return word
With the getch module you can use getch.getche() to act as the input function. You save the users input to a variable until they press whichever key you want then save that elsewhere. So eg,
while inp != 'd':
inp = getch.getche() # this displays the input
btw, getch is not in the standard library so do 'pip install getch' into the console to use it.

Noob Question How would I update a print a function's output without creating a new line in my term in python3?

I'm not exactly sure how to word this to be honest, but here's a simplified version of my current code.
for idx in range(0,11):
print('Failed:',idx)
This outputs:
Failed: 0
Failed: 1
Failed: 2
Failed: 3
Failed: 4
Failed: 5
Failed: 6
Failed: 7
Failed: 8
Failed: 9
Failed: 10
I'm trying to replace the original int with the next int in the range instead of spamming my terminal with a new line for every int in the range.
How could I update "Failed: 1" to "Failed: 2" without creating a new line for "Failed: 2"?
Sorry if this is poorly worded, if you're willing to help me but like me to elaborate further please say so and I will try my best.
What you probably want to do is change 'Failed: 1' to 'Failed: 2', not have 'Failed: 1 Failed: 2' on the same line or new lines.
The ASCII backslash b (backspace) helps erase characters on the same line. You'd want to move the cursor back to where the last number was and replace it.
Here's a simple program that moves back on the same line and replaces the counter.
import time
import sys
print(0, end="")
prev = 0
for i in range(20):
print(("\b" * (len(str(prev)) + 1)), i, end="")
sys.stdout.flush()
prev = i
time.sleep(1)
And to complete your example:
import time
import sys
last_idx = None
prefix = ''
print("Failed: ", end="")
for idx in range(0,11):
if last_idx is not None:
prefix = '\b' * len(str(last_idx))
print(prefix + str(idx), end='')
# python buffers output so you want to flush it everytime.
sys.stdout.flush()
last_idx = idx
# I've added a time.sleep here so you can see it happen rather than zoom past you
time.sleep(1)
Alternatively, instead of just backspacing few characters, you can go back to the beginning of the line with "carriage return" (\r instead of \b).
Try this :
import sys
import time
for i in range(10):
sys.stdout.write("\rFailed: {}".format(i))
sys.stdout.flush()
time.sleep(0.5)
There is a second parameter that the function print takes to to specify what should print do at the end of line
print("Text here", end="")
whoops let's try again...
Your only option is to clear the whole console between prints. there are two ways of going about this.
option 1: You could try and use ANSI escape sequence but might be a little flakey
print(chr(27)+'[2j')
print('\033c')
print('\x1bc')
Option 2: use the os module
from os import system, name
# Only on Unix
system('cls')
# Only on windows
system('clear')

Detect arrow keys being pressed on console in Python

I am trying to write a console program in Python 3 that provides some sort of shell for the user, just like the Python 3 shell in a console. I was able to achieve this relatively quickly by using the input()method. However, it would be nice if, in that shell, one could use the arrow keys to cycle through the most recently typed commands, just like you can in other shells. The input() method does not provide this feature, and I did not find any other simple tools to do this, except for the curses module, which needs to take over the whole screen to work. One of my approaches was to read the typed text from stdin byte by byte and then check it against the codes for the special characters I'm looking for. This works pretty well, but it would run into problems when the user (for some reason) types a weird unicode character that contains the code for a key like the arrow key somewhere in the middle. While this is still an acceptable solution for me, I feel like this is a problem which ought to have been solved (better) before, given how often it has got to occur.
In Python 3, sys.stdin.read returns unicode characters as a single character. Escape sequences for arrow keys are delivered as multiple ASCII characters. Here is an example program , using tty and termios, which parses inputs accordingly.
import sys,tty,termios
# Commands and escape codes
END_OF_TEXT = chr(3) # CTRL+C (prints nothing)
END_OF_FILE = chr(4) # CTRL+D (prints nothing)
CANCEL = chr(24) # CTRL+X
ESCAPE = chr(27) # Escape
CONTROL = ESCAPE +'['
# Escape sequences for terminal keyboard navigation
ARROW_UP = CONTROL+'A'
ARROW_DOWN = CONTROL+'B'
ARROW_RIGHT = CONTROL+'C'
ARROW_LEFT = CONTROL+'D'
KEY_END = CONTROL+'F'
KEY_HOME = CONTROL+'H'
PAGE_UP = CONTROL+'5~'
PAGE_DOWN = CONTROL+'6~'
# Escape sequences to match
commands = {
ARROW_UP :'up arrow',
ARROW_DOWN :'down arrow',
ARROW_RIGHT:'right arrow',
ARROW_LEFT :'left arrow',
KEY_END :'end',
KEY_HOME :'home',
PAGE_UP :'page up',
PAGE_DOWN :'page down',
}
# Blocking read of one input character, detecting appropriate interrupts
def getch():
k = sys.stdin.read(1)[0]
if k in {END_OF_TEXT, END_OF_FILE, CANCEL}: raise KeyboardInterrupt
print('raw input 0x%X'%ord(k),end='\r\n')
return k
# Println for raw terminal mode
def println(*args):
print(*args,end='\r\n',flush=True)
# Preserve current terminal settings (we will restore these before exiting)
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
# Enter raw mode (key events sent directly as characters)
tty.setraw(sys.stdin.fileno())
# Loop, waiting for keyboard input
while 1:
# Parse known command escape sequences
read = getch()
while any(k.startswith(read) for k in commands.keys()):
if read in commands:
println('detected command (%s)'%commands[read])
read = ''
break
read += getch()
# Interpret all other inputs as text input
for c in read:
println('detected character 0x%X %c'%(ord(c),c))
# Always clean up
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
println('')
sys.exit(0)

Resources