Getting 27 for the “white” count instead of 28

Hi everyone, just started this challenge, and my first forum post, but for some reason i’m getting 27 for the “white” count instead of 28 and i’m not sure why.

daily_sales_replaced=daily_sales.replace(“;,;”,“:”)
daily_transactions=daily_sales_replaced.split(“,”)
#print(daily_transactions)

daily_transactions_split=
for transaction in daily_transactions:
daily_transactions_split.append(transaction.split(“:”))
#print(daily_transactions_split)

transactions_clean=
for transaction in daily_transactions_split:
for instance in transaction:
transactions_clean.append(instance.strip())
#print(transactions_clean)

customers=
sales=
thread_sold=
i=0
for i in range(0,len(transactions_clean)-4,4):
customers.append(transactions_clean[i])
sales.append(transactions_clean[i+1])
thread_sold.append(transactions_clean[i+2])
#print(customers, sales, thread_sold)

total_sales=0
for purchase in sales:
total_sales+=float(purchase.replace(“$”,“”))
#print(total_sales)

#print(thread_sold)
thread_sold_split=
for sale in thread_sold:
for colour in sale.split(“&”):
thread_sold_split.append(colour)
#print(thread_sold_split)

def color_count(color):
count=0
for colour in thread_sold_split:
if colour==color:
count+=1
return count
print(color_count(“white”))

Hi I wrote the following code for “Thread Shed” but the counting that I receiving is not even close to the counts in the example (and in the video) I don’t understand what’s wrong in my counter function
this is the code:
daily_sales_replaced = daily_sales.replace(’;,;’,’;’)
daily_transaction = daily_sales_replaced.split(’,’)
#print (daily_transaction)
daily_transactions_split =
for tran in daily_transaction:
daily_transactions_split.append(tran.split(’;’))
#print(daily_transactions_split)

transactions_clean =
for trans in daily_transactions_split:
transaction_clean =
for data in trans:
transaction_clean.append(data.replace(“\n”," “).strip(” "))
transactions_clean.append(transaction_clean)

customers =
sales =
thread_sold =

for transa in transactions_clean:
customers.append(transa[0])
sales.append(transa[1])
thread_sold.append(transa[2])

total_sales = 0
for price in sales:
total_sales+=float(price.strip(’$’))

#print (total_sales)
#print (thread_sold)

thread_sold_split =
for sale in thread_sold:
for color in sale.split(’&’):
thread_sold_split.append(color)

print (thread_sold_split)

def color_count(color):
total_colors = 0
for tred_color in thread_sold_split:
if tred_color == color:
total_colors += 1
return total_colors

#print(color_count(‘white’))

colors = [‘red’,‘yellow’,‘green’,‘white’,‘black’,‘blue’,‘purple’]

for color in colors:
print (“Thread Shed sold {} threads of {} threads today.”.format(color_count(color),color))

and these are the results:
Thread Shed sold 96 threads of red threads today.
Thread Shed sold 136 threads of yellow threads today.
Thread Shed sold 120 threads of green threads today.
Thread Shed sold 112 threads of white threads today.
Thread Shed sold 104 threads of black threads today.
Thread Shed sold 88 threads of blue threads today.
Thread Shed sold 68 threads of purple threads today.

If you write lots of code, then run it, then, yeah, it’s probably wrong. It’s a more interactive process than that. Write one action, run it, did it have the desired effect, write another, and so on.

You made a measurement at the end of your code by printing something out. You can make measurements earlier in the process as well in order to observe what is being done.

So if you start making measurements throughout the code, when do things start being wrong?

Great explanation. But how do you fix the nesting list of lists?
I am stuck on the same problem and did the same thing haha.

I have a strange result in this challenge. In place where we are supposed to sum all sales I do this with following code:

total_sales = 0
for sale in sales:
  cs = sale.strip("$")
  total_sales += float(cs)
print(total_sales)

My result is 1498.7400000000005

Where is that 00000000005 at the end coming from? All that is added are prices, so max two numbers after a decimal point

2 Likes

Use int rather than float if you do not wish to approximate.
float is NOT for representing fractional values, it is for fast (implemented by hardware) approximation of numbers of both large and small numbers. Not suitable if you expect them to behave like school book math.

