Python Command line execution - python

I am trying to rename a set of pdf files in my desktop using a simple python script. I am somehow not very successful. My current code is :
import os,subprocess
path = "/Users/armed/Desktop/"
for file in os.listdir(path)
command = ['mv', '*.pdf' , 'test.pdf'] // mv Command to rename files to test.pdf
subprocess.call(command)
The output i get for this code is 1 and the files are not renamed. The same command works when executed in the terminal. I am using a Mac (if that helps in any way)

The same command works when executed in the terminal.
Except it's not the same command. The code is running:
'mv' '*.pdf' 'test.pdf'
but when you type it out it runs:
'mv' *.pdf 'test.pdf'
The difference is that the shell globs the * wildcard before executing mv. You can simulate what it does by using the glob module.

Python is not going to expand the shell wildcard in the string by default. You can also do this without a subprocess. But your code will lose all pdf files except the last one.
from glob import glob
import os
path = "/Users/armed/Desktop/"
os.chdir(path)
for filename in glob("*.pdf"):
os.rename(filename, "test.pdf")
But I'm sure that's not what you really want. You'll need a better destination name.

Related

Running Python code from Notepad++ doesn't generate .txt files

So currently I'm practicing Python and I have this line of code:
print(f"{someList}", file=open("generatedList.txt", "w"))
When I tried to run it on Notepad++ using a run command of python "$(FULL_CURRENT_PATH)", it doesn't generates the .txt file but in the Notepad++ folder. When I tried to run exactly the same code to the IDLE it generates the .txt file on the working folder.
Why is that? Should I change something to the run command? I prefer Notepad++ as a text editor.
Btw, I'm using Python 3.8.5
So I don't know if it is okay but I think I know now how to make it save on wherever directory you want I just experimented and tried it out.
from this code :
print(f"{flippedCoins}", file=open("generatedFlips.txt", "w"))
You'll just need to add the directory where would like to save it!
print(f"{flippedCoins}", file=open("C:\The\Directory\You\Want\to\Save\it\generatedFlips.txt", "w"))
You can use the __file__ variable to retrieve the location of the script, and use that to construct an absolute path for your output file:
import os.path
SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))
FILE_PATH = os.path.join(SCRIPT_DIR, "generatedList.txt")
...
with open(FILE_PATH, "w") as fh:
print(f"{someList}", file=fh)
If you prefer to work with local file paths, you could change the working directory to the one where you want to dump the file:
import os
os.chdir("c:/path/to/some/directory")
If you can't locate the output file when launching the script from and IDE and want to figure out what the script's working directory is, you can print it:
import os
print(os.getcwd())
You can always provide an absolute path to the file, wherever the script is executed from:
with open("c:/path/to/some/file.txt", "w") as fh:
print(f"{someList}", file=fh)

Code works in Visuall Studio Coe when i use debug but not when i run in terminal python

When i run in terminal i get the [Errno 2] No such file or directory error, but when i use debug mode it works.
the error occurs here,
list = open(filename, "r")
the code also works with IDLE
Your debugger is most likely running in a different location than your terminal. cd your terminal to where the file is located, or try using the absolute path instead of a relative one.
If you add these few lines in your code and run it using your IDE or Terminal, you'll notice the difference:
import os
curdir = os.getcwd()
print('My current directory is {}'.format(curdir))
fullpath_to_filename = os.path.join(curdir, filename)
print('When I run `open(filename)`, python sees: {}'.format(fullpath_to_filename))
print('This filepath is {}valid'.format('' if os.path.exists(fullpath_to_filename) else 'not '))
You'll likely experience something similar to below:
# on IDE:
My current directory is c:\Users\me\Projects\
When I run `open(filename)`, python sees: c:\Users\me\Projects\test.txt
This filepath is valid
# on Terminal:
My current directory is c:\Programs\Python38\
When I run `open(filename)`, python sees: c:\Programs\Python38\test.txt
This filepath is not valid
Solution: use absolute path for your filename, or os.chdir(...) to the correct parent path before location filename. I would recommend the former to avoid managing directories.

Run all Python scripts in a folder - from Python

