Python data output formatting

Asked

Viewed 4,515 times

2

My question is about formatting output data from the program. I’m solving one of the exercises wiki.python.org, whose data entry is as follows::

alexandre       456123789
anderson        1245698456
antonio         123456456
carlos          91257581
cesar           987458
rosemary        789456125

This entry was saved in a type file .txt which must be opened by the programme, the data output must be similar to this:

ACME Inc.               Uso do espaço em disco pelos usuários
------------------------------------------------------------------------
Nr.  Usuário        Espaço utilizado     % do uso

1    alexandre       434,99 MB             16,85%
2    anderson       1187,99 MB             46,02%
3    antonio         117,73 MB              4,56%
4    carlos           87,03 MB              3,37%
5    cesar             0,94 MB              0,04%
6    rosemary        752,88 MB             29,16%

Espaço total ocupado: 2581,57 MB
Espaço médio ocupado: 430,26 MB

To solve the problem I wrote the following program:

soma = 0
nome, espaco = [], []
a = open("usuarios.txt")
for line in a:
    b = line.strip().split(" ")
    nome.append(b[0])
    espaco.append(b[1])
print("ACME Inc.               Uso do espaço em disco pelos usuários")
print("------------------------------------------------------------------------")
print("Nr.",end = "  ")
print("Usuário",end = "      ")
print("Espaço utilizado",end = "      ")
print("% do uso")
print(" ")
for j in range(len(nome)):
    espaco[j] = int(espaco[j])
    soma += espaco[j]
for i in range(len(nome)):
    print(i+1,end = "    ")
    print(nome[i],end = "    ")
    espaco[i] = int(espaco[i])
    print("{:.2f} MB".format(espaco[i]/(1024*1024)),end = "    ")
    print("{:.2f}%".format((espaco[i]/soma)*100))
print("")
print("Espaço total ocupado: {:.2f} MB".format(soma/(1024*1024)))
print("Espaço médio ocupado: {:.2f} MB".format((soma/(1024*1024))/len(espaco)))

My data output is as follows:

ACME Inc.               Uso do espaço em disco pelos usuários
------------------------------------------------------------------------
Nr.  Usuário      Espaço utilizado      % do uso

1    alexandre    434.99 MB    16.85%
2    anderson    1187.99 MB    46.02%
3    antonio    117.74 MB    4.56%
4    carlos    87.03 MB    3.37%
5    cesar    0.94 MB    0.04%
6    rosemary    752.88 MB    29.16%

Espaço total ocupado: 2581.58 MB
Espaço médio ocupado: 430.26 MB

As you can see, the output is all crooked, doesn’t have the values exactly under each other, as the statement asks. How do I format this?

1 answer

4


You formulated the solution incorrectly. It is not the size of the spacing between the values that is constant, but the width available for each column.

If you notice the desired output:

1    alexandre       434,99 MB             16,85%
2    anderson       1187,99 MB             46,02%
3    antonio         117,73 MB              4,56%
4    carlos           87,03 MB              3,37%
5    cesar             0,94 MB              0,04%
6    rosemary        752,88 MB             29,16%

You’ll see that:

  • The first column has 5 characters wide, aligned to the left;
  • The second column has 12 characters wide, aligned to the left;
  • The third column has 13 characters wide, aligned to the direct;
  • The fourth column has 19 characters wide, aligned to the right;

Thus, considering the data:

número, nome, espaço, porcentagem = 1, 'alexandre', '434,99 MB', '16,85%'

You can format the line using f-string:

f'{número: <5}{nome: <12}{espaço: >13}{porcentagem: >19}'

In which the instruction {número: <5} means:

  • Use the value of the object número;
  • Use whitespace as the fill character;
  • Line up on the left;
  • Occupying at least 5 characters wide;

Equivalent to other objects. You can read more on:

The way I would solve it is:

output = '''
ACME Inc.               Uso do espaço em disco pelos usuários
------------------------------------------------------------------------
Nr.  Usuário        Espaço utilizado     % do uso

{usuarios}

Espaço total ocupado: {total:.2f} MB
Espaço médio ocupado: {media:.2f} MB
'''

def format_user_info(i, name, space, total):
    percentage = 100*space/total
    return f'{i: <5}{name: <12}{space: >10.2f} MB{percentage: >18.2f}%'

users = []

with open('data.txt') as stream:
    for line in stream:
        name, space = line.strip().split(' ', 1)
        users.append((name, int(space)/1024**2))

total = sum(user[1] for user in users)
media = total / len(users)

users = [
    format_user_info(i, name, space, total) 
        for i, (name, space) in enumerate(users, 1)
]

print(output.format(usuarios='\n'.join(users), total=total, media=media))

See working on Repl.it

What would produce the output:

ACME Inc.               Uso do espaço em disco pelos usuários
------------------------------------------------------------------------
Nr.  Usuário        Espaço utilizado     % do uso

1    alexandre       434.99 MB             16.85%
2    anderson       1187.99 MB             46.02%
3    antonio         117.74 MB              4.56%
4    carlos           87.03 MB              3.37%
5    cesar             0.94 MB              0.04%
6    rosemary        752.88 MB             29.16%

Espaço total ocupado: 2581.58 MB
Espaço médio ocupado: 430.26 MB

Browser other questions tagged

You are not signed in. Login or sign up in order to post.