Jupyter note book not executing properly - python-3.x

Hello i've been having some issues with jupyter notebook lately and am wondering if anyone knows why.
I'll sometimes have the program not execute and it'll have this symbol [*] so ill restart the kernal. Then it executes. However sometimes it wont produce the correct execution even though the code is correct. so I'll restart the kernel and clear my outputs. That usually fixes it. Now i'm working on this problem where i ask the user to answer a math problem if their input sum is correct it will say congrats if wrong it will say they got it incorrect. The program initially kept saying that user_answer was not defined. Then it didn't give me an error at all but would skip over the if statement and just print out the else: statement even if the answer given by the user was correct. is it my code? or is it the editor i'm using and if so how can i make it execute properly. I'm trying to learn python and i'm finding this a bit frustrating because i don't know if its my code or the editor half the time.
Here's my code:
import random
number_1 = random.randint(1,250)
number_2 = random.randint(1,250)
def main():
ask_question()
check_answer(user_answer)
def ask_question():
user_answer = int( input( "What is " +\
str(number_1 )+ ' + ' +\
str( number_2 ) + '? '))
return user_answer
def check_answer( user_answer ):
correct_answer = number_1 + number_2
if user_answer == correct_answer:
print("Congratulations", user_answer, +\
"is correct!")
else:
print("Sorry that is not correct the" +\
" answer should be", correct_answer)
main()
outputs:
**most common one**
What is 126 + 250? 8 (enter)
----------------------------------------------------
-----------------------
NameError Traceback
(most recent call last)
<ipython-input-2-99955f4e983a> in <module>
29 " answer should be",
correct_answer)
30
---> 31 main()
32
<ipython-input-2-99955f4e983a> in main()
6 def main():
7 ask_question()
----> 8 check_answer(user_answer)
9
10 def ask_question():
NameError: name 'user_answer' is not defined
OR
I'll get this and i didn't change anything in my
code..
What is 126 + 250? 376 (enter)
Sorry that is not correct the answer should be 376

The main function of your code is slightly wrong.
def main():
ask_question()
check_answer(user_answer)
In the check_answer function, replace user_answer with the number that the user enters. So, assign a variable to the ask_question function, which is then put into the check_answer function.
def main():
user_answer = ask_question()
check_answer(user_answer)
Also, it is not a good idea to mix local variables (variables that are inside functions) and global variables (variables that are outside functions). in your case, you are calling global variables (number_1 and number_2) inside the check_answer function, which is not good python.
A better way of creating this code would be to have only one function which chooses two random numbers, asks for the user answer and verifies if it is correct or not.
I was unable to reproduce the other error (of the answer being wrong).

Related

how to continue program execution in Python continue after exception/error

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)

Python code does not come out when first return statement is executed

enter image description hereI am a begineer in Python development and learning python on python 3.6
When I executed below code ,I expected it to terminate when first return statement is executed and I was expecting Output 4.
But It is iterating 3 times and giving output as 8.
As per my understanding as soon as return statement is executed it should come out of the function. Why this is not happening.
#!/bin/python3
def stockmax(prices):
# Write your code here
# Write your code here
count=0
profit=0
maximum=max(prices)
#print(maximum)
index_max=prices.index(maximum)
#print(index_max)
if len(prices)<=1:
return(profit)
else:
for i in range(len(prices)):
if i<index_max:
profit=profit-prices[i]
#print("profit if",profit)
count=count+1
#print("count is",count)
elif i==index_max:
#print(profit)
profit=profit+(prices[i]*count)
#print("profit elif",profit)
count=0
else:
profit=profit+stockmax(prices[i:])
return(profit) # should terminate on executing first return
x=(stockmax([5,4,3,4,5]))
print(x)
By calling stockmax inside of itself, you are opening up a new 'scope'. We can treat these as levels on a building. When you call it, you are essentially moving up a floor, or gaining a level. To get back to the ground floor, or the main 'scope' you need to go back through all of the lower floors. We can do this easily by using return a little bit sooner. In your code it would look a little like this:
def stockmax(prices):
count=0
profit=0
maximum=max(prices)
index_max=prices.index(maximum)
if len(prices)<=1:
return(profit)
else:
for i in range(len(prices)):
if i<index_max:
profit=profit-prices[i]
count=count+1
elif i==index_max:
profit=profit+(prices[i]*count)
count=0
else:
profit=profit+stockmax(prices[i:])
return(profit) # Use return here instead!
This would give us the desired output of 4.

Memory game timer implementation and error handling

