How to tell Python to start executing code from a given line - python

I am completely new to Python, just learning strings and variables at the moment. I know you can put a "#" before code to comment it, but is there an option for Python to completely ignore part of the code and start working from the lines after this code?
For example:
old_price = 30
new_price = 25
difference = old_price - new_price
name = "John Smith"
age = 15
print(name, age)
I would like the code to start working from the line name="John Smith", without having to comment the first 3 lines.

You can use multiline strings to comment the whole block, not having to put # in each line:
"""
old_price = 30
new_price = 25
difference = old_price - new_price
"""
name = "John Smith"
age = 15
print(name, age)

You could define a function an call it:
# define function old()
def old():
old_price = 30
new_price = 25
difference = old_price - new_price
print (difference)
# define function string()
def string():
name = "John Smith"
age = 15
print (name, age)
string() # out: John Smith 15

I don't believe that there is and I don't think that it's actually a good idea to do so. Why would you have code you don't want to execute?
If you don't want to execute it YET, you can put code into a function and not call it.
If you're just experimenting and want to play around around you should consider things like IPython or Jupyter Notebook where you can execute code interactively

Python is a structured programming language and therefore this type of things is discouraged and not supported internally (just like goto instructions). Moreover, usually the first lines of code would be import statements that would be needed later, so you don't really want to skip them.
You SHOULD use the benefits of a structured language and put your code into functions, then you can decide later if you want to execute those functions. Another solution is to use comments (or block comments) for code that you don't want to execute currently, or for other textual lines that don't contain code.
However, just for fun, here are two ways to skip lines.
Using -x flag
You can run your program with -x flag: python -x <python_file>. This will only skip the first line. This flag is used for allowing non-Unix forms of #!cmd (as describing when running python -h).
Using another script to run your script
Python has no internal support to run from a given line, so let's cheat. We can create a script file that its only purpose is to execute another file from a given line. In this example I implemented three ways to do so (note that the exec command is bad and you should not really use that).
import os
import subprocess
import sys
import tempfile
skip_to = int(sys.argv[1])
file_path = sys.argv[2]
with open(file_path, 'r') as sourcefile:
new_source = '\n'.join(sourcefile.readlines()[skip_to:])
# Several ways to execute:
# 1. Create tempfile and use subprocess
temp = tempfile.NamedTemporaryFile(mode='w+', delete=False)
temp.write(new_source)
temp.close()
subprocess.call(['python', temp.name] + sys.argv[2:])
os.remove(temp.name)
# 2. Run from memory using subprocess and python -c
subprocess.call(['python', '-c', new_source] + sys.argv[2:])
# 3. Using exec (usually a very bad idea...)
exec(new_source)
An example code to skip:
print("first line")
print("second line")
print("third line")
from datetime import datetime
print(datetime.now())
>>python skip.py 3 main.py
>>2019-12-05 20:50:50.759259
>>2019-12-05 20:50:50.795159
>>2019-12-05 20:50:50.800118

Related

How to gather return value from function in another script in python?

fw_test.py
def _testmethod_():
x = []
y = 0
while y !=5:
x.append(y)
y +=1
return x
t = _testmethod_()
main_test.py
import subprocess
p = subprocess.call(['python', 'main_test.py'])
Due to the guidelines I cannot import fw_test.py into main_test.py. I want to be able to store the value returned by _testmethod_() from fw_test.py in a variable inmain_test.py. I learned that with subprocess I can run the fw_test.py, but that is not enough for me.Is there a way to go about this?
Edit: The reason why fw_test.py cannot be imported to main_test.py is that there are many test scripts like fw_test.py which keeps on changing according to test. The main_test.py is supposed to be a generic framework which has basic functions to evaluate the test passed or failed by reading the return value from fw_test.py(the return value is True/False). If I import the script in the top of the file it will not be generic anymore, I think. I'm open to other suggestions.
Why the downvotes?
You could use subprocess.check_output to get the output written by another script
the file "b.py" writes its output to stdout
print("hi")
print(1)
the file "a.py" executes "b.py" as subprocess
import subprocess
a = subprocess.check_output(["python", "/tmp/b.py"])
print(a.decode('utf-8'))
Note: value returned by check_output is a byte array and should be decoded to convert it to string
Executing "a.py" from command line
$ python a.py
hi
1
Disclaimer: This is the simplest solution for the given (for training) problem (not the best). Technically I am printing the output to stdout and capturing it in parent process. To solve the same on a more serious problem mechanism such as IPC, RPC, etc should be used.
If you can't use import fw_test statement; you could use importlib.import_module() instead, to get the return value from fw_test.testmethod() function:
import importlib
fw_test = importlib.import_module('fw_test')
value = fw_test.testmethod()
The simplest way is probably to drop the return value into a file, then have your main pick it up.
fw_test.py
def _testmethod_():
x = []
y = 0
while y !=5:
x.append(y)
y +=1
return x
t = _testmethod_()
with open("fileToStoreValue.txt", 'w') as f:
f.write(t)
main_test.py
import subprocess
p = subprocess.call(['python', 'main_test.py'])
t = eval(open("fileToStoreValue.txt", 'r').read().strip())
Note that I included strip when reading to prevent you from picking up any trailing new line.
Also keep in mind that this will work as written if both python files are in teh same directory. If they differ in location, you will need to specify a path to fileToSTtoreValue.txt in the open statements.

