How to get execution of python print statements as a string? [duplicate] - python

This question already has answers here:
python: get the print output in an exec statement
(7 answers)
Closed 6 years ago.
I am writing a python script which contains a list containing python print statements as a string. In my function, I am using a for loop to run exec function to run those statements.
Here is my function:
g_list = ["print('Wow!')\n", "print('Great!')\n", "print('Epic!')\n"]
def run_statements():
for item in g_list:
exec(item)
When I run run_statements() function, I get the following output:
Wow!
Great!
Epic!
Basically, I want to save the output as a string so that later, I can save it to my database.
Does anyone have any idea how can I do it?
EDIT: At the following question: python: get the print output in an exec statement He is trying to get output, My question is different in a way that I am trying to get output as a string

If you really need a print statement in the list of strings (as opposed to a print-like function with a different name, as suggested in another answer), you can reassign the name print to your own function, after carefully, carefully, carefully saving the old print function so you can carefully, carefully, carefully restore the name print to its proper definition. Like this:
>>> g_list = ["print('Wow!')\n", "print('Great!')\n", "print('Epic!')\n"]
>>> old_print = print
>>> def print(s): # redefining the built-in print function! terrible idea
... global catstr
... catstr += s
...
>>> catstr = ""
>>> for s in g_list: exec(s)
...
>>> catstr
'Wow!Great!Epic!'
>>> print = old_print # Don't forget this step!
This is completely immoral, and I did not advise you to do it. I only said you can do it.
To stress the inadvisability of this plan: exec should be used rarely; it is dangerous; reassigning the names of built-in functions to different functions should be done very rarely; it is dangerous. Doing both in the same code could really ruin your day, especially after a maintenance programmer edits your code "just a little," without realizing the potential impact.

