(gelöst)Schwierigkeiten bei einem Runleght Encoder

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
Schaf220
User
Beiträge: 113
Registriert: Montag 11. August 2008, 16:00
Wohnort: Bremen
Kontaktdaten:

Hallo liebe Community,
Ich hatte schon mal ein Thema, was dieses Programm betrifft, aber leider
ist noch ein weiteres Problem aufgetreten.
Ich möchte also einen Packer und einen Unpacker coden, das mit dem Packer hat auch jetzt super geklappt nur beim Unpacker haperts noch ein wenig. Dem packer werden Listen in einer Liste übergeben, die die entstanden sind als ein txt-Dokument eingelesen wurde das sind z.B so aus:
txt - Dokument "abcdEEEEEEEEEEEEEEEEEEEEEEEEEEEabcd".
das wird mit der der Funktion packer zu:
liste = [ ['a', 1], ['b', 1], ['c', 1], ['d', 1], ['E', 27], ['a', 1], ['b', 1], ['c', 1], ['d', 1], ['\n', 1]]
Die 27 wird dann in ein Ascii-Zeichen umgewandelt und der Rest der Buchstaben wird einfach in die neue Darei geschrieben:
gepacke Datei= "rldtxtabcd›Eabcd"
das rld ist die neue Extension, txt ist die Extension von vorher und das zeichen vor dem E ist die 27.
So weit so gut, Beim unpacken wird die Funktion "iter" verwendet, damit man auf das nächste zeichen zugreifen kann und dann
das Ascii-zeichen * das "E" nehmen kann.
Nur jetzt habe ich in einem Testfile das E 390x gegeben und es gibt nur 255 Ascii-Zeichen deswegen muss er mehrere Zeichen erstellen.
Testfile = [ ['a', 1], ['b', 1], ['c', 1], ['d', 1], ['E', 390], ['a', 1], ['b', 1], ['c', 1], ['d', 1], ['\n', 1]]

Das habe ich auch gelöst!
Testfile = rldtxtabcdÿÿÿ‰E

Jetzt kommt das Problem:

Da ich mit "iter" und next() auf das nächste zugegriffen habe hat das jetzt nicht mehr hin wenn ich mehrere Zähler hintereinender habe.
Ich muss jetzt die Zähler irgentwie zusammen zählen und dann mal das E nehmen, ich habe da auch schon eine Idee gehabt aber das klappt nicht so wie es soll. Die Stelle mit den Fragezeichen ist das was nicht funktioniert. Das ist halt das Zusammenzählen von den Ascci-Zeichen und das dann * das E zu nehmen.

Hier mal der Code:

Code: Alles auswählen


import sys
from optparse import OptionParser

#variables

data_list = []

#Parser

parser = OptionParser()
parser.add_option("-r", "--read", dest = "read",
                  help="File that will be read",
                  metavar="FILE")
parser.add_option("-c", "--compress", dest="compress",
                  help="File will be compress",
                  metavar="FILE")
parser.add_option("-u", "--uncompress", dest="uncompress",
                  help="liste wird angezeigt",
                  metavar="FILE")
parser.add_option("-e", "--extension", dest="extension",
                  help="add your own extension",
                  metavar="FILE")
parser.add_option("-q", "--quiet", dest="quiet",
                  help="programm will works without soft copy")


(options, args) = parser.parse_args()

def packer(data):
    pack_list = []
    number = 1
    place = ""
    for element in data:
        if element != place:
            pack_list.append([element, number])
        else:
            pack_list[-1][1] += 1

        place = element
    return pack_list

