Python print evenly spaced columns

I am trying to get my output data to look like this:

-------------------------------------------------------
            Grade Report for Programs 
-------------------------------------------------------
Jacobson, Mark      19.0 <--- 20,17,20
Snurd, Mortimur     16.5 <--- 20,19,18,17,16,15,14,13
Luxemburg, Rosa     15.0 <--- 18,15,20,10,12
Atanasoff, John     20.0 <--- 20,20,20,20,20,20,20
Hopper, Grace       20.0 <--- 20,20,20,20,20,20
-------------------------------------------------------

But I don't know how to deal with the varying name length. My output currently looks like this.


            Grade Report for Programs 
-------------------------------------------------------
Jacobson, Mark   19.0 <--- 20,17,20
Snurd, Mortimur   16.5 <--- 20,19,18,17,16,15,14,13
Luxemburg, Rosa   15.0 <--- 18,15,20,10,12
Atanasoff, John   20.0 <--- 20,20,20,20,20,20,20
Hopper, Grace   20.0 <--- 20,20,20,20,20,20
-------------------------------------------------------

The program I have written is to take an input file of grade scores and collect the data and neatly print out the average.

The input file looks something like this:

Mark Jacobson,20,17,20
Mortimur Snurd,20,19,18,17,16,15,14,13
Rosa Luxemburg,18,15,20,10,12
John Atanasoff,20,20,20,20,20,20,20
Grace Hopper,20,20,20,20,20,20

And here is my code that collects the name and scores, and prints out the data with last name, first name, average score, then the actual scores that resulted to the average.

file = input("Enter filename: ")

grade_file = open(file, 'r')

print()

print('---------------------------------------------------------')
print('\t\tGrade Report for Programs')
print('---------------------------------------------------------')

for text in grade_file:
    end_of_name = text.find(',')
    name_seperated = text.find(' ')

    first_name = text[0:name_seperated]
    last_name = text[name_seperated+1:end_of_name]

    name_last_first = last_name + "," + " " + first_name

    grades = text[end_of_name+1:]

    start = 0
    index = 0
    sum_n = 0
    average= 0
    score = 0
    count = 0

    while index < len(grades):
        if grades[index] == ',':
            score = int(grades[start:index])
            count += 1
            sum_n = score + sum_n
            start = index + 1
        index += 1

    count += 1       

    score = int(grades[start:index])
    sum_n = score + sum_n
    average = sum_n / count



    print(name_last_first, " ", average, "<---", grades)


print('---------------------------------------------------------')


grade_file.close()

I just need to figure out how to have even spaces so it makes an even row and column like the first output. Help is greatly appreciated! Thanks!

I have this function here that is an example from a book im following:

def print_multiples(n):
    """ Prints multiples of n, within the range 1 - 6 """   # encapsulation and generaliztion of above
    for i in range(1,7):
        print(n*i, end = " ")   #end appends the end of a line instead of starting a new one
    print() # starts a new line

The book has the output as these neat rows and columns but when I run the function the columns and rows aren't lined up. This makes sense because a digit like 14 takes up an extra space as opposed to a single digit like 7, anything after 14 is going to shifted one space ahead of something after 7 from the previous row. The book however, has the output perfectly formatted and the wording indicates to me that this program should output like that without any further manipulation. So my question is why am I not getting this output and how do I?

Thanks in advance

In the last post, we learned how to control the precision of the number we print as well as the number of spaces these numbers take up. The last thing we need to learn to output nice data tables is how to align text and numbers when we use .format().

Aligning text and numbers with .format()

We previously learned to specify the number of spaces allocated to the inputs we provide to .format(). Now we will see that we can tell Python how we want to align our text or numbers in these spaces. We can left-adjust (<), right-adjust (>) and center (^) our values. Here is a brief example:

# Example 1
print('L {:<20} R'.format('x'))
# Example 2
print('L {:^20} R'.format('x'))
# Example 3
print('L {:>20} R'.format('x'))

The output of these examples is:

Pretty cool. We told Python to leave 20 spaces for the text we wanted to enter, and depending on the symbol we specified, we were able to change the justification of our text.

