0

I want to print out a report with the following python (3.8) code, but you can see that the pandas info prints at the top instead of the bottom. I can't seem to find any solutions to this odd behavior. Any ideas for how to fix this?

time = 600
file = 'election_file.csv'
report = (
    f'Data Diagnostic Report\n'
    f'Date & time: {time}\n'
    f'Data file: {file}\n'
    f'Data frame header (first five lines):\n {election.head()}\n\n'
    f'Data frame information:\n {election.info()}\n'
    f'end of report\n'
)
print(report)

OUTPUT:

time = 600...
<class 'pandas.core.frame.DataFrame'>
Index: 10 entries, Adams to Butler
Data columns (total 8 columns):
 #   Column   Non-Null Count  Dtype  
---  ------   --------------  -----  
 0   Obama    10 non-null     float64
 1   Romney   10 non-null     float64
 2   margin   10 non-null     float64
 3   state    10 non-null     object 
 4   total    10 non-null     int64  
 5   turnout  10 non-null     float64
 6   voters   10 non-null     int64  
 7   winner   9 non-null      object 
dtypes: float64(4), int64(2), object(2)
memory usage: 720.0+ bytes
Data Diagnostic Report
Date & time: 600
Data file: election_file.csv
Data frame header (first five lines):
                Obama     Romney     margin state   total    turnout  voters  \
Adams      35.482334  63.112001  27.629667    PA   41973  68.632677   61156   
Allegheny  56.640219  42.185820  14.454399    PA  614671  66.497575  924351   
Armstrong  30.696985  67.901278  37.204293    PA   28322  67.198140   42147   
Beaver     46.032619  52.637630   6.605012    PA   80015  69.483401  115157   
Bedford    22.057452  76.986570  54.929118    PA   21444  66.619031   32189   

           winner  
Adams      Romney  
Allegheny   Obama  
Armstrong  Romney  
Beaver     Romney  
Bedford    Romney  

Data frame information:
 None
end of report
BlueFruit
  • 21
  • 3
  • It seems to me that `election.info()` returns `None` which is exactly what you see printed. The problem with `f'{func()}'` strings is that when you create the string the `func()` has to be called while the string is being created. Then it gets printed. So you can see that both `election.head()` *and* `election.info()` are called **in the process** of creating `report`, but `report` is printed later. – quamrana Aug 23 '20 at 12:23

3 Answers3

1

That is because dataframe.info() prints when it is called. So first you see the result (output in this case) of the call to dataframe.info() and only then the f-string is printed.

In other words, the interpreter first evaluates all the "variables" used in the f-string, and only then print the formated string itself. That is also the reason you see

Data frame information:
  None

In the output. info() prints the data then returns None (much like the built-in print).

This behavior can be reproduced easily:

def foo():
    print('foo')

print(f'Generated string {foo()}')

This outputs

foo
Generated string None
DeepSpace
  • 78,697
  • 11
  • 109
  • 154
1

A solution to fix this is to split the report in two:

time = 600
file = 'election_file.csv'
report = (
    f'Data Diagnostic Report\n'
    f'Date & time: {time}\n'
    f'Data file: {file}\n'
    f'Data frame header (first five lines):\n {election.head()}\n\n'
    f'Data frame information:\n '
)
print(report)
election.info()

report = (
    f'\n'
    f'end of report\n'
)
print(report)
quamrana
  • 37,849
  • 12
  • 53
  • 71
  • Thank you! Not as elegant as I would like, but it works. And it makes sense: at another point, I am calling some functions I wrote and they appeared at the top too until I used a return statement in them. – BlueFruit Aug 23 '20 at 14:58
1

This is because df.info() prints the moment it is called, and returns none. try this instead, should solve:

import io
buf = io.StringIO()
election.info(buf=buf)
electioninfo = buf.getvalue()

report = (
    f'Data Diagnostic Report\n'
    f'Date & time: {time}\n'
    f'Data file: {file}\n'
    f'Data frame header (first five lines):\n {election.head()}\n\n'
    f'Data frame information {electioninfo}:\n '
)
print(report)
Sayan Dey
  • 771
  • 6
  • 13