Pasting Lines of Code onto Python Command Line - python

I am working in Aptana Studio and Python shell in the built-in terminal there. I am running some
rather long snippets of code on the shell command line. I keep tripping over typos so is there
a way to write all the code and copy and paste it onto the command line.

Yes, you can copy and paste code into the terminal, as long as complete definitions do not have blank lines in them.
You can paste:
def foo(bar):
print(bar)
return bar
but not
def foo(bar):
print(bar)
return bar
because the interpreter interprets the empty line as the end of the definition of foo.
The same applies to class definitions and suites (if, try, except, while, finally, etc.); no blank lines allowed anywhere in attribute and function definitions.

If it's not already configured that way, you may want configure your IDE to use IPython as your interpreter. With it, you can use the magic function %cpaste to allow you to paste full chunks of code. Just end your chunk with a line containing only -- to tell IPython that you're done.

Related

Launching Python script from zsh and staying in Python shell

I would like to simplify running Python scripts from within the Python shell. In Python 2, you could just use execfile(path). But in Python 3 it's harder to remember:
exec(open(path).read())
So I want a function to run a script, as simple as run(path). I can do this from the Python shell:
def run(filename):
source = open(filename).read()
code = compile(source, filename, 'exec')
exec(code)
Then I can just type in run(path). This works great, and now I want to simplify things by defining the run function every time I launch Python 3.
I'd like to configure my ~/.zshenv with a zsh alias or function (say, py) that launches Python and tells it to define the run function. So that's where I'm stumped. What would a such a zsh command look like? I've tried and failed with things like:
py () {
python -c "\
def run(filename): \
source = open(filename).read() \
code = compile(source, filename, 'exec') \
exec(code)" \
}
But that fails miserably:
% py
File "<string>", line 1
def run(filename): source = open(filename).read() code = compile(source, filename, 'exec') exec(code)
IndentationError: unexpected indent
%
And even if it were to work, it would drop back out of the Python shell once the function was defined. Obviously I don't know what I'm doing here. Any pointers?
Also… please don't assume I have asked the right question. Usually on StackOverflow we try to avoid second-guessing posters' assumptions. But go ahead and second-guess mine if there's a better way to get Python to always define a run function when it is launched.
If you need this function only for interactive shells, you can write it in a file and then run python -i file_with_function.py. The -i option will tell the interpreter to drop into an interactive session after whatever is in the file_with_function.py file runs.
If you want it for any .py file that you will run non-interactively then you can do one of the following:
Create a package that contains your run function and install your package on your interpreter. There is a detailed guide on the Python docs (https://packaging.python.org/tutorials/packaging-projects/).
Add the directory that contains a .py file with your function on the PYTHONPATH environmental variable and import it from there.
In the command which you are passing to Python (using python -c), you start the function definition with a couple of spaces. Spaces at the start of a line are significant in Python. You would get the same error, if you would open a Python shell and write
def foo:
with several spaces in front: Python responds with IndentationError: unexpected indent.
In addition, your use of backslash characters makes all the linefeeds disappear, with the effect that you are going to define the complete function in a single line. This is also invalid in Python, so even if you would fix the initial spaces, you would still get SyntaxError: invalid syntax.
Note that you can use the -m option of Python to load initial definition together with starting Python. You can do a
python -h
to get a list of the valid command line options.

debug a function in pycharm

I have a validator function as part of a bigger program which is fifty lines long which returns True or False when you give it a string. For a certain string, it is currently returning False, and I don't which of the many return statements is firing. I can open the Python Console of the interpreter and import the function then give it its argument, but not see on which line it is returning False. Would rather not alter the main program to feed it its argument, would also rather not set breakpoints in the program for this. Is it possible in PyCharm to isolate a function, give it your own custom argument and then step through it line by line?
Am using PyCharm version 2018.2.4
Is it possible in PyCharm to isolate a function, give it your own custom argument and then step through it line by line?
No, it's not unless you create another file and write something like tests there
By clicking on left side of each line you can declare a breakpoint on the line like this:
Then you can go to debug tool window and click on the green play button
More about debuging using PyCharm
Also you can use python's breakpoint()
It is added as a built-in function in Python 3.7 but u can import it to your file on Python's 3.7-

IDLE autocomplete in a new file do not work

If I testing my codes on IDLE the autocomplete its works but if I open a new file don't.
See there pictures below:
I just press CTRL + SPACE.
So.. don't work in this case:
I'll think there are some configuration for solve this, any one knows?
Python idle doesn't work that way. You get autocomplete in idle shell because values are deduced in every run. When you use files your program is not evaluated until you run. Because you can assign any type to a variable at run time, there is no way for idle to confirm the type of variable.
Understand with an example
>> a = dict()
>> a = set()
>> a. # <-- autocomplete knows type of a is set
but the same code in a file
a = dict()
a = set()
a. # <-- How does idle come to know what this variable is without running
but when you run this file once your global variables will show autocomplete feature, but not the local scope variables.
Have you tried saving the script as a *.py file before trying to use IDLE's autocomplete?
More than that, have you considered using a text editor with Python plugins, like Sublime Text and Atom? Or even a python-compatible IDE, like PyCharm, Spyder or even JupyterNotebook.

Ignore the rest of the python file

My python scripts often contain "executable code" (functions, classes, &c) in the first part of the file and "test code" (interactive experiments) at the end.
I want python, py_compile, pylint &c to completely ignore the experimental stuff at the end.
I am looking for something like #if 0 for cpp.
How can this be done?
Here are some ideas and the reasons they are bad:
sys.exit(0): works for python but not py_compile and pylint
put all experimental code under def test():: I can no longer copy/paste the code into a python REPL because it has non-trivial indent
put all experimental code between lines with """: emacs no longer indents and fontifies the code properly
comment and uncomment the code all the time: I am too lazy (yes, this is a single key press, but I have to remember to do that!)
put the test code into a separate file: I want to keep the related stuff together
PS. My IDE is Emacs and my python interpreter is pyspark.
Use ipython rather than python for your REPL It has better code completion and introspection and when you paste indented code it can automatically "de-indent" the pasted code.
Thus you can put your experimental code in a test function and then paste in parts without worrying and having to de-indent your code.
If you are pasting large blocks that can be considered individual blocks then you will need to use the %paste or %cpaste magics.
eg.
for i in range(3):
i *= 2
# with the following the blank line this is a complete block
print(i)
With a normal paste:
In [1]: for i in range(3):
...: i *= 2
...:
In [2]: print(i)
4
Using %paste
In [3]: %paste
for i in range(10):
i *= 2
print(i)
## -- End pasted text --
0
2
4
In [4]:
PySpark and IPython
It is also possible to launch PySpark in IPython, the enhanced Python interpreter. PySpark works with IPython 1.0.0 and later. To use IPython, set the IPYTHON variable to 1 when running bin/pyspark:1
$ IPYTHON=1 ./bin/pyspark
Unfortunately, there is no widely (or any) standard describing what you are talking about, so getting a bunch of python specific things to work like this will be difficult.
However, you could wrap these commands in such a way that they only read until a signifier. For example (assuming you are on a unix system):
cat $file | sed '/exit(0)/q' |sed '/exit(0)/d'
The command will read until 'exit(0)' is found. You could pipe this into your checkers, or create a temp file that your checkers read. You could create wrapper executable files on your path that may work with your editors.
Windows may be able to use a similar technique.
I might advise a different approach. Separate files might be best. You might explore iPython notebooks as a possible solution, but I'm not sure exactly what your use case is.
Follow something like option 2.
I usually put experimental code in a main method.
def main ():
*experimental code goes here *
Then if you want to execute the experimental code just call the main.
main()
With python-mode.el mark arbitrary chunks as section - for example via py-sectionize-region.
Than call py-execute-section.
Updated after comment:
python-mode.el is delivered by melpa.
M-x list-packages RET
Look for python-mode - the built-in python.el provides 'python, while python-mode.el provides 'python-mode.
Developement just moved hereto: https://gitlab.com/python-mode-devs/python-mode
I think the standard ('Pythonic') way to deal with this is to do it like so:
class MyClass(object):
...
def my_function():
...
if __name__ == '__main__':
# testing code here
Edit after your comment
I don't think what you want is possible using a plain Python interpreter. You could have a look at the IEP Python editor (website, bitbucket): it supports something like Matlab's cell mode, where a cell can be defined with a double comment character (##):
## main code
class MyClass(object):
...
def my_function():
...
## testing code
do_some_testing_please()
All code from a ##-beginning line until either the next such line or end-of-file constitutes a single cell.
Whenever the cursor is within a particular cell and you strike some hotkey (default Ctrl+Enter), the code within that cell is executed in the currently running interpreter. An additional feature of IEP is that selected code can be executed with F9; a pretty standard feature but the nice thing here is that IEP will smartly deal with whitespace, so just selecting and pasting stuff from inside a method will automatically work.
I suggest you use a proper version control system to keep the "real" and the "experimental" parts separated.
For example, using Git, you could only include the real code without the experimental parts in your commits (using add -p), and then temporarily stash the experimental parts for running your various tools.
You could also keep the experimental parts in their own branch which you then rebase on top of the non-experimental parts when you need them.
Another possibility is to put tests as doctests into the docstrings of your code, which admittedly is only practical for simpler cases.
This way, they are only treated as executable code by the doctest module, but as comments otherwise.

Enabling execution of multi-line statements within the Python's debugger(pdb) conveniently

Running !import code; code.interact(local=vars()) inside the pdb prompt allows you to input multiline statements(e.g. a class definition) inside the debugger(source). Is there any way to omit having to copy paste/type that full line each time?
I was thinking about Conque for vim and setting something like :noremap ,d i!import code; code.interact(local=vars())<Esc> but editing anything outside of insert mode doesn't seem to have any effect on the prompt.
PDB reads in a .pdbrc when it starts. From the Python docs:
If a file .pdbrc exists in the user’s home directory or in the current directory, it is read in and executed as if it had been typed at the debugger prompt. This is particularly useful for aliases. If both files exist, the one in the home directory is read first and aliases defined there can be overridden by the local file.
So try creating that file and putting that command in there as is.

Categories

Resources