# Dynamic String Alignment Code

My code works for user output alignment to the right side by maximum length of 4 different user input. I have 2 question.

1. Is there a simplier way for append method in my code ?
2. Is there a simplier way for right alignment by maximum legth of 4 different user input.

"""
Main purpose of this code is alignment of the user output to the right
"""
# Take Input from User
name = input("Name: ")
surname = input("Surname: ")
age = input("Age: ")
occupation = input("Occupation: ")
person_dict = {"Name": name, "Surname": surname, "Age": age, "Occupation": occupation}

# Calculate Maximum Character Length
len_list1 = []
len_name = len(name)
len_list1.append(len_name)
len_surname = len(surname)
len_list1.append(len_surname)
len_age = len(age)
len_list1.append(len_age)
len_occupation = len(occupation)
len_list1.append(len_occupation)
a = max(len_list1)

# Output
print(f'Name:       {person_dict["Name"]:>{a}}\n'
f'Surname:    {person_dict["Surname"]:>{a}}\n'
f'Age:        {person_dict["Age"]:>{a}}\n'
f'Occupation: {person_dict["Occupation"]:>{a}}'
)


All the code from len_list1 = [] to a = max(len_list1) can be replaced with:

a = len(max(person_dict.values(), key=len))


max's key parameter is really helpful here. key is called on each element before max checks it. Dictionary's values method is useful here too. If you already have the data in a dictionary, you might as well make use of that fact.

You could also use a generator expression here to have the same effect:

a = max(len(val) for val in person_dict.values())


Or, since we're just mapping using an existing function, map would be clean here as well:

a = max(map(len, person_dict.values()))


The point is, use iteration constructs to avoid needing to repeat the same code over and over again for different objects.

Your in- and output and the calculation of the column width can be simplified. The latter has already been shown in the other answer, but the former can just use a loop and the fact that dictionaries are guaranteed to be ordered (Python 3.7+, use a OrderedDict otherwise).

keys = ["Name", "Surname", "Age", "Occupation"]
person = {key: input(f"{key}: ") for key in keys}
width_keys = max(map(len, person.keys()))
width_values = max(map(len, person.values()))

for key, value in person.items():
print(f"{key+':':<{width_keys+1}} {value:>{width_values}}")


Note that I also made the justification of the keys automatic. If you want to take this further, a nice exercise would be to write a function that takes a 2D nested list and a list of alignments and which outputs the correctly justified table (which is what this is in the end).

• Thank you for your improvement advice. I don't understand the way you take input 'person = {key: input(f"{key.......' is there any recomendation about how can i learn this expression ? – Gokberk Apr 24 '20 at 11:29
• @Gokberk It is a dictionary comprehension, which builds the dictionary in one go. It works similar to a list comprehension except that you set the key and value, instead of just a value. A simplified version you might see more often would be {key: value for key, value in zip(keys, values)} or, more similar to the case here, {key: func(key) for key in keys}. – Graipher Apr 24 '20 at 11:35
• I feel like level up :) Thank You again – Gokberk Apr 24 '20 at 12:17