2

I'm making an EMI calculator, which displays an amortization table after displaying monthly EMI.

How can I right align the currency symbol and any n-digit decimal number?

I tried to right align currency symbol and amount by using '{0}{1:5.2f}'.format(rupee, amount) but it didn't solve the problem stating incorrect format string.

The amounts are floating point numbers with more than 2 decimal places, they need to rounded off upto 2 decimal places.

Here's the code which displays 4 amount values (I'm using INR as the currency symbol) :

rupee = chr(8377)
print('{0}{1:.2f}'.format(rupee, amount1))
print('{0}{1:.2f}'.format(rupee, amount2))
print('{0}{1:.2f}'.format(rupee, amount3))
print('{0}{1:.2f}'.format(rupee, amount4))

Some edits need to be made in this sample code to right align the currency symbol and amount, but I'm not able to figure that out.

Actual Output:

$1.07
$22.34
$213.08
$4.98

Expected Output:

  $1.07
 $22.34
$213.08
  $4.98

Taking $ symbol as the currency symbol because the rupee symbol can't be typed directly from the keyboard.

Preetkaran Singh
  • 502
  • 5
  • 19

2 Answers2

2

Extending the previous answer a little:

rupee = u'\u20B9'
amounts = [12345.67, 1.07, 22.34, 213.08, 4.98]

for amount in amounts:
    print('{:>10}'.format(rupee + '{:>.2f}'.format(amount)))

Output:

 ₹12345.67
     ₹1.07
    ₹22.34
   ₹213.08
     ₹4.98
hjonez
  • 71
  • 3
  • It's unclear what this answer adds to any other answers. –  Dec 20 '18 at 21:27
  • 1
    The question was how to format a number, not a string, which this answer shows – hjonez Dec 20 '18 at 21:40
  • Fair enough. That being said, why not have the currency symbol substitution part of the format string? Also, this code won't run because `format` appears to convert the Unicode to encoded text. e.g.: `print('{:>10}'.format('{}{:>.2f}'.format(rupee.encode('utf-8'), amount)))` –  Dec 20 '18 at 21:50
  • Thanks @hjonez, the print command `print('{:>10}'.format(rupee + '{:>.2f}'.format(amount)))` made my day and saved a lot of time, now all the amounts in my amortization table are right aligned. – Preetkaran Singh Dec 20 '18 at 23:24
  • @PreetkaranSingh as I mentioned earlier, this code isn't strictly portable, and could fail at runtime as per https://stackoverflow.com/q/9942594/1531971 There is a way to gaurd against Unicode encoding issues in that Q&A. –  Dec 21 '18 at 14:52
  • Thanks @jdv for the information about unicode characters in your mentioned link, actually I'm using `rupee = chr(8377)` `#ASCII code` for the currency symbol. So, what do u think about this? Would it still fail at runtime? Let me know by adding a comment – Preetkaran Singh Dec 21 '18 at 15:29
  • Moreover, I accepted this answer because only the **last line of @hjonez's code** solved my problem – Preetkaran Singh Dec 21 '18 at 15:31
  • @PreetkaranSingh on some systems with `chr` using larger Unicode values you might get "ValueError: chr() arg not in range". If you truly need to be portable (and maybe you don't) then you have to specify the encoding. See https://docs.python.org/2.7/howto/unicode.html –  Dec 21 '18 at 15:36
  • @jdv, You are absolutely correct in this context, I'm using `chr(8377)` which is actually a `utf-16` character code. So, In order to make my EMI calculator portable, what should I add/replace in the code? – Preetkaran Singh Dec 21 '18 at 15:47
  • 1
    @PreetkaranSingh portability and Unicode is too big to tack onto an already too long comment thread on an unrelated Answer! I suspect this has been answered already, so maybe research it a bit and read the link I gave that is the official discussion of Unicode-on-Python. But a quickish fix is in my code snippet, above where I use `.encode` against a Unicode String. Bear in mind I'm coming at this as a Java coder, so maybe Python has other considerations. –  Dec 21 '18 at 15:51
  • Thanks @jdv for your valuable comments and giving me an opportunity to learn about unicode strings. The following code also gives me satisfactory output, encoding and then decoding the string: `rupee = u'\u20B9'.encode('utf-8', errors='strict'); print(str(rupee, 'utf-8'))`. Let me know if it can be portable. Thanks again. – Preetkaran Singh Dec 26 '18 at 13:48
1

If you know the maximum number of characters in your output, then you can do something like the following. See Format Specification Mini-Language for the various available format specifiers.

amounts = ['$1.07', '$22.34', '$213.08', '$4.98']

for amount in amounts:
    print('{:>8}'.format(amount))

# OUTPUT
#   $1.07
#  $22.34
# $213.08
#   $4.98
benvc
  • 14,448
  • 4
  • 33
  • 54
  • I don't know the maximum number of digits, a number can have, due to the variability of EMIs in EMI calculator. Moreover, the numbers are not listed, they are stored into 4 float variables (principal, interest_amt, EMI, balance) – Preetkaran Singh Dec 20 '18 at 22:50
  • 1
    @PreetkaranSingh - the list was just for convenience to demonstrate the example. I don't know of a way to get python to dynamically align the print output without specifying the number of characters. You may have to test the length of each output to find the maximum and then generate your print statement accordingly. – benvc Dec 20 '18 at 22:55