TypeError: 'instancemethod' object is not iterable (Python)

Nebih Başaran picture Nebih Başaran · Nov 28, 2016 · Viewed 13.3k times · Source

I am pretty new with python and threading. I am trying to write a program which uses threads and queues in order to encrypt a txt file using caesar cipher. The encrypting function works well on its own when I use it exclusively, but I get an error when I use it in my program. The error starts from this line:

for c in plaintext:

And here is the whole code:

import threading
import sys
import Queue

#argumanlarin alinmasi
if len(sys.argv)!=4:
    print("Duzgun giriniz: '<filename>.py s n l'")
    sys.exit(0)
else:
    s=int(sys.argv[1])
    n=int(sys.argv[2])
    l=int(sys.argv[3])

#Global
index = 0

#caesar sifreleme


#kuyruk deklarasyonu
q1 = Queue.Queue(n)
q2 = Queue.Queue(2000)


lock = threading.Lock()

#Threadler
threads=[]

#dosyayi okuyarak stringe cevirme
myfile=open('metin.txt','r')
data=myfile.read()


def caesar(plaintext, key):
    L2I = dict(zip("ABCDEFGHIJKLMNOPQRSTUVWXYZ", range(26)))
    I2L = dict(zip(range(26), "ABCDEFGHIJKLMNOPQRSTUVWXYZ"))

    ciphertext = ""
    for c in plaintext:
        if c.isalpha():
            ciphertext += I2L[(L2I[c] + key) % 26]
        else:
            ciphertext += c
    return ciphertext

#Thread tanimlamasi
class WorkingThread(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    def run(self):
        lock.acquire()
        q2.put(caesar(q1.get, s))
        lock.release()

for i in range(0,n):
    current_thread = WorkingThread()
    current_thread.start()
    threads.append(current_thread)

output_file=open("crypted"+ "_"+ str(s)+"_"+str(n)+"_"+str(l)+".txt", "w")

for i in range(0,len(data),l):
    while not q1.full:
        q1.put(data[index:index+l])
        index+=l
    while not q2.empty:
        output_file.write(q2.get)

for i in range(0,n):
    threads[i].join()

output_file.close()
myfile.close()

Would appreciate any help, thanks in advance.

Answer

Anonymous picture Anonymous · Nov 28, 2016

In your code you are using q1.get and q2.get which are function objects. Instead call it with parenthesis:

q1.get()

which will fetch the value from the Queue.

As per the Queue.get() document:

Remove and return an item from the queue. If optional args block is true and timeout is None (the default), block if necessary until an item is available.