santa
santa

Reputation: 303

Modulo large prime - TypeError: unsupported operand type(s) for %: 'int' and 'str'

I am trying to partition a large string F to m blocks as follows:

import random
from largeprimes import generateRandom

def generateRandom(length):
    t = random.randint(0, 2**length)
    str = "{0:b}".format(t)
    if (len(str) < length):
        str.zfill(length)
    return str

def divide_file_block (): #return bi: int
    b = []
    for i in range (0, m):
        b_i = F[(i*blocklen) : ((i+1)* blocklen)]
        temp = int(b_i, 2) % q
        b.append(temp)
    return b

F = generateRandom(102400)
m = 100
blocklen = len(F)/m
q = generateLargePrime(1024) # generateLargePrime is from https://langui.sh/2009/03/07/generating-very-large-primes/
print divide_file_block ()

Note: you shall copy the code from 1 to the current directory, remove the last print statement there and name it largpeprimes.py. This makes the generateLargePrime function importable.

When I test on a small example, it printed out correct result. But when I test on b_i and q having 1024 bits, it printed out the error:

temp = int(b_i, 2) % q

TypeError: unsupported operand type(s) for %: 'int' and 'str'

Could you please explain me why and give me a suggestion to show this problem. Thanks in advance.

Upvotes: 0

Views: 781

Answers (1)

Jan Vlcinsky
Jan Vlcinsky

Reputation: 44112

The function generateLargePrime sometime returns string

Trying the code I run into the same problem.

Testing it in debugger I got the cause: q has a value of `'Failure after 1100.0 tries.'

This is definitely a string an causes the failures.

I would recommend modifying the generateLargePrime code to throw an exception instead of reporting the failure by returned value.

Few tips for detecting this kind of problems

print out the problematic value

This is the simplest (and probably most popular) quick solution.

something like

b_i = F[(i*blocklen) : ((i+1)* blocklen)]
print "q", q # here is all the magic
temp = int(b_i, 2) % q

would tell you the value

place assert into your code

b_i = F[(i*blocklen) : ((i+1)* blocklen)]
assert isinstance(q, int)
temp = int(b_i, 2) % q

would throw an exception as soon as q is not of type int

run the code in debugger

pdb comes with Python, I prefer ipdb which comes with IPython, both would help you.

  1. have the failing code written as a script
  2. Try to run it via Python interpreter

    $ python failingscript.py

  3. as it fails, you simply try once more, but instead of python use pdb or ipdb

    $ ipdb failingscript.py

  4. the debugger let you control running the code line by line. Usually I let it run by "c" (continue) command and it soon crashes at the problematic point. Then I use "l" (list) to see, what line of code we are at, and finally use "p" (print) command to print values of variables, which are making problems. This way I used "p q" and found, it is a string.

It takes a moment to learn pdb or ipdb, but it works as turbo resolver so it is definitely the skill to learn. Great tutorial is at PMotW

Upvotes: 2

Related Questions