[Tutor] flag to call methods on objects?
Dave Angel
davea at ieee.org
Sat Aug 1 13:28:33 CEST 2009
(You replied off-list, so I'm copying your email, plus my response, to
the list)
prasad rao wrote:
> >I still see four problems.
>
>
> Hello Dave.I made modification as suggested by you.
>
>
>
You made the first three. But the problem of zlib.compress() producing
a string with an embedded (0a) still hasn't been addressed. And I
suspect this is your next problem. If you don't give the whole string
that zlib.compress() produced to zlib.uncompress(), then it'll fail as
you saw here.
>>>> import mcript
>>>>
>
> Traceback (most recent call last):
> File "<pyshell#13>", line 1, in <module>
> import mcript
> File "C:\Python26\mcript.py", line 84, in <module>
> a.main()
> File "C:\Python26\mcript.py", line 65, in main
> nl= self.__shorten(self.__undigi(self.__decompress(line.strip())))+'\n'
> File "C:\Python26\mcript.py", line 47, in __decompress
> astring=zlib.decompress(astring)
> error: Error -5 while decompressing data
>
> on interactive mode it is(decompress())working well.
>
> What should I do to rectifi this error?
>
> I dont know java,know basics of c++
>
> I started to lear python hardly onyear back.
>
> This is my 1st program using classes.
>
> Thanks for your time.
>
>
>
> #! usr/bin/env python
>
> import ast,random,os,zlib,string
> key=5
> class Cripto(object):
> def __init__(self,afile):
> self.afile=afile
> def __digi(self,astring):
> y=[]
> for x in astring:
> y.append(ord(x))
> y=str(y)
>
> return y
> def __undigi(self,astring):
>
> alist=ast.literal_eval(astring)
> y=[]
> for x in alist:
> y.append(chr(x))
> astring=''.join(y)
> return astring
> def __gen_string(self):
> s=''
> nl=random.sample(string.ascii_letters,key)
> for x in nl:s+=x
> return s
>
> def __lengthen(self,astring):
> s=list(astring)
> ns=''
> for x in s:
> ns+=x
> ns+=self.__gen_string()
> return ns
> def __shorten(self,astring):
>
> s=list(astring)
> ns=''
> for x in range(0,len(s),key+1):
> ns+=s[x]
> return ns
> def __compress(self,astring):
> astring=zlib.compress(astring)
> return astring
> def __decompress(self,astring):
> astring=zlib.decompress(astring)
> return astring
> def main(self):
> sorce=open(self.afile,'r')
> data=(sorce.readlines())
> dest=open((os.path.split(self.afile)[0]+os.sep+'temp'),'w')
> if (data[0]).strip()=='flag1':
>
> ns='flag0\n'
> data=data[1:]
> for line in data:
> nl=
> self.__compress(self.__digi(self.__lengthen(line.strip())))+'\n'
> ns+=nl
> dest.write(ns)
> elif data[0].strip()=='flag0':
> ns='flag1\n'
> data=data[1:]
> for line in data:
> nl=
> self.__shorten(self.__undigi(self.__decompress(line.strip())))+'\n'
> ns+=nl
> dest.write(ns)
> else:
> print 'File does not begin with the flag'
> sorce.close()
> dest.close()
> os.remove(os.path.split(self.afile)[0]+os.sep+'temp')
> return
>
> sorce.close()
> dest.close()
>
> os.remove(self.afile)
> os.rename((os.path.split(self.afile)[0]+os.sep+'temp'),self.afile)
>
>
> #========
> a=Cripto('C:/pp.txt')
> a.main()
>
>
There are a couple of places where indentation has been broken. For
example, in method __shorten(), the for loop body isn't indented. Are
you retyping these, or are you using tabs in your source, or is paste
broken on your system?
What Python version are you using? It's clear that you're using
Windows, so you will need to store the encoded file as binary.
Furthermore, something I didn't spot before is that strip() isn't safe
on the compressed data.
You said you tested the lower-level functions manually. But they're not
correct, so clearly it's past time to put in place some form of test
harness.
To properly test the code, you'll need to remove most of those
double-underscores. And I'd suggest factoring out two methods, encode()
and decode(), as follows:
def encode(self, unencoded):
nl=
self.__compress(self.digi(self.lengthen(unencoded.strip())))+'\n'
return nl
def decode(self, encoded):
nl=
self.shorten(self.undigi(self.__decompress(encoded.strip())))+'\n'
return nl
I don't have your data file to test with, so I may not get exactly the
same errors. In fact, multiple runs with the same data give different
results. Sometimes I get bad data, and sometimes an exception like
yours. Probably that's because of the random string you append in
lengthen(). But the crash itself is probably caused by the bug I
described in #4 of my previous message. zlib.compress() produces binary
data, and you're assuming leading and trailing whitespace is irrelevant,
and that there are no embedded 0a codes.
So the first test I wrote was:
def test_lengthen(line):
xx = a.lengthen(line)
yy = a.shorten(xx)
if yy != line:
print "shorten did not reproduce original data for ", line
#else:
#test_digi(xx, line) #this will be the next level of
testing.
Make up a few strings, and call this function. It fails every time.
Your shorten() and lengthen() methods are not inverses. shorten() does
not recreate the original text passed to lengthen. You'll have to fix
that before you can do anything else.
More information about the Tutor
mailing list