Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

[Dúvida] Alinhar na escrita do arquivo

Olá galera! Tudo bom??

Estou estudando a manipulação de arquivos no Python e me deparei com um exercício que devo manipular um arquivo para gerar uma saída.

Contudo, estou com dificuldades para alinhar os elementos na escrita do arquivo final.

Alguém poderia por favor me dar uma luz?

def converter_bytes(memoria):
    memoria = round(memoria / 1048576, 2)
    return memoria


def calculo_percentual(dado, total):
    percentual = round((dado / total) * 100, 2)
    return percentual


usuarios = []
total = 0
media = 0
i = 1

with open('usuarios.txt', 'r') as arquivo:
    for linha in arquivo:
        usuarios.append(linha.split())
    for usuario in usuarios:
        usuario[1] = converter_bytes(int(usuario[1]))
        total += usuario[1]
    for usuario in usuarios:
        usuario.append(calculo_percentual(usuario[1], total))
    media = round(total / len(usuarios), 2)

with open('relatório.txt', 'w') as arquivo2:
    arquivo2.write('ACME Inc.               Uso do espaço em disco pelos usuários\n')
    arquivo2.write('-----------------------------------------------------------------\n')
    arquivo2.write('-------\n')
    arquivo2.write('Nr.  Usuário        Espaço utilizado     % do uso\n\n')
    for usuario in usuarios:
        arquivo2.write('{}{}{} MB{}%\n'.format(i, usuario[0], usuario[1], usuario[2]))
        i += 1
    arquivo2.write('\nEspaço total ocupado: {} MB\n'.format(total))
    arquivo2.write('Espaço médio ocupado: {} MB\n'.format(media))
2 respostas

Olá!

Sei que vai rolar um monólogo hahhah, mas dei uma estudada a mais e consegui escrever esse código.

def converter_bytes(memoria):
    memoria = round(memoria / 1048576, 2)
    return memoria


def calculo_percentual(dado, total):
    percentual = round((dado / total) * 100, 2)
    return percentual


usuarios = []
total = 0
media = 0
i = 1

with open('usuarios.txt', 'r') as arquivo:
    for linha in arquivo:
        usuarios.append(linha.split())
    for usuario in usuarios:
        usuario[1] = converter_bytes(int(usuario[1]))
        total += usuario[1]
    for usuario in usuarios:
        usuario.append(calculo_percentual(usuario[1], total))
    media = round(total / len(usuarios), 2)

with open('relatório.txt', 'w') as arquivo2:
    arquivo2.write('ACME Inc.               Uso do espaço em disco pelos usuários\n')
    arquivo2.write('-----------------------------------------------------------------\n')
    arquivo2.write('-------\n')
    arquivo2.write('Nr.  Usuário        Espaço utilizado     % do uso\n\n')
    for usuario in usuarios:
        arquivo2.write(
            str(i) + '\t' +
            '{:<15}'.format(str(usuario[0])) + '\t' +
            '{:<16}'.format(str(usuario[1])) + 'MB' + '\t' +
            str(usuario[2]) + '%' + '\n'
        )
        i += 1
    arquivo2.write('\nEspaço total ocupado: {} MB\n'.format(total))
    arquivo2.write('Espaço médio ocupado: {} MB\n'.format(media))

Mas o "MB" ao final não está alinhado com os números.

Obs:

Arquivo de entrada

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Arquivo de saída(esperado)

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Arquivo de saída que ocorre:

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

solução!

Opa, Adriano, como vai?

Fique tranquilo que não vai rolar um monólogo, estou aqui para tentar lhe ajudar!

O problema em questão, está sendo causado pelo uso de um alinhamento fixo para o valor da memória usando {:<16}'.format(str(usuario[1])), o que pode não funcionar bem quando o valor da memória for maior ou menor.

Uma maneira de resolver isso é calcular o comprimento máximo dos valores de memória (MB) e, em seguida, usar esse comprimento máximo para alinhar os valores no relatório. Aqui está uma versão modificada do seu código que faz isso:

def converter_bytes(memoria):
    memoria = round(memoria / 1048576, 2)
    return memoria


def calculo_percentual(dado, total):
    percentual = round((dado / total) * 100, 2)
    return percentual


usuarios = []
total = 0
media = 0
i = 1

with open('usuarios.txt', 'r') as arquivo:
    for linha in arquivo:
        usuarios.append(linha.split())
    for usuario in usuarios:
        usuario[1] = converter_bytes(int(usuario[1]))
        total += usuario[1]
    for usuario in usuarios:
        usuario.append(calculo_percentual(usuario[1], total))
    media = round(total / len(usuarios), 2)

# Encontar o comprimento máximo dos valores de memória e porcentagem
max_len_memoria = max(len('{:.2f}MB'.format(usuario[1])) for usuario in usuarios)
max_len_percentual = max(len('{:.2f}%'.format(usuario[2])) for usuario in usuarios)

with open('relatório.txt', 'w') as arquivo2:
    arquivo2.write('ACME Inc.               Uso do espaço em disco pelos usuários\n')
    arquivo2.write('-----------------------------------------------------------------\n')
    arquivo2.write('-------\n')
    arquivo2.write('Nr.  Usuário        Espaço utilizado     % do uso\n\n')
    for usuario in usuarios:
        arquivo2.write(
            str(i) + '\t' +
            '{:<15}'.format(str(usuario[0])) + '\t' +
            '{:<{max_len_memoria}}MB'.format('{:.2f}'.format(usuario[1]), max_len_memoria=max_len_memoria) + '\t' +
            '{:>{max_len_percentual}}%'.format('{:.2f}'.format(usuario[2]), max_len_percentual=max_len_percentual) + '\n'
        )
        i += 1
    arquivo2.write('\nEspaço total ocupado: {:.2f} MB\n'.format(total))
    arquivo2.write('Espaço médio ocupado: {:.2f} MB\n'.format(media))

Quando estava tentando ajustar o MB acabei deixando os valores da porcentagem um pouco desalinhados, então, implementei para ele um ajuste igualmente como fiz para o MB.

Espero ter lhe ajudado e caso tenha mais problemas ou dúvidas acerca deste tópico, estarei à disposição para ajudá-lo.

Grande abraço e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓.