L.B.
L.B.

Reputation: 1

TypeError: __init__() takes exactly 2 arguments (1 given)

I don't understand why I'm getting the following error and would appreciate some advice. Thanks.

Error:

Traceback (most recent call last):
  File "test.py", line 5, in <module>
    ciphertext = md.encrypt(plaintext)
  File "/Volumes/Mac/Computer/Programming/Cryptography/crypto.py", line 87, in encrypt
    ciphertext = Text()
TypeError: __init__() takes exactly 2 arguments (1 given)

Code:

import crypto

plaintext = crypto.Text('plaintext.txt')
md = crypto.MonomeDinome('fred', 'wilma')
ciphertext = md.encrypt(plaintext)
print ciphertext

Crypto.py has the following code:

class Text:
    def __init__(self, filename):
        self.load(filename)

    def load(self, filename):
        fp = open(filename, "r")
        self.rawtext = fp.read()
        fp.close
        self.text = self.convert(self.rawtext)

    def convert(self, txt):
        rval = ""
        for c in txt.upper():
            if c.isalpha():
                rval += c
        return rval

    def set(self, lst):
        self.text = "".join(lst)

    def get(self):
        return self.text

    def __str__(self):
        rval = ""
        pos = 0
        for c in self.text:
            rval += c
            pos += 1
            if pos % 60 == 0:
                rval += '\n'
            elif pos % 5 == 0:
                rval += " "
        return rval

class MonomeDinome:
    def __init__(self, dkw, lkw):
        self.digitsKey = self.digitsScramble(dkw)
        self.lettersKey = self.lettersScramble(lkw)

    def digitsScramble(self, dkw):
        dkl = list((dkw.upper() + "ZZZZZZZZZZ")[0:10])

        for i in "0123456789":
            pos = self.findLowestLetter(dkl)
            if pos != -1:
                dkl[pos] = i

        return "".join(dkl)

    def findLowestLetter(self, lst):
        pos = -1
        lowest = ''

        for i in range(len(lst)):
            if lst[i].isalpha():
                if (lowest == '') or (lst[i] < lowest):
                    lowest = lst[i]
                    pos = i
        return pos

    def lettersScramble(self, lkw):
        rlist = []
        for a in lkw.upper():
            if a == "W":
                a = "V"
            if a == "J":
                a = "I"
            if not a in rlist:
                rlist.append(a)

        for a in "ABCDEFGHIKLMNOPQRSTUVXYZ":
            if not a in rlist:
                rlist.append(a)

        return "".join(rlist)

    def __str__(self):
        return "digitsKey = " + self.digitsKey + "\n" + \
                "lettersKey = " + self.lettersKey

    def encrypt(self, plaintext):
        rlist = []
        for char in plaintext.get():
            rlist.append(char)
        ciphertext = Text()
        ciphertext.set(rlist)
        return ciphertext

Upvotes: 0

Views: 10853

Answers (2)

unutbu
unutbu

Reputation: 880657

I think you want Text to take 0 or 1 option argument.

class Text:
    def __init__(self, filename=None):
        if filename is not None:
            self.load(filename)

I believe

    ciphertext = Text()

makes sense since

    ciphertext.set(rlist)

is another way of setting ciphertext.text, rather than calling the load method.


By the way, there is also an error in load:

def load(self, filename):
    ...
    fp.close()   # <--- You need parentheses or else the closed method is not called

You could avoid the error by using the with syntax:

def load(self, filename):
    with open(filename, "r") as fp:
        self.rawtext = fp.read()
    self.text = self.convert(self.rawtext)

With the with syntax, the filehandle, fp, is automatically closed when Python leaves the with-suite.

Upvotes: 2

Ben Jackson
Ben Jackson

Reputation: 93890

The filename argument to the constructor isn't optional, so in encrypt this fails: ciphertext = Text(). It would have to be ... = Text(some_filename)

Upvotes: 4

Related Questions