Incremental for loop in Python

I have a hard time understanding for loops in Python. I have the following code in Javascript (Modolus 11 test) I want to convert to Python:

    var secNumber = this.dob + lastDigits;
    var factors = [4, 3, 2, 7, 6, 5, 4, 3, 2, 1];

    for (var i = 0, sum = 0; i < factors.length; i++) {
      sum += secNumber.substring(i, i + 1) * factors[i];
    }

    // modulus 11 test
    return sum % 11 !== 0 ? false : true;

What would the Python equivalent be ?

Upvotes: 0

Views: 1825

Answers (5)

Martijn Pieters
Martijn Pieters

Reputation: 1123410

Python uses for each loops, so iterating over numbers would require you to produce a sequence of numbers first. Python uses the range() type for this:

sum = 0
for i in range(len(factors)):
    pass

Note that sum is assigned 0 explicitly, separately.

Usually however, you'd just loop over objects directly, rather than generate indices:

sum = 0
for element in factors:
    pass

But if you are summing the factors, just use the sum() function:

total = sum(factors)

Note that I avoided using the name sum there to avoid masking the built-in function.

To multiply bytes from a sequence of bytes, just zip() the bytes and factors together:

sum = 0
for byte, factor in zip(string, factors):
    sum += byte * factor

which can be collapsed with sum() and a generator expression:

total = sum(byte * factor for byte, factor in zip(string, factors))

This only works if string is a bytes object, not a Unicode str string object; bytes objects are really sequences of integers in the range 0-255.

If you wanted to interpret the characters as digits, use a Unicode string and use int() to convert each to an integer:

total = sum(int(digit) * factor for digit, factor in zip(string, factors))

Demo of the latter with the sample input you provided:

>>> sec_number = '0411994545'
>>> factors = [4, 3, 2, 7, 6, 5, 4, 3, 2, 1]
>>> sum(int(digit) * factor for digit, factor in zip(string, factors))
164
>>> total = sum(int(digit) * factor for digit, factor in zip(string, factors))
>>> total % 11 == 0
False

Note that the == test already produces a boolean; there is no need to use a conditional expression in Python to produce a boolean result.

Upvotes: 4

Paul
Paul

Reputation: 27443

Python doesn't strictly have C/Javascript style for loops but prefers a simpler syntax.

The C/JS style for has:

  • an initializer var i=0, sum=0
  • a conditional test, i< factors.length
  • an iterator, i++
  • and a task to repeat sum += string.substring(i, i + 1) * factors[i]

A pythonic for loop has only a variable and a list or iterable and a task, and looks like this:

mysum = 0
for i in range(length):
    mysum += int(strings[i])*factors[i]

where range(length) is a built-in function that expands to [0,1,2,3,.., length-1] and the task consists of the indented block after the colon

In JS strings and numeric types are automatically converted (even when you dont want it), but in Python that is not true. int() converts to integer and float() converts to floating point number.

Upvotes: 1

Hackaholic
Hackaholic

Reputation: 19753

read about documentation of for in python:

 for i in range(len(factors)):
     # do stuff

Note: indexing start from 0 and end one less

demo:

>>> [x for x in range(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

I think this is what you want:

>>> s="0411994545"
>>> f="1234567894"
>>> sum([int(x)*int(y) for x,y in zip(s,f)])
238

>>> sum([int(s[i])*int(f[i]) for i in range(len(s))])
238

Upvotes: 2

daniel451
daniel451

Reputation: 11002

In Python there is no "traditional" for-loop, but there are many constructs which make loops in Python very powerful:

for i in range(0, 10):
    print(str(i))

This prints integers from 0 to 9, range creates an iterator with the interval [low, high)

for i in range(0, 10, 2):
    print(str(i))

Prints 0, 2, 4, 6, 8 because the steps (third optional parameter are set to 2).

Also you can enumerate through your factors:

for key, val in enumerate(factors):
    pass

This gets you a key and the corresponding value of each element in factors.

If you do not need keys, than this simply does the job for you:

for val in factors:
    # some stuff to do

This iterates over every element in factors.

If you need a special condition to be checked, you can use break or continue:

for val in factors:
    if val == 0:
        continue # skips one iteration
    elif val == 1:
        break # cancels the whole loop
    else
        # do some stuff

Upvotes: 1

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 799082

ssum = sum(int(x) * y for (x, y) in zip(S, factors))

Upvotes: 2

Related Questions