You can even specify the character you want to use instead of empty spaces.

print ('{:=<20}'.format('hello'))
print ('{:_^20}'.format('hello'))
print ('{:.>20}'.format('hello'))

The output of these example is:

hello===============
_______hello________
...............hello

As you can see, .format() has lots of options. Visit the string documentation or this useful site if you want to learn more.

Putting it all together

When working with data, we often want to have a quick look to make sure there are no mistakes and to see if any patterns are present. One way to do this is to plot your data. However, some types of data tend to be better presented in a nicely structured table.

For this example, we will work with some made-up data:

data = [['NAME', 'AGE', 'HANDEDNESS', 'SCORE (%)'],
        ['Martin', 38, 'L', 54.123],
        ['Marty', 33, 'L', 32.438],
        ['Martine', 25, 'R', 71.128],
        ['Martyn', 59, 'R', 50.472],
        ['Mart', 23, 'L', 2.438],
        ['Martyne', 15, 'R', 71.128],
        ['Marlyn', 101, 'R', 0.472],
        ['Marti', 2, 'L', 55.438],
        ['Mardi', 9, 'R', 81.128],
        ['Martyne', 49, 'R', 24.472],
        ['Marteen', 91, 'L', 1.128]]

Note that the first row of data (data[0]) contains the column labels. The other rows contain the data for each subject.

As you might suspect, running print(data) does not result in a nice output (try it to see for yourself!). A better solution is to apply what we have learned to generate a nice table. Here is the code:

dash = '-' * 40

for i in range(len(data)):
    if i == 0:
      print(dash)
      print('{:<10s}{:>4s}{:>12s}{:>12s}'.format(data[i][0],data[i][1],data[i][2],data[i][3]))
      print(dash)
    else:
      print('{:<10s}{:>4d}{:^12s}{:>12.1f}'.format(data[i][0],data[i][1],data[i][2],data[i][3]))

The output of this code look like this:

----------------------------------------
NAME       AGE  HANDEDNESS   SCORE (%)
----------------------------------------
Martin      38     L              54.1
Marty       33     L              32.4
Martine     25     R              71.1
Martyn      59     R              50.5
Mart        23     L               2.4
Martyne     15     R              71.1
Marlyn     101     R               0.5
Marti        2     L              55.4
Mardi        9     R              81.1
Martyne     49     R              24.5
Marteen     91     L               1.1

In terms of the code, we first create a variable called dash that contains 40 dashes.

The code then looped over each of the 12 items in our data variable. If we are dealing with our first item (i.e., i = 0), we tell Python that we want to print a line of dashes, then print our headers, followed by another line of dashes. Notice how we specify the number of spaces we want for each header as well as the alignment of the text.

For all the other items in our data variable, we print the text and values using the same number of spaces used for the header, and specify whether we want to print integers (d), a strings (s) or floating point numbers (f). Note that because HANDEDNESS is such a long word, it looks better to center the text printed below it. Otherwise, the alignment is the same as for the header row.

Make sure you understand how this code works. To really consolidate your learning, try changing things in the print statements and see if it generates the expected outcome.

Conclusion

Hopefully you enjoyed these tutorials on the .format() string method and the print() function. Now you have no more excuses for ugly and uninformative print statements!

And if you want more readable Python print statements, consider using f-strings. As I discuss in this post, they are the modern way to print text in Python.

How do you do equal spacing in Python?

Use the center() Function to Pad Both Ends of a String With Spaces in Python. The center() function adds padding to both ends of a string in equal amounts.

How do you align prints in Python?

3. Aligning the output neatly using f-prefix. You can use the :> , :< or :^ option in the f-format to left align, right align or center align the text that you want to format. We can use the fortmat() string function in python to output the desired text in the order we want.

How do I print to the next column in Python?

Print With Column Alignment in Python.
Use the % Formatting to Print With Column Alignment in Python..
Use the format() Function to Print With Column Alignment in Python..
Use f-strings to Print With Column Alignment in Python..
Use the expandtabs() Function to Print With Column Alignment in Python..

What does %4d mean in Python?

%4d means 4 spaces and then after print and same %7.2f, but .2 indicate after point only show two values.