Formatting output from print on respective lines? - python

I am trying to format the results of a query such that results are printed on their respective lines. For example, I am querying stores by store number and obtaining the location from a JSON file, but when printing, the store number and location are printing on separate lines:
Code Snippet: (Searching for stores 35 and 96)
for store, data in results.items():
print('Store: {}'.format(store))
if data:
for location in data:
print(location)
Current Output:
Store: 35
{'location': Iowa}
Store: 96
{'location': Minnesota}
Desired output (or something similar):
Store: 35, 'location': Iowa
Store: 96, 'location': Minnesota

Adding end='' to your first print statement should fix the problem. By specifying that the end character is an empty string you will override the default \n character (by default print statements end with a new line character).
for store, data in results.items():
print('Store: {}'.format(store), end='')
if data:
for location in data:
print(location)
We will only add end='' to the first print statement because we want the new line to print after you print out the location.
If you want to separate your prints with a , of course you would just add + ',' to your first print statement.
This will work right off the bat if you're using Python 3. If you're using Python 2.X you will have to add this line to the top of your file: from __future__ import print_function
Here's a simple example of this in action:
from __future__ import print_function
l1 = ['hello1', 'hello2', 'hello3']
l2 = ['world1', 'world2', 'world3']
for i,j in zip(l1, l2):
print (i, end='')
print (j)
Output:
hello1world1
hello2world2
hello3world3
If we took the same code but altered it slightly and just removed the end='', this is what would happen:
from __future__ import print_function
l1 = ['hello1', 'hello2', 'hello3']
l2 = ['world1', 'world2', 'world3']
for i,j in zip(l1, l2):
print (i)
print (j)
Output:
hello1
world1
hello2
world2
hello3
world3
As you can see each line would end with a new line character, this printing a new line for each statement.

I would write all the output in a variable and print the variable only once at the end. This also allows you to save time (despite using more memory) since you need only a single access to the stdout. The code is also easier to follow (in my opinion):
output = ''
for store, data in results.items():
output += 'Store: {}'.format(store)
if data:
for location in data:
output += location+'\n'
# Only at the end you print your output
print(output)
You can also print at the end of each iteration (you still access half of the times to the stdout) with the following:
for store, data in results.items():
output = 'Store: {}'.format(store)
if data:
for location in data:
output += location+'\n'
# Print only at the end of the loop
print(output)
If you want a new line for each Store but not for each "location":
output = ''
for store, data in results.items():
output += 'Store: {}'.format(store)
if data:
for location in data:
output += location
output += '\n'
# Only at the end you print your output
print(output)
I think this approach is much more flexible, easier to read in the code and is also faster.
Hope to be helpful

Related

My program can't write output in a file in the expected format

I'm working through a few coding problems on this website I found. To my understanding, what the website does to check whether my program is outputting the expected results is that it makes me write the output on a new file line by line, and then it compares my file with the file that contains the answers. I'm trying to submit my solution for a problem and keep getting the following error message:
> Run 1: Execution error: Your program did not produce an answer
that was judged as correct. The program stopped at 0.025 seconds;
it used 9360 KB of memory. At character number 7, your answer says
'<Newline>' while the correct answer says ' '.
Here are the respective outputs:
----- our output ---------
mitnik_2923
Poulsen_557
Tanner_128
Stallman_-311
Ritchie_-1777
Baran_245
Spafford_-1997
Farmer_440
Venema_391
Linus_-599
---- your output ---------
mitnik
_2923Poulsen
_557Tanner
_128Stallman
_-311Ritchie
_-1777Baran
_245Spafford
_-1997Farmer
_440Venema
_391Linus
_-599
--------------------------
I'm pretty sure my program outputs the expected results, but in the wrong format. Now, I've never written stuff on files using Python before, and therefore don't know what I'm supposed to change to get my output in the proper format. Can someone help me? Here's my code:
fin = open ('gift1.in', 'r')
fout = open ('gift1.out', 'w')
NP,d=int(fin.readline()),dict()
for _ in range(NP):
d[fin.readline()]=0
for _ in range(NP):
giver=fin.readline()
amt,ppl=list(map(int,fin.readline().split()))
if ppl==0 or amt==0:sub=-amt;give=0
else:sub=amt-(amt%ppl);give=amt//ppl
d[giver]-=sub
for per in range(ppl):
d[fin.readline()]+=give
for i in d: ##I'm doing the outputting in this for loop..
ans=str(i)+' '+str(d[i])
fout.write(ans)
fout.close()
The line returned by find.readline() includes the trailing newline. You should strip that off before using it as the dictionary key. That's why you see a newline after all the names.
fout.write() doesn't add a newline after the string you're writing, you need to add that explicitly. That's why there's no newline between the number and the next name.
with open ('gift1.in', 'r') as fin:
NP = int(fin.readline())
d = {fin.readline().strip(): 0 for _ in range(NP)}
for _ in range(NP):
giver=fin.readline().strip()
amt, ppl= map(int,fin.readline().split())
if ppl==0 or amt==0:
sub=-amt
give=0
else:
sub=amt-(amt%ppl)
give=amt//ppl
d[giver]-=sub
for per in range(ppl):
d[fin.readline().strip()]+=give
with open ('gift1.out', 'w') as fout:
for i in d: ##I'm doing the outputting in this for loop..
ans= i + " " + str(d[i])+'\n'
fout.write(ans)
Other points:
Don't cram multiple assignments onto the same line unnecessarily. And no need to put the if and else all on 1 line.
i is a string, there's no need to use str(i)
Use a context manager when opening files.

