Python does not allow additional comment with env python - python

I have a commenting line problem in python. I created a ages.py with vim and here is my script
#!/usr/bin/env python
ages={"dad":42, "mom":35, "lisa":7}
for item in ages:
print item
When I add a comment above the !/usr/bin, like
# this is a python script
#!/usr/bin/env python
ages={"dad":42, "mom":35, "lisa":7}
for item in ages:
print item
and after I go back to directory, which includes the same script, and run the script with writing to terminal ages.py but I get this error
$ ./ages.py
./ages.py: line 3: mom:35,: command not found
./ages.py: line 5: syntax error near unexpected token `print'
./ages.py: line 5: 'print item'
I know that when I remove the #!/usr/bin/env python line # works perfectly for commenting. However, I would like to add this line to run the script only writing its name to prompt. Otherwise, I have to write python ages.py every single time to run it, which I see as a burden.
1st Q: How can I comment to .py script with still having the '#!/usr/bin/env python' line
P.S: I've already tried """ ''' before and after comment line, it does not work either.
2nd Q: Is there a way to run a .py script in python environment? For instance, I can run .m file in octave simply writing its name to command line. But I could not figure out if there is a same way in python?
P.S: I know the questions are so easy and deserve -1, however, for new python users, the all answers will provide great information, thanks for all of them. It is so subtle solution but without it, I've constantly got the errors

That first line is a very important one. It's called the Hashbang and sometimes known as the shebang. It tells the operating system what interpreter to use to execute the script. When the shebang is used, it has to be the first line. Other variations include
#!/bin/sh
#!/usr/bin/perl/
#!/usr/bin/python
These are for system default sh, perl and python. Any other comments in your code has to be after this line.

the line containing #!/usr/bin/env python must be first, you can add your comments below;
yes, you can do it like this: exec(open('yourscript.py').read()) - however, results might sometimes differ from your expectations.

Related

Linux bash executables behave differently depending on whether I am activating from the command line or with os.system('')

I've been attempting to execute a certain CLI from within python and store the output for later use within the same script. I suspect this question has a simple answer, but if one wishes to go through the entire pipeline, here is the tool in question.
wget http://rna.urmc.rochester.edu/Releases/current/RNAstructureForLinux.tgz
tar xvf as usual, go inside the resulting directory and execute 'make all', the executables I use in the bash script are within the 'exe' directory.
I attempted to execute the commands with os.system(), but with little luck. The CLI I am using; however, seems to be running. The function which I have set to execute the os.system() commands contains the following block.
txt = open('home/spectre/tools/RNAstructure/exe/RNAStructure_nucleic_acid.txt',"w")
txt.write('AAGGCTGTCCAGGCGCAATGTGGTGGCTGCTTCTCTGGGGAGTCCTCCAGGCTTGCCCAACCCGGGGCTCCGTCCTCTTGGCCCAAGAGCTACCCCAGCAGCTGACATCCCCCGGGTACCCAGAGCCGTATGGCAAAGGCCAAGAGAGCAGCACGGACATCAAGGCTCCAGAGGGCTTTGCTGTGAGGCTCGTCTTCCAGGACTTCGACCTGGAGCCGTCCCAGGACTGTGCAGGGGACTCTGTCACAGTGAGCTGGGGATGGGGGGGGTCCCGCCAGGACTGTGGCCAGGGAGATTCCCGGGGTTGTGGGAAGTGGCGGTGCCCTGAATCCCCCATCTGGAGGAGGGATGAAT')
os.system(' cd ~/tools/RNAstructure/exe ; ./python_RNA_structure.sh')
nucleotides, structure, MFE =
RNAStructure_from_file('home/spectre/tools/RNAstructure/exe/RNAStructure_bracket_output.txt')
The executable *.sh file contains this.
#!/bin/bash
cd ~/tools/RNAstructure/exe
./Fold RNAStructure_nucleic_acid.txt RNAStructure_nucleic_acid_output.txt
./ct2dot RNAStructure_nucleic_acid_output.txt -1 RNAStructure_bracket_output.txt
If I execute the bash script from the command line the output should look a little like this
Initializing nucleic acids...
Using auto-detected DATAPATH: "../data_tables" (set DATAPATH to avoid this warning).
done.
98% \[==================================================\] \\ done.
Writing output ct file...done.
Single strand folding complete.
Converting CT file...
Using auto-detected DATAPATH: "../data_tables" (set DATAPATH to avoid this warning).
CT file conversion complete.
If I execute the bash script form the python file.
Initializing nucleic acids...
Using auto-detected DATAPATH: "../data_tables" (set DATAPATH to avoid this warning).
Error reading sequence. The file did not contain any nucleotides.
Single strand folding complete with errors.
Converting CT file...
Using auto-detected DATAPATH: "../data_tables" (set DATAPATH to avoid this warning).
CT file conversion complete.
It looks an awful lot like my CLI can find the files it needs inside the terminal, but not outside of it. I haven't experimented with any parameters like trying absolute paths, but I understood by using os.system() I could execute a bash script, but it is not clear to me why this is changing how that script behaves.
What I've done to resolve the problem:
reopening the file seems to resolve the problem, but I am still working out why.
The problem seems to resolve when I reopen the file within the python script like so:
txt = open('home/spectre/tools/RNAstructure/exe/RNAStructure_nucleic_acid.txt',"w")
txt.write('AAGGCTGTCCAGGCGCAATGTGGTGGCTGCTTCTCTGGGGAGTCCTCCAGGCTTGCCCAACCCGGGGCTCCGTCCTCTTGGCCCAAGAGCTACCCCAGCAGCTGACATCCCCCGGGTACCCAGAGCCGTATGGCAAAGGCCAAGAGAGCAGCACGGACATCAAGGCTCCAGAGGGCTTTGCTGTGAGGCTCGTCTTCCAGGACTTCGACCTGGAGCCGTCCCAGGACTGTGCAGGGGACTCTGTCACAGTGAGCTGGGGATGGGGGGGGTCCCGCCAGGACTGTGGCCAGGGAGATTCCCGGGGTTGTGGGAAGTGGCGGTGCCCTGAATCCCCCATCTGGAGGAGGGATGAAT')
txt = open('home/spectre/tools/RNAstructure/exe/RNAStructure_nucleic_acid.txt')
os.system(' cd ~/tools/RNAstructure/exe ; ./python_RNA_structure.sh')
nucleotides, structure, MFE =
RNAStructure_from_file('home/spectre/tools/RNAstructure/exe/RNAStructure_bracket_output.txt')
I am not sure why this resolves the problem, I found this solution serendipitously. I'll update the answer when I figure out why, unless someone wants to beat me to it. It's magic to me for now.
It seems that after opening the file, RNAStructure_nucleic_acid.txt, and assigning it to the txt variable for writing, I need to reopen it after writing is complete. Otherwise the file is blank when I try printing it's output within the program, but after the program finishes executing, the file contains the correct text.

Execute Knime with multiple arguments in Python (subprocess.run)

Hello all,
i'm looking for a way to execute a KNIME workflow in Python in batch mode (without opening the GUI of KNIME, https://www.knime.com/faq#q12)
After hours of trying I am asking you whether you can help me in this case:
When I run the python file, it opens the Knime exe, after some seconds the knime GUI is also opened. Unfortunately, the exe is not excuting the workflow (for testing the workflow should read an csv file and save it in another file destination)
This is actual code in python 3.7:
import subprocess
subprocess.run(["C:/Program Files/KNIME/knime.exe","-consoleLog","-nosplash","-noexit","-nosave","-reset","-application org.knime.product.KNIME_BATCH_APPLICATION","-workflowDir= C:/Users/jssch/knime-workspace/testexecute"]
When i paste the following code in command line the code is working and is executed correctly (it just hands over the arguments and does not open the knime GUI):
C:\Program Files\KNIME\knime.exe" -consoleLog -noexit -nosplash -nosave -reset -application org.knime.product.KNIME_BATCH_APPLICATION -workflowDir="C:\Users\jssch\knime-workspace\testexecute"
Thanks for your help in advance!
I think you made a mistake with the -application part, they should be in different Strings. Also the -workflowDir= C:/... seems to have an extra space too.
The problematic part:
"-application org.knime.product.KNIME_BATCH_APPLICATION"
it should be:
"-application", "org.knime.product.KNIME_BATCH_APPLICATION"
Probably you do not want the -noexit argument either.
All together:
import subprocess
subprocess.run(["C:/Program Files/KNIME/knime.exe", "-consoleLog", "-nosplash", "-nosave", "-reset", "-application", "org.knime.product.KNIME_BATCH_APPLICATION", "-workflowDir=C:/Users/jssch/knime-workspace/testexecute"]
(I usually prefer the paths without spaces, strange characters, I would use a KNIME installation from a different path, though this is fine too.)

Determine the window name/number in iTerm2

I am using iTerm2 on MacOS (Sierra). I have multiple instances of iterm2 running, each has a title that are prefixed with a number which increments with each running window.
I would like to run a shell command to return this number on the command line, does any one know how to get this information?
I am looking for something like:
$ iterm_get_number()
2
I was able to get the names using applescript, the following script dumps a list of the open iTerm windows. Since I am interested in using these names in a python script I included a small snippet for doing this as well.
get_window_names.applescript
on run
set returnNames to {}
tell application "iTerm"
repeat with theWindow in windows
tell theWindow
set end of returnNames to get name
end tell
end repeat
end tell
return returnNames
end run
python for extracting information from above script
out = subprocess.check_output(['osascript', 'get_window_names.applescript'])
print [x.strip() for x in out.split(',')]

Capture dynamic command prompt output in text file [duplicate]

This question already has answers here:
how to direct output into a txt file in python in windows
(6 answers)
Closed 6 years ago.
I am running a python script which checks for the modifications of files in a folder. I want that output to be printed in a file. The problem is that the output is DYNAMIC , the cmd is always open and when a file is modified, I will have an information right-ahead about that in the cmd window. All the solutions which I found were matching the situations were I just run a command and I finish with that.
I tryed with:
python script.py > d:\output.txt but the output.txt file is empty
An example of the command prompt windows, after I run the command python script.py and I touch the 2 files, the command prompt will look like this. I want to capture that output.
Solution: In the python script which I use, add to the logging.basicConfig function, one more argument : filename='d:\test.log'
The issue is output buffering. If you wait long enough, you'll eventually see data show up in the file in "blocks". There are a few ways around it, for example:
Run python with the -u (unbuffered) flag
Add a sys.stdout.flush() after all print statements (which can be simplified by replacing stdout with a custom class to do it for you; see the linked question for more)
Add flush=True option to print statements if your version of Python supports it
If appropriate, use the logging module instead of print statements.
python test.py>test.txt
It's working for me in windows cmd prompt
As I see it the simplest would be to add the file handling (the writing to output.txt ) inside your script. Thus, when it is time to print the information you need to have (as your example shows when you touch two files you print two lines), you can open the file, write the specific line and close it after it is done (then you can see the updated output.txt).
Get the file path for the output.txt as a command line argument like
python script.py --o 'd:\output.txt'
for example.

Passing a multi-line string as an argument to a script in Windows

I have a simple python script like so:
import sys
lines = sys.argv[1]
for line in lines.splitlines():
print line
I want to call it from the command line (or a .bat file) but the first argument may (and probably will) be a string with multiple lines in it. How does one do this?
Of course, this works:
import sys
lines = """This is a string
It has multiple lines
there are three total"""
for line in lines.splitlines():
print line
But I need to be able to process an argument line-by-line.
EDIT: This is probably more of a Windows command-line problem than a Python problem.
EDIT 2: Thanks for all of the good suggestions. It doesn't look like it's possible. I can't use another shell because I'm actually trying to invoke the script from another program which seems to use the Windows command-line behind the scenes.
I know this thread is pretty old, but I came across it while trying to solve a similar problem, and others might as well, so let me show you how I solved it.
This works at least on Windows XP Pro, with Zack's code in a file called
"C:\Scratch\test.py":
C:\Scratch>test.py "This is a string"^
More?
More? "It has multiple lines"^
More?
More? "There are three total"
This is a string
It has multiple lines
There are three total
C:\Scratch>
This is a little more readable than Romulo's solution above.
Just enclose the argument in quotes:
$ python args.py "This is a string
> It has multiple lines
> there are three total"
This is a string
It has multiple lines
there are three total
The following might work:
C:\> python something.py "This is a string^
More?
More? It has multiple lines^
More?
More? There are three total"
This is the only thing which worked for me:
C:\> python a.py This" "is" "a" "string^
More?
More? It" "has" "multiple" "lines^
More?
More? There" "are" "three" "total
For me Johannes' solution invokes the python interpreter at the end of the first line, so I don't have the chance to pass additional lines.
But you said you are calling the python script from another process, not from the command line. Then why don't you use dbr' solution? This worked for me as a Ruby script:
puts `python a.py "This is a string\nIt has multiple lines\nThere are three total"`
And in what language are you writing the program which calls the python script? The issue you have is with argument passing, not with the windows shell, not with Python...
Finally, as mattkemp said, I also suggest you use the standard input to read your multi-line argument, avoiding command line magic.
Not sure about the Windows command-line, but would the following work?
> python myscript.py "This is a string\nIt has multiple lines\there are three total"
..or..
> python myscript.py "This is a string\
It has [...]\
there are [...]"
If not, I would suggest installing Cygwin and using a sane shell!
Have you tried setting you multiline text as a variable and then passing the expansion of that into your script. For example:
set Text="This is a string
It has multiple lines
there are three total"
python args.py %Text%
Alternatively, instead of reading an argument you could read from standard in.
import sys
for line in iter(sys.stdin.readline, ''):
print line
On Linux you would pipe the multiline text to the standard input of args.py.
$ <command-that-produces-text> | python args.py

Categories

Resources