How to run only specific lines of code from a file? - python

I was wondering how can I run only a small part of the code without running all the previous ones, such a thing would be very handy to me because I'm writing code just to see how it works and I do that in the same Python file, so when I want to run just the one I recently wrote it also runs all the previous ones.
I only want to run the highlighted part, not all the previous lines:

you should make all your codes inside functions.
and call it inside the main function.
for example:
# Import necessary libraries.
# Define your functions from the top
def Foo():
print('foo')
def Bar():
print('bar')
if __name__ == '__main__':
# Run your code from here, call the needed functions.
Foo()
Bar()
# If you don't want to run Bar(), simply comment it.

Definitions/ Functions are the best way to go for this.
def afunc():
print('This is the function printed after the other function')
def func(): # Starts the definition
print('This is a function')
afunc()
func() # Runs the Code

I've not used Pycharm specifically, but I know in many other IDEs for python (VS Code, Spyder, Jupyter), you can break out the script into cells and run each cell individually.
For VS Code and Spyder, you desginate different cells by including lines that start with #%%
This will also open up an interactive python shell where you can modify and re-run each section or type out individual lines to run

Related

How to use Python Interactive Window in VS Code with functions

I am new to using the python interactive window and I like it but it seems to clear local variables in between runs, so if I run something like
def main():
dates = '2012152'
# %%
print(dates) # want to just run this
# %%
if __name__ == '__main__':
main()
# or even
main()
all at once it works fine but then if I just run the middle cell I get "dates not defined" error. It works outside of the function because apparently a global variable is saved:
dates = '2012152'
# %%
print(dates) # this works if this cell is run
# %%
Is there any way to get a similar behavior inside a function? If not it doesn't seem useful to me at all (maybe I have designed my code badly?).
Cells are a great way to experiment with flat code, but they are limited when working nested inside functions.
One way to work around this is to use a regular built-in python debugger and set a breakpoint within the function.
Here is a process I use for experimenting with code inside a function:
Set a breakpoint in the function, after the code you want to experiment with and start debugging.
Make any necessary changes to the code.
Select the lines that you've changed and that you want to run again. Make sure to include all the indentations as well.
Right-click and select Evaluate in Debug Console.
This will allow you to run the code one line at a time, see results, and make any necessary adjustments as you go along.
The process could be further improved by binding a keyboard shortcut to the this command.
Yes, print(dates) will not run as the dates variable isn't in scope, unless the function main is called and even then dates will be only in the local scope of the function, not in global scope.
So to print it outside the function, you need to first define it.

Imitate command line execution from within code

