Prev - #32 Convert Strings To Integers | Table of Contents | Next - #34 Uppercase Letters
commaFormat(12345) → '12,345'
In the US and UK, the digits of numbers are grouped with commas every three digits. For example, the number 79033516 is written as 79,033,516 for readability. In this exercise, you’ll write a function that takes a number and returns a string of the number with comma formatting.
Exercise Description
Write a commaFormat()
function with a number parameter. The argument for this parameter can be
an integer or floating-point number. Your function returns a string of this
number with proper US/UK comma formatting. There is a comma after every third
digit in the whole number part. There are no commas at all in the fractional
part: The proper comma formatting of 1234.5678 is 1,234.5678 and not
1,234.567,8.
These Python assert
statements stop
the program if their condition is False
. Copy them
to the bottom of your solution program. Your solution is correct if the following
assert
statements’ conditions are all True:
assert commaFormat(1) == '1'
assert commaFormat(10) == '10'
assert commaFormat(100) == '100'
assert commaFormat(1000) == '1,000'
assert commaFormat(10000) == '10,000'
assert commaFormat(100000) == '100,000'
assert commaFormat(1000000) == '1,000,000'
assert commaFormat(1234567890) == '1,234,567,890'
assert commaFormat(1000.123456) == '1,000.123456'
Try to write a solution based on the information in this description. If you still have trouble solving this exercise, read the Solution Design and Special Cases and Gotchas sections for additional hints.
Prerequisite concepts: strings, str()
,
in
operator, index()
,
slices, string concatenation
Solution Design
Despite involving numbers, this exercise is actually about text manipulation. The characters of the string just happen to be numeric digits.
First, we convert the number
argument
to a string with the str()
function. This will work whether
the number is an integer or a floating-point number. Once we have the number as a string, we can check for the existence of a
period which indicates it was a floating-point number with a fractional part. The
expression '.' in number
evaluates to True if the string in number has a period character. Next,
we can use number.index('.')
to find the index of
this period character. (The index()
method raises a ValueError exception if '.'
doesn’t appear in the string, but the previous '.'
in number expression being True
guarantees that it
does.)
We need to remove this fractional part from number
while saving it in another variable to add back in later. This way we are only
adding commas to the whole number part of the number
argument, whether or not it was an integer or floating-point number.
Next, let’s start variables named triplet
and commaNumber
as blank strings. As we loop over
the digits of number
, the triplet
variable will store digits until it has three of them, at which point we add
them to commaNumber
(which contains the
comma-formatted version of number) with a comma. The first time we add triplet to commaNumber
, there
will be an extra comma at the end of a number. For example, the triplet '248' gets added to commaNumber
as '248,'
. We can remove the extra comma just before
returning the number.
We need to loop starting at the one’s place in the number and
moving left, so our for
loop should work in reverse:
for i in range(len(number) - 1, -1, -1)
. For
example, if number
is 4096
,
then the first iteration of the loop can access number[3]
,
the second iteration can access number[2]
, and so
on. This way the first triplet ends up being '096'
instead of '409'
.
If the loop finishes and there are leftover digits in triplet, add them to commaNumber
with a comma. Finally, return commaNumber
except
with the comma at the end truncated: commaNumber[:-1]
evaluates to everything in commaNumber
except the
last character.
Finally, we need to add the fractional part back in the number if there was one originally.
Special Cases and Gotchas
Several bugs that can occur in our code. We should consider them ahead of writing our code so we can ensure they don’t sneak past us. These bugs could include:
·
A comma at the end of number, e.g., 386
producing '386,'
·
A comma at the front of a number, e.g., 499000
producing ',499,000'
·
Commas appearing in the fraction part, e.g., 12.3333
producing '12.3,333'
·
Grouping triplets in reverse order, e.g., 4096
producing '409,6'
However you tackle this exercise, ensure that your code doesn’t make any of these mistakes.
Now try to write a solution based on the information in the previous sections. If you still have trouble solving this exercise, read the Solution Template section for additional hints.
Solution Template
Try to first write a solution from scratch. But if you have difficulty, you can use the following partial program as a starting place. Copy the following code from https://invpy.com/commaformat-template.py and paste it into your code editor. Replace the underscores with code to make a working program:
def commaFormat(number):
# Convert the number to a string:
number = str(____)
# Remember the fractional part and remove it from the number, if any:
if '.' in ____:
fractionalPart = number[number.index(____):]
number = number[:number.index('.')]
else:
fractionalPart = ''
# Create a variable to hold triplets of digits and the
# comma-formatted string as it is built:
triplet = ____
commaNumber = ____
# Loop over the digits starting on the right side and going left:
for i in range(len(number) - 1, ____, ____):
# Add the digits to the triplet variable:
triplet = ____[i] + ____
# When the triplet variable has three digits, add it with a
# comma to the comma-formatted string:
if ____(triplet) == ____:
commaNumber = triplet + ',' + ____
# Reset the triplet variable back to a blank string:
triplet = ____
# If the triplet has any digits left over, add it with a comma
# to the comma-formatted string:
if triplet != '':
commaNumber = ____ + ',' + ____
# Return the comma-formatted string:
return ____[:____] + fractionalPart
The complete solution for this exercise is given in Appendix A and https://invpy.com/commaformat.py. You can view each step of this program as it runs under a debugger at https://invpy.com/commaformat-debug/.
Prev - #32 Convert Strings To Integers | Table of Contents | Next - #34 Uppercase Letters