Test condition not work - python

I'm using python with select and system library here the code :
from __future__ import (absolute_import, division,
print_function, unicode_literals)
from select import select
import sys
def main():
timeout = 5
print('Please type something: ', end = '')
sys.stdout.flush()
rlist, wlist, xlist = select([sys.stdin],[],[], timeout)
k=sys.stdin.readline()
if k=="f":
data = sys.stdin.readline()
print('you entered', data)
else:
print('\nSorry, {} seconds timeout expired!'.format(timeout))
print(k) #see the sys.stdin result
if __name__ == '__main__':
main()
this program wait the user until put a char
i put in the program a condition if the user put a char after 5 second so the program stop also if the user give something different of the 'f' char but the problem the condition doesn't work i put a test to see the result of the sys.stdin value he give me the 'f char but when i put the result in the if statement the program don't work
this screenshot of the result:
enter image description here
Can someone give me the reason of this result ?

I don't know much about the select library. But here is an error the immediately caught my eyes.
You read from the input with k=sys.stdin.readline(). This means that k will contain the complete line, including the \n (newline) symbol. So if you press f + Enter the value of k will be "f\n", not "f". This is the reason why the comparison is always wrong.
It would be best to compare the values with if k.strip() == "f":.
Edit
Just had a quick look into the select library. If you want to determine if a timeout happened, you need to work with the return values of the select function. And not read from input directly. Otherwise you will wait regardless if a timeout happened or not.
I'm not sure what you want to accomplish, but something similar to the following code will work.
from __future__ import print_function
from select import select
import sys
timeout = 5
print('Please type something: ', end = '')
sys.stdout.flush()
inputready, _, _ = select([sys.stdin],[],[], timeout)
if inputready:
k = sys.stdin.readline()
if k.strip()=="f":
print("You printed 'f'")
else:
print("Not 'f'")
else:
print('\nSorry, {} seconds timeout expired!'.format(timeout))

Related

How to reject input until needed in Python?

I have taken an excerpt from my code where the problem still happens. I believe this is because of my slow_type function but while the dialogue is being "slow typed" my input will take any values typed during the "slow_type" even before the input shows up. I want the input to only be able to be typed in once the slow_type function is finished. How would I do this?
import time
import sys
def slow_type(line, speed):#You input the dialogue and speed(smaller = faster)
for l in line:
sys.stdout.write(l)
sys.stdout.flush()
time.sleep(speed)
time.sleep(.5)
NL1 = "Huh, I see you finally came. "
NL2 = "You know I sent you that message a long time ago.\n"
NL3 = "But I guess you are here now, and that's what matters. "
NL4 = "So...\n"
NL5 = "\n\t\t\t\tAre you ready?\n\n"
slow_type(NL1, .05)
slow_type(NL2, .05)
slow_type(NL3, .05)
slow_type(NL4, .2)
slow_type(NL5, .05)
print("\t\t1:Yes, I am. 2:Who are you? 3:No, I am leaving.\n")
first_choice = input("\t\t\t\t ").lower()
I am using Windows 10 cmd.

Python program doesn't quit; import random causing errors

