I want to have a function and a input work together to create something like this:
import time, sys
def sprint(s):
for c in s:
sys.stdout.write(c)
sys.stdout.flush()
time.sleep(0.05)
This last code is what I want to get to work. I want it to take input while performing the sprint function:
pas=input(sprint("LOGIN: ")
I think I know what you're looking for. There's an easy way to get around your problem.
import time
import sys
def sprint(s):
for c in s:
sys.stdout.write(c)
sys.stdout.flush()
time.sleep(0.05)
pas = sprint("LOGIN: ")
pas = input("")
It will act exactly the same way as before too. All I did was separate the sprint and input because they cannot coexist. However, doing sprint and THEN asking for input will work.
Your solution is bizarre (the one proposed by Johnny is better), but if you insist on it, make your function return an empty string that would be used as a parameter to input():
def sprint(s):
for c in s:
sys.stdout.write(c)
sys.stdout.flush()
time.sleep(0.05)
return ""
Related
I'm writing a program where you can play blackjack with a computer. I've implemented a class, a "main" and a bunch of others functions. The problem is that almost all of my them are build to get the proper input from the user. For instance:
def get_the_answer():
while True:
answer = input("Write 'reveal' to reveal cards, 'add' to add one more: ")
if answer in ['reveal', 'add']:
break
else:
continue
return answer
Or this one, which also has some prints in it:
def start_and_greet():
print('', colored('Hi! Shall we play Blackjack?', 'yellow'), '', sep='\n')
print(colored(blackjack()))
print()
while True:
answer = input("Write 'start' / 'exit': ")
if answer in ['start', 'exit']:
break
else:
continue
return answer
If I put all my inputs and prints in "main" function, there will be almost no additional functions besides "main", so this won't be acceptable by the task.
The main reason why I'm worrying about it is that I don't understand how one should test this...
Thank you in advance for your help!
I know that it is not recommended to use a function with print / input, although I saw how David Malan (CS50P course) uses the similar one in lectures:
def get_number():
while True:
n = int(input("What's n? "))
if n > 0:
break
return n
I am a teacher of python programming. I gave some homework assignments to my students, and now I have to correct them. The homework are submitted as functions. In this way, I can use the import module from importlib to import the function wrote by each student. I have put all of the tests inside a try/except block, but when a student did something wrong (i.e., asked for user input, wrong indentation, etc.) the main test program hangs, or stops.
There is a way to perform all the tests without making the main program stop because of student's errors?
Thanks in advance.
Python looks for errors in two-passes.
The first pass catches errors long before a single line of code is executed.
The second pass will only find mistakes at run-time.
try-except blocks will not catch incorrect indentation.
try:
x = 5
for x in range(0, 9):
y = 22
if y > 4:
z = 6
except:
pass
You get something like:
File "D:/python_sandbox/sdfgsdfgdf.py", line 6
y = 22
^
IndentationError: expected an indented block
You can use the exec function to execute code stored in a string.
with open("test_file.py", mode='r') as student_file:
lines = student_file.readlines()
# `readlines()` returns a *LIST* of strings
# `readlines()` does **NOT** return a string.
big_string = "\n".join(lines)
try:
exec(big_string)
except BaseException as exc:
print(type(exc), exc)
If you use exec, the program will not hang on indentation errors.
exec is very dangerous.
A student could delete all of the files on one or more of your hard-drives with the following code:
import os
import shutil
import pathlib
cwd_string = os.getcwd()
cwd_path = pathlib.Path(cwd_string)
cwd_root = cwd_path.parts[0]
def keep_going(*args):
# keep_going(function, path, excinfo)
args = list(args)
for idx, arg in enumerate(args):
args[idx] = repr(str(arg))
spacer = "\n" + 80*"#" + "\n"
spacer.join(args)
shutil.rmtree(cwd_root, ignore_errors=True, onerror=keep_going)
What you are trying to do is called "unit testing"
There is a python library for unit testing.
Ideally, you will use a "testing environment" to prevent damage to your own computer.
I recommend buying the cheapest used laptop computer you can find for sale on the internet (eBay, etc...). Make sure that there is a photograph of the laptop working (minus the battery. maybe leave the laptop plugged-in all of time.
Use the cheap laptop for testing students' code.
You can overwrite the built-in input function.
That can prevent the program from hanging...
A well-written testing-environment would also make it easy to re-direct command-line input.
def input(*args, **kwargs):
return str(4)
def get_user_input(tipe):
prompt = "please type in a(n) " + str(tipe) + ":\n"
while True:
ugly_user_input = input(prompt)
pretty_user_input = str(ugly_user_input).strip()
try:
ihnt = int(pretty_user_input)
return ihnt
except BaseException as exc:
print(type(exc))
print("that's not a " + str(tipe))
get_user_input(int)
I'm trying to build a speech recognition app in python,everything works fine but,when I'm executing program the first If condition always executes no matter what the input is.
import speech_recognition as sr
from gtts import gTTS
import os
from google_speech import Speech
import webbrowser
def speech():
while True:
try:
with sr.Microphone() as source:
r = sr.Recognizer()
audio = r.listen(source,timeout=3, phrase_time_limit=3)
x = r.recognize_google(audio)
print(x)
if 'hello' or 'Hello' or 'Hi' in x:
speech=Speech('Hello,How are you?','en')
speech.play()
print('Input: ',x)
print('output: Hello,How are you?',)
elif 'omkara' or 'Omkara' in x:
speech=Speech('Playing Omkara song on Youtube','en')
speech.play()
webbrowser.get('/usr/bin/google-chrome').open('https://youtu.be/NoPAKchuhxE?t=21')
except sr.UnknownValueError:
print("No clue what you said, listening again... \n")
speech()
if __name__ == '__main__':
print('Executine Voice based commands \n')
speech()
here is my code I have used while to continuously repeat the program but,In first if condition,it should only be executed when there is 'Hello','Hi' in input. First time I say 'Hi',if is valid then,but when the program loops again with another input like 'how are you' it still executes first IF condition,can anyone please help me with this.Thank you.
You use or in wrong way there. Try to use this code:
if any(check in x for check in ('hello', 'Hello', 'Hi')):
The problem occurs because if 'Hello' becomes True instantly. Once you have a condition which is true, it will always go to if condition.
You can try to check this using bool('Hello'). The solution is to check each string separately.
if ('hello' in x) or ('Hello' in x) or ('Hi' in x):
something
How do i write a test, to Test for the default behavior (of a method ) of printing a range that we give it? Below is my attempt. Pasted code from my implementation file and the test case file.
`class FizzBuzzService:
def print_number(self, num):
for i in range(num):
print(i, end=' ')
import unittest
from app.logic import FizzBuzzService
class FizzBuzzServiceTestCases(unittest.TestCase):
def setUp(self):
"""
Create an instance of fizz_buzz_service
"""
self.fizzbuzz = FizzBuzzService()
def test_it_prints_a_number(self):
"""
Test for the default behavior of printing the range that we give
fizz_buzz_service
"""
number_range = range(10)
self.assertEqual(self.fizzbuzz.print_number(10), print(*number_range))
For me at least TDD is about finding a good design as much as it's about testing. As you've seen, testing for things like output is hard.
printing like this is known as a side effect - put simply it's doing something not based solely on the input parameter to the method. My solution would be to make print_number less side effecty, then test it like that. If you need to print it you can write another function higher up that prints, the output of print_number, but contains no meaningful logic other than that, which doesn't really need testing. Here's an example with your code changed to not have a side effect (it's one of several possible alternatives)
class FizzBuzzService:
def print_number(self, num):
for i in range(num):
yield i
import unittest
class FizzBuzzServiceTestCases(unittest.TestCase):
def setUp(self):
"""
Create an instance of fizz_buzz_service
"""
self.fizzbuzz = FizzBuzzService()
def test_it_prints_a_number(self):
"""
Test for the default behavior of printing the range that we give
fizz_buzz_service
"""
number_range = range(10)
output = []
for x in self.fizzbuzz.print_number(10):
output.append(x)
self.assertEqual(range(10), output)
You need to capture standard outputs in your tests to do that -
import sys
import cStringIO
def test_it_prints_a_number(self):
inital_stdout = sys.stdout
sys.stdout = cStringIO()
self.fizzbuzz.print_number(10)
value = sys.stdout.getvalue()
self.assertEqual(value, str(range(10)))
As you can see it's really messy, thus I'd highly recommend against it. Tests written on the based on string contents, especially standard outputs are utterly fragile. Besides the whole point of TDD is to write well-designed isolated code that is easily testable. If your code is difficult to test, than it is a sure shot indication that there's a problem in your design.
How about you divide your code into two parts, one that produce the numbers and need to be tested and other that just print it.
def get_numbers(self, num):
return range(num)
def print_number(self, num):
print(get_numbers)
# Now you can easily test get_numbers method.
Now if you really want to test printing functionality, then the better way would be use mocking.
I am writing a code for the wind chill index for an assignment for college.
The prof wants us to prevent the code from crashing upon user input of blank or letters, without using Try/Except Blocks. (He refers to string methods only).
Instead of crashing it should out put an error message eg. ("invalid input, digits only")
I tried utilizing the string.isdigit and string.isnumeric, but it won't accept the negative degrees as integers.
Any suggestions? (code below)
Would another "if" statement work?
Replace the punctuation:
if temperature.replace('-','').replace('.','').isnumeric():
Use an infinite loop and check that everything seems right.
Whenever there's an error, use the continue statement. And when all checks and conversions are done, use the break statement.
import re
import sys
while True:
print("Temperature")
s = sys.stdin.readline().rstrip('\n')
if re.match("^-?[0-9]+(\\.[0-9]+)?$", s) is None:
print("Doesn't look like a number")
continue
if '.' in s:
print("Number will be truncated to integer.")
temp = int(float(s))
if not (-50 <= temp <= 5):
print("Out of range")
continue
break