can some one help me with my code. thanks

T

Tamanna Sultana

can some one help me??
I would like to create a function that, given a bin, which is a list
(example below), generates averages for the numbers separated by a
string 'end'. I am expecting to have 4 averages from the above bin,
since there are 4 sets of numbers separated by 4 'end' strings

['2598.95165', '2541.220308', '221068.0401', 'end', '4834.581952',
'1056.394859', '3010.609563', '2421.437603', '4619.861889',
'746.040504', '268.3881793', '379.3934898', '1252.527752',
'11459.88522', '4862.167506', '506.924289', '634.6737389',
'496.4679199', '17941.59143', '919.4998935', '7247.610974',
'1166.053214', '47360.91508', '855.2426137', '4020.444585',
'4469.896904', '2615.874982', '19862.92009', '2379.619573',
'1203.268956', '4399.589212', '6838.825864', '1848.407564',
'3527.198403', '33976.85042', '818.8722263', '634.6652078',
'469.2685928', '4864.830004', '5103.222941', '1011.239929',
'829.9915382', '8571.237936', '3301.953656', '14594.47385',
'25688.83822', '4024.393045', '4163.775185', '1775.894366',
'3682.012227', '3371.092883', '6651.509488', '7906.092773',
'7297.133447', 'end', '4566.874299', 'end', '4255.700077',
'1857.648393', '11289.48095', '2070.981805', '1817.505094',
'1892.256615', '1757.0048', '59458.46328', '778.5755201', '54987.32423',
'2245.172711', '722.2619663', '5116.616632', '3427.865861',
'17973.07118', '14398.74281', '66313.92115', '11585.24151',
'45294.03043', '6524.744077', '25958.80015', '593.3786209',
'2899.040703', '85577.21342', '153576.2633', '5852.008444',
'563.0265409', '70796.45356', '565.2123689', '6560.030116',
'2668.934414', '418.666014', '5216.392132', '760.894589', '8072.957639',
'346.5905371', 'end']
If you can give me some lead to fix the code I wrote below that will be great:
def average(bin):
num=[]
total = 0.0
count=0
for number in bin:
while True:
if number!='end':
number=float(number)
total += float(number)
count+=1
avg = total/count
if number=='end':
break
num.append(avg)
return num
 
T

Terry Reedy

can some one help me??

[Posting your overly long set of data lines with a '>' quote at the
beginning of each line was a nuisance. Reposted with few lines. I will
let you compare your code to mine.]

bin = ['2598.95165', '2541.220308', '221068.0401', 'end', '4834.581952',
'1056.394859', '3010.609563', '2421.437603', '4619.861889',
'3682.012227', '3371.092883', '6651.509488', '7906.092773',
'7297.133447', 'end', '4566.874299', 'end', '4255.700077',
'1857.648393', '11289.48095', '2070.981805', '1817.505094',
'563.0265409', '70796.45356', '565.2123689', '6560.030116',
'2668.934414', '418.666014', '5216.392132', '760.894589', '8072.957639',
'346.5905371', 'end']

def average(bin):
num=[]
total = 0.0
count=0
for number in bin:
if number!='end':
total += float(number)
count+=1
else:
num.append(total/count)
total = 0.0
count= 0
return num

print(average(bin))
[75402.73735266666, 4485.0726684, 4566.874299, 7817.36494866]
 
T

Tim Chase

def average(bin):
num=[]
total = 0.0
count=0
for number in bin:
if number!='end':
total += float(number)
count+=1
else:
num.append(total/count)
total = 0.0
count= 0
return num

print(average(['end']))

ka-blooie! :)

would be worth noting what should happen in the event of an empty
bin.

-tkc
 
T

Terry Reedy

can some one help me??

[Posting your overly long set of data lines with a '>' quote at the
beginning of each line was a nuisance. Reposted with few lines. I will
let you compare your code to mine.]

bin = ['2598.95165', '2541.220308', '221068.0401', 'end', '4834.581952',
'1056.394859', '3010.609563', '2421.437603', '4619.861889',
'3682.012227', '3371.092883', '6651.509488', '7906.092773',
'7297.133447', 'end', '4566.874299', 'end', '4255.700077',
'1857.648393', '11289.48095', '2070.981805', '1817.505094',
'563.0265409', '70796.45356', '565.2123689', '6560.030116',
'2668.934414', '418.666014', '5216.392132', '760.894589', '8072.957639',
'346.5905371', 'end']

def average(bin):
num=[]
total = 0.0
count=0
for number in bin:
if number!='end':
total += float(number)
count+=1
else:
num.append(total/count)
total = 0.0
count= 0
return num

print(average(bin))
[75402.73735266666, 4485.0726684, 4566.874299, 7817.36494866]

