detect keyboard key presses in python3 - python-3.x

I am completely new to programming and python so i wanted to know if there is any way to for the program to recognize when i have pressed a specific key and continue rather than using input() function where i have to press enter after i have entered my data.
I've tried using the getch() but the program just continues without waiting for a key to be pressed.
from msvcrt import getch
x=0
while ord(getch() == 117):
print("worked")
TypeError: ord() expected string of length 1, but bool found

You wrote this expression:
ord(getch() == 117)
Instead, use one of these (equivalent) expressions:
ord(getch()) == 117
getch() == chr(117)
getch() == 'u'

Related

How to fix this gnuplot error to handle key presses?

I'm trying to provide basic keyboard interaction for my gnuplot script.
With gnuplot 5.4 patchlevel 1 I'm using MOUSE_CHAR as documented, I believe, however with the simplest script below, I get an error no matter what key I press.
while (1) {
pause mouse keypress
show variable MOUSE_
if (exists("MOUSE_CHAR")) {
if (MOUSE_CHAR == "w") {
print "w"
}
} # <-- line 114
replot
}
The output shows the correct key pressed, for example:
MOUSE_KEY = 119
MOUSE_CHAR = "w"
or
MOUSE_KEY = 114
MOUSE_CHAR = "r"
But immediately after I get
"hrtp.gp" line 114: Non-numeric string found where a numeric expression was expected
The test for string equality is eq not ==, so you want if (MOUSE_CHAR eq "w") { print "w" }.

How do I get the values in my dictionary that I have created in python, to be used, instead of the strings?

Below is a shortened version of my code, without all the validation. I am writing a program that tells the user how strong their password is, by seeing their overall score at the end. If the password has 3 letters next to each other in a row, and those three letters are also next to each other on the 'qwerty' keyboard, then their overall score goes down by 5. I have created a dictionary to assign each letter on the keyboard a value, and then if 2 consecutive letters in the password have a difference of 1, it means there are 3 letters in a row on the keyboard.
However, I keep getting a
ValueError: invalid literal for int() with base 10:
I don't really know how to use dictionaries, so any help is much appreciated!
password=str(input("Please enter a password with more than 4 digits, and it should only be letters:"))
score=0
keyboard={'Q':1,'q':1,'W':2,'w':2,'E':3,'e':3,'R':4,'r':4,'T':5,'t':5,'Y':6,'y':6,'U':7,'u':7,'I':8,'i':8,'O':9,'o':9,'P':10,'p':10,'A':12,'a':12,'S':13,'s':13,'D':14,'d':14,'F':15,'f':15,'G':16,'g':16,'H':17,'h':17,'J':18,'j':18,'K':19,'k':19,'L':20,'l':20,'Z':22,'z':22,'X':23,'x':23,'C':24,'c':24,'V':25,'v':25,'B':26,'b':26,'N':27,'n':27,'M':28,'m':28}
for n in range ((len(password))-2):
if (int(password[n+1])-int(password[n])==1) and (int(password[n+2])-int(password[n+1]==1)):
score=score-5
print(score)
If your password input is only letters, then this following line will raise an error.
int(password[n+1])
and so will int(password[n]) and all your other int casts. The reason for this is because you're casting non-digit characters to int. That's what's causing the error you're seeing.
I believe, your intention is to do
int(keyboard[password[n+1]]) - int(keyboard[password[n]]) == 1
but since, the values of your keyboard dictionary are already int's, then the int casts in your if-statement are not required.
keyboard[password[n+1]] - keyboard[password[n]] == 1

Printing a string character by character including control characters

