Help with Exercise Project Thread Shed

Hey all,

I’m currently working my way through the ‘Thread Shed’ exercise project in the Python 3 course.
https://www.codecademy.com/courses/learn-python-3/projects/thread-shed

I have a question about steps 13-15.

Here’s my code:

#10
customers = []
sales = []
thread_sold = []

#13
total_sales = 0

#14
for sale in sales:
  s = float(sale.strip('$'))
  total_sales += s

#15
print(format(total_sales, '.2f'))

given that the values in the list [sales] are all money values (ex: 12.23), how can the result be “1498.7400000000005”? I had to format it to 1498.74 in order for it to make sense as a money value. From my understanding, all the code is doing is sequentially adding values that were provided in the list.

How can the sum of a series of numbers that only extend to two digits right of the period return a number that is 13 digits right of the period? Did I do something wrong? The exercise says to use float. I can provide the list of numbers, but its quite long so it was intentionally excluded.

Thanks

Hello @wontoncracker, welcome back! Could you post your full code, so we can see what is happening? Other than that, I would guess this is the problem:

You’re concatenating the strings, but you aren’t adding them. So if you have two strings:

a = "2"
b = "3"
c = a + b
print(c)#Will print "23", because you are concatenating strings, not actually
#adding numbers

You could try to use a built in method to convert types.

I hope this helps!
EDIT: Sorry, I didn’t see the use of float().

Here’s all of my code so far:

#2
daily_sales_replaced = daily_sales.replace(';,;', ';')
#print(daily_sales_replaced)
#3
daily_transactions = daily_sales_replaced.split(',')
#4
#print(daily_transactions)
#5
daily_transactions_split = []
#6
for i in daily_transactions:
  daily_transactions_split.append(i.split(';'))
#7
#print(daily_transactions_split)
#8
transactions_clean = []
for transaction in daily_transactions_split:
  transaction_clean = []
  for trans in transaction:
    transaction_clean.append(trans.strip())
  transactions_clean.append(transaction_clean)
#9
#print(transactions_clean)
#10
customers = []
sales = []
thread_sold = []
#11
for t in transactions_clean:
  customers.append(t[0])
  sales.append(t[1])
  thread_sold.append(t[2])
#12
#print(customers)
print(sales)
#print(thread_sold)
#13
total_sales = 0
#14
for sale in sales:
  s = float(sale.strip('$'))
  total_sales += s
#15
print("The total sales are: $" + (format(total_sales, '.2f')))

Here’s the list of numbers in the list [sales]:

['$1.21', '$7.29', '$12.52', '$5.13', '$20.39', '$30.82', '$1.85', '$17.98', '$17.41', '$28.59', '$14.51', '$19.64', '$11.40', '$8.79', '$8.65', '$10.53', '$16.49', '$6.55', '$11.86', '$22.29', '$8.35', '$2.91', '$22.94', '$4.70', '$3.59', '$5.66', '$17.51', '$5.54', '$17.13', '$21.13', '$0.35', '$13.91', '$19.26', '$5.45', '$5.50', '$14.56', '$7.33', '$20.22', '$8.67', '$8.31', '$15.70', '$6.74', '$30.84', '$12.31', '$2.94', '$22.46', '$6.60', '$6.27', '$21.12', '$2.10', '$14.22', '$11.60', '$25.27', '$8.26', '$30.80', '$22.61', '$22.19', '$7.47', '$5.49', '$23.70', '$26.66', '$25.95', '$19.55', '$15.68', '$23.57', '$29.32', '$26.44', '$17.24', '$8.49', '$13.10', '$20.39', '$14.70', '$22.45', '$28.46', '$23.89', '$24.49', '$1.81', '$6.81', '$0.65', '$26.45', '$7.69', '$8.74', '$1.86', '$14.75', '$28.10', '$9.91', '$16.34', '$27.57', '$5.25', '$9.51', '$20.56', '$21.64', '$24.99', '$29.70', '$15.52', '$15.70', '$12.36', '$13.66', '$30.52', '$22.66']

The sum of the numbers is accurate. Im just confused as to why the result is 13 digits long, instead of 2, like the numbers in the list.

I reviewed the video solution, and it returned the same results in the tutorial as it did for me.

Is this just how float works? I’m really confused how that works out mathematically.

Hello @wontoncracker. Yes as far as I know, floats do work like, that’s why there are built in methods to round them when using them with strings (.2f), etc. But I could be wrong. @thepitycoder, do you know why this happens?

Yes, that’s just how floats work.

The reason for this is because floating point arithmetic has an intrinsic inaccuracy.

The simple explanation of why this happens is because Python, like any programming language, uses a finite number of bits to store numbers. It’s not always possible to store a precise binary representation of a number in that finite space, and so you get a small rounding error.

A simple example of this is to do the following in Python:

>>> 1.2 - 1.0
0.19999999999999996
>>>

You and I know that 1.2 - 1.0 = 0.2, so why is Python saying it’s 0.19999999999999996?

It all comes down to binary fractions.

In decimal (base-10) numbers, we know that fractions work like this:

0.1 = 1/10
0.01 = 1/100
0.001 = 1/1000
...

It’s not the same in binary (base-2), which is what your computer understands. Binary fractions look like this:

0.1 = 1/2
0.01 = 1/4
0.001 = 1/8
0.0001 = 1/16
...

0.2 = 1/5 (one fifth), but we don’t have 1/5 in the binary fractions above…

As it happens, 1/5 === 2/10, and one-tenth is an infinitely repeating binary fraction:

0.0001100110011001100110011001100110011001100110011...

If we multiply that by two, to make 2/10 (or 1/5), we move everything after the point one digit to the left, to get:

0.0011001100110011001100110011001100110011001100110...

This is still an infinitely repeating fraction.

We don’t have infinite space to store this value, so at some point Python (like all programming languages) cuts it off. As a result, your calculation is ever so slightly off

If you’re interested in reading more about floating point arithmetic, there’s a section of the Python documentation which deals with it. You can also do a Google search for “floating point arithmetic inaccuracy”, and you’ll likely find a wealth of information on the subject.

Yay for math! :smiley:

2 Likes

I guess this means there is still room for improvement in coding. :grinning:

Thanks so much for the explanation! I understand now.

1 Like

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.