3
\$\begingroup\$

I'm a beginner in Python, and computer languages in general, and I'm totally stumped on how to format this iteration into a function. The iteration takes the sum of someone's birth year, month, and day and adds it together to create a sum of those numbers, and then the second iteration takes the first sum and adds those numbers together to create a final sum.

I have the users input their birthyear, month, and day (all converted to int) and this is the first sum (Example: A bday of 01/01/1997= 1999):

first_sum=b_yr + b_dy + b_mo

Then the first iteration takes the sum and adds the numbers together (Example: 1999 = 1+9+9+9 = 28):

z = first_sum
zstr1=str(z)
accum1=0
for x in zstr1:
    accum1 += int(x)
(accum1)

Then the second iteration takes the first sum and adds those numbers again to create the final sum (Example: 28 = 2+8 = 10):

str2=str(accum1)
accum2=0
for cnt2 in str2:
    accum2 += int(cnt2)
\$\endgroup\$
2
\$\begingroup\$

Despite your code being cumbersome, I would like to point out that you did well by writing for x in zstr1, iterating over the characters of the string. Python beginners often try to iterate over character indexes instead, resulting in unnatural Python code.


I would decompose the problem differently than @jonrsharpe. sum_digits(n) is a generally useful operation to define as a function.

def sum_digits(n):
    return sum(int(char) for char in str(n))

sum_digits(sum_digits(b_yr + b_mo + b_dy))

Actually, it's not necessary to conflate the summing and the digit breakdown.

def digits(n):
    return [int(char) for char in str(n)]

sum(digits(sum(digits(b_yr + b_mo + b_dy))))

The last line reads just like the problem description: "sum of the digits of the sum of the digits of the year, month, and day".


Here's another implementation of digits(n), using a generator. This avoids stringification.

def digits(n):
    """Produce the base-10 digits of n from least to most significant."""
    while n:
        yield n % 10
        n /= 10
\$\endgroup\$
  • \$\begingroup\$ sum_digits could be sum(map(int, str(n))) if I am not mistaken. \$\endgroup\$ – Morwenn Apr 23 '15 at 15:20
1
\$\begingroup\$

A few notes on your code:

  • You should be more consistent with whitespace. The style guide suggests a space each side of = in assignments - you use this once, but elsewhere leave them out.
  • Variable names could be a bit more useful/consistent - for example, you have z (what does that mean?) and zstr1 but str2 (why not str1 and str2, or zstr1 and zstr2?) A good choice of name can make the code much easier to understand.
  • In fact, z is redundant; you can replace z = first_sum and zstr1=str(z) with zstr1 = str(first_sum).

Your approach is fine as far as it goes, but here is a neater implementation:

def process(b_yr, b_dy, b_mo):
    total = b_yr + b_dy + b_mo
    for _ in range(2):
        total = sum([int(char) for char in str(total)])
    return total

Note that:

  1. You need to sum over the digits of a number - it uses a "list comprehension" to apply the same process to each character/digit in the number, and sum to add up the total.
  2. You need to repeat this process twice - it uses a for loop to repeat the process, rather than just writing it out again; this reduces duplication and makes it much easier to repeat the process a different number of times.

As a more shorter and more "functional programming", but perhaps less readable, alternative for step 1. you can replace the list comprehension with map:

total = sum(map(int, str(total)))
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.