I've implemented a memory game where the user has to sort numbers in his head while a timer of 5 sec is running.
Please see code below:
from random import randint
from threading import Timer
def timeout():
print("Time over\n#####################\n")
while True:
list = []
for i in range(5):
list.append(randint(1000, 10000))
t = Timer(5, timeout)
t.start()
print(list)
print('[ 1 , 2 , 3 , 4 , 5 ]')
solution = sorted(list)[2]
print('please select the 3rd largest number in this row (1-5):')
input_string = input()
selection = int(input_string)
if solution == list[selection - 1]:
print("Your guess is correct\n")
else:
print("Your guess is wrong\n")
t.join()
Here is the game interaction itself (please ignore the syntax highlighting):
USER#HOST:~/$ python3 memory_game.py
[8902, 8655, 1680, 6763, 4489]
[ 1 , 2 , 3 , 4 , 5 ]
please select the 3rd largest number in this row (1-5):
4
Your guess is correct
Time over
#####################
[5635, 3810, 1114, 5042, 1481]
[ 1 , 2 , 3 , 4 , 5 ]
please select the 3rd largest number in this row (1-5):
4
Your guess is wrong
Time over
#####################
[6111, 1430, 7999, 3352, 2742]
[ 1 , 2 , 3 , 4 , 5 ]
please select the 3rd largest number in this row (1-5):
23
Traceback (most recent call last):
File "memory_game.py", line 24, in <module>
if solution == list[selection - 1]:
IndexError: list index out of range
Time over
#####################
Can anybody help me with these things:
1. 'Time over' should only be written if the player needs more than 5 sec for the answer. If the player solves it in time the next challenge should appear silently.
2. If the player does not write any guess and presses 'Enter' the program terminates with error message:
Traceback (most recent call last):
File "memory_game.py", line 22, in
selection = int(input_string)
ValueError: invalid literal for int with base 10:''
3. If the player enters any random number the program quits with an 'Index out of range error' - I couldn't find out where to put try: except:
Any help would be appreciated - Thanks!
As for your questions:
You can accomplish that with t.cancel() (stop the timer and do not call the function) instead of t.join() (wait until the thread has finished; this will ALWAYS result in a timeout, of course)
(and 3.) These are basically the same -- put the query message and all input handling into a while loop, and break out of it once you know that the input is valid
...
As an extra, the "time over" message wasn't really doing anything useful (e.g. you could still enter a valid answer after the time over occurred. I "fixed" that in a brute force way by making the program exit if the timeout is hit. Instead of doing that, you can also use a global variable to store whether the timeout was hit or not and handle that in your input accordingly (make sure to make it threadsafe using e.g. a mutex).
In general, it might be easier to turn around the structure of the program -- let the main thread handle the timeout and verification of the input, let the thread only handle the input (this way, it's easy to kill the thread to stop the input from being handled).
Of course, using the select module, one could implement this even nicer without threads (have one pipe that gets written to by a thread/timer, and the standard input, then select both for reading and it will block until either user input or the timeout occurs).
And maybe someone will post a nice asyncio-based solution? ;)
Here's the modified solution (modifying only as little as possible to get it to work, one could refactor other parts to make it nicer in general):
import random
import threading
import os
def timeout():
print("Time over\n#####################\n")
# You can't use sys.exit() here, as this code is running in a thread
# See also: https://stackoverflow.com/a/905224/1047040
os._exit(0)
while True:
list = []
for i in range(5):
list.append(random.randint(1000, 10000))
t = threading.Timer(5, timeout)
t.start()
print(list)
print('[ 1 , 2 , 3 , 4 , 5 ]')
solution = sorted(list)[2]
while True:
try:
print('please select the 3rd largest number in this row (1-5):')
input_string = input()
selection = int(input_string)
chosen = list[selection - 1]
# If we arrive here, the input was valid, break out of the loop
break
except Exception as e:
# Tell the user that the input is wrong; feel free to remove "e"
# from the print output
print('Invalid input:', e)
if solution == chosen:
print("Your guess is correct\n")
else:
print("Your guess is wrong\n")
# Make sure to cancel the thread, otherwise guessing correct or wrong
# will block the CLI interface and still write "time out" at the end
t.cancel()

Defining function difficulties ["NameError: name 'number' is not defined"]

