Question

Before I debug my code, I would like to know why there's an error occurred when I call the function? It says "NameError: name 'stDigs' is not defined". I've tried using "avgUntilLetter(0123a)" and "avgUntilLetter("0123a")" but none of them works. Help me plz!

This function receives as input one string containing digits or letters. The function should return one float number contaning the average calculated considering all the digits in the string starting form the first position and considerign all digits until one letter is found or until reaching the end of the string.

An example: avgUntilLetter('0123a456') should return 1.5

def avgUntilLetter (stDigs):
    num = 0
    each_char = stDigs[num]

    while each_char.isdigit() == True and num < len(stDigs):
        num = num + 1
        each_char = stDigs[num]

    digits = stDigs[0:num]
    avg = sum(digits)/len(digits)

    return avg

avgUntilLetter(stDigs)

Yes, I know there are a lot errors needed to be solved. I just need to solve it one at a time. When I call the function using "avgUntilLetter ("0123a")", the defined error disappeared but a type error popped up. Hmm.. I'm still keeping trying it.

Was it helpful?

Solution

There are several problems in your code:

  1. You can end up trying to access stDigs[len(stDigs)] because num < len(stDigs) might be true, but you then add 1 before using it as an index.

  2. sum(digits) won't work because digits is a string.

Just loop over the string directly instead of using a while loop, add up the digits in the loop:

def avgUntilLetter(stDigs):
    total = i = 0
    for i, each_char in enumerate(stDigs):
        if not each_char.isdigit():
            break
        total += float(each_char)
    if i:
        return total / i
    return 0.0

This handles edge-cases as well:

>>> avgUntilLetter('0123a456')
1.5
>>> avgUntilLetter('')
0.0
>>> avgUntilLetter('abc')
0.0

OTHER TIPS

stDigs is not assigned to any value.

avgUntilLetter([])

stDigs = []
avgUntilLetter(stDigs)

In you case, it's a string, jsut set stDigs to a string first.

stDigs = ""
avgUntilLetter(stDigs)

The TypeError comes from this line:

avg = sum(digits)/len(digits)

because the one before it makes digits a string. And, you can't use sum on strings.

You can fix your code by changing the above line to:

# `avg = float(sum(map(int, digits)))/len(digits)` if you are on Python 2.x
avg = sum(map(int, digits))/len(digits)

However, you can do this job a lot easier and more efficiently with a list comprehension and itertools.takewhile:

>>> from itertools import takewhile
>>> def avgUntilLetter(stDigs):
...     digits = [int(x) for x in takewhile(str.isdigit, stDigs)]
...     return sum(digits)/len(digits) if digits else 0.0
...
>>> avgUntilLetter('0123a456')
1.5
>>> avgUntilLetter('123456789')
5
>>> avgUntilLetter('a1')
0.0
>>> avgUntilLetter('')
0.0
>>>

Note that the above code is for Python 3.x. To convert it to Python 2.x., change the return-statement to this:

return float(sum(digits))/len(digits) if digits else 0.0

You need float in there because of how Python 2.x handles division.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top