How can I write a Python program that runs all Python scripts in the current folder? The program should run in Linux, Windows and any other OS in which python is installed.
Here is what I tried:
import glob, importlib
for file in glob.iglob("*.py"):
importlib.import_module(file)
This returns an error: ModuleNotFoundError: No module named 'agents.py'; 'agents' is not a package
(here agents.py is one of the files in the folder; it is indeed not a package and not intended to be a package - it is just a script).
If I change the last line to:
importlib.import_module(file.replace(".py",""))
then I get no error, but also the scripts do not run.
Another attempt:
import glob, os
for file in glob.iglob("*.py"):
os.system(file)
This does not work on Windows - it tries to open each file in Notepad.
You need to specify that you are running the script through the command line. To do this you need to add python3 plus the name of the file that you are running. The following code should work
import os
import glob
for file in glob.iglob("*.py"):
os.system("python3 " + file)
If you are using a version other than python3, just change the argument from python3 to python
Maybe you can make use of the subprocess module; this question shows a few options.
Your code could look like this:
import os
import subprocess
base_path = os.getcwd()
print('base_path', base_path)
# TODO: this might need to be 'python3' in some cases
python_executable = 'python'
print('python_executable', python_executable)
py_file_list = []
for dir_path, _, file_name_list in os.walk(base_path):
for file_name in file_name_list:
if file_name.endswith('.csv'):
# add full path, not just file_name
py_file_list.append(
os.path.join(dir_path, file_name))
print('PY files that were found:')
for i, file_path in enumerate(py_file_list):
print(' {:3d} {}'.format(i, file_path))
# call script
subprocess.run([python_executable, file_path])
Does that work for you?
Note that the docs for os.system() even suggest using subprocess instead:
The subprocess module provides more powerful facilities for spawning new processes and retrieving their results; using that module is preferable to using this function.
If you have control over the content of the scripts, perhaps you might consider using a plugin technique, this would bring the problem more into the Python domain and thus makes it less platform dependent. Take a look at pyPlugin as an example.
This way you could run each "plugin" from within the original process, or using the Python::multiprocessing library you could still seamlessly use sub-processes.

running bash script from python file

I have a bash script which changes the path on my command line,
This one,
#!/usr/bin/env python
cd /mnt/vvc/username/deployment/
I have a python script which i wish to run after the path changes to the desired path,
The script,
#!/usr/bin/env python
import subprocess
import os
subprocess.call(['/home/username/new_file.sh'])
for folder in os.listdir(''):
print ('deploy_predict'+' '+folder)
I get this
File "/home/username/new_file.sh", line 2
cd /mnt/vvc/username/deployment/
^
SyntaxError: invalid syntax
Any suggestions on how can i fix this?thanks in advance
You need to explicitly tell subprocess which shell to run the sh file with. Probably one of the following:
subprocess.call(['sh', '/home/username/new_file.sh'])
subprocess.call(['bash', '/home/username/new_file.sh'])
However, this will not change the python program's working directory as the command is run in a separate context.
You want to do this to change the python program's working directory as it runs:
os.chdir('/mnt/vvc/username/deployment/')
But that's not really great practice. Probably better to just pass the path into os.listdir, and not change working directories:
os.listdir('/mnt/vvc/username/deployment/')

open(file) from anywhere

Working on OS X Lion, I'm trying to open a file in my python-program from anywhere in the terminal. I have set the following function in my .bash_profile:
function testprogram() {python ~/.folder/.testprogram.py}
This way I can(in the terminal) run my testprogram from a different directory than my ~/.
Now, if I'm in my home directory, and run the program, the following would work
infile = open("folder2/test.txt", "r+")
However, if I'm in a different directory from my home-folder and write "testprogram" in the terminal, the program starts but is unable to find the file test.txt.
Is there any way to always have python open the file from the same location unaffected of where i run the program from?
If you want to make it multiplatform I would recommend
import os
open(os.path.join(os.path.expanduser('~'),'rest/of/path/to.file'))
Use the tilde to represent the home folder, just as you would in the .bash_profile, and use os.path.expanduser.
import os
infile = open(os.path.expanduser("~/folder2/test.txt"), "r+")
This is no different than referring to a file via anything else besides Python, you need to use an absolute path rather than a relative one.
If you'd like to refer to files relative to the location of the script, you can also use the __file__ attribute in your module to get the location of the currently running module.
Also, rather than using a shell function, just give your script a shebang line (#!/usr/bin/env python), chmod +x it, and put it someplace on your PATH.
You could simply run the function in a subshell so you can cd home before running it:
function testprogram() { (
cd && python .folder/.testprogram.py
) }
In python sys.argv[0] will be set to the path of the script (if known). You can use this plus the functions in os.path to access files relative to the directory containing the script. For example
import sys, os.path
script_path = sys.argv[0]
script_dir = os.path.dirname(script_path)
def script_relative(filename):
return os.path.join(script_dir, filename)
infile = open(script_relative("folder2/test.txt"), "r+")
David Robinson points out that sys.argv[0] may not be a full pathname. Instead of using sys.argv[0] you can use __file__ if this is the case.
Use either full path like
/path/to/my/folder2/test.txt
or abbreviated one
~/folder2/test.txt

Categories

Resources