If you want to save what you print, you could create a custom command, and save the output to a variable. For example
output_bin = ""
def printsave(string):
print string
if len(string) > 1:
if string[-2] == "\n":
output_bin = output_bin + string
else:
output_bin = output_bin + string + "\n"
else:
output_bin = output_bin + string + "\n
Then, whenever you call printsave() it is saved to the string output_bin. And if you want it to be saved to an array...
output_bin = []
def printsave(string):
print string
if len(string) > 1:
if string[-2] == "\n":
output_bin.append(string)
else:
output_bin.append(string + "\n")
else:
output_bin.append(string + "\n)

Related

Python - Case where Print works but Return doesn't in a basic function [duplicate]

This question already has answers here:
How can I use `return` to get back multiple values from a loop? Can I put them in a list?
(2 answers)
Closed 2 years ago.
So as the title suggests, I made a simple function like this:
import sys
string = sys.argv[1]
def position():
for index in range(len(string)):
if string[index] == 'A':
print(int(index+1))
position()
Which, when used with a test string like "AABABC", will return the position of each "A" as a number.
Here I increment the index with 1 because I noticed the range is starting at 0. While I can pass 1 or any number I want to it to make it start to that, it will remove/not print everything I want. So I found that this worked best in this case.
Everything works here. What doesn't is when I replace the print in the function, with a return statement:
import sys
string = sys.argv[1]
def position():
for index in range(len(string)):
if string[index] == 'A':
return int(index+1)
print(position())
Here I only show this edit to the code, but I did try a couple of different things, all with a similar results (in that it doesn't work):
not using int() and instead incrementing the index with += -> doesn't work in this specific case?
using another variable (a naive test which obviously didn't work)
Compared to the other "questions" that might be seen as duplicate/similar ones to mine, I'm using print() on the function outside of it in the last example. So the problem is likely not coming from there.
I don't think my indentation is wrong here either.
To give even more details on "what doesn't work", when I use return instead of print here and using a test string like "ABABACD", it would output the correct "136" as a result. But when using return along with the other failed attempt I listed earlier, it would only output "1" instead....
Return ends the run of the function whether or not there are more "loops" left. If you want to have it return all of the positions there is an "A" in your string you can try something like this:
def position():
return [i+1 for i, j in enumerate(string) if j == "A"]
same as
def position():
pos = []
for i, j in enumerate(string):
if j == "A":
pos.append(i+1)
return pos
It can also be done using regular expressions:
import re
[i.start()+1 for i in re.finditer("A", string)]

How can I tell my function to do something specific thing when it receives no parameters?

So, I have the following function which should resemble the already implemented " print " function in Python. ( I know it is silly to make a function that only uses a pre-defined function but I am practicing with different things ) The thing that I want to do with my function is: make it act the same as the pre-defined one. That is, when the print function is called with no parameters, I would like it to print an empty line just as " print() " does. How do i do that ?
def print_str( string, how_many_times, tail ):
print ( string * how_many_times, end = tail )
print doesn't take a single string, it takes 0 or most strings as argument. end has a reasonable default. You can imagine a (simplified) definition of
def print(*args, end='\n'):
...
You need to do the same for yours. A reasonable default for how_many_times would be 1. If you don't want print_str to take multiple arguments, "" would be a reasonable default for string.
def print_str(string="", how_many_times=1, tail='\n'):
print(string * how_many_times, end=tail)
You can do something like this:
def myfunc(a=None):
if a == None:
print()
else:
print("hi")
If no arguments are presented it prints nothing, but if an argument is given it prints 'hi'.

Do Python functions modify their arguments?

I was in my computer science class today and the teacher put a piece of python coding on the board and said he couldn't figure out why it wasn't working. He was showing us functions and said:
def app(x):
x.append(" ")
print(x)
def ext(x,y):
x.extend(y)
print(y)
nums = [1,2,3,4,5,6]
numbers = [7,8,9,10]
app(nums)
ext(nums,numbers)
print("End of program")
The code was meant to show how when you don't type
return x
in the function then the variable doesn't change when you return to the main program however when he ran the program, the first function added the space and kept it there when it returned resulting in the following text being printed...
['1','2','3','4','5','6',' ']
['1','2','3','4','5','6',' ','7','8','9','10']
End of program
Please help me out.
You say that the point was to demonstrate that a list won't be changed unless it is returned. That is false. The list is a mutable object. When you pass it (by name) to a function and change it, it will be changed. If you don't want the change, you need to work with a copy.
def app(x):
return x + [" "]
def ext(x,y):
return x + y
might be what you are trying to do ... im not sure, this will not alter either of the original lists, but will return a new list as the result

Print formatting a string and function call in python

I've got a function, displayHand() which looks like this:
def displayHand(hand):
"""
Displays the letters currently in the hand.
For example:
>>> displayHand({'a':1, 'x':2, 'l':3, 'e':1})
Should print out something like:
a x x l l l e
The order of the letters is unimportant.
hand: dictionary (string -> int)
"""
for letter in hand.keys():
for j in range(hand[letter]):
print letter, # print all on the same line
print # print an empty line
It was provided for me (from the 600x class). As described, it takes a dict of string->ints and prints out the "hand".
What I'm having troubles with is getting this to show up properly. When I try
print('Current Hand: ', displayHand(hand))
This is what I get:
a d d m o q y
('Current Hand: ', None)
Since this was provided by the instructor, I'm sure there's a reason the code was written this way and that there's something I'm not getting.
What I'd like to get is output like this:
Current Hand: a d d m o q y
I'm absolutely brand new to this stuff so I don't even know what questions to ask.
My assessment: As far as I can piece together, displayHand() doesn't return anything and that's what's screwing it all up. But how do I catch the print output of this function and present it the way I want? I was thinking I should try to catch it in a string and have that returned, but assuming
the instructor was trying to demonstrate something, how would I do it without changing the displayHand() method?
If my assessment is off, what's going on?
Edit: This function was given to me by the class, and I'll have to use it as such. I understand changing it to return a str would be much easier, but how could I accomplish the correct output without doing that?
Further Edit: I'm dealing with an autograder that demands the output exactly as I've written. Sorry to be so fussy, I appreciate the answers and would use them if it wasn't for this.
Final Edit: Thanks for the clarification -- I'm going to use your idea and make a helper function inside this function that does what I need it to do!
FINAL final Edit: I figured it out! All I had to do was,
print('Current Hand:'),
displayHand(hand)
For real final edit:
Hah! you got it too! thank you so much for the help, I appreciate it!
Your function already prints, it does not return anything.
Don't try to 'catch' the printed output, simply change the function to return the hand, formatted to a string:
def displayHand(hand):
letters = []
for letter, count in hand.iteritems():
letters.extend([letter] * count)
return ' '.join(letters)
which gives:
>>> hand = {'a': 1, 'q': 1, 'd': 2, 'y': 1, 'm': 1, 'o': 1}
>>> displayHand(hand)
'a q d d y m o'
>>> print 'Current Hand:', displayHand(hand)
Current Hand: a q d d y m o
If you are not supposed to change the displayHand() function, then use the same trick using in the function and do not print a newline by adding a comma to the end of the print statement:
print 'Current Hand:',
displayHand(hand)
You can do this if you must use the provided function and must not try to fix it:
print('Current Hand: ', end='')
displayHand(hand)
I'm confused, do you use python 2 or 3?
In python 2:
print 'Current Hand" ',
displayHand(hand)
First, your displayHand function doesn't return anything so when you try to print its result you get None. You probably need to remove those print statements from the function and return the string instead.
Second, you try to use print as a function which is possible obly in python 3 while you seem to be using python 2. If that's the case you need to remove parentheses around the print statement arguments.
If you really can't modify that function then you might want to redirect the standard output to a string before calling the function and setting it back to normal afterwards.
This post explains how to do it: Can I redirect the stdout in python into some sort of string buffer?

What is the formal difference between "print" and "return"? [duplicate]

This question already has answers here:
What is the purpose of the return statement? How is it different from printing?
(15 answers)
Closed 7 years ago.
Lets say I define a simple function which will display an integer passed to it:
def funct1(param1):
print(param1)
return(param1)
the output will be the same but and I know that when a return statement is used in a function the output can be used again. Otherwise the value of a print statement cannot be used. But I know this is not the formal definition, Can anyone provide me with a good definition?
Dramatically different things. Imagine if I have this python program:
#!/usr/bin/env python
def printAndReturnNothing():
x = "hello"
print(x)
def printAndReturn():
x = "hello"
print(x)
return x
def main():
ret = printAndReturn()
other = printAndReturnNothing()
print("ret is: %s" % ret)
print("other is: %s" % other)
if __name__ == "__main__":
main()
What do you expect to be the output?
hello
hello
ret is : hello
other is: None
Why?
Why? Because print takes its arguments/expressions and dumps them to standard output, so in the functions I made up, print will output the value of x, which is hello.
printAndReturn will return x to the caller of the method, so:
ret = printAndReturn()
ret will have the same value as x, i.e. "hello"
printAndReturnNothing doesn't return anything, so:
other = printAndReturnNothing()
other actually becomes None because that is the default return from a python function. Python functions always return something, but if no return is declared, the function will return None.
Resources
Going through the python tutorial will introduce you to these concepts: http://docs.python.org/tutorial
Here's something about functions form python's tutorial: http://docs.python.org/tutorial/controlflow.html#defining-functions
This example, as usual, demonstrates some new Python features:
The return statement returns with a value from a function. return without an expression argument returns None. Falling off the end of a function also returns None.
With print() you will display to standard output the value of param1, while with return you will send param1 to the caller.
The two statements have a very different meaning, and you should not see the same behaviour. Post your whole program and it'll be easier to point out the difference to you.
Edit: as pointed by others, if you are in an interactive python shell you see the same effect (the value is printed), but that happens because the shell evaluates expressions and prints their output.
In this case, a function with a return statement is evaluated as the parameter of return itself, so the return value is echoed back. Don't let the interactive shell fool you! :)
Simple example to show the difference:
def foo():
print (5)
def bar():
return 7
x = foo()
y = bar()
print (x)
# will show "None" because foo() does not return a value
print (y)
# will show "7" because "7" was output from the bar() function by the return statement.
I'll start with a basic explanation. print just shows the human user a string representing what is going on inside the computer. The computer cannot make use of that printing. return is how a function gives back a value. This value is often unseen by the human user, but it can be used by the computer in further functions.
On a more expansive note, print will not in any way affect a function. It is simply there for the human user's benefit. It is very useful for understanding how a program works and can be used in debugging to check various values in a program without interrupting the program.
return is the main way that a function returns a value. All functions will return a value, and if there is no return statement (or yield but don't worry about that yet), it will return None. The value that is returned by a function can then be further used as an argument passed to another function, stored as a variable, or just printed for the benefit of the human user.
Consider these two programs:
def function_that_prints():
print "I printed"
def function_that_returns():
return "I returned"
f1 = function_that_prints()
f2 = function_that_returns()
print "Now let us see what the values of f1 and f2 are"
print f1
print f2
print (or print() if you're using Python 3) does exactly that—print anything that follows the keyword. It will also do nice things like automatically join multiple values with a space:
print 1, '2', 'three'
# 1 2 three
Otherwise print (print()) will do nothing from your program's point of view. It will not affect the control flow in any way and execution will resume with the very next instruction in your code block:
def foo():
print 'hello'
print 'again'
print 'and again'
On the other hand return (not return()) is designed to immediately break the control flow and exit the current function and return a specified value to the caller that called your function. It will always do this and just this. return itself will not cause anything to get printed to the screen. Even if you don't specify a return value an implicit None will get returned. If you skip a return altogether, an implicit return None will still happen at the end of your function:
def foo(y):
print 'hello'
return y + 1
print 'this place in code will never get reached :('
print foo(5)
# hello
# 6
def bar():
return # implicit return None
print bar() is None
# True
def baz(y):
x = y * 2
# implicit return None
z = baz()
print z is None
# True
The reason you see returned values printed to the screen is because you are probably working in the interactive Python shell that automatically prints any result for your own convenience.
The output is only the same in the interactive terminal. When you execute your program normally the results will be completely different.
I would suggest you to read a book about Python or read a tutorial that teaches you the basics, because this is a very basic thing.

Categories

Resources