Count Even Digits In Number
You should have a look at Loop like a native!. Explicitly iterating over the indices is usually not the best way to do something in Python. By directly iterating over the string representation of n you won't even need the second argument (and you should remove it if the assignment/defined interface would not require it). This will help you a lot later, when you start using generators or other iterables which are not indexable.

In addition, you can use the built-in sum together with the fact that bools are integers with True == 1 and False == 0 and a generator expression to make your function a lot shorter:

def count_even_digits(n, n_digits):
    """Return the number of digits of n which are even.
    Second argument (number of digits) is unused.
    """
    return sum(int(d) % 2 == 0 for d in str(n))


I also added a docstring describing what the function does.



An alternative that does not use the casting to str is to make a digits function:

def digits(n):
    """Yields the digits of `n`, from smallest to largest."""
    while n &gt; 10:
        n, d = divmod(n, 10)
        yield d
    yield n

def count_even_digits2(n, n_digits):
    return sum(d % 2 == 0 for d in digits(n))




Timing wise, these two solutions are both very fast, but the conversion to str stays faster, now tested up to 10**308. I also added the functions shown in the answer by @vurmux and the answer by @spyr03, which are even faster than these two solutions:



Interestingly the manual for loop is faster than the generator expression with sum.



For numbers with a lot of digits, it becomes a bit more complicated. This includes a function proposed in an answer to my question on SO about why the for loop is better than the sum. This function is even faster, but I would only recommend using it if you need that last bit of speed.

def count_even_digits_count_unrolled(n):
    s = str(n)
    return s.count("0") + s.count("2") + s.count("4") + s.count("6") + s.count("8")