0

Is there any way to do this kind of string formatting using PYTHON3

*************Food*************
initial deposit        1000.00
groceries               -10.15
restaurant and more foo -15.89
Transfer to Clothing    -50.00

where the numbers are aligned to the right and the texts are aligned to the left

ledger = [

    {'amount':10000,'description': 'initial deposit'},
    {'amount':-10.15,'description': 'groceries'},
    {'amount':-15.89,'description': 'restaurant and more food costings'},
    {'amount':-50,'description': 'Transfer to Clothing'}
    
]

please note that the value of the description key might depending on the user... so It might be much longer or it might also not these ones

if I do

string = ''
for dic in ledger:
    string += '{description:<23}{amount:>7.2f}'.format(**dic)
    string += '\n'

print(string)

the output is like this...

initial deposit        10000.00
groceries               -10.15
restaurant and more food costings -15.89
Transfer to Clothing    -50.00

but I want the description part to stop before the numbers

also the decimal points are not aligning

so what else am I missing here Thank You!!!!

4
  • Perhaps f-string helps. Commented Oct 19, 2021 at 19:14
  • yes it is! could add your python code of your data? Commented Oct 19, 2021 at 19:15
  • All the Python formatting methods allow you to specify whether a field is left or right aligned. Read the documentation. Commented Oct 19, 2021 at 19:16
  • Check out github.com/astanin/python-tabulate Commented Oct 19, 2021 at 19:18

2 Answers 2

2

You can do that by first calculating the with of the columns and then using f-strings. Also for the header of the table, str.center() is useful. Try:

ledger = [{'amount': 10000, 'description': 'initial deposit'},
          {'amount': -10.15, 'description': 'groceries'},
          {'amount': -15.89, 'description': 'restaurant and more food costings'},
          {'amount': -50, 'description': 'Transfer to Clothing'}]

width_desc = max(len(d['description']) for d in ledger)
width_amnt = max(len(f"{d['amount']:.2f}") for d in ledger)

print('Food'.center(width_desc + 1 + width_amnt, '*'))
for d in ledger:
    print(f"{d['description']:{width_desc}} {d['amount']:>{width_amnt}.2f}")

# *******************Food*******************
# initial deposit                   10000.00
# groceries                           -10.15
# restaurant and more food costings   -15.89
# Transfer to Clothing                -50.00
Sign up to request clarification or add additional context in comments.

Comments

0

By using f-strings you can do a lot of cool formating things in python 3. This guide is pretty good for learning about the different ways you can use f-strings in python.

To do a aligned table you can use fields like:

ages = {"Mike":10, "Leonardo":32, "Donatello":144, "Raphael":5}

for k, v in ages.items():
    print(f"{k:10}\t{v:10}")

Which will output

Mike            10        
Leonardo        32        
Donatello       144
Raphael         5

The f at the start of the string means its a f-string. The :10 after the variable means that it will be aligned in a ten character wide field. By default strings and most objects are left aligned while numbers are right aligned. To change the alignement you can use the < or > option before the number e.g. :<10. You could automatically determine the field width or cut off strings that are too long easily.

3 Comments

If i do this ages = {"Mike":10, "Leonardo":32, "Donatello the Donny":144, "Raphael":5} # in the place of Donatello using _DONATELLO THE DONNY_ for k, v in ages.items(): print(f"{k:10}\t{v:7.2f}") The alignment doesn't work anymore. Is there a way to cut of the rest of the strings
For example, you could slice the string. If you change the print statement to print(f"{k[:10]:10}\t{v:10}") it will cut off the string.
Or if you wanted it to automatically determine the length with a set max length:MAX_WIDTH = 20 width = max(a for a in ages.values()) if width > MAX_WIDTH: width = MAX_WIDTH for k, v in ages.items(): print(f"{k[:width]:{width}}\t{v:10}")

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.