What causes this return() to create a SyntaxError?

I need this program to create a sheet as a list of strings of ' ' chars and distribute text strings (from a list) into it. I have already coded return statements in python 3 but this one keeps giving
return(riplns)
^
SyntaxError: invalid syntax
It's the return(riplns) on line 39. I want the function to create a number of random numbers (randint) inside a range built around another randint, coming from the function ripimg() that calls this one.
I see clearly where the program declares the list I want this return() to give me. I know its type. I see where I feed variables (of the int type) to it, through .append(). I know from internet research that SyntaxErrors on python's return() functions usually come from mistype but it doesn't seem the case.
#loads the asciified image ("/home/userX/Documents/Programmazione/Python projects/imgascii/myascify/ascimg4")
#creates a sheet "foglio1", same number of lines as the asciified image, and distributes text on it on a randomised line
#create the sheet foglio1
def create():
ref = open("/home/userX/Documents/Programmazione/Python projects/imgascii/myascify/ascimg4")
charcount = ""
field = []
for line in ref:
for c in line:
if c != '\n':
charcount += ' '
if c == '\n':
charcount += '*' #<--- YOU GONNA NEED TO MAKE THIS A SPACE IN A FOLLOWING FUNCTION IN THE WRITER.PY PROGRAM
for i in range(50):#<------- VALUE ADJUSTMENT FROM WRITER.PY GOES HERE(default : 50):
charcount += ' '
charcount += '\n'
break
for line in ref:
field.append(charcount)
return(field)
#turn text in a list of lines and trasforms the lines in a list of strings
def poemln():
txt = open("/home/gcg/Documents/Programmazione/Python projects/imgascii/writer/poem")
arrays = []
for line in txt:
arrays.append(line)
txt.close()
return(arrays)
#rander is to be called in ripimg()
def rander(rando, fldepth):
riplns = []
for i in range(fldepth):
riplns.append(randint((rando)-1,(rando)+1)
return(riplns) #<---- THIS RETURN GIVES SyntaxError upon execution
#opens a rip on the side of the image.
def ripimg():
upmost = randint(160, 168)
positions = []
fldepth = 52 #<-----value is manually input as in DISTRIB function.
positions = rander(upmost,fldepth)
return(positions)
I omitted the rest of the program, I believe these functions are enough to get the idea, please tell me if I need to add more.
You have incomplete set of previous line's parenthesis .
In this line:-
riplns.append(randint((rando)-1,(rando)+1)
You have to add one more brace at the end. This was causing error because python was reading things continuously and thought return statement to be a part of previous uncompleted line.

How to print output in single line in linux terminal

Below is the code:
data2 = [["jsdfgweykdfgwey",
"kdgwehogfdoyeo",
"ndlgyehwfgdiye",
"ndfluiwgmdfho"],
["---------------------------------------------------------------------------------",
"-------------------------------------------------------------------------------",
"------------------------------------------------------------------------------",
"-----------------------------------------------------------------------------"],
["kdglwduifgeuifeudiwfkjkedluefywduifkcjkewfgpt1",
"kdglwduifgeuifeudiwfkjkedluefywduifkcjkewfgpt2",
"kdglwduifgeuifeudiwfkjkedluefywduifkcjkewfgpt3",
"kdglwduifgeuifeudiwfkjkedluefywduifkcjkewfgpt4\
kdglwduifgeuifeudiwfkjkedluefywduifkcjkewfgpt4 \
kdglwduifgeuifeudiwfkjkedluefywduifkcjkewfgpt4"]]
data = [x for x in data2 if x is not None]
col_width = max(len(word) for row in data for word in row) + 2
for row in data:
print "".join(word.ljust(col_width) for word in row)#print in single line in output console.
It is not printing output properly
How to print output in single line in command output (OS Linux)
or any other suggestions to print in column wise for long line printing.
Each element in your list is printed out as a combined string as you wished. But by doing the word.ljust(col_width) step, where col_width is about 140, you are taking up a lot of empty space for printing. If your console size is small it will seem like you are printing in a new line. Try to replace col_width by 10, you will probably get the elements of data2[0] printed in one line.
If you want data2 to be printed as a single string then you can do the following:
tmp=''
for row in data:
a = " ".join(word.ljust(col_width) for word in row)
tmp = tmp + a
tmp will contain each element of data2 in a string one after the other

Bell character as Fields separator in Python print output

I am fairly new to Python and need a little help here.
I have a Python script running on Python 2.6 that parses some JSON.
Example Code:
if "prid" in data[p]["prdts"][n]:
print data[p]["products"][n]["prid"],
if "metrics" in data[p]["prdts"][n]:
lenmet = len(data[p]["prdts"][n]["metrics"])
i = 0
while (i < lenmet):
if (data[p]["prdts"][n]["metrics"][i]["metricId"] == "price"):
print data[p]["prdts"][n]["metrics"][i]["metricValue"]["value"]
break
Now, this prints values in 2 columns:
prid price
123 20
234 40
As you see the fields separator above is ' '. How can I put a field separator like BEL character in the output?
Sample expected output:
prid price
123^G20
234^G40
FWIW, your while loop doesn't increment i, so it will loop forever, but I assume that was just a copy & paste error, and I'll ignore it in the rest of my answer.
If you want to use two separate print statements to print your data on one line you can't avoid getting that space produced by the first print statement. Instead, simply save the prid data until you can print it with the price in one go using string concatenation. Eg,
if "prid" in data[p]["prdts"][n]:
prid = [data[p]["products"][n]["prid"]]
if "metrics" in data[p]["prdts"][n]:
lenmet = len(data[p]["prdts"][n]["metrics"])
i = 0
while (i < lenmet):
if (data[p]["prdts"][n]["metrics"][i]["metricId"] == "price"):
price = data[p]["prdts"][n]["metrics"][i]["metricValue"]["value"]
print str(prid) + '\a' + str(price)
break
Note that I'm explicitly converting the prid and price to string. Obviously, if either of those items is already a string then you don't need to wrap it in str(). Normally, we can let print convert objects to string for us, but we can't do
print prid, '\a', price
here because that will give us an unwanted space between each item.
Another approach is to make use of the new print() function, which we can import using a __future__ import at the top of the script, before other imports:
from __future__ import print_function
# ...
if "prid" in data[p]["prdts"][n]:
print(data[p]["products"][n]["prid"], end='\a')
if "metrics" in data[p]["prdts"][n]:
lenmet = len(data[p]["prdts"][n]["metrics"])
i = 0
while (i < lenmet):
if (data[p]["prdts"][n]["metrics"][i]["metricId"] == "price"):
print(data[p]["prdts"][n]["metrics"][i]["metricValue"]["value"])
break
I don't understand why you want to use BEL as a separator rather than something more conventional, eg TAB. The BEL char may print as ^G in your terminal, but it's invisible in mine, and if you save this output to a text file it may not display correctly in a text viewer / editor.
BTW, It would have been better if you posted a Minimal, Complete, Verifiable Example that focuses on your actual printing problem, rather than all that crazy JSON parsing stuff, which just makes your question look more complicated than it really is, and makes it impossible to test your code or their modifications to it.

Python for loop scope

I'm trying to format a dictionary variable to use as a report. I want to recurse through the dictionary and concatenate the items from the dictionary into a formatted string that will be printed/emailed out to users. I'm having issues getting with the string variable (text) losing some of the text concatenated to it.
What I want is:
first \n
\t status: first did not have any updates to apply \n
second \n
\t status: first did not have any updates to apply \n
My function is:
def formatReport(report, text = ""):
for x in report:
if isinstance(report[x], dict):
text += "{0} \n".format(x)
formatReport(report[x], text)
else:
text += "\t{0}: {1} \n".format(x, report[x])
return text
When I call:
report = {'first': {'status': 'first did not have any updates to apply'}, 'second': {'status': 'second did not have any updates to apply'}}
formatReport(report)
I get (note the order of the output is not important to me):
'second \nfirst \n'
After adding a ton of debugging:
def formatReport(report, text = ""):
for x in report:
print "before if: " + text
if isinstance(report[x], dict):
text += "{0} \n".format(x)
print "if: " + text
formatReport(report[x], text)
else:
text += "\t{0} : {1} \n".format(x, report[x])
print "else: " + text
return text
I have narrowed the issue to down to the fact that the text variable is losing the string appended after the else. ie on this line:
text += "\t{0} : {1} \n".format(x, report[x])
So the output of the debugging code after the else is run the first time in the first for loop looks like:
else: second
status : first did not have any updates to apply
When it loops back to the top of the for loop is looks like:
before if: second
From what I have read for loops and if/else statements do not have their own scope as Python does not have block level scoping. I'm at a lose here I have tried all kinds of different combinations or variable names, parameters, etc.... It's worth noting I want to run this code on dictionaries that are 3+ levels deep, hence the need for the recursive call in the if statement.

Categories