U're welcome. But do notice Tim's comment. In non-toy situations, you
have to decide how to handle empty collections (return float('nan')?),
or whether to just let whatever happens happen.

If you control the input format, a list of lists would be easier than an
end marker. But sometimes one is handed data and asked to process it as is.

Also note (this is a more advanced topic) that average() could be turned
into a generator function by replacing 'num.append(total/count)' with
'yield total/count' and removing the initialization and return of num.
 
R

Rick Johnson

Your variable names need a bit more thought
def average(bin):

What is a "bin"? Maybe you shoulc have called this a "lst" eh?
    num=[]
Why would you call a list of numbers (that's plural BTW) the singular
name "num"? Not to mention that even "numbers" is the wrong
identifier. Use "averages" instead. Heck, even "buffer" would have
been a better choice that "num".
    total = 0.0
    count = 0
    for number in bin:

Not every "item" in the lst is a number so we should use the generic
"item" identifier here.
        while True:
What the hell is a loop doing here???
            if number!='end':
                number=float(number)
                total += float(number)
                count+=1
                avg = total/count
            if number=='end':
                    break

This block of logic is ugly. Try this instead...
            if number == 'end':
break
            number=float(number)
            total += float(number)
            count+=1
            avg = total/count

....but that whole loop thing is nonsense anyway. I would reconsider
this code completely. Here is an outline:

for item in lst
if item equals "end":
compute the current average from buffers
else:
increment the running total
increment the count.
 
J

Jon Clements

On 1/20/2012 1:49 PM, Tamanna Sultana wrote:
[Posting your overly long set of data lines with a '>' quote at the
beginning of each line was a nuisance. Reposted with few lines. I will
let you compare your code to mine.]
bin = ['2598.95165', '2541.220308', '221068.0401', 'end', '4834.581952',
'1056.394859', '3010.609563', '2421.437603', '4619.861889',
'3682.012227', '3371.092883', '6651.509488', '7906.092773',
'7297.133447', 'end', '4566.874299', 'end', '4255.700077',
'1857.648393', '11289.48095', '2070.981805', '1817.505094',
'563.0265409', '70796.45356', '565.2123689', '6560.030116',
'2668.934414', '418.666014', '5216.392132', '760.894589', '8072.957639',
'346.5905371', 'end']
def average(bin):
num=[]
total = 0.0
count=0
for number in bin:
if number!='end':
total += float(number)
count+=1
else:
num.append(total/count)
total = 0.0
count= 0
return num
print(average(bin))

[75402.73735266666, 4485.0726684, 4566.874299, 7817.36494866]

U're welcome. But do notice Tim's comment. In non-toy situations, you
have to decide how to handle empty collections (return float('nan')?),
or whether to just let whatever happens happen.

If you control the input format, a list of lists would be easier than an
end marker. But sometimes one is handed data and asked to process it as is.

Also note (this is a more advanced topic) that average() could be turned
into a generator function by replacing 'num.append(total/count)' with
'yield total/count' and removing the initialization and return of num.

Not directing this at you Terry, and you and Tim have made fine points
-- this just appears to me to be the best point at which to respond to
a thread.

To the OP - you have great answers, and, please note this just happens
to be the way I would do this.

I would separate the parsing of the data, and the calculation code
out. I've whipped this up rather quickly, so it might have a few flaws
but...

from itertools import groupby
def partition(iterable, sep=lambda L: L == 'end', factory=float):
for key, vals in groupby(iterable, sep):
if not key: yield map(factory, vals)

# And a pure cheat, but useful if more complex calculations are
required etc... (Plus covers NaN)
import numpy as np
print map(np.mean, partition(bin))

What you've got will work though, so wouldn't worry too much and this
is just my 2p,

Jon.
 
C

Chris Angelico

"Bin" is a standard English world. You know, like "rubbish bin" or
"recycling bin".

Or my first thought: stock location. Inventory software often doesn't
care whether your physical stock is organized by shelf, box,
warehouse, planet, or secret-space-on-Firefly-class-ship; just number
each location, and that's the bin number. (And no, that isn't like
"PIN number".) It's then quite logical to want various stats to be
per-bin, which would lead exactly to the OP's problem - including the
odd notation of input data, all too likely in a real-world scenario.

ChrisA
 
T

Tamanna Sultana

Or my first thought: stock location. Inventory software often doesn't
care whether your physical stock is organized by shelf, box,
warehouse, planet, or secret-space-on-Firefly-class-ship; just number
each location, and that's the bin number. (And no, that isn't like
"PIN number".) It's then quite logical to want various stats to be
per-bin, which would lead exactly to the OP's problem - including the
odd notation of input data, all too likely in a real-world scenario.

ChrisA

Thanx all.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top