For most purposes you do not want to use float.

But integer doesn’t store numbers with decimal points so in this example it wouldn’t work. What datatype should I use to properly calculate decimals?

It’s an integer amount of cents.

For things that really aren’t integer (this is), you can use fractions or Decimal

1 Like

You mean to first split it around “.” and then add everything together and then somehow add the dot back? I have to look up that Decimal datatype, because that seems like too much work :stuck_out_tongue:

As if you weren’t doing all kinds of splitting already…

I suggest using int over Decimal because int is a simpler type and it is able to represent what you have.

In my version of this I parsed each entry like so:

pPurchase :: Parser Purchase
pPurchase = do
  name <- T.strip <$> takeWhileP Nothing (/= '|')
  "|" >> space >> "$"
  dollars <- decimal
  "."
  cents <- decimal
  space >> "|"
  item <- T.strip <$> takeWhileP Nothing (/= '|')
  "|"
  date <- T.strip <$> takeRest
  pure $ Purchase { name, cents = dollars * 100 + cents, item, date }

read up until | for the name
then read the | and spaces and $
read a number
read a dot (ignore)
read a second number
… another |
read up until next | for the name of the item
and a date for the rest

Which is matching on different things and extracting matches.
You could use regex to similar effect I suppose, but splitting will do the job just fine.

1 Like

This is too much for me right now. I cannot understand it, is this Python? But I have another problem.

This code

thread_sold_split = []
for item in thread_sold:
  if item.count("&") == 0:
   thread_sold_split.append(item)
  else:
    thread_sold_split.append(item.split('&'))

Gives me the list of sold colours, but in case of the ones that were joined with “&” I get a list inside a list i.e. [‘white’, [‘white’, ‘blue’], [‘white’, ‘blue’], ‘white’, [‘white’, ‘yellow’], ‘purple’, [‘purple’, ‘yellow’], [‘purple’, ‘yellow’], ‘blue’, ‘blue’, [‘purple’, ‘blue’], ‘white’, [‘white’, ‘red’]]

Is there a way to avoid it? I tried but I always end up with lists inside lists.

You weren’t exactly expected to understand it (it’s not python), only to see that parts are being extracted and treated differently to produce an internal representation.

So you’d grab the dollar amount and the cent amount which are delimited by ".", convert each number to int, multiply the dollar amount by 100 and add to the cents


Your nested lists, you have a condition to tell apart single value from multiple values, so maybe you should add the multiple values instead of adding the list of multiple values…? Add the values, not the structure holding the values.

You should at the very least be able to trace where you’re introducing the nested list, and then reconsider what you were doing there. Well I guess I did but. Yeah.

Ok, now I see that I’m adding a list that contains “&” to the list so yeah, that was not intended. ut whateer other methods I can think of will just do the same. I tried going deeper like
for element in list:
for piece of element:
but it just made my list full of individual characters.

I don’t know any way to acces individual colors we get . I even tried this:

thread_sold_split = []
for item in thread_sold:
  if item.count("&") == 0:
    thread_sold_split.append(item)
  else:
    thread_sold_split += item.replace("&", ", ")

And again I got individual letters. And I don’t know why, because “item” in my code refers to each sale of thread. In the if loop it is treated as such ut somehow in the else loop it refers to each individual letter, why is that?

So I can get them as lists inside lists, as individual letters ot not in between - separate words. Could I ask you for a tiny hint? My only other idea is to use count() and a for loop and for each time a color is on a list append it to the thread_sold_split, but it doesn’t seem good, what if we wanted to zip those lists later? :confused:

EDIT: I gave up and checked the solution and not happy with it. The specifically tell us in the exercise description:

Next, iterate through thread_sold. For each item, check if it is a single color or multiple colors. If it is a single color, append that color to thread_sold_split .

If it is multiple colors, first split the string around the & character and then add each color indivudally to thread_sold_split .

The way it’s worded I understood that we were supposed to do one thing first and then the second one, this is eacuse I used for, else and didn’t even consider doing it any other way. But problem is that in solution they this line:

for color in sale.split("&"):