def unpacker(data):
    unpack_list = []
    data = iter(data)
    for character in data:
        if(ord(character) > 128):
            unpack_list.append(data.next() * (ord(character) - 128)
        ???elif(ord(character) > 128) and (data.next() > 128):
            number_count = (ord(character) - 128) + (ord(data.next()) - 128)
            unpack_list.append(data.next() * (number_count - 128))???
        else:
            unpack_list.append(character)
    return unpack_list

def write_file_pack(final_list):
  try:
      if options.compress and options.extension:
          new_file = file(options.compress[:-3] + options.extension, "w")
          new_file.write("rld" + options.compress[-3:])
      else:
          new_file = file(options.compress[:-3] + "rld", "w")
          new_file.write("rld" + options.compress[-3:])
      for element in final_list:
          if element[1] == 1:
            new_file.write(element[0])
     ???elif element[1] > 128:
            counter_1 = element[1] / 127
            counter_2 = chr((element[1] - (counter_1 *127) + 128))
            new_file.write(chr(255)* counter_1 + counter_2)???
            new_file.write(element[0])
          else:
             new_file.write(chr(128 + element[1]))
             new_file.write(element[0])
      new_file.close()
  except StandardError, why:
      print "StandardError:", why
      print "Error in definition of functions (line 49 - 70)"
  except IOError, why:
      print "IOError:", why
      print "Error in definition of functions (line 49 - 70)"
  except:
      print "Error in definition of functions (line 49 - 70)"


def write_file_unpack(final_list):
    try:
        compressfile = open(options.uncompress, "r")
        line = compressfile.read()
        right = line[3:6]
        new_file = file(options.uncompress[:-3] + "_neu." + right, "w")
        for word in final_list[6:]:
            new_file.write(word)
        new_file.close()
    except StandardError, why:
        print "StandardError:", why
        print "Error in definition of functions (line 81 - 89)"
    except IOError, why:
        print "IOError:", why
        print "Error in definition of functions (line 81 - 89)"
    except:
        print "Error in definition of functions (line 81 - 89)"
    return

if options.compress or options.compress and options.extension:
    try:
        compressfile = open(options.compress, "r")          # open the named file
        line = compressfile.readline()                      # read one line of the file
        while(line):                                        # while there are lines
            for element in line:
                data_list.append(element)                   # continue to read the lines and
                line = compressfile.readline()              # append the signs to a list
        compressfile.close()                                # close the file
    except StandardError, why:
        print "StandardError:", why
        sys.exit(1)

    pack_file = packer(data_list)
    #print pack_file
    write = write_file_pack(pack_file)
    print "File has been created"

elif options.uncompress:
    try:
        compressfile = open(options.uncompress, "r")        # open the named file
        line = compressfile.readline()                      # read one line of the file
        while(line):                                        # while there are lines
            for element in line:
                data_list.append(element)                   # continue to read the lines and
                line = compressfile.readline()              # append the signs to a list
        compressfile.close()                                # close the file
    except StandardError, why:
        print "StandardError:", why
        print "Error in file reading (line 175 - 183)"
    except IOError, why:
        print "IOError:", why
        print "Error in file reading (line 175 - 183)"
    except:
        print "Error in file reading (line 175 - 183)"
        sys.exit(1)
    #print data_list
    unpack_file = unpacker(data_list)
    new = write_file_unpack(unpack_file)
    print "File has been decoded"
else:
    pass

MfG Schaf220
Zuletzt geändert von Schaf220 am Montag 29. September 2008, 17:15, insgesamt 3-mal geändert.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Villeicht solltest Du noch einmal expliziter beschrieben, wie Du das Problem bei einer Anzahl > 255 gelöst hast und dann mal den Code-Schnipsel zeigen und erläutern, der das Problem eigentlich beim decodieren lösen sollte. So ist mir das noch nicht klar und ich habe keine große Lust mir den gesamten Code durchzulesen ;-)
Benutzeravatar
Schaf220
User
Beiträge: 113
Registriert: Montag 11. August 2008, 16:00
Wohnort: Bremen
Kontaktdaten:

Ok ich habs verbessert! Bevor der Code anfägt hab ich was hinzugefügt!
Und in der Funktion unpacker im elif Zweig da wo die Fragezeichen sind.
Zuletzt geändert von Schaf220 am Freitag 26. September 2008, 18:21, insgesamt 1-mal geändert.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Schaf220 hat geschrieben:Ok ich habs verbessert!
Wo denn? Ich sehe da keinen Unterschied ;-)
BlackJack

@Schaf220: Dein Entpackalgorithmus ist einfach falsch. Überleg doch mal was Du genau in welcher Reihenfolge machen musst, am besten an einem Beispiel mit Stift und Papier durchgespielt.

Ach und: Die `next()`-Methode hat doch einen Seiteneffekt, nämlich dass das nächste Element gelesen wird. Wenn Du also ``data.next() > 127`` in einer ``if``-Bedingung schreibst, weisst Du am Ende zwar, dass der Wert grösser oder kleiner als 127 war, aber der Wert selber ist "weg", weil Du ihn nirgends gespeichert hast.

Das Programm hat auch noch zwei Beschränkungen, die ich eigentlich sogar als Fehler ansehen würde: Bytes mit Werten >127 dürfen nicht in den ungepackten Daten vorkommen, und in den ungepackten Daten darf kein Byte öfter als 16384 mal in einem Lauf vorkommen. In beiden Fällen scheint das Programm ohne einen Mucks von sich zu geben "kaputte" Daten zu produzieren.
Benutzeravatar
Schaf220
User
Beiträge: 113
Registriert: Montag 11. August 2008, 16:00
Wohnort: Bremen
Kontaktdaten:

Ich habe auf deinen Rat hin mal ein Zettel genaommen und das nochmal gründlich durchgespielt.
Daher habe ich jetzt einen anderen Lösungsweg der auch hin haut, aber wieder nur, wenne es nur einen Zähler gibt.
Ich denke mir das ich diese bedingung mit einer while- Schliefe konstruieren muss aber ich bekomme das irgentwie nicht hin.
Mir wird immer die Fehlermeldung "StopInteration" angezeigt.
Ich nehme an, das kommt daher das er auf das nächste Element der Liste zugreifen will, aber es keines mehr gibt ist das so?
Wenn ja könntet ihr mir einen Tipp geben wie ich das mit ner while-Schleife oder anders lösen kann?

Code: Alles auswählen

def unpacker(data):
    unpack_list = []
    metavar = 0
    data = iter(data)
    for character in data:
        if(ord(character) > 128):
            metavar += ord(character) - 128
            unpack_list.append(metavar * data.next())
        else:
            unpack_list.append(character)
    return unpack_list
Antworten