I have a python project that is intended to be executed by running the head routine from the command line, i.e.:
python ssd.py --train
However, since this is a machine learning model and I don't have a GPU, I want to run the project entirely within Google Colab. This means I can't start files using the command line (or at least I don't know how). The workaround I've chosen is to use a single notebook as the header routine.
MWE-sketch (edited):
launcher.ipynb
!cp drive/MyDrive/.../ssd.py
from ssd import SSD
SSD("train")
ssd.py
...
__init__():
# here is code that will
# result in an error unless
# the code below is executed first
...
# the code below is not inside any function
if __name__ == '__main__':
# here is code that
# must be executed first
If I type python ssd.py --train into the command line, the code in ssd.py proper is executed first. If I use launcher.ipnyb, the code in __init__() is executed first, resulting in an error.
I've gotten it to work like this:
ssd.py
import sys as _sys
...
__init__():
# here is the same code as before
...
def set_args(args):
_sys.argv[1:] = args
def setup():
# here is code that was previously
# outside any function (i.e., right below)
# the code below is not inside any function
if __name__ == '__main__':
setup()
launcher.ipynb
!cp drive/MyDrive/.../ssd.py
import ssd
ssd.set_args(["--train"])
ssd.setup()
This seems like way too complex and primitive of a solution, but I guess there's nothing better?

How can I import the value of a variable into another Python file? [duplicate]

I have a Python program I'm building that can be run in either of 2 ways: the first is to call python main.py which prompts the user for input in a friendly manner and then runs the user input through the program. The other way is to call python batch.py -file- which will pass over all the friendly input gathering and run an entire file's worth of input through the program in a single go.
The problem is that when I run batch.py, it imports some variables/methods/etc from main.py, and when it runs this code:
import main
at the first line of the program, it immediately errors because it tries to run the code in main.py.
How can I stop Python from running the code contained in the main module which I'm importing?
Because this is just how Python works - keywords such as class and def are not declarations. Instead, they are real live statements which are executed. If they were not executed your module would be empty.
The idiomatic approach is:
# stuff to run always here such as class/def
def main():
pass
if __name__ == "__main__":
# stuff only to run when not called via 'import' here
main()
It does require source control over the module being imported, however.
Due to the way Python works, it is necessary for it to run your modules when it imports them.
To prevent code in the module from being executed when imported, but only when run directly, you can guard it with this if:
if __name__ == "__main__":
# this won't be run when imported
You may want to put this code in a main() method, so that you can either execute the file directly, or import the module and call the main(). For example, assume this is in the file foo.py.
def main():
print "Hello World"
if __name__ == "__main__":
main()
This program can be run either by going python foo.py, or from another Python script:
import foo
...
foo.main()
Use the if __name__ == '__main__' idiom -- __name__ is a special variable whose value is '__main__' if the module is being run as a script, and the module name if it's imported. So you'd do something like
# imports
# class/function definitions
if __name__ == '__main__':
# code here will only run when you invoke 'python main.py'
Unfortunately, you don't. That is part of how the import syntax works and it is important that it does so -- remember def is actually something executed, if Python did not execute the import, you'd be, well, stuck without functions.
Since you probably have access to the file, though, you might be able to look and see what causes the error. It might be possible to modify your environment to prevent the error from happening.
Put the code inside a function and it won't run until you call the function. You should have a main function in your main.py. with the statement:
if __name__ == '__main__':
main()
Then, if you call python main.py the main() function will run. If you import main.py, it will not. Also, you should probably rename main.py to something else for clarity's sake.
There was a Python enhancement proposal PEP 299 which aimed to replace if __name__ == '__main__': idiom with def __main__:, but it was rejected. It's still a good read to know what to keep in mind when using if __name__ = '__main__':.
You may write your "main.py" like this:
#!/usr/bin/env python
__all__=["somevar", "do_something"]
somevar=""
def do_something():
pass #blahblah
if __name__=="__main__":
do_something()
I did a simple test:
#test.py
x = 1
print("1, has it been executed?")
def t1():
print("hello")
print("2, has it been executed?")
def t2():
print("world")
print("3, has it been executed?")
def main():
print("Hello World")
print("4, has it been executed?")
print("5, has it been executed?")
print(x)
# while True:
# t2()
if x == 1:
print("6, has it been executed?")
#test2.py
import test
When executing or running test2.py, the running result:
1, has it been executed?
5, has it been executed?
1
6, has it been executed?
Conclusion: When the imported module does not add if __name__=="__main__":, the current module is run, The code in the imported module that is not in the function is executed sequentially, and the code in the function is not executed when it is not called.
in addition:
def main():
# Put all your code you need to execute directly when this script run directly.
pass
if __name__ == '__main__':
main()
else:
# Put functions you need to be executed only whenever imported
A minor error that could happen (at least it happened to me), especially when distributing python scripts/functions that carry out a complete analysis, was to call the function directly at the end of the function .py file.
The only things a user needed to modify were the input files and parameters.
Doing so when you import you'll get the function running immediately. For proper behavior, you simply need to remove the inside call to the function and reserve it for the real calling file/function/portion of code
Another option is to use a binary environment variable, e.g. lets call it 'run_code'. If run_code = 0 (False) structure main.py to bypass the code (but the temporarily bypassed function will still be imported as a module). Later when you are ready to use the imported function (now a module) set the environment variable run_code = 1 (True). Use the os.environ command to set and retrieve the binary variable, but be sure to convert it to an integer when retrieving (or restructure the if statement to read a string value),
in main.py:
import os
#set environment variable to 0 (False):
os.environ['run_code'] = '0'
def binary_module():
#retrieve environment variable, convert to integer
run_code_val = int(os.environ['run_code'] )
if run_code_val == 0:
print('nope. not doing it.')
if run_code_val == 1:
print('executing code...')
# [do something]
...in whatever script is loading main.py:
import os,main
main.binary_module()
OUTPUT: nope. not doing it.
# now flip the on switch!
os.environ['run_code'] = '1'
main.binary_module()
OUTPUT: executing code...
*Note: The above code presumes main.py and whatever script imports it exist in the same directory.
Although you cannot use import without running the code; there is quite a swift way in which you can input your variables; by using numpy.savez, which stores variables as numpy arrays in a .npz file. Afterwards you can load the variables using numpy.load.
See a full description in the scipy documentation
Please note this is only the case for variables and arrays of variable, and not for methods, etc.
Try just importing the functions needed from main.py? So,
from main import SomeFunction
It could be that you've named a function in batch.py the same as one in main.py, and when you import main.py the program runs the main.py function instead of the batch.py function; doing the above should fix that. I hope.

Function is called multiple times when importing but runs only once when used in the .py file where it was created [duplicate]

I have a Python program I'm building that can be run in either of 2 ways: the first is to call python main.py which prompts the user for input in a friendly manner and then runs the user input through the program. The other way is to call python batch.py -file- which will pass over all the friendly input gathering and run an entire file's worth of input through the program in a single go.
The problem is that when I run batch.py, it imports some variables/methods/etc from main.py, and when it runs this code:
import main
at the first line of the program, it immediately errors because it tries to run the code in main.py.
How can I stop Python from running the code contained in the main module which I'm importing?
Because this is just how Python works - keywords such as class and def are not declarations. Instead, they are real live statements which are executed. If they were not executed your module would be empty.
The idiomatic approach is:
# stuff to run always here such as class/def
def main():
pass
if __name__ == "__main__":
# stuff only to run when not called via 'import' here
main()
It does require source control over the module being imported, however.
Due to the way Python works, it is necessary for it to run your modules when it imports them.
To prevent code in the module from being executed when imported, but only when run directly, you can guard it with this if:
if __name__ == "__main__":
# this won't be run when imported
You may want to put this code in a main() method, so that you can either execute the file directly, or import the module and call the main(). For example, assume this is in the file foo.py.
def main():
print "Hello World"
if __name__ == "__main__":
main()
This program can be run either by going python foo.py, or from another Python script:
import foo
...
foo.main()
Use the if __name__ == '__main__' idiom -- __name__ is a special variable whose value is '__main__' if the module is being run as a script, and the module name if it's imported. So you'd do something like
# imports
# class/function definitions
if __name__ == '__main__':
# code here will only run when you invoke 'python main.py'
Unfortunately, you don't. That is part of how the import syntax works and it is important that it does so -- remember def is actually something executed, if Python did not execute the import, you'd be, well, stuck without functions.
Since you probably have access to the file, though, you might be able to look and see what causes the error. It might be possible to modify your environment to prevent the error from happening.
Put the code inside a function and it won't run until you call the function. You should have a main function in your main.py. with the statement:
if __name__ == '__main__':
main()
Then, if you call python main.py the main() function will run. If you import main.py, it will not. Also, you should probably rename main.py to something else for clarity's sake.
There was a Python enhancement proposal PEP 299 which aimed to replace if __name__ == '__main__': idiom with def __main__:, but it was rejected. It's still a good read to know what to keep in mind when using if __name__ = '__main__':.
You may write your "main.py" like this:
#!/usr/bin/env python
__all__=["somevar", "do_something"]
somevar=""
def do_something():
pass #blahblah
if __name__=="__main__":
do_something()
I did a simple test:
#test.py
x = 1
print("1, has it been executed?")
def t1():
print("hello")
print("2, has it been executed?")
def t2():
print("world")
print("3, has it been executed?")
def main():
print("Hello World")
print("4, has it been executed?")
print("5, has it been executed?")
print(x)
# while True:
# t2()
if x == 1:
print("6, has it been executed?")
#test2.py
import test
When executing or running test2.py, the running result:
1, has it been executed?
5, has it been executed?
1
6, has it been executed?
Conclusion: When the imported module does not add if __name__=="__main__":, the current module is run, The code in the imported module that is not in the function is executed sequentially, and the code in the function is not executed when it is not called.
in addition:
def main():
# Put all your code you need to execute directly when this script run directly.
pass
if __name__ == '__main__':
main()
else:
# Put functions you need to be executed only whenever imported
A minor error that could happen (at least it happened to me), especially when distributing python scripts/functions that carry out a complete analysis, was to call the function directly at the end of the function .py file.
The only things a user needed to modify were the input files and parameters.
Doing so when you import you'll get the function running immediately. For proper behavior, you simply need to remove the inside call to the function and reserve it for the real calling file/function/portion of code
Another option is to use a binary environment variable, e.g. lets call it 'run_code'. If run_code = 0 (False) structure main.py to bypass the code (but the temporarily bypassed function will still be imported as a module). Later when you are ready to use the imported function (now a module) set the environment variable run_code = 1 (True). Use the os.environ command to set and retrieve the binary variable, but be sure to convert it to an integer when retrieving (or restructure the if statement to read a string value),
in main.py:
import os
#set environment variable to 0 (False):
os.environ['run_code'] = '0'
def binary_module():
#retrieve environment variable, convert to integer
run_code_val = int(os.environ['run_code'] )
if run_code_val == 0:
print('nope. not doing it.')
if run_code_val == 1:
print('executing code...')
# [do something]
...in whatever script is loading main.py:
import os,main
main.binary_module()
OUTPUT: nope. not doing it.
# now flip the on switch!
os.environ['run_code'] = '1'
main.binary_module()
OUTPUT: executing code...
*Note: The above code presumes main.py and whatever script imports it exist in the same directory.
Although you cannot use import without running the code; there is quite a swift way in which you can input your variables; by using numpy.savez, which stores variables as numpy arrays in a .npz file. Afterwards you can load the variables using numpy.load.
See a full description in the scipy documentation
Please note this is only the case for variables and arrays of variable, and not for methods, etc.
Try just importing the functions needed from main.py? So,
from main import SomeFunction
It could be that you've named a function in batch.py the same as one in main.py, and when you import main.py the program runs the main.py function instead of the batch.py function; doing the above should fix that. I hope.

ipdb: tracing via additional code on demand | python

I use import ipdb;ipdb.set_trace()
Sometimes, while debugging with set_trace I want verify some method out of frame/source (invoke it with my parameters, and see how it works inside). Method is not used yet in code, so jump is impossible.
sth like:
def do_a(): ...
def do_b(): ...
def do_c(): ...
def do_d():
do_a()
import ipdb;ipdb.set_trace()
# here: wanna check do_c before do_b, but not just get result from do_c (it's easy), rather trace throught entire do_c and keep position in current frame.
do_b()
there is debug command, but do not work with functions, I expect interactive shell.
Workaround is time-consuming: stop debugger, modify code (add do_c() in example) and restart debugger)
Not sure this works as this is quite rare use case.
Set breakpoint with breakpoint settings command like tbreak:
http://georgejhunt.com/olpc/pydebug/pydebug/ipdb.html
tbreak do_b # Might or might not work
Then just execute do_b and it should hit the breakpoint
do_b()

Categories