Okay, trying to make a simple game of Guessing Numbers but I can't find the mistake in this code. Still pretty new to python so probably the reason why but I can't figure out what is wrong with it.
import random
from time import sleep
def start():
print("Welcome To The Guessing Game \n Try to guess the number I'm thinking of \n Good luck!")
selectRandomNumber()
guessCheck(number, numberInput=1)
def restart():
print("Creating new number ...")
sleep(1)
print("OK")
selectRandomNumber()
guessCheck(number,numberInput=1)
def selectRandomNumber():
number = random.randint(0,1000)
tries = 0
return
def tryAgain():
while True:
try:
again = int(input("Do you want to play again? y/n:"))
except ValueError:
print("Couldn't understand what you tried to say")
continue
if again == "y" or "yes":
print("Awesome! Lets go")
restart()
elif again == 'n' or "no":
print("Goodbye!")
break
else:
print("Not a valid option")
continue
def guessCheck(number,numberInput=1):
while True:
try:
numberInput = int(input("What number do you think it is?: "))
except ValueError:
print("Couldn't understand that. Try again")
continue
if numberInput > number:
print("Too high")
tries += 1
continue
elif numberInput < number:
print("Too low")
tries += 1
continue
elif numberInput == number:
print("Congrats! You got my number")
tryAgain()
number = selectRandomNumber()
print(number)
start()
Every time I try to run the program I keep getting the same mistake.
It tells me:
Traceback (most recent call last):
File "python", line 60, in <module>
start()
File "python", line 8, in start
guessCheck(number, numberInput)
NameError: name 'number' is not defined
Don't quite understand what that means.
Some help would be appreciated. Thanks!
* UPDATE *
Was able to fix the part about defining the variable but now new problem happened where when I try to run
Same code as before but added
guessCheck(number,numberInput=1)
and also added the variable number at the end
number = selectRandomNumber()
print(number)
start()
when I run it I get this
None # this is from `print(number)` so instead of getting a number here I'm getting `None`
Welcome To The Guessing Game
Try to guess the number I'm thinking of
Good luck!
What number do you think it is?:
The Traceback is telling you this:
We got to start().
start() called guessCheck().
We tried to pass two pieces of information to guessCheck(): the variable names number and numberInput.
We don't have those variables defined yet! numberInput doesn't get defined until once we've already started guessCheck(), and number isn't actually defined anywhere.
As Manoj pointed out in the comments, you probably want number to hold the output of selectRandomNumber(). So, instead of just calling selectRandomNumber() in start(), try number = selectRandomNumber() instead.
You can add a print(number) on the line right after that to make sure number has a value assigned to it.
Now number has a value, going into your call to guessCheck(). That still leaves numberInput undefined though. You can set a default value for function arguments like this:
guessCheck(number, numberInput=1)
That way, when guessCheck is called but numberInput hasn't been defined yet, it will automatically give it the value 1 until you set it explicitly.
You may encounter other issues with your code the way it is. My advice would be to start really simply - build up your game from each individual piece, and only put the pieces together when you're sure you have each one working. That may seem slower, but trying to go too fast will cause misunderstandings like this one.

Python Recrusive Statement Error not Defined

I am trying to test each input then return that the number is cleared then do the math. For Example is a user inputs N instead of a number I want it to output that its not a number whereas if the user inputs 1 then I want it to move to the next function asking for a power then do the same thing and if that passes then goes to the final section which output the answer to the problem.
The program passes both the errors for the non number areas yet when it get to very last function it is telling me base nor power are defined.
Code is written in some Python2 and some Python3. All works fine though. I use python3 mostly.
[Test Picture/Error Msg][1]
# Below we are creating the recursive statement to do the math for us. We are calling Base and Power
# from the main function where the user Inputs the numbers.
def pow(base, power):
if power == 0:
return 1
if power == 1:
return base
else :
return base * pow(base, power - 1)
def determineBase():
while True:
try:
base = int(input ('Please Enter A Base: '))
except ValueError:
print("Please use whole numbers only. Not text nor decimals.")
continue
else:
return base
def determinePower():
while True:
try:
power = int(input ('Please Enter A Power: '))
except ValueError:
print("Please use whole numbers only. Not text nor decimals.")
continue
else:
return power
def main():
determineBase()
determinePower()
pow(base,power)
print("The answer to",base,"to the power of", power,"is", pow(base,power),".")
main()
def main():
determineBase()
determinePower()
pow(base,power)
Here, neither base nor power are defined. What you meant instead was to store the result from those function calls and pass those then:
def main():
base = determineBase()
power = determinePower()
pow(base, power)
The issue isn't inside the recursive function, it's inside your main function.
The problem is arising due to the fact that you are passing base as an argument to the pow() function without defining the variable base first (the same would subsequently be true for power).
In other words you need something along the lines of:
def main():
base = determineBase()
power = determinePower()
pow(base,power) #this line could probably be removed
print("The answer to",base,"to the power of", power,"is", pow(base,power),".")
As currently, you're not storing the values of these two functions.

Resources