Adding a variable into a string - python

I added this line of Code:
tweet_string = 'Starting activity for insta'
os.system("python3 tweet.py tweet_string")
As you can see the tweet script uses the first argument as tweet context. Unfortunately I don't know how to use the variable correct... Can you assist me here?

Of course, don't pass your variable name in the literal string...
Just adding out of quotes doesn't cut it because of the spaces. You have to protect with quotes.
it should be:
os.system('python3 tweet.py "{}"'.format(tweet_string))
(better, but if there's a quote in tweet_string you'll have an issue again)
Anyway: don't use os.system it's deprecated. This is better and handles quoting automatically:
import subprocess
subprocess.check_call(["python3","tweet.py",tweet_string])
(Python 3.5 added a unified subprocess.run method which can check return code or not, redirect output in a variable or not, which is the recommended approach to run a subprocess if you don't need to be compatible with previous versions)
Of course, always ask yourself the question when running a python subprocess inside a python module: wouldn't it be easier to import the module and call a function?

In general
('python3 tweet.py "' + tweet_string + '"')
If you're using python 3.6
f('python3 tweet.py "{tweet_string}"')

Related

For what uses do we need `sys` module in python?

I'm a bit experienced without other languages but, novice with Python. I have come across made codes in jupyter notebooks where sys is imported.
I can't see the further use of the sys module in the code. Can someone help me to understand what is the purpose of importing sys?
I do know about the module and it's uses though but can't find a concise reason of why is it used in many code blocks without any further use.
If nothing declared within sys is actually used, then there's no benefit to importing it. There's not a significant amount of cost either.
Sys module is a rather useful module as it allows you to work with your System and those things. Eg:
You can access any command line arguments using sys.argv[1:]
You can see the Path to files.
Version of your Python Interpreter using sys.version
Exit the running code with sys.exit
Mostly you will use it for accessing the Command Line arguments.
I'm a new pythonista bro, I learned to import it whenever I want to exit the program with a nice exit text in red
import sys
name = input("What's your name? ")
if name == "Vedant":
print(f"Hello There {name}.")
else:
sys.exit(f"You're not {name}!")
The sys includes "functions + variable " to help you control and change the python environment #runtime.
Some examples of this control includes:
1- using other sources data as input via using:
sys.stdin
2- using data in the other resources via using:
sys.stdout
3- writing errors when an exception happens, automatically in :
sys.stderr
4- exit from the program by printing a message like:
sys.exit("Finish with the calculations.")
5- The built-in variable to list the directories which the interpreter will looking for functions in them:
sys.pasth
6- Use a function to realize the number of bytes in anonymous datatype via:
sys.getsizeof(1)
sys.getsizeof(3.8)

Python - Execute program with parameters with file output

I am trying to use Python to run an executable (Windows 7) with parameters. I have been able to make the program run, but the amount of parameters I can use that will prove the Python script worked with parameters is limited. The best one is formatted like so:
-debugoutput debug.txt
I have tested this using a windows shortcut with an edited target and it works, it creates a debug output in the program directory.
Here is the code I am using:
import subprocess
args = [r"C:\Users\MyName\LevelEditor\LevelEditor.exe", "-debugoutput debug.txt"]
subprocess.call(args)
This does run the program, but the debug output is not created. I have tried putting an "r" in front of the parameter but this made no difference. I assume it is a simple formatting error but I can't find any examples to learn from that are doing the same thing.
UPDATE:
Thanks for the answers everyone, all the same, simple formatting error indeed.
In-code definition results in invocation of shell command line:
C:\Users\MyName\LevelEditor\LevelEditor.exe "-debugoutput debug.txt"
As you can see, by merging -debugoutput debug.txt to single list element, you explicitly stated that space between them shouldn't be parsed as command line argument separator.
To achieve expected behavior put file name string as separate element to argument list.
[r"C:\Users\MyName\LevelEditor\LevelEditor.exe", "-debugoutput", "debug.txt"]
As far as I know you need to split the arguments by the space, so your args would look like:
args = [r"C:\Users\MyName\LevelEditor\LevelEditor.exe", "-debugoutput", "debug.txt"]
Does that work?
I do not know if it works, but
import subprocess
args = [r"C:\Users\MyName\LevelEditor\LevelEditor.exe", "-debugoutput", "debug.txt"]
subprocess.run(args)
Following the docs

How to use subprocess to fire and forget in python 2.7

I need to execute a command line in the bakground in python 2.7. I need to fire and forget.
Here is the command:
cmd = "/usr/local/bin/fab -H %s aws_bootstrap initial_chef_run:%s,%s,%s -w" % (...)
How do I use the subproccess module?
e.g. is it
subprocess.call([cmd])
or
subprocess.call(["/usr/local/bin/fab", "-H %s aws_bootstrap initial_chef_run:%s,%s,%s -w"])
I dont get how to use the list. Or is every element of the list what would be a white space.
Thanks
each thing that would be seperated by whitespace is a seperate entity of the list
subprocess.call is blocking however
subprocess.popen is non-blocking
cmd = ["/usr/local/bin/fab", "-H",var1,"aws_bootstrap initial_chef_run:%s,%s,%s"%(var2,var3,var4), "-w"]
subprocess.popen(cmd) # dopnt wait just keep going
#or
subprocess.call(cmd) # wait until the command returns
you may however alternatively pass the command as one big string
cmd = "/usr/local/bin/fab -H %s aws_bootstrap initial_chef_run:%s,%s,%s -w" % (...)
subprocess.call(cmd)
in general this method(passing a single string) is frowned upon for some reason that has never been explained sufficiently to me
I used this recently to fire a perl script, like so:
var = "C:\Users\user\Desktop"
retcode = subprocess.call(["perl", '.\hgncDL.pl',var])
Working code
Define hParam and runParams in following code and you're good to go:
hParam = 'hParam'
runParams = (a,b,c)
args = ('/usr/local/bin/fab', '-H', hParam, 'aws_bootstrap', 'initial_chef_run:%s,%s,%s' % runParams, '-w')
subprocess.Popen(args)
Details
How do I use <any python module> module?
https://docs.python.org is a good starting point.
In particular, docs for subprocess module available here.
I can't provide direct links for each case later in this answer due to restriction imposed by low reputation. Each time I will be referring to 'docs', look for a section in docs on the module.
I need to execute a command line in the background in python 2.7. I need to fire and forget
Consider subprocess.Popen(args). Note capital 'P'.
See docs for more details.
subprocess.call(args) works in similar way, but it would block until the command completes. As stated in docs:
Run the command described by args. Wait for command to complete, then return the returncode attribute.
How to use the sequence form of args parameter?
This is covered in "Frequently used arguments" section of docs:
args is required for all calls and should be a string, or a sequence of program arguments. Providing a sequence of arguments is generally preferred, as it allows the module to take care of any required escaping and quoting of arguments (e.g. to permit spaces in file names).
Also, passing an args in a string form has its limitation:
If passing a single string, either shell must be True or else the string must simply name the program to be executed without specifying any arguments.
Despite mentioned limitation, subprocess.Popen('cmd.exe /?') works for me. Win7, Python 2.7.8 64bit.
HTH, cheers.

Python indentation when adding looping statements to existing code

In Python, what do you do when you write 100 lines of code and forget to add a bunch of loop statements somewhere?
I mean, if you add a while statement somewhere, you've to now indent all the lines below it. It's not like you can just put braces and be done with it. Go to every single line and add tabs/spaces. What if you were adding nested loops/if/then statements to existing code?
Am I missing some shortcut?
I think every serious editor or IDE supports the option to select multiple lines and press tab to indent or Shift-Tab to unindent all that lines.
in IDLE, the standard python IDE, select the code, go on 'format' and you can chooose indent region, dedent region and so on
You have to use an editor command to re-indent.
Keep in mind: Beautiful is better than ugly.
... and the rest of "The Zen of Python, by Tim Peters"
# python -c "import this"
edit: rewrote to accomodate fileinput's "eccentricities"*
def indent_code(filename, startline, endline):
from fileinput import input
from itertools import izip, count
all_remaining = count()
def print_lines(lines, prefix='', range=all_remaining):
for _, line in izip(range, lines):
print prefix + line,
lines = input(filename, inplace=1)
print_lines(lines, range=xrange(1, startline)) # 1-based line numbers
print_lines(lines, ' ', xrange(startline, endline + 1)) # inclusive
print_lines(lines)
def main():
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('filename')
parser.add_argument('startline', type=int)
parser.add_argument('endline', type=int)
ns = parser.parse_args()
indent_code(ns.filename, ns.startline, ns.endline)
if __name__ == '__main__':
main()
Well, either that or >}.
*: I originally wrote this using a nice, concise combination of stdout.writelines and some generator expressions. Unfortunately, that code didn't work. The iterator returned by fileinput.input() doesn't actually open a file until you call its next method. It works its sketchy output-redirection magic on sys.stdout at the same time. This means that if you call sys.stdout.writelines and pass it the fileinput.input iterator, your call, and the output, goes to the original standard out rather than the one remapped by fileinput to the file "currently" being processed. So you end up with the lines that are supposed to replace the contents of the file being instead just printed to the terminal.
It's possible to work around this issue by calling next on the fileinput iterator before calling stdout.writelines, but this causes other problems: reaching the end of the input file causes its handle to be closed from the iterator's next method when called within file.writelines. Under Python 2.6, this segfaults because there's no check made (in the C code which implements writelines) to see if the file is still open, and the file handle non-zero, after getting the next value from the iterator. I think under 2.7 it just throws an exception, so this strategy might work there.
The above code actually does test correctly.
textmate (and maybe e?): select then apple-]
bbedit:
also select then apple-]
emacs:
select then M-x 'indent-region'
bpython: don't know, autoindenting is
so easy in bpython, you'd have to
work to break it
xcode: don't do python in xcode
that's generally all I need to know. also yeah it's easy to slap a brace above or below a poorly indented block, but you know it's just going to confuse the shit out of you a week later when you haven't been staring at it for like a day. srsly u guys.

How to write a Python 2.6+ script that gracefully fails with older Python?

I'm using the new print from Python 3.x and I observed that the following code does not compile due to the end=' '.
from __future__ import print_function
import sys
if sys.hexversion < 0x02060000:
raise Exception("py too old")
...
print("x",end=" ") # fails to compile with py24
How can I continue using the new syntax but make the script fails nicely? Is it mandatory to call another script and use only safe syntax in this one?
The easy method for Python 2.6 is just to add a line like:
b'You need Python 2.6 or later.'
at the start of the file. This exploits the fact that byte literals were introduced in 2.6 and so any earlier versions will raise a SyntaxError with whatever message you write given as the stack trace.
There are some suggestions in this question here, but it looks like it is not easily possible. You'll have to create a wrapper script.
One way is to write your module using python 2.x print statement, then when you want to port it into python 3, you use 2to3 script. I think there are scripts for 3to2 conversion as well, although they seems to be less mature than 2to3.
Either way, in biggers scripts, you should always separate domain logic and input/output; that way, all the print statements/functions are bunched up together in a single file. For logging, you should use the logging module.

Categories