Forgive me if this comes out a bit scatter-brained, I'm not exaggerating when I say I've been working on this program for over 13 hours now and I am seriously sleep deprived. This is my 4th revision and I honestly don't know what to do anymore, so if anyone can help me, it would be greatly appreciated. My introduction to programming teacher wanted us to make a "flash card" study program from his template. I am using Idle 3.3.3 on a windows 7 machine.
#Flash Cards
#Uses parallel arrays to store flash card data read from file
#Quizzes user by displaying fact and asking them to give answer
import random
def main():
answer = [] #array to store answer for each card
fact = [] #array to store fact/definition for each card
totalTried = 0 #stores number of cards attempted
totalRight = 0 #stores number of correct guesses
loadCards(answer, fact) #call loadcards() and pass it both arrays
numCards = len(answer) #find number of cards loaded
keepGoing = "y"
while keepGoing == "y" or keepGoing == "Y":
#Enter your code below this line
# 2a. Pick random integer between 0 and numCards and store the
# number in a variable named randomPick.
randomPick = random.randint (0, numCards)
# 2b. Add one to the totalTried accumulator variable.
totalTried = totalTried + 1
# 2c. Print element randomPick of the fact array. This shows the
# user the fact/definition for this flashcard.
print (fact [randomPick] )
# 2d. Prompt the user to input their guess and store the string they
# enter in a variable named "userAnswer"
userAnswer = input ('What is your answer?' )
# 2e. Compare the user's guess -userAnswer- to element
# -randomPick- of the answer array.
if userAnswer == (answer [randomPick]):
# 2e-1 If the two strings are equal, tell the user they
# guessed correctly and add 1 to the totalRight
# accumulator variable.
print ('That is correct.')
totalRight == totalRight + 1
# 2e2. If the two strings are not equal, tell the user they guessed
# wrong and display the correct answer from the answer array.
else:
print ('That is incorrect.')
print (answer [randomPick])
#2f. Prompt the user the user to see if they want to continue and
#store their response in the keepGoing variable.
keepGoing = input ('Would you like to continue?')
#Enter your code above this line
print("You got", totalRight, "right out of", totalTried, "attempted.")
def loadCards(answer, fact):
#Enter your code below this line
# 1a. Open flashcards.txt in read mode & assign it var name "infile"
infile = open('flashcards.txt', 'r')
# 1b. Read 1st line from file and store in var. name "line1"
line1 = infile.readline ()
# 1c. Use while loop to make sure EoF has not been reached.
while line1 != '':
# 1c1. Strip newline escape sequence (\n)from variable's value.
line1 = line1.rstrip ('\n')
# 1c2. Append string to answer array.
answer.append (line1)
# 1c3. Read next line from file and store in var. name "line2"
line2 = infile.readline ()
# 1c4. Strip newline escape sequence (\n) from variable's value.
line2 = line2.rstrip ('\n')
# 1c5. Append the string to the fact array.
fact.append (line2)
# 1c6. Read next line from file and store it in var. name "line3".
line3 = infile.readline ()
# 1d. Close file.
infile.close()
#Enter your code above this line
main()
When I run the program nothing actually happens, but when I try to close the shell window afterwards, it tells me that the program is still running and asks if I want to kill it.
Debugger shows me no information when I try to check it, also.
However, if I copy the code into the shell and run it from there, I get "SyntaxError: multiple statements found while compiling a single statement". Neither file has changed, but earlier it was telling me there was a problem with "import random".
Thanks in advance for any help.
I took a quick look and it mostly seems okay to me. I changed input() to raw_input() (two of them in your code) and noticed you had a double equals when you probably meant a single one
line 36:
totalRight == totalRight + 1
changed to
totalRight = totalRight + 1
which fixes your correct answer counter and line 68:
line3 = infile.readline ()
changed to
line1 = infile.readline ()
else it gets caught in your while loop forever. And I just copied line 54:
line1 = infile.readline ()
and pasted it so it is there twice to add another readline() call, just a lazy way of skipping the first line in your text file, since it seems to be a comment and not part of the answers and questions. You probably don't want to do that and just remove the comment from your text file. =b
With those changes, it seems to work fine for me.
Since this is for a class (and I can't only comment, I can just answer) I want to add that there actually is such a thing as too many comments
These comments (and to be honest, most of your comments) are distracting and unnecessary
answer = [] #array to store answer for each card
fact = [] #array to store fact/definition for each card
totalTried = 0 #stores number of cards attempted
totalRight = 0 #stores number of correct guesses
loadCards(answer, fact) #call loadcards() and pass it both arrays
numCards = len(answer) #find number of cards loaded
Also, the whole point of putting your program inside of a function called main is so you can run that function only if you are calling that file directly and you should probably put
if __name__ == '__main__':
main()
at the bottom of your code instead of just
main()
Use of input() is generally considered dangerous (unless you're using Python3 or later where it is the same as raw_input()) due to the fact that it evaluates the input. You should handle the type yourself with something like, if you want an integer,
foo = int(raw_input('Input a number: '))
(Note that the return of raw_input is a string, so if you want a string you don't have to do anything)

Output Daffodils-Numbers with python

I want to write a python program, first it asks you to enter two numbers, and then output all daffodil numbers between the two numbers, and it will continue run, until I enter a "q". I write a program, but it is wrong:
#coding=utf-8
while 1:
try:
x1=int(raw_input("please enter a number x1="))
x2=int(raw_input("please enter a number x2="))
except:
print("please enter only numbers")
continue
if x1>x2:
x1,x2=x2,x1
pass
for n in xrange(x1,x2):
i=n/100
j=n/10%10
k=n%10
if i*100+j*10+k==i+j**2+k**3:
print ("%-5d")%n
pass
Can somebody help? I think it should be simple, but I am not able to write it correctly.
I believe you've misunderstood the problem statement. Try this instead:
if i*100+j*10+k==i**3+j**3+k**3:
ref: http://en.wikipedia.org/wiki/Narcissistic_number
for n in xrange(x1,x2):
digits = map(int,str(n))
num_digits = len(digits)
if sum(map(lambda x:x**num_digits,digits)) == n:
print "%d is a magic number"%n
you will still have the issue of not being able to enter "q" since you force the input to be integers
I would like to address the quit event.
while True:
x1 = raw_input("please enter a number x1=")
x2 = raw_input("please enter a number x2=")
quit = ('q','Q')
if x1 in quit or x2 in quit:
break
else:
try:
x1, x2 = int(x1), int(x2)
except:
print("please enter only numbers")
continue
# The mathematical part... (for completeness) (not my code)
if x1>x2:
x1,x2=x2,x1
for n in xrange(x1,x2):
i=n/100
j=n/10%10
k=n%10
if i*100+j*10+k==i+j**2+k**3:
print "%-5d"%n
The pass statement is used only when you don't have anything to be executed in certain block of code. It does nothing more, so don't use it if not needed. It is there for the sake of the code looking clean & with correct indentation.
if some_thing: # don't do anything
else:
some_thing = some_thing_else
Note how the above if statement is syntactically incorrect. This is where pass comes handy. Say, you decide to write the if part later, till then you must provide pass.
if some_thing: # don't do anything
pass
else:
some_thing = some_thing_else
It's a bit tricky to know what's going on without more hints, but some issues I see right off:
You need to be consistent with indentation in Python. Your last if statement is less indented than statements above it (like the previous if and the for loop). This will cause an error. You're also using different amounts of indentation in other places, but since it's not inconsistent that's allowed (if a bad idea). Its usually best to pick one indentation standard (like four spaces) and stick with it. Often you can set your text editor to help you with this (turn on "Expand tabs to spaces" or something in the settings).
You've got two pass statements where they're unneeded or harmful. The first, after the line that has if x1>x2: x1,x2=x2,x1 is going to cause an error. You can't have an indented "suite" of code if you've put a series of simple statements on the end of your compound statement like an if. Either put the assignment on its own line, indented, or get rid of the pass. The last pass at the end of the code is not an error, just unnecessary.
You're missing a colon at the end of your try statement. Every statement in Python that introduces an indented suite ends with a colon, so it should be easy to learn where they're needed.
while True:
x1 = raw_input("please enter a number x1=")
x2 = raw_input("please enter a number x2=")
quit = ('q','Q')
if x1 in quit or x2 in quit:
break
else:
try:
x1, x2 = int(x1), int(x2)
except:
print("please enter only numbers")
continue
if x1>x2:
x1,x2=x2,x1
pass
for n in xrange(x1,x2):
i=n/100
j=n/10%10
k=n%10
if i*100+j*10+k==i+j**2+k**3:
print ("%-5d")%n
pass
i have it! thx to Ashish! it is exactly what i want! and i will quit wenn i enter q! thx a lot!

Getting user input and making a decision

I start my python script asking the user what they want to do?
def askUser():
choice = input("Do you want to: \n(1) Go to stack overflow \n(2) Import from phone \n(3) Import from camcorder \n(4) Import from camcorder?");
print ("You entered: %s " % choice);
I would then like to:
Confirm the user has entered something valid - single digit from 1 - 4.
Jump to corresponding function based on import. Something like a switch case statement.
Any tips on how to do this in a pythonic way?
Firstly, semi-colons are not needed in python :) (yay).
Use a dictionary. Also, to get an input that will almost certainly be between 1-4, use a while loop to keep on asking for input until 1-4 is given:
def askUser():
while True:
try:
choice = int(input("Do you want to: \n(1) Go to stack overflow \n(2) Import from phone \n(3) Import from camcorder \n(4) Import from camcorder?"))
except ValueError:
print("Please input a number")
continue
if 0 < choice < 5:
break
else:
print("That is not between 1 and 4! Try again:")
print ("You entered: {} ".format(choice)) # Good to use format instead of string formatting with %
mydict = {1:go_to_stackoverflow, 2:import_from_phone, 3:import_from_camcorder, 4:import_from_camcorder}
mydict[choice]()
We use the try/except statements here to show if the input was not a number. If it wasn't, we use continue to start the while-loop from the beginning.
.get() gets the value from mydict with the input you give. As it returns a function, we put () afterwards to call the function.

NameError: global name 'PIN' is not defined

I am getting the following Error Message :
Traceback (most recent call last):
File "/Volumes/KINGSTON/Programming/Assignment.py", line 17, in <module>
Assignment()
File "/Volumes/KINGSTON/Programming/Assignment.py", line 3, in Assignment
My code is:
def Assignment():
prompt = 'What is your PIN?'
result = PIN
error = 'Incorrect, please try again'
retries = 2
while result == PIN:
ok = raw_input(Prompt)
if ok == 1234:
result = menu
else:
print error
retries = retries - 1
if retries < 0:
print 'You have used your maximum number of attempts. Goodbye.'
Assignment():
would really appreciate a little help if anyone knows where i am going wrong and can explain
That particular error is raised because when you say result = PIN, PIN doesn't actually exist. Since it isn't in quotes, Python assumes it is a variable name, but when it goes to check what that variable is equal to, it doesn't find anything and raises the NameError. When you fix that, it will also happen with prompt since you later refer to it as Prompt.
I'm not sure if this is your full code or not, so I'm not sure what the other issues could be, but it looks like you are using result and PIN to control your while loop. Remember that a while loop runs until the condition it is checking is False (or if you manually break out of it), so instead of declaring the extra variables, you could start with something like this:
def Assignment():
# No need to declare the other variables as they are only used once
tries = 2
# Go until tries == 0
while tries > 0:
ok = raw_input('What is your PIN?')
# Remember that the output of `raw_input` is a string, so either make your
# comparison value a string or your raw_input an int (here, 1234 is a string)
if ok == '1234':
# Here is another spot where you may hit an error if menu doesn't exist
result = menu
# Assuming that you can exit now, you use break
break
else:
print 'Incorrect, please try again'
# Little shortcut - you can rewrite tries = tries - 1 like this
tries -= 1
# I'll leave this for you to sort out, but do you want to show them both
# the 'Please try again' and the 'Maximum attempts' messages?
if tries == 0:
print 'You have used your maximum number of attempts. Goodbye.'

Categories