python3: how can I paste code directly into console that calls a function instead of having to load a .py file? - python-3.x

In a python3 console I just want to copy and paste code directly into the console without loading a .py file but I get an error, probably because it's executing only one line at a time?
>>> def k():
... print("Hi")
... k()
File "<stdin>", line 3
k()
^
SyntaxError: invalid syntax
>>>
How can I run multi-line python code by just copying and pasting what I've written, into console instead of loading a .py file? I realize people will say it's stupid to do this, but hypothetically if it weren't stupid to do this, what's the easiest way to do it?

your problem is this:
you have to paste the def k(): after the prompt >>> then paste your function code one line at a time after ... (with indents) then at the end of your function definition add an empty line (no indent) then you will get the >>> prompt again where you paste your function call k() .
this was what I got
>>> def k():
... print("hi")
...
>>> k()
hi
>>>

Related

Python script does not print output as supposed

I have a very simple (test) code which I'm running either from a Linux shell, or in interactive mode, and I have two different behaviours I cannot figure out the reason of.
I have a file generated by a Popen call, previously, where each line is a file path. This is the code used to generate the file:
with open('find.txt','w') as f:
find = subprocess.Popen(["find",".","-name","myfile.out"],stdout=f)
(Incidentally, I was trying to build a PIPE originally, namely inputting the output of this command to a grep command, and since I wasn't successful in any way, I decided to break the problem down and just read the file paths from a file, and process them one by one. So maybe there is a common issue that is blocking me somewhere in this procedure).
Since in this second step I wasn't even able to open and process the files by opening the addresses contained in each line of the find.txt file, I just tried to print the file lines out, because for sure they're available in there:
with open('find.txt','r') as g:
for l in g.readlines():
print(l)
Now, the interesting part:
if I paste the lines above into a python shell, everything works fine and I get my outputs as expected
if, on the other hand, I try to run python test.py, where test.py is the name of the file containing the lines above, no output appears in the shell's stdout.
I've tried sys.stdout.flush() to no avail. I've also inserted some dummy print() statements along the way: everything gets printed but what's after the g.readlines() statement.
Here's the full script I'm trying to make work (a pre-precursor of what I'm actually after, tbh).
#!/usr/bin/env python3
import subprocess
import sys
with open('find.txt','w') as f:
find = subprocess.Popen(["find",".","-name","myfile.out"],stdout=f)
print('hello')
with open('find.txt','r') as g:
print('hello?')
for l in g.readlines():
print('help me!')
print(l)
sys.stdout.flush()
output being:
{ancis:>106> python test.py
hello
hello?
{ancis:>106>
EDIT
I've quickly tried the very same lines (but without the call to find, which isn't available) on my python installation in Windows: it works as expected)
Based on that, I've tried to run the simpler code below:
print('hello')
with open('find.txt','r') as g:
print('hello?')
for l in g.readlines():
print('help me!')
print(l)
sys.stdout.flush()
as a script, in Linux - This also works w/o problems.
This should mean that somehow I'm messing things up with the call to Popen... But what?
This is a race condition.
Your call to
find = subprocess.Popen(["find",".","-name","myfile.out"],stdout=f)
is opening another process and running your find command which takes a bit of time to fully execute.
Python then continues on and reaches the reading of the file portion before the command is fully executed and the file is generated.
Want to test it out?
Add a time.sleep(1) just before the opening of the file.
Full test script:
#!/usr/bin/env python3
import subprocess
import time
with open('find.txt','w') as f:
find = subprocess.Popen(["find",".","-name","myfile.out"],stdout=f)
time.sleep(1)
with open('find.txt','r') as g:
for l in g:
print(l)
To block until the process is complete you can use find.communicate().
With this you can also optionally set a timeout if that's something that you want.
#!/usr/bin/env python3
import subprocess
with open('find.txt','w') as f:
find = subprocess.Popen(["find",".","-name","myfile.out"],stdout=f)
find.communicate()
with open('find.txt','r') as g:
for l in g:
print(l)
Source:
https://docs.python.org/3/library/subprocess.html#subprocess.Popen.communicate

Indentation error while importing python file in Juypter Notebook

I am running simple code mentioned below, but getting indentation error. I am using Python 3.x and Juypter notebook. Help will be appreciated.
import os
import sys
sys.path.insert(0, os.path.abspath('C:\dir python util'))
import h
h.my_first_function()
In file h.py, which is in drive c:\dir python util contents are below:
def my_first_function():
print ("my first program of python")
Error I am getting:
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 3331, in run_code exec(code_obj, self.user_global_ns, self.user_ns)
File "", line 5, in import h
File "C:\dir python util\h.py", line 2 print ("my first program of python") ^ IndentationError: expected an indented block
File "C:\dir python util\h.py", line 2 print ("my first program of python") ^ IndentationError: expected an indented block
Error indicates that it is simple indentation error. You need to maintain the appropriate indentation in the code.
With corrected indentation, it'll be as follows:
def my_first_function():
print ("my first program of python")
So print statement needs to have 4 spaces rather than one.
Suggest you to go through this document to get idea about Python's indentation rules, if you don't know that already.

How can I log a print statement to a file in Python 3.6?

I am going off of this thread.
First, I added import sys to the top of my file. The print statement that I want to log is inside of an if/else statement, specifically in the else portion. It looks like this:
else:
sys.stdout = open('logfile', 'w')
print("hi")
This does create a file called logfile in the same directory as the .py file, but it is emtpy and does not include "hi".

Python: NameError from calling a file from the commandline arguments

For an assignment I'm supposed to have to have a line to open a file that is passed as an argument in the commandline, I keep getting
Traceback (most recent call last):
File "execute.py", line 1, in <module>
program=open(programfilename, "r")
NameError: name 'programfilename' is not defined
My code to this point is program=open(programfilename, "r"). I'm not quiet sure what is wrong. It is the first line in my program. Execute.py is the name of my code.
You need to set the programfilename variable to the name/path of the file on a previous line. Alternatively, you could put the filename in quotes instead.
It is the first line in my program
Well there's your problem. You are using programfilename without having defined it first.
Try something like
import sys
programfilename = sys.argv[0] # argument you passed into your program.
program=open(programfilename, "r")
I am not sure what exactly you are trying to.
If you want to call a file using command line, the code can be like this
import sys
with open(sys.argv[1], 'r') as f:
print(f.read())
Run like this
python3 execute.py programfilename
If you want your program to get printed on the console, the code can be like this
import sys
with open(sys.argv[0], 'r') as f:
print(f.read())
This will print the code on the console.
Run like this
python3 execute.py

Testing python programs without using python shell

I would like to easily test my python programs without constantly using the python shell since each time the program is modified you have to quit, re-enter the python shell and import the program again. I am using a 2012 Macbook pro with OSX. I have the following code:
import sys
def read_strings(filename):
with open(filename) as file:
return file.read().split('>')[1:0]
file1 = sys.argv[1]
filename = read_strings(file1)
Essentially I would like to read into and split a txt file containing:
id1>id2>id3>id4
I am entering this into my command line:
pal-nat184-102-127:python_stuff ceb$ python3 program.py string.txt
However when I try the sys.argv approach on the command line my program returns nothing. Is this a good approach to testing code, could anyone point me in the correct direction?
This is what I would like to happen:
pal-nat184-102-127:python_stuff ceb$ python3 program.py string.txt
['id1', 'id2', 'id3', 'id4']
Let's take this a piece at a time:
However when I try the sys.argv approach on the command line my
program returns nothing
The final result of your program is that it writes a string into the variable filename. It's a little strange to have a program "return" a value. Generally, you want a program to print it's something out or save something to a file. I'm guessing it would ease your debugging if you modified your program by adding,
print (filename)
at the end: you'd be able to see the result of your program.
could anyone point me in the correct direction?
One other debugging note: It can be useful to write your .py files so that they can be run both independently at the command line or in a python shell. How you've currently structured your code, this will work semi-poorly. (Starting a shell and then importing your file will cause an error because sys.argv[1] isn't defined.)
A solution to this is to change your the bottom section of your code as follows:
if __name__ == '__main__':
file1 = sys.argv[1]
filename = read_strings(file1)
The if guard at the top says, "If running as a standalone script, then run what's below me. If you imported me from some place else, then do not execute what's below me."
Feel free to follow up below if I misinterpreted your question.
You never do anything with the result of read_strings. Try:
print(read_strings(file1))

Resources