EDIT - The problem that I was having was with the library that i was trying to use, colorama, I probably should have been more specific.
I want to be able to print a string character-by-character with an extrememly short pause inbetween each character for effect but my code ignores control characters and just prints the individual characters. Not sure how to counter this.
Here is the part of the code that does it:
import time, sys
def slowprint(message, speed):
for x in range(0, len(message)):
if x == len(message)-1:
print(message[x])
else:
print(message[x], end="")
sys.stdout.flush()
time.sleep(speed)
I'm on python 3.2.
I'm not completely sure to understand your question, but I'll assume you're trying to print control characters like '\t' or '\n'.
When you create a string like "A\tB" it's made of three characters and not four. '\t' get converted to a single character directly.
So when you iterate through characters you'd need to map back these control characters to their string representation. For this you can use repr() (see this answer) and you're good
>>> slowprint(repr("abs\tsd\n"), 0.1)
Maybe something like this ?
import time, sys
def slowprint(message, speed):
i = iter(message)
# output first character before pausing
sys.stdout.write(next(i))
sys.stdout.flush()
for letter in i:
time.sleep(speed)
sys.stdout.write(letter)
sys.stdout.flush()
EDIT: fixed

How to compare upper and lowercase letters in a conditional in Swift

Apologies if this is a duplicate. I have a helper function called inputString() that takes user input and returns a String. I want to proceed based on whether an upper or lowercase character was entered. Here is my code:
print("What do you want to do today? Enter 'D' for Deposit or 'W' for Withdrawl.")
operation = inputString()
if operation == "D" || operation == "d" {
print("Enter the amount to deposit.")
My program quits after the first print function, but gives no compiler errors. I don't know what I'm doing wrong.
It's important to keep in mind that there is a whole slew of purely whitespace characters that show up in strings, and sometimes, those whitespace characters can lead to problems just like this.
So, whenever you are certain that two strings should be equal, it can be useful to print them with some sort of non-whitespace character on either end of them.
For example:
print("Your input was <\(operation)>")
That should print the user input with angle brackets on either side of the input.
And if you stick that line into your program, you'll see it prints something like this:
Your input was <D
>
So it turns out that your inputString() method is capturing the newline character (\n) that the user presses to submit their input. You should improve your inputString() method to go ahead and trim that newline character before returning its value.
I feel it's really important to mention here that your inputString method is really clunky and requires importing modules. But there's a way simpler pure Swift approach: readLine().
Swift's readLine() method does exactly what your inputString() method is supposed to be doing, and by default, it strips the newline character off the end for you (there's an optional parameter you can pass to prevent the method from stripping the newline).
My version of your code looks like this:
func fetchInput(prompt: String? = nil) -> String? {
if let prompt = prompt {
print(prompt, terminator: "")
}
return readLine()
}
if let input = fetchInput("Enter some input: ") {
if input == "X" {
print("it matches X")
}
}
the cause of the error that you experienced is explained at Swift how to compare string which come from NSString. Essentially, we need to remove any whitespace or non-printing characters such as newline etc.
I also used .uppercaseString to simplify the comparison
the amended code is as follows:
func inputString() -> String {
var keyboard = NSFileHandle.fileHandleWithStandardInput()
var inputData = keyboard.availableData
let str: String = (NSString(data: inputData, encoding: NSUTF8StringEncoding)?.stringByTrimmingCharactersInSet(
NSCharacterSet.whitespaceAndNewlineCharacterSet()))!
return str
}
print("What do you want to do today? Enter 'D' for Deposit or 'W' for Withdrawl.")
let operation = inputString()
if operation.uppercaseString == "D" {
print("Enter the amount to deposit.")
}

Why is my string nil?

I made this simple program that reads characters until the enter key is pressed
var data: string
while true:
var c = readChar(stdin) # read char
case c
of '\r': # if enter, stop
break
else: discard
data.add(c) # add the read character to the string
echo data
But when it tries to echo data, it crashes
> ./program
hello
Traceback (most recent call last)
program.nim(11) program
SIGSEGV: Illegal storage access. (Attempt to read from nil?)
This means data is nil. But every time I press enter a character, it adds the character to data. Something goes wrong, but where?
data is initially nil when you define it as var data: string. Instead you can use var data = "" to make it an initialized string.
The stream stdin buffers all the characters until the newline key is pressed, then it will submit the character(s). I expected the behavior to be reading direct characters.
That means that \r will never be the case, it will try to add a character to data but data is nil, so that fails. I thought it failed at the echo statement.
To demonstrate, this code works:
var data = ""
while true:
var c = readChar(stdin) # read char
case c
of '\e': # if escape, stop
break
else:
data.add(c) # add the read character to the string
echo data

Resources