Counting significant figures in a number I decided to make something to count the significant figures in a number to see how easily it could be done, but I think there may have been a better or simpler way. Any advice even just for conventional purposes is appreciated!

def count_sig_figs(answer):
    '''This fucntion will count the sigfigs used in the answer of a user'''
    sig_fig_count = 0
    num_list = list(answer)

    for index in range(len(num_list)):
        try:
            fig = int(num_list[index])
            if fig != 0:
                sig_fig_count +=1
            elif check_zero_sig(index, num_list, sig_fig_count):
                sig_fig_count += 1
        except:
            continue
    return sig_fig_count

def check_zero_sig(index, num_list, sig_fig_count):
    '''Checks for significance in a zero from a list'''
    try:
        decimal = num_list.index('.')
        if index &gt; decimal and sig_fig_count &gt; 0:
            return True
    except:
        if index == 0:
            return False
        elif index == len(num_list):
            return False
        new_index = index+1

        if num_list[new_index] == '.' and sig_fig_count &gt; 0:
            return True
        elif num_list[new_index] == '.' and sig_fig_count == 0:
            return False
        elif num_list[new_index] != '.' and sig_fig_count &gt; 0:
            fig = int(num_list[new_index])
            if fig != 0:
                return True
            else:
                return check_zero_sig(new_index, num_list, sig_fig_count)
        elif num_list[new_index] != '.' and sig_fig_count == 0:
            fig = int(num_list[new_index])
            if fig != 0:
                return True
            else:
                return check_zero_sig(new_index, num_list, sig_fig_count)
        else:
            return False

def test():
    print(count_sig_figs('1')) # 1 sig fig
    print(count_sig_figs('10')) # 1 sig fig
    print(count_sig_figs('100')) # 1 sig fig
    print(count_sig_figs('1004')) # 4 sig figs
    print(count_sig_figs('10004')) # 5 sig figs
    print(count_sig_figs('105')) # 3 sig figs
    print(count_sig_figs('01')) # 1 sig fig
    print(count_sig_figs('1.2035')) # 5 sig figs
    print(count_sig_figs('001.09508')) # 6 sig figs
    print(count_sig_figs('0.00110')) # 3 sig figs

if __name__ == "__main__":
    test()
num_list is better named digits; don't describe the type, describe the value.

test's output is unhelpful; the result should be much more obvious, especially when it fails. Keeping along the given lines, I might do something like

def test():
    def should_be(string, count):
        assert count_sig_figs(string) == count
        print("{!r} has {} sf.".format(string, count))

    should_be('1', 1)
    should_be('10', 1)
    should_be('100', 1)
    should_be('1004', 4)
    should_be('10004', 5)
    should_be('105', 3)
    should_be('01', 1)
    should_be('1.2035', 5)
    should_be('001.09508', 6)
    should_be('0.00110', 3)


Of course, a proper test suite is probably better.

This isn't idiomatic:

for index in range(len(digits)):
    try:
        fig = int(digits[index])
        if fig != 0:
            sig_fig_count +=1
        elif check_zero_sig(index, digits, sig_fig_count):
            sig_fig_count += 1
    except:
        continue
return sig_fig_count


Bare try...excepts are bad. Even

except (ValueError, IndexError):


is bad. Primarily this is because you're spreading out the checks where they don't belong and it should instead be

try:
    fig = int(digits[index])
except ValueError:
    continue

if fig != 0:
    sig_fig_count +=1
else:
    try:
        zero_sig = check_zero_sig(index, digits, sig_fig_count)
    except IndexError:
        continue
    if zero_sig:
        sig_fig_count += 1


But then because... why is check_zero_sig throwing an IndexError? Surely that's a bug.

Before we get there, quickly change this to

for index, digit in enumerate(digits):
    if digit == ".":
        continue
    if digit != '0':
        sig_fig_count += 1
    else:
        sig_fig_count += check_zero_sig(index, digits, sig_fig_count)


That's pretty much what we want expressed more simply.

check_zero_sig's except also needs updating:

try:
    decimal = digits.index('.')
except ValueError:
    ...
else:
    return index &gt; decimal and sig_fig_count &gt; 0


I don't get why you don't just mutate index instead of using new_index.

This can be simplified:

if digits[index] == '.' and sig_fig_count &gt; 0:
    return True
elif digits[index] == '.' and sig_fig_count == 0:
    return False


to

if digits[index] == '.':
    return bool(sig_fig_count)


The

elif digits[index] != '.' and sig_fig_count &gt; 0:


and

elif digits[index] != '.' and sig_fig_count == 0:


branches are the same.

This then simplifies to

if digits[index] == '.':
    return bool(sig_fig_count)
elif digits[index] != '.':
    digit = int(digits[index])
    return bool(digit) or check_zero_sig(index, digits, sig_fig_count)
else:
    return False


which is just

if digits[index] == '.':
    return bool(sig_fig_count)
else:
    digit = int(digits[index])
    return bool(digit) or check_zero_sig(index, digits, sig_fig_count)


Then we see

elif index == len(digits):
    return False


cannot fire until after index += 1. This lets us fix our IndexError.

Back to count_sig_figs. The documentation is not written idiomatically. Documentation should be to the point, direct and not talk in third person.

def count_sig_figs(digits):
    '''Return the number of significant figures of the input digit string'''
    sig_fig_count = 0
    for index, digit in enumerate(digits):
        if digit == ".":
            continue
        if digit != '0':
            sig_fig_count += 1
        else:
            sig_fig_count += check_zero_sig(index, digits, sig_fig_count)
    return sig_fig_count


Back to check_zero_sig, which is now

def check_zero_sig(index, digits, sig_fig_count):
    '''Checks for significance in a zero from a list'''
    try:
        decimal = digits.index('.')
    except ValueError:
        if index == 0:
            return False
        index += 1
        if index == len(digits):
            return False
        if digits[index] == '.':
            return bool(sig_fig_count)
        else:
            digit = int(digits[index])
            return bool(digit) or check_zero_sig(index, digits, sig_fig_count)
    else:
        return index &gt; decimal and sig_fig_count &gt; 0


The if digits[index] == '.' check can't fire; we're in the except. Then

digit = int(digits[index])
return bool(digit) or check_zero_sig(index, digits, sig_fig_count)


can be

return digit != '0' or check_zero_sig(index, digits, sig_fig_count)


and the recursion, which would end up re-calling .index, can just be

if index == 0:
    return False
return any(digit != '0' for digit in digits[index+1:])


index == 0 is a very strange special case; you deal with 01 but not 001 or 00001. I suggest removing the special-case and using sig_fig_count.

Now we have

def check_zero_sig(index, digits, sig_fig_count):
    '''
    Returns if a zero digit at a given position is significant,
    given a count of significant digits preceding it.
    '''
    if not sig_fig_count:
        return False
    try:
        decimal = digits.index('.')
    except ValueError:
        return any(digit != '0' for digit in digits[index+1:])
    else:
        return index &gt; decimal


Most of this complexity is avoidable by using string operations and splitting cases:

def count_sig_figs(digits):
    '''Return the number of significant figures of the input digit string'''

    integral, _, fractional = digits.partition(".")

    if fractional:
        return len((integral + fractional).lstrip('0'))
    else:
        return len(integral.strip('0'))


That's the entirety of the logic!

Another test case you should consider is 100.. Does that have 1 significant figure or 3?