We were not told that we can use string method inside for loop declaration like this. It’s not obvious for someone with no coding experience and if they want us to be able to come with solutions like this they should give us more exercises to help with this type of thinking.

We were also told that split does not create new list so if you want to use it you have to create variable that will hold it. How could I know that “for x in y” is creating a variable?!

To access each thing in a list… use a loop.

that’s going to result in one string, wasn’t the purpose to have several strings? you’d need to split it

stop trying random things and consider what you’ve got, and then decide what you want from it, and then decide on an action that matches that.

decide what you need to do, and do that, and nothing else. there’s no trying various stuff involved in that.

same as “and not” those are two separate things each of which, yes, you know, so using both near each other is not a new thing

nor do you need to write exactly that, there isn’t one single valid solution.

Uhm. You’ve probably been using that a lot, how else would you use a loop if it didn’t create the variable x?

if it doesn’t create a new list then what does it do?
it gives you a value you can do whatever you want with that value, you can bind a variable to it if you want but that doesn’t really change anything in any meaningful way.
and yes, that value is a list.

When we are taught for loops, it is described something like this…

for element in iterable:

It can be any iterable, a string, a list, a tuple, a set, a dict, or an iterator such as map, filter, zip, etc.

We learned that str.split() returns a new list, so as it appears here is also iterable, so,

for x in str.split(separator):

where separator can be any character string, hence we see,

for color in sale.split('&'):

It is not necessary in this case to assign it to any variable since it is a list object, already. Nothing is keeping us from creating an intermediate variable, and then using it, but on refactoring we would eventually revert to the above.

sale_split_on_ampersand = sale.split('&')

for color in sale_split_on_ampersand:

Blockquote
My code for this, is there any way to make it cleaner ?

daily_sales_replaced = daily_sales.replace(";,;",";")
daily_transactions = daily_sales_replaced.split(",")

daily_transactions_split = []

for i in daily_transactions:
  daily_transactions_split.append(i.split(";"))

transactions_clean = []

for i in daily_transactions_split:
  for a in i:
    transactions_clean.append(a.strip())


customers = transactions_clean[0::4]
sales = transactions_clean[1::4]
thread_sold = transactions_clean[2::4]


total_sales = 0
for i in sales:
  value = float(i.strip("$"))
  total_sales += value
thread_sold_a = []
thread_sold_split = []
for i in thread_sold:
  if i.find("&") == True:
    thread_sold_split.append(i)
  else:
    for a in i.split("&"):
      thread_sold_split.append(a)
#print(thread_sold_split)
      
def color_count(color):
  color_count = 0
  for a in thread_sold_split:
    if a == color:
      color_count += 1
  return color_count

#print(color_count("white"))  

colors = ['red','yellow','green','white','black','blue','purple']

for i in colors:
  print(f"Thread Shed sold {color_count(i)} threads of {i} thread today")
    

If you think of your program like a big math expression to be simplified with parts of it cancelling out and removed … then yeah there’s a fair bit you can get rid of in that.

For example, a lot of your loops are iterating through the same thing. An entry from the input. They could all be the same loop.

Splitting on “&” can be done regardless of whether there’s a “&” in it. You have two separate cases for that, they’re the same thing.

This really helped thanks.

1 Like

I am stuck at #11 where it’s asking for customer, sales, and thread_sold.
Does anyone here have the solution to this, or the entire project?

I have managed to produced transactions_clean to be a list of lists of strings.
e.g.

print(transactions_clean[0]) 
['Edith Mcbride   ;$1.21   ;   white ; 09/15/17']
print(transactions_clean[99])
['Myrtle Morris \n;   $22.66   ; green&white&blue;09/15/17']

Is this what we are suppose to have right up to this point?

If not, then what is transactions_clean suppose to look like?

This is what I get…

['Edith Mcbride', '$1.21', 'white', '09/15/17']
# ...
['Myrtle Morris', '$22.66', 'green&white&blue', '09/15/17']

It is still possible for you to finish cleaning up the content you have to this point.

transactions_cleaner = []
for x in transactions_clean:
    transactions_cleaner.append(x.split(';').strip())

print (transactions_cleaner[0])

See what that looks like. In review, how could we write the earlier code so this step is not needed (that is, so we get the result shown above).