How to save python screen output to a text file

I'd like to query items from a dict and save the printed output to a text file.
Here's what I have:
import json
import exec.fullog as e
inp = e.getdata() #inp now is a dict() which has items, keys and values.
#Query
print('Data collected on:', inp['header']['timestamp'].date())
print('\n CLASS 1 INFO\n')
for item in inp['Demographics']:
if item['name'] in ['Carly', 'Jane']:
print(item['name'], 'Height:', item['ht'], 'Age:', item['years'])
for item in inp['Activity']:
if item['name'] in ['Cycle', 'Run', 'Swim']:
print(item['name'], 'Athlete:', item['athl_name'], 'Age:', item['years'])
A quick and dirty hack to do this within the script is to direct the screen output to a file:
import sys
stdoutOrigin=sys.stdout
sys.stdout = open("log.txt", "w")
and then reverting back to outputting to screen at the end of your code:
sys.stdout.close()
sys.stdout=stdoutOrigin
This should work for a simple code, but for a complex code there are other more formal ways of doing it such as using Python logging.
Let me summarize all the answers and add some more.
To write to a file from within your script, user file I/O tools that are provided by Python (this is the f=open('file.txt', 'w') stuff.
If don't want to modify your program, you can use stream redirection (both on windows and on Unix-like systems). This is the python myscript > output.txt stuff.
If you want to see the output both on your screen and in a log file, and if you are on Unix, and you don't want to modify your program, you may use the tee command (windows version also exists, but I have never used it)
Even better way to send the desired output to screen, file, e-mail, twitter, whatever is to use the logging module. The learning curve here is the steepest among all the options, but in the long run it will pay for itself.
abarnert's answer is very good and pythonic. Another completely different route (not in python) is to let bash do this for you:
$ python myscript.py > myoutput.txt
This works in general to put all the output of a cli program (python, perl, php, java, binary, or whatever) into a file, see How to save entire output of bash script to file for more.
If you want the output to go to stdout and to the file, you can use tee:
$ python myscript.py | tee myoutput.txt
For more on tee, see: How to redirect output to a file and stdout
What you're asking for isn't impossible, but it's probably not what you actually want.
Instead of trying to save the screen output to a file, just write the output to a file instead of to the screen.
Like this:
with open('outfile.txt', 'w') as outfile:
print >>outfile, 'Data collected on:', input['header']['timestamp'].date()
Just add that >>outfile into all your print statements, and make sure everything is indented under that with statement.
More generally, it's better to use string formatting rather than magic print commas, which means you can use the write function instead. For example:
outfile.write('Data collected on: {}'.format(input['header']['timestamp'].date()))
But if print is already doing what you want as far as formatting goes, you can stick with it for now.
What if you've got some Python script someone else wrote (or, worse, a compiled C program that you don't have the source to) and can't make this change? Then the answer is to wrap it in another script that captures its output, with the subprocess module. Again, you probably don't want that, but if you do:
output = subprocess.check_output([sys.executable, './otherscript.py'])
with open('outfile.txt', 'wb') as outfile:
outfile.write(output)
You would probably want this. Simplest solution would be
Create file first.
open file via
f = open('<filename>', 'w')
or
f = open('<filename>', 'a')
in case you want to append to file
Now, write to the same file via
f.write(<text to be written>)
Close the file after you are done using it
#good pracitice
f.close()
Here's a really simple way in python 3+:
f = open('filename.txt', 'w')
print('something', file = f)
^ found that from this answer: https://stackoverflow.com/a/4110906/6794367
This is very simple, just make use of this example
import sys
with open("test.txt", 'w') as sys.stdout:
print("hello")
python script_name.py > saveit.txt
Because this scheme uses shell command lines to start Python programs, all the usual shell syntax applies. For instance, By this, we can route the printed output of a Python script to a file to save it.
I found a quick way for this:
log = open("log.txt", 'a')
def oprint(message):
print(message)
global log
log.write(message)
return()
code ...
log.close()
Whenever you want to print something just use oprint rather than print.
Note1: In case you want to put the function oprint in a module then import it, use:
import builtins
builtins.log = open("log.txt", 'a')
Note2: what you pass to oprint should be a one string (so if you were using a comma in your print to separate multiple strings, you may replace it with +)
We can simply pass the output of python inbuilt print function to a file after opening the file with the append option by using just two lines of code:
with open('filename.txt', 'a') as file:
print('\nThis printed data will store in a file', file=file)
Hope this may resolve the issue...
Note: this code works with python3 however, python2 is not being supported currently.
idx = 0
for wall in walls:
np.savetxt("C:/Users/vimal/OneDrive/Desktop/documents-export-2021-06-11/wall/wall_"+str(idx)+".csv",
wall, delimiter=",")
idx += 1
class Logger:
def __init__(self, application_log_file, init_text="Program started", print_with_time=True):
import sys
self.__output_num = 0
self.origin = sys.stdout
self.init_text = init_text
self.__init = False
self.print_with_time = print_with_time
self.log_file = application_log_file
self.data = ""
self.last_time = 0
sys.stdout = self
sys.stderr = self
def flush(self):
if self.data == "\n":
return
sys.stdout = self.origin
print(self.__create_log_text(self.data) if self.print_with_time else self.data)
with open(self.log_file, "a", encoding="utf-8") as log:
log.write(self.__create_log_text(self.data))
self.data = ""
sys.stdout = self
def __create_log_text(self, string: str):
if self.last_time == str(datetime.datetime.today())[:-7]:
return string
self.last_time = str(datetime.datetime.today())[:-7]
if not self.__init:
self.__init = True
return str(datetime.datetime.today())[:-7] + " | " + f"{self.init_text}\n"
return str(datetime.datetime.today())[:-7] + " | " + string
def write(self, data):
self.data += data

