Why am I getting the following error? The last print statement should not be a part of the while loop.
>>> while n>= 0:
... n = n-1
... print(n)
... print ("TO A!!")
File "<stdin>", line 4
print ("TO A!!")
^
SyntaxError: invalid syntax
You need to press enter after your while loop to exit from the loop
>>> n = 3
>>> while n>=0:
... n = n-1
... print (n)
... # Press enter here
2
1
0
-1
>>> print ("To A!!")
To A!!
Note:- ... implies that you are still in the while block
The default python shell works OK for typing but it really does not understand pasting from clipboard. The real solution is to install ipython, which is an advanced shell for python with many niceties:
% ipython3
Python 3.4.2 (default, Oct 8 2014, 13:08:17)
Type "copyright", "credits" or "license" for more information.
IPython 2.3.0 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help -> Python's own help system.
object? -> Details about 'object', use 'object??' for extra details.
In [1]: n = 5
In [2]: while n >= 0:
...: n = n-1
...: print(n)
...: print ("TO A!!")
...:
4
3
2
1
0
-1
TO A!!
In [3]:
I guess that the error shows up because python shell don't support that. It want you to do one thing in a time.! I do the same things in my python 2.7 shell and it said:
File "<pyshell#4>", line 4
print 'to all'
^
IndentationError: unindent does not match any outer indentation level
when I do the same thing in my python 3.4 shell, it said: unexpected indent.
Related
I was reading through this question and began to wonder why the _ character only represents the result of the last executed statement in interactive modes, and not through actual script execution.
Script execution mode:
$ python3 -c '1;print(_)'
Traceback (most recent call last):
File "<string>", line 1, in <module>
NameError: name '_' is not defined
Interactive mode:
Tue Dec 18 09:41:20 CST 2018 | /Users/user
$ python3
Python 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 03:03:55)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 1
1
>>> print(_)
1
What is the reasoning for this "feature" only being available in interpretive modes?
The major use case for the sys.displayhook() is to provide the feature in interactive mode where a non-None expression result will print magically for you, so you don't have to explicitly print() it. It's primarily used for just kicking up the interpreter to experiment with things:
>>> None
>>> 1 + 7
8
It's only a short step from this auto-printing to realise that you may want to keep doing stuff with the result in interactive mode. Hence the value is also stored in builtins._ so that you can re-use it:
>>> 1 + 7
8
>>> _ * 3 -.5
23.5
>>> _ * _
552.25
>>> import math
>>> math.sqrt(_ + 7)
23.648467180770936
>>> f"I am {5 * 11} years old."
'I am 55 years old.'
>>> _[:-1] + ", and I sometimes feel it!"
'I am 55 years old, and I sometimes feel it!'
That basically makes interactive mode a handy desktop interpreter, something you can easily experiment with, rather than having to explicitly assign everything to variables so you can re-use it or, even worse, writing monstrosities like:
>>> 1 + 7
8
>>> (1 + 7) * 3 -.5
23.5
>>> ((1 + 7) * 3 -.5) * ((1 + 7) * 3 -.5)
552.25
>>> import math
>>> math.sqrt(((1 + 7) * 3 -.5) * ((1 + 7) * 3 -.5) + 7)
23.648467180770936
And the reason why it's not so useful in a program is because a program won't generally be used for experimentation in the same way as interactive mode.
I would hope that, by the time you get around to writing a program, you really shouldn't have to be experimenting :-)
I am calling pdb on some function func i.e.,
def fun():
a = 10
c = fun2(a)
d = 40
return c+d
def fun2(a):
xyz ='str'
return a+10
Now I am running pdb using pdb.runcall(func,a,b) now It will open a pdb console for debugging, now suppose I press 2 time s(step) and q to quit in pdb console
but problem is I don't want to do this manually, I want to make some script which do something like this (automatic tell pdb first two command is s then third is q) , I am asking because there are many functions which needs atleast two time c (continue) to overall excecution of function so that it can yield/return some valid output (like say generators)
Any help will be a serious help for me.
Update after better understanding the question:
In general, I don't think this is the ideal way to test code; designing code for testability (e.g. using TDD) will often result in functions that are easier to test (e.g. using mocks/fake objects, dependency injection etc), and I would encourage you to consider refactoring the code if possible. The other issue with this approach is that the tests may become very tightly coupled to the code. However, I'll assume here that you know what you are doing, and that the above is not an option for whatever reason.
Scripting pdb
If you want to script pdb from code, this is actually possible by instantiating your own pdb.Pdb class and passing in the stdin and, at the time of writing, stdout argument (I'm not sure both should be required - I've filed https://bugs.python.org/issue33749).
Example (I just added the extra input argument to fun):
def fun(i):
a = 10 + i
c = fun2(a)
d = 40
return c+d
def fun2(a):
xyz ='str'
return a+10
import pdb
import io
output = io.StringIO()
# this contains the pdb commands we want to execute:
pdb_script = io.StringIO("p i;; i = 100;; n;; p a;; c;;")
mypdb = pdb.Pdb(stdin=pdb_script, stdout=output)
Normal result (no scripting):
In [40]: pdb.runcall(fun, 1)
...:
> <ipython-input-1-28966c4f6e38>(2)fun()
-> a = 10 + i
(Pdb)
(Pdb) c
Out[40]: 61
Scripted pdb:
In [44]: mypdb = pdb.Pdb(stdin=pdb_script, stdout=output)
In [45]: mypdb.runcall(fun, 1)
Out[45]: 160
In [50]: print(output.getvalue())
> <ipython-input-1-28966c4f6e38>(2)fun()
-> a = 10 + i
(Pdb) 1
> <ipython-input-1-28966c4f6e38>(3)fun()
-> c = fun2(a)
110
You may find using pdb_script.seek(0) helpful to reset the script.
Original answer - using conditional breakpoints
It sounds like what you really want is to only get into the debugger when your code is in a certain state. This can be done with conditional breakpoints (see pdb docs for details).
For example, let's say you want to break in fun2 if a > 10:
...:
In [2]: import pdb
In [3]: pdb.runcall(fun, 1)
> <ipython-input-1-28966c4f6e38>(2)fun()
-> a = 10 + i
(Pdb) break fun2, a > 10
Breakpoint 1 at <ipython-input-1-28966c4f6e38>:6
(Pdb) c
> <ipython-input-1-28966c4f6e38>(7)fun2()
-> xyz ='str'
(Pdb) c
Out[3]: 61
In [4]: pdb.runcall(fun, -1)
> <ipython-input-1-28966c4f6e38>(2)fun()
-> a = 10 + i
(Pdb) c
Out[4]: 59
Notice in the first case you hit the breakpoint, in the second you didn't.
Original answer - using breakpoints and executing commands when hit
You could also try setting a breakpoint and using the commands facility.
I am trying to write a piece of code to handle the exception of negative square roots, since I only want a positive result. My code is:
def sqRoot(x):
try:
result = (x)**0.5
except ValueError:
result = "This is a negative root"
except TypeError:
result = "Please enter a number"
return result
For some reason, when I run this code using the call
x = sqRoot(-200)
I don't get the error, but instead python is giving me the result as a complex number. I can't seem to see the error in my code.
Shifting this discussion from the comments...
In Python 3.0 the behaviour of the power operator changed. In earlier versions of python, raising a negative number to a fractional power raised a ValueError exception, but in Python 3 it yields a complex result.
An alternative for finding the square root is the python is the math.sqrt function. In Python 3 this raises a ValueError exception when used with a negative number:
Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:43:06) [MSC v.1600 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import math
>>> math.sqrt(-200)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: math domain error
If python 3 returns a complex number and that is not what you want, you can always achieve the desired output with an if statement:
def sqRoot(x):
if not isinstance(x, (int, long, float)):
return "Please enter a number"
if x < 0:
return "This is a negative root"
return (x)**0.5
Since in python 3, the square root of a negative number is defined (as complex), you will have to test for it yourself:
def sqRoot(x):
if not type(x) in [int, long, float]:
result = "Please enter a number"
elif x < 0:
result = "This is a negative root"
else:
result = (x)**0.5
return result
By the way, I don't think that it's good programming practice to have the function return numbers in one case, and strings in the other. I think that is better done by raising errors.
I seem to be having a problem using sublimeREPL to run python code with user input in sublime text 2. I have a working piece of code that I can use in the command prompt that will not execute inside REPL. The error seems to be that REPL cannot handle the format of the input and assumes it is a string. My python is fairly limited so is there a way to make the REPL play nice with my code or do I need to specify the input?
Note: Casting tempInput as a int each time will work but is tedious.
The Code:
# Matthew P
# A program to calculate average grades
def avg(total, elements):
return total / elements
tempInput = 0
runningTot = 0
numGrades = 0
print("\nEnter Grades (Negative Value to Escape): ")
while tempInput > -1:
tempInput = input("-->")
if tempInput > -1:
runningTot = runningTot + tempInput
numGrades = numGrades + 1
print("\nQuit Command Givem")
print("Average Grade: " + str(avg(runningTot,numGrades)))
print("Grade Sum: " + str(runningTot))
print("Number of Grades" + str(numGrades))
The Output from command prompt:
~\Documents\Python Scripts>userinput.py
Enter Grades (Negative Value to Escape):
-->99
-->98
-->97
-->96
-->95
-->-1
Quit Command Givem
Average Grade: 97
Grade Sum: 485
Number of Grades 5
and the error when running in sublimeREPL (I ran is using the ctrl+,,f command)
Python 3.3.3 (v3.3.3:c3896275c0f6, Nov 18 2013, 21:18:40) [MSC v.1600 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
Enter Grades (Negative Value to Escape):
-->100
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 17, in <module>
TypeError: unorderable types: str() > int()
>>>
input() returns a string, but you are comparing it against an integer:
tempInput = input("-->")
if tempInput > -1:
Use int() to make the comparison:
tempInput = int(input("-->"))
You ran the code on the command line with Python 2, where input() evaluates the entered string as a Python expression. Python 2 also doesn't mind you comparing numbers and strings; numbers always sort before numbers.
In Sublime, you ran the code under Python 3, however, where input() only takes string input.
My OS doesn't support Sage 5.4 so I'm stuck with 5.0 for now.
Defining this function registers no syntax errors in python, and I don't think it makes errors in Sage 5.4 (I'd appreciate confirmation if possible.) I'd like to know why it is failing in 5.0.
def num_matchings(G):
if min(G.degree_sequence())== 0 or G.num_edges()==0:
return 0
elif G.num_edges()==1:
if G.edges()[0][2] ==None:
return 1
else:
return G.edges()[0][2]
else:
H = copy(G)
K = copy(G)
e = G.edges()[0]
if e[2] ==None:
w=1
else:
w = e[2]
H.delete_edge(e)
K.delete_vertices([e[0],e[1]])
return num_matchings(H) + w*num_matchings(K)
The first error I get when I try to define is
File "<ipython console>", line 4
==Integer(1):
^
SyntaxError: invalid syntax
and they pile on after that. To my eye, the syntax looks fine.
I'm on Mac OS 10.5 with GCC 4.0.1.
Any help much appreciated.
[Aside: typo in .delete_vertives().]
Your syntax itself is fine. From the error message, though, it looks like you've simply copied and pasted code into the console. That will only work in certain very simple cases. You're also using tabs for indentation, which can cause a whole other set of headaches too. You should really switch to 4-space tabs instead.
If you want to insert code into a live console, you can use %paste (which copies from the clipboard if it can), or %cpaste instead.
For example, if I copy and paste your code, I get:
sage: def num_matchings(G):
....: if min(G.degree_sequence())== 0 or G.num_edges()==0:
....: return 0
....: elif G.num_edges()==1:
------------------------------------------------------------
File "<ipython console>", line 4
==Integer(1):
^
SyntaxError: invalid syntax
sage: if G.edges()[0][2] ==None:
....: return 1
------------------------------------------------------------
File "<ipython console>", line 2
SyntaxError: 'return' outside function (<ipython console>, line 2)
but if I use %cpaste with the 4-space equivalent (unfortunately %paste isn't working on my 5.4.1 install at the moment):
sage: %cpaste
Pasting code; enter '--' alone on the line to stop.
:
:def num_matchings(G):
: if min(G.degree_sequence())== 0 or G.num_edges()==0:
: return 0
[etc.]
: K.delete_vertices([e[0],e[1]])
: return num_matchings(H) + w*num_matchings(K)
:--
sage: num_matchings(graphs.LadderGraph(5))
8