When I write something into the python console, it repeats back what I write.
Like if I write 1, it displays 1 in output, and if I write True it gives True.
Why is this?
Example:
>>1
1
>>True
True
What actually happens in background?
You're typing into a REPL. It Reads input, Evaluates it, Prints the result, then Loops back and starts again.
You're having it read the number 1, evaluate it (although it's just a number), then print the result of the evaluation (the number). After that it waits for more input to be entered so it can run again.
If you typed a more complicated expression, it would be evaluated as well. 1 + 1 will show 2, and [1] * 5 will show [1, 1, 1, 1, 1] for example.
If you want to think about how this is achieved in terms of code, the most basic implementation of a REPL would be something along the lines of:
while True:
user_input = input(">> ")
result = eval(user_input) # eval evaluates a string as code
print(result)
Code similar to this (although likely far more complicated) is just running in the background.
You're talking about one way to invoke the Python interpreter.
This is a computer program designed to accept Python statements, and to print the evaluated result of each one.
In your examples, your statements are simple expressions that evaluate to pretty much what you typed in.
More complex examples include expressions like 1+1, or function calls.
How this works "in [the] background" is far too large a topic for a Stack Overflow answer, but you could study the Python project's source code if you really wanted to know what kind of programming constructs have been used to produce this computer program.
Short answer:
Jeffrey Elkner in his book says that:
When you type a statement on the command line, Python executes it. The interpreter does not display any results....
An expression is a combination of values, variables, operators, and calls to functions. If you type an expression at the Python prompt, the interpreter evaluates it and displays the result, which is always a value
More details:
You know, what a computer really understands is consecutive zero's and one's.
Your hardware is the one who specifies the format of these one's and zero's.
it is hard for people to know about how to order a hardware to do a task. To solve this problem,high level languages and VHLL(very high-level programming languages) such as Python are created.
How do they solve the problem?
These languages are more similar to human languages. In addition, each of these languages has some tool to convert the code to a machine-readable format! (of course, without this, they were worth nothing)
Actually the tools used to convert a human-readable format to machine-readable format, fall into one of these categories: Interpreters, Compilers, Hybrid approach(used in languages like C# and Java).
Python code is executed using an Interpreter!
So when you type an expression or an statement, in python shell, the interpreter comes and executes the statements and evaluates the expressions in your code!
One final point:
Python docs considers expressions, just as a subset of statements(look at the link).
Related
I have tried the same code in python, once ran as a .py file and once typed in IDLE, but it gives different output for the same code:
a = 3.4
b = 3.4
a is b
I have attached a screenshot taken while trying by both methods:
The reason for why your left window returns false and the right true is because of each command you type is a block, as stated in the manual:
A Python program is constructed from code blocks. A block is a piece of Python program text that is executed as a unit. The following are blocks: a module, a function body, and a class definition. Each command typed interactively is a block.
Thus when you are using your console, each individual command you type is considered a block. Each block has constants which are reused. In your case 3.4 is a constant. But when you are typing the second command, it is considered a new block so it won't find a constant which it can reuse. In the second case of using a .py file the constant is saved and reused, because a file is seen as a single code block.
A way for you to check this is to declare both variables on the same line like this:
>>> a = 3.4; b = 3.4;
>>> print(a is b)
This will output True, because you declare both variables in the same command, thus block.
If you however are trying to just compare two variables you should use the ==. Keep in mind that you are doing floating point comparison, check out this stackoverflow on how to best do that: floating point comparison in Python
I'm returning 0 all over the place in a python script but would prefer something more semantic, something more readable. I don't like that magic number. Is there an idea in python similar to how in C you can return EXIT_SUCCESS instead of just 0?
I was unable to find it here:
https://docs.python.org/3.5/library/errno.html
I'm returning 0
return is not how you set your script's exit code in Python. If you want to exit with an exit code of 0, just let your script complete normally. The exit code will automatically be set to 0. If you want to exit with a different exit code, sys.exit is the tool to use.
If you're using return values of 0 or 1 within your code to indicate whether functions succeeded or failed, this is a bad idea. You should raise an appropriate exception if something goes wrong.
Since you discuss return here, it seems like you may be programming Python like C. Most Python functions should ideally be written to raise an exception if they fail, and the calling code can determine how to handle the exceptional conditions. For validation functions it's probably best to return True or False - not as literals, usually, but as the result of some expression like s.isdigit().
When talking about the return value of a process into its environment you caonnt use return because a module isn't a function, so a return statement at top level would be flagged as a syntax error. Instead you should use sys.exit.
Python might seem a little minimalist in this respect, but a call to sys.exit with no arguments defaults to success (i.e. return code zero). So the easiest way to simplify your program might be to stop coding it with an argument where you don't want to indicate failure!
As the documentation reminds us, integer arguments are passed back, and string arguments result in a return code of 1 and the string is printed to stderr.
The language doesn't, as far as I am aware, contain any constants (while it does have features specific to some environments, if it provided exit codes their values might need to be implementation- or platform-specific and the language developers prefer to avoid this where possible.
I just finished watching this video https://www.youtube.com/watch?v=qO4ZN5uZSVg, and even though it teaches 2.0 edition Python, some notes pop up for the 3.0 uses of python. Nevertheless, in the end, some challenges are provided, one of them is this:
def returnTwo():
return 20,30
x,y = returnTwo()
print(x,y)
Whenever i try to see what the conclusion will be, this is what comes up
def returnTwo():
return 20,30
(red X in the 3.5 Shell) x,y = returnTwo()
SyntaxError: invalid syntax.
What can I do?
The python shell allows to interactively run commands. This is very useful when doing quick calculations of to quickly check some small pieces of code.
In this case, you want to define a function. Defining a function is just that: a definition. Later on, you actually call the function and make it run. The issue here is that a function is (often) defined in more than one line. That means, you actually hit enter before you finish to define the function. For that reason, you tell the shell that you finished with an extra enter:
This also applies if you define your function in a single line:
And that's the reason why you get a SyntaxError: The line x, y = returnTwo() is supposed to be in the function, but for that, it would need to indented (to the level of return 20, 30):
Like #jim said, just try pressing enter until you get the >>> prompt again!
Remember that the three little dots do have a meaning too.
This question was already answered in the comments by #helios35 and #jim!
I just elaborate and post as an answer here for future users.
I've encounter a following statement by Richard Stallman:
'When you start a Lisp system, it enters a read-eval-print loop. Most other languages have nothing comparable to read, nothing comparable to eval, and nothing comparable to print. What gaping deficiencies! '
Now, I did very little programming in Lisp, but I've wrote considerable amount of code in Python and recently a little in Erlang. My impression was that these languages also offer read-eval-print loop, but Stallman disagrees (at least about Python):
'I skimmed documentation of Python after people told me it was fundamentally similar to Lisp. My conclusion is that that is not so. When you start Lisp, it does 'read', 'eval', and 'print', all of which are missing in Python.'
Is there really a fundamental technical difference between Lisp's and Python's read-eval-print loops? Can you give examples of things that Lisp REPL makes easy and that are difficult to do in Python?
In support of Stallman's position, Python does not do the same thing as typical Lisp systems in the following areas:
The read function in Lisp reads an S-expression, which represents an arbitrary data structure that can either be treated as data, or evaluated as code. The closest thing in Python reads a single string, which you would have to parse yourself if you want it to mean anything.
The eval function in Lisp can execute any Lisp code. The eval function in Python evaluates only expressions, and needs the exec statement to run statements. But both these work with Python source code represented as text, and you have to jump through a bunch of hoops to "eval" a Python AST.
The print function in Lisp writes out an S-expression in exactly the same form that read accepts. print in Python prints out something defined by the data you're trying to print, which is certainly not always reversible.
Stallman's statement is a bit disingenuous, because clearly Python does have functions named exactly eval and print, but they do something different (and inferior) to what he expects.
In my opinion, Python does have some aspects similar to Lisp, and I can understand why people might have recommended that Stallman look into Python. However, as Paul Graham argues in What Made Lisp Different, any programming language that includes all the capabilities of Lisp, must also be Lisp.
Stallman's point is that not implementing an explicit "reader" makes Python's REPL appear crippled compared to Lisps because it removes a crucial step from the REPL process. Reader is the component that transforms a textual input stream into the memory — think of something like an XML parser built into the language and used for both source code and for data. This is useful not only for writing macros (which would in theory be possible in Python with the ast module), but also for debugging and introspection.
Say you're interested in how the incf special form is implemented. You can test it like this:
[4]> (macroexpand '(incf a))
(SETQ A (+ A 1)) ;
But incf can do much more than incrementing symbol values. What exactly does it do when asked to increment a hash table entry? Let's see:
[2]> (macroexpand '(incf (gethash htable key)))
(LET* ((#:G3069 HTABLE) (#:G3070 KEY) (#:G3071 (+ (GETHASH #:G3069 #:G3070) 1)))
(SYSTEM::PUTHASH #:G3069 #:G3070 #:G3071)) ;
Here we learn that incf calls a system-specific puthash function, which is an implementation detail of this Common Lisp system. Note how the "printer" is making use of features known to the "reader", such as introducing anonymous symbols with the #: syntax, and referring to the same symbols within the scope of the expanded expression. Emulating this kind of inspection in Python would be much more verbose and less accessible.
In addition to the obvious uses at the REPL, experienced Lispers use print and read in the code as a simple and readily available serialization tool, comparable to XML or json. While Python has the str function, equivalent to Lisp's print, it lacks the equivalent of read, the closest equivalent being eval. eval of course conflates two different concepts, parsing and evaluation, which leads to problems like this and solutions like this and is a recurring topic on Python forums. This would not be an issue in Lisp precisely because the reader and the evaluator are cleanly separated.
Finally, advanced features of the reader facility enable the programmer to extend the language in ways that even macros could not otherwise provide. A perfect example of such making hard things possible is the infix package by Mark Kantrowitz, implementing a full-featured infix syntax as a reader macro.
In a Lisp-based system one typically develops the program while it is running from the REPL (read eval print loop). So it integrates a bunch of tools: completion, editor, command-line-interpreter, debugger, ... The default is to have that. Type an expression with an error - you are in another REPL level with some debugging commands enabled. You actually have to do something to get rid of this behavior.
You can have two different meanings of the REPL concept:
the Read Eval Print Loop like in Lisp (or a few other similar languages). It reads programs and data, it evaluates and prints the result data. Python does not work this way. Lisp's REPL allows you to work directly in a meta-programming way, writing code which generates (code), check the expansions, transform actual code, etc.. Lisp has read/eval/print as the top loop. Python has something like readstring/evaluate/printstring as the top-loop.
the Command Line Interface. An interactive shell. See for example for IPython. Compare that to Common Lisp's SLIME.
The default shell of Python in default mode is not really that powerful for interactive use:
Python 2.7.2 (default, Jun 20 2012, 16:23:33)
[GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> a+2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>>
You get an error message and that's it.
Compare that to the CLISP REPL:
rjmba:~ joswig$ clisp
i i i i i i i ooooo o ooooooo ooooo ooooo
I I I I I I I 8 8 8 8 8 o 8 8
I \ `+' / I 8 8 8 8 8 8
\ `-+-' / 8 8 8 ooooo 8oooo
`-__|__-' 8 8 8 8 8
| 8 o 8 8 o 8 8
------+------ ooooo 8oooooo ooo8ooo ooooo 8
Welcome to GNU CLISP 2.49 (2010-07-07) <http://clisp.cons.org/>
Copyright (c) Bruno Haible, Michael Stoll 1992, 1993
Copyright (c) Bruno Haible, Marcus Daniels 1994-1997
Copyright (c) Bruno Haible, Pierpaolo Bernardi, Sam Steingold 1998
Copyright (c) Bruno Haible, Sam Steingold 1999-2000
Copyright (c) Sam Steingold, Bruno Haible 2001-2010
Type :h and hit Enter for context help.
[1]> (+ a 2)
*** - SYSTEM::READ-EVAL-PRINT: variable A has no value
The following restarts are available:
USE-VALUE :R1 Input a value to be used instead of A.
STORE-VALUE :R2 Input a new value for A.
ABORT :R3 Abort main loop
Break 1 [2]>
CLISP uses Lisp's condition system to break into a debugger REPL. It presents some restarts. Within the error context, the new REPL provides extended commands.
Let's use the :R1 restart:
Break 1 [2]> :r1
Use instead of A> 2
4
[3]>
Thus you get interactive repair of programs and execution runs...
Python's interactive mode differs from Python's "read code from file" mode in several, small, crucial ways, probably inherent in the textual representation of the language. Python is also not homoiconic, something that makes me call it "interactive mode" rather than "read-eval-print loop". That aside, I'd say that it is more a difference of grade than a difference in kind.
Now, something tahtactually comes close to "difference in kind", in a Python code file, you can easily insert blank lines:
def foo(n):
m = n + 1
return m
If you try to paste the identical code into the interpreter, it will consider the function to be "closed" and complain that you have a naked return statement at the wrong indentation. This does not happen in (Common) Lisp.
Furthermore, there are some rather handy convenience variables in Common Lisp (CL) that are not available (at least as far as I know) in Python. Both CL and Python have "value of last expression" (* in CL, _ in Python), but CL also has ** (value of expression before last) and *** (the value of the one before that) and +, ++ and +++ (the expressions themselves). CL also doesn't distinguish between expressions and statements (in essence, everything is an expression) and all of that does help build a much richer REPL experience.
As I said at the beginning, it is more a difference in grade than difference in kind. But had the gap been only a smidgen wider between them, it would probably be a difference in kind, as well.
This is a bit of an odd question; it came up in the context of a tool that exposes a Python API, which we spend a lot of time querying interactively from the REPL. The particular idiom causing issues is something like this:
for var in slow_generator_of_giant_list():
stats = update(stats, var)
print stats
To enter this at the REPL, I can type this:
>>> for var in slow_generator_of_giant_list():
... stats = update(stats, var)
...
If I now attempt to type the print, I get a syntax error due to improper indentation. (Or else I put the print inside the loop and do it on every iteration.)
But if I hit enter to go to the next line, the loop runs immediately, and I have to wait for it to finish, or type the print command in the face of possible output coming at me, etc.
Obviously I can define a function containing the above, and it might be worth saving into a file anyway, but in the general case we're constructing these on the fly, and it would be nice to have a way to "schedule" a command to run after the end of a loop from the REPL. In a language with block delimiters, I could of course put it after the ending delimiter (and any necessary statement separator). But my coworkers and I were stumped trying to do something similar here.
Is there perhaps an ugly abuse of Pythonic syntax that will do the trick that my coworkers and I couldn't think of? Or a recommended way to avoid the problem while still making it easy to throw together ad hoc interactive queries?
Thanks for any pointers.
Not beautiful, but this should work:
>>> mygen = slow_generator_of_giant_list()
>>> try:
... while True: stats = update(stats, mygen.next())
... except StopIteration:
... print stats
...
I would just say that you would find it easier just to not use the interactive shell for this.
It's not much effort to save a file and run it. You only have to keep it around for as long as you use it.
I actually have found this answering on SO. I keep a file open in my text editor with a terminal in the right directory, and just use it as a scratchpad for mocking up answers in.