input result from one program file into another program in python

The first python program called first.py includes the following code:
print ('my name is viena')
How can I input the result from that first program, i.e., 'my name is viena' as input into my second program called second.py which includes the following code:
question = 'what\'s your name?'
answer = ?????HERE HOW TO INPUT THE RESULT FROM FIRST PROGRAM
print (answer)
my name is viena
Note: There should be two different python script files as I mentioned in the question.
If you can wrap the print statement in your first program inside a function (say print_name) , then you can so something like
import first
first.print_name()
to get the name.
For a completely general purpose solution that involves shelling out, take a look at the subprocess module.
How about change the first script as importable module:
# Changed the print function call with function.
def my_name():
return 'my name is viena'
if __name__ == '__main__':
print(my_name())
Another script can now import the first script using import statement, and use its functions.
import name_of_the_first_script
question = "what's your name?"
answer = name_of_the_first_script.my_name()

Good strategy to perform unit tests on program that prints to stdout?

I have a python program of about 500 lines that writes to stdout (using print statements). Now I'd like to make some changes and do refactoring of the program, but I want to make sure that in the process of doing so I keep getting the same output (given the same input, of course).
What would be a good strategy to do so, without rewriting the functions to return strings (allowing for easier testing) instead of the current print-ing?
I though of redirecting the initial output (before I start changing it) to a text file. How can I then easily and automatically check the output of the modified program with the textfile (without redirecting that output again to a temporary text file and comparing the files)?
Edit: This is the solution I settled on:
def test_something():
# using lambda because we might test function with parameters
f = lambda: thing_to_test
test_generic('expect_output.txt', f)
def test_generic(filename_expected, function_to_test):
#Run and write to tmp file
tmpfile = 'test-tmp.txt'
sys.stdout = open(tmpfile, 'w')
function_to_test()
sys.stdout = sys.__stdout__
#compare with expected output
expected = open(filename_expected).read()
result = open(tmpfile).read()
d = difflib.Differ()
diff = d.compare(expected.splitlines(), result.splitlines())
#print result (different lines only)
diff_lines_only = [line for line in diff if line[0] in "+-?"]
if not diff_lines_only:
print "Test succeeded (%s)\n" % filename_expected
os.remove(tmpfile)
else:
print "Test FAILED (%s):\n" % filename_expected
print '\n'.join(list(diff_lines))
Edit 2: Actually, I think the doctest solution which I provided as an answer below is much nicer.
You can obtain the string representing the output of your program redirecting sys.stdout.
To compare the outputs you can use the difflib module. In particular the Differ class does more or less what the diff command does:
>>> import difflib
>>> text = '''bar
... baz
... '''
>>> text2 = '''foo
... bar
... '''
>>> d = difflib.Differ()
>>> for line in d.compare(text.splitlines(), text2.splitlines()):
... print line
...
+ foo
bar
- baz
If I'm not mistaken unittest2's assertEqual already tries to show the difference of the strings, but I do not know at what level and if the output is simple enough.
Assuming you're running Bash, you could run diff -u orig-file <(python my-program.py). This will do a diff between the original file (which you've already written your original output to), and a named pipe that your program will write out to.
Here's a quick trivial example, using echo instead of an actual Python script:
$ diff -u <(echo $'foo\nbar\nbaz') <(echo $'foo\nbar\nquux')
--- /dev/fd/63 2012-11-08 15:07:09.000000000 -0500
+++ /dev/fd/62 2012-11-08 15:07:09.000000000 -0500
## -1,3 +1,3 ##
foo
bar
-baz
+quux
Interesting little example question - i took it to create a print/capture/diffcompare solution using pytest. Note that this example makes advanced use of pytest features but those are linked and fully documented and are useful also in many other situations. Effectively, the solution needs less than half the code of the current top solution and you may find it nice to be able to selectively run tests or some of the other other pytest features.
A solution using the doctest library, which I consider actually much nicer and self-contained as the test code and the expected output are now together in one file.
In a python script (actually, I included it in my main program, and is executed if I provide "test" as a first command line argument):
import doctest
doctest.testfile('test-program.txt', optionflags = doctest.NORMALIZE_WHITESPACE)
And the test file test-program.txt now goes along the lines of:
>>> import my_python_script
>>> whatever_I want_to_test_or_call_goes_here
and_here_I pasted_the_expected_output
This has the added benefit of having access to all doctest features (such as the -v switch for more verbose output). So I just do the following from the command line to get a full report:
C:\wherever> python my_python_script test -v

