I am trying to do some scripting with IPython, but I am finding that it behaves very differently in a script to when I run an interactive shell.
For example, I can run the following interactively:
In [1]: %profile
default
In [2]: ls /
bin/ cdrom/ etc/ initrd.img# lib/ lib64/ media/ opt/ root/ sbin/ sys/ usr/ vmlinuz#
boot/ dev/ home/ initrd.img.old# lib32/ lost+found/ mnt/ proc/ run/ srv/ tmp/ var/ vmlinuz.old#
In [3]: mkdir tmpdir
In [4]: cd tmpdir
/home/alex/tmp/tmpdir
No problem.
However, none of these commands works when I run them in a script:
#!/usr/bin/ipython3
%profile
ls /
mkdir tmpdir
cd tmdir
I get an error:
$ ./tmp.py
File "/home/alex/tmp/tmp.ipython", line 3
%profile
^
SyntaxError: invalid syntax
I have tried running this by:
calling the file directly as above,
calling it explicitly with ipython: `ipython3 tmp.py'
passing the -i or --profile=sh arguments to ipython when calling it with ipython
changing the file extension to .ipython and .ipy
My question:
Why is it behaving differently in a script to the shell? How can I get IPython to run these commands in a script?
They are working due to IPython magic but they are shell commands and do not work in Python. To get them consider the subprocess library. Where you would have spaces in a shell command instead have comma-separated values in the list.
import subprocess
subprocess.check_call(['ls'])
subprocess.check_call(['ls', '-a'])
Related
I'm trying to use pytest with a simple example, saved as "test_lesson1.py" with directory structure as shown below.
import pytest
TOL = 2e-2
def squared(x):
return x**2
def test_squared():
x = 4
expected = 16
computed = squared(x)
msg = "fail"
np.testing.assert_allclose(expected, computed, rtol=TOL, err_msg=msg)
Example directory structure:
proj
|--tests
|--|--test_lesson1.py
On Windows but using Git Bash as a bash terminal, how can I run pytest? Here is what I am entering the terminal:
alias py='C:/Users/name/anaconda3/envs/myenv/python.exe'
. C:/Users/name/anaconda3/etc/profile.d/conda.sh
conda activate myenv
cd tests/
py -c "pytest test_lesson1.py"
which returns
File "<string>", line 1
pytest test_lesson1.py
^
SyntaxError: invalid syntax
(myenv)
I can confirm that python works with py -c "print('hello world')", which prints as expected.
pytest is a command that will execute all tests in all files whose names follow the form test_*.py or \*_test.py in the current directory and its subdirectories, therefore you don't need python to invoke it.
Just run
pytest test_lesson1.py
On the other hand, print is a python function and you need python to invoke it.
I got a Node.js CLI program called meyda installed (Mac OS 10.14) using:
sudo npm install --global meyda
From the Terminal I can call the program and it works as expected; like:
meyda --bs=256 --o=apagodis2.csv DczN6842.wav rms
Now, I want to call it from inside a python script (using Spyder) at the same location and tried this – but getting error:
import os
os.system ('/usr/local/bin/meyda --bs=256 --o=apagodis4.csv samples_training/DczN6842.wav rms')
>>> env: node: No such file or directory
I can issue more "traditional" shell commands like this from the same Python script and it works:
os.system ('cp samples_training/DczN6842.wav copy.wav')
Also tried subprocess call with same result. I confirmed the executable is at /usr/local/bin/
To make sure I also removed all file arguments calling the program using only the help flag but same, error.
os.system ('/usr/local/bin/meyda -h')
>>> env: node: No such file or directory
Why is the command not found from inside Python but sucessfully in the macOS Terminal?
I don't really know how to ask this question but I can describe what I want to achieve. I would update any edits that would be suggested.
I have a python module that makes use of some command line arguments. Using the module requires some initial setup outside of the python interpreter. The python file that does the setup runs fine, but the problem is that I have to dig through the python installation to find where that file is located i.e. I have to do python full-path-to-setup-script.py -a argA -b argB etc.I would like to call the setup script like this
some-setup-command -a argA -b argB etc.
I want to achieve something like
workon environmnent_name as in the virtualenv module or
pipenv install as in the pipenv module.
I know both of the above commands call a script of some kind (whether bash or python). I've tried digging through the source codes of virtualenv and pipenv without any success.
I would really appreciate if someone could point me to any necessary resource for coding such programs.
If full-path-to-setup-script.py is executable and has a proper shebang line
#! /usr/bin/env python
then you can
ln -s full-path-to-setup-script.py ~/bin/some-command
considering ~/bin exists and is in your PATH,
and you'll be able to invoke
some-command -a argA -b argB
It's a bit difficult to understand what you're looking for, but python -m is my best guess.
For example, to make a new Jupyter kernel, we call
python -m ipykernel arg --option --option
Where arg is the CLI argument and option is a CLI option, and ipykernel is the module receiving the args and options.
Commands that are callable from the command prompt are located in one of the directories in your system's PATH variable. If you are on Windows, you see the locations via:
echo %PATH%
Or if you want a nicer readout:
powershell -c "$env:path -split(';')"
One solution is to create a folder, add it to your system's PATH, and then create a callable file that you can run. In this example we will create a folder in your user profile, add it to the path, then create a callable file in that folder.
mkdir %USERPROFILE%\path
set PATH=%PATH%%USERPROFILE%\path;
setx PATH %PATH%
In the folder %USERPROFILE%\path, we create a batch file with following content:
# file name:
# some-command.bat
#
python C:\full\path\to\setup-script.py %*
Now you should be able to call
some-command -a argA -b argB
And the batch file will call python with python script and pass the arguments you added.
Looking at the above answers, I see no one has mentioned this:
You can of course compile the python file and give executable permissions with
chmod +x filename.py
and then run it as
./filename.py -a argA -b argB ...
Moreover, you can also remove the extention .py (since it is an executable now) and then run it only as
./filename -a argA -b argB ...
I am trying to pipe output from a command written in the terminal to a Python script.
For example:
ls | ./foo.py
I wrote a Python script to do the same:
#foo.py
import fileinput
with fileinput.input() as f_input :
for line in f_input :
print(line,end='')
But this does not seem to work,
when I run the following command:
$ ls | sudo ./foo.py
I get an error that says:
$ ./foo.py: command not found
I have checked the working directory and I can see the foo.py when I use the ls command, so what am I doing wrong here?
It seems like you forgot the Shebang:
#!/usr/bin/env python3
import fileinput
with fileinput.input() as f_input :
for line in f_input :
print(line,end='')
Also remember make it as executable via command:
chmod +x foo.py
Then run your command again.
You have to pipe it to the Python executable, not to the name of a file. As the error says, that filename doesn't represent a command it knows.
ls | py ./foo.py
Use py or python or however you run the Python interpreter on your particular system.
I have a Python script script.py that has been defined as executable and which begins with the following sha-bang:
#!/usr/bin/env python -W all
But when I call it from the shell, this is what I get:
$ ./script.py
/usr/bin/env: python -W all: No such file or directory
Calling it directly works though:
$ env python -W all script.py
... some good stuff happens here
What am I doing wrong here?
On a shebang line, you only get one argument. So python -W all is being passed to env as one argument. On the command line, the shell correctly parses the arguments before invoking env.