I am trying to format a group of columns in python 3. So far I have not had much luck. I managed to get the columns to print, but I can't get them to line up. I am trying to make each column dynamic so that it can adapt if different information needs to be printed. But because I am trying to use variables in the column formatting, I keep getting Key Errors. Any idea how I can fix this?
Indicator :Min :Max
----------------------------------------------------------------------------
Traceback (most recent call last):
File "G:/test.py", line 154, in <module>
print('{heart:{heart_col_width}}:{motor:{motor_col_width}} {teen:{teen_col_width}{smoke: {smoke_col_width}}{obese:{obese_col_width}'.format(heart, motor, teen, smoke, obese ))
KeyError: 'heart'
This is the code I am using.
first_row = ['Indicator',':Min',':Max']
col_width = max(len(word) for word in first_row) +20# padding
print ("".join(word.ljust(col_width) for word in first_row))
print('----------------------------------------------------------------------------')
heart=['Heart Disease Death Rate (2007)',stateheart_min(),heartdis_min(),stateheart_max(),heartdis_max()]
motor=[ 'Motor Vehicle Death Rate (2009)',statemotor_min(),motordeath_min(),statemotor_max(),motordeath_max()]
teen=['Teen Birth Rate (2009)',stateteen_min(),teenbirth_min(),stateteen_max(),teenbirth_max()]
smoke=['Adult Smoking (2010)',statesmoke_min(),adultsmoke_min(),statesmoke_max(),adultsmoke_max()]
obese=['Adult Obesity (2010)',stateobese_min(),adultobese_min(),stateobese_max(),adultobese_max()]
heart_col_width = max(len(word) for word in heart)
motor_col_width = max(len(word) for word in motor)
teen_col_width = max(len(word) for word in teen)
smoke_col_width = max(len(word) for word in smoke)
obese_col_width = max(len(word) for word in obese)
for heart, motor, teen, smoke, obese in zip(heart, motor, teen, smoke, obese ):
print('{heart:{heart_col_width}}:{motor:{motor_col_width}} {teen:{teen_col_width}{smoke: {smoke_col_width}}{obese:{obese_col_width}'.format(heart, motor, teen, smoke, obese ))
When you use
the
format
function doesn't know how to "match" or "connect" the whatever in"{whatever}"
to the whatever informat(whatever)
For the interpreter, they have nothing to do with each other. When the.format
function sees the"{whatever}"
it will try to look for a keyword argumentwhatever
in its call, but there's none. It only knows that there's a positional argument (which is not thedroid... erm... the argument that it's looking for)You might want to understand what positional arguments are versus keyword arguments (check this SO thread) In general, you're gonna need to know that difference very well for any Python development that you work on.
Knowing that, let's go back to the
.format
method:You need to explicitly tell the
.format
method the connection between the two whatevers:Maybe it's clearer by doing:
So in your case, you can do:
Thanks to the use of these keyword arguments, if the column width is the same for all the columns, you don't need to re-specify it. You can just reuse them in different parts of your string:
Check this string formatting tutorial (particularly its examples section). It might give you some alternative ideas.