Python: how to input python-code part like \input in Tex?

I want to input code in Python like \input{Sources/file.tex}. How can I do it in Python?
[added]
Suppose I want to input data to: print("My data is here"+<input data here>).
Data
1, 3, 5, 5, 6
The built-in execfile function does what you ask, for example:
filename = "Sources/file.py"
execfile( filename )
This will execute the code from Sources/file.py almost as if that code were embedded in the current file, and is thus very similar to #include in C or \input in LaTeX.
Note that execfile also permits two optional arguments allowing you to specify the globals and locals dicts that the code should be executed with respect to, but in most cases this is not necessary. See pydoc execfile for details.
There are occasional legitimate reasons to want to use execfile. However, for the purpose of structuring large Python programs, it is conventional to separate your code into modules placed somewhere in the PYTHONPATH and to load them using the import statement rather than executing them with execfile. The advantages of import over execfile include:
Imported functions get qualified with the name of the module, e.g. module.myfunction instead of just myfunction.
Your code doesn't need to hard-code where in the filesystem the file is located.
You can't do that in Python. You can import objects from other modules.
otherfile.py:
def print_hello():
print "Hello World!"
main.py
import otherfile
otherfile.print_hello() # prints Hello World!
See the python tutorial
Say you have code in "my_file.py". Any line which is not in a method WILL get executed when you do:
import my_file
So for example if my_file.py has the following code in it:
print "hello"
Then in the interpreter you type:
import my_file
You will see "hello".
My question was clearly too broad, as the variety of replies hint -- none of them fully attack the question. The jchl targets the scenario where you get python-code to be executed. The THC4k addresses the situation where you want to use outside objects from modules. muckabout's reply is bad practice, as Xavier Ho mentioned, why on earth it uses import when it could use exec as well, the principle of least privileges to the dogs. One thing is still missing, probably because of the conflict between the term python-code in the title and the addition of data containing integers -- it is hard to claim that data is python-code but the code explains how to input data, evaluations and executable code.
#!/usr/bin/python
#
# Description: it works like the input -thing in Tex,
# you can fetch outside executable code, data or anything you like.
# Sorry I don't know precisely how input(things) works, maybe misusing terms
# or exaggerating.
#
# The reason why I wanted input -style thing is because I wanted to use more
# Python to write my lab-reports. Now, I don't need to mess data with
# executions and evalutions and data can be in clean files.
#TRIAL 1: Execution and Evaluation not from a file
executeMe="print('hello'); a = 'If you see me, it works'";
exec( executeMe )
print(a);
#TRIAL 2: printing file content
#
# and now with files
#
# $ cat IwillPrint007fromFile
# 007
f = open('./IwillPrint007fromFile', 'r');
msg = f.read()
print("If 007 == " + msg + " it works!");
# TRIAL 3: Evaluation from a file
#
# $cat IwillEvaluateSthing.py
# #!/usr/bin/python
# #
# # Description:
#
#
# evaluateMe = "If you see me again, you are breaking the rules of Sky."
f = open('./IwillEvaluateSthing.py', 'r');
exec(f.read());
print(evaluateMe);

Categories

Resources