• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Kompresor - wczytywanie i odczytywanie wyniku

Object Storage Arubacloud
0 głosów
202 wizyt
pytanie zadane 28 stycznia 2018 w Python przez krystian26a Nowicjusz (120 p.)

Witam! Mało się znam na programowaniu i dlatego tutaj jestem, dla większości obecnych na tym forum mój problem będzie banalny. Poniższy kod to kompresor danych wykorzystujący kodowanie metodą Shannona-Fano, program nie jest mojego autorstwa a chciałbym skompresować kilka plików używając tej metody i tego programu. W MAIN'ie jest linia kodu jak mam wczytać plik

fi = open(inputFile, 'rb')

 

no i daje swój plik i za cholerę nie dzieję się nic. Plik który chce skompresować jest plikiem tekstowym i wrzuciłem go bezpośrednio do folderu który utworzył mi program tworząc nowy projekt. Więc zrobiłem tak

fi = open('test.txt', 'rb')

 

Kolejny problem stwarza mi to

# write a list of (byteValue,3-bit(len(encodingBitStr)-1),encodingBitStr)
    # tuples as the compressed file header
    bitStream = ''
    fo = open(outputFile, 'wb')

jeśli w outputFile wpisze 'wynik.txt' to w jakim miejscu zostanie mój wynik zapisany ? a w tej linii bitStream co powinno się znajdować, powinno być puste czy to z komentarza wpisać.

I to kolejne ostatnie wyjście gdzie się zapisze ;p

# read the encoded data, decode it, write into the output file
    fo = open(outputFile, 'wb')

Wiem że zajeżdża strasznie jakąś paniką, ale jestem nowy w tym rzeczach a wiedza ta jest mi potrzebna na gwałt :P Dodam że plik który chce skompresować jest w txt.



Program: Pycharm   Mój Phyton: 2.7.14

import sys
import os
 
def shannon_fano_encoder(iA, iB): # iA to iB : index interval
    global tupleList
    size = iB - iA + 1
    if size > 1:
        # Divide the list into 2 groups.
        # Top group will get 0, bottom 1 as the new encoding bit.
        mid = int(size / 2 + iA)
        for i in range(iA, iB + 1):
            tup = tupleList[i]
            if i < mid: # top group
                tupleList[i] = (tup[0], tup[1], tup[2] + '0')
            else: # bottom group
                tupleList[i] = (tup[0], tup[1], tup[2] + '1')
        # do recursive calls for both groups
        shannon_fano_encoder(iA, mid - 1)
        shannon_fano_encoder(mid, iB)
 
def byteWriter(bitStr, outputFile):
    global bitStream
    bitStream += bitStr
    while len(bitStream) > 8: # write byte(s) if there are more then 8 bits
        byteStr = bitStream[:8]
        bitStream = bitStream[8:]
        outputFile.write(chr(int(byteStr, 2)))
 
def bitReader(n): # number of bits to read
    global byteArr
    global bitPosition
    bitStr = ''
    for i in range(n):
        bitPosInByte = 7 - (bitPosition % 8)
        bytePosition = int(bitPosition / 8)
        byteVal = byteArr[bytePosition]
        bitVal = int(byteVal / (2 ** bitPosInByte)) % 2
        bitStr += str(bitVal)
        bitPosition += 1 # prepare to read the next bit
    return bitStr
 
# MAIN
if len(sys.argv) != 4:
    print 'Usage: ShannonFano.py [e|d] [path]InputFileName [path]OutputFileName'
    sys.exit()
mode = sys.argv[1] # encoding/decoding
inputFile = sys.argv[2]
outputFile = sys.argv[3]
 
# read the whole input file into a byte array
fileSize = os.path.getsize(inputFile)
fi = open(inputFile, 'rb')     <----TUTAJ
# byteArr = map(ord, fi.read(fileSize))
byteArr = bytearray(fi.read(fileSize))
fi.close()
fileSize = len(byteArr)
print 'File size in bytes:', fileSize
print
 
if mode == 'e': # FILE ENCODING
    # calculate the total number of each byte value in the file
    freqList = [0] * 256
    for b in byteArr:
        freqList[b] += 1
 
    # create a list of (frequency, byteValue, encodingBitStr) tuples
    tupleList = []
    for b in range(256):
        if freqList[b] > 0:
            tupleList.append((freqList[b], b, ''))
 
    # sort the list according to the frequencies descending
    tupleList = sorted(tupleList, key=lambda tup: tup[0], reverse = True)
 
    shannon_fano_encoder(0, len(tupleList) - 1)
    # print 'The list of (frequency, byteValue, encodingBitStr) tuples:'
    # print tupleList
    # print
 
    # create a dictionary of byteValue : encodingBitStr pairs
    dic = dict([(tup[1], tup[2]) for tup in tupleList])
    del tupleList # unneeded anymore
    # print 'The dictionary of byteValue : encodingBitStr pairs:'
    # print dic
 
    # write a list of (byteValue,3-bit(len(encodingBitStr)-1),encodingBitStr)
    # tuples as the compressed file header
    bitStream = ''
    fo = open(outputFile, 'wb')
    fo.write(chr(len(dic) - 1)) # first write the number of encoding tuples
    for (byteValue, encodingBitStr) in dic.iteritems():
        # convert the byteValue into 8-bit and send to be written into file
        bitStr = bin(byteValue)
        bitStr = bitStr[2:] # remove 0b
        bitStr = '0' * (8 - len(bitStr)) + bitStr # add 0's if needed for 8 bits
        byteWriter(bitStr, fo)
        # convert len(encodingBitStr) to 3-bit and send to be written into file
        bitStr = bin(len(encodingBitStr) - 1) # 0b0 to 0b111
        bitStr = bitStr[2:] # remove 0b
        bitStr = '0' * (3 - len(bitStr)) + bitStr # add 0's if needed for 3 bits
        byteWriter(bitStr, fo)
        # send encodingBitStr to be written into file
        byteWriter(encodingBitStr, fo)
 
    # write 32-bit (input file size)-1 value
    bitStr = bin(fileSize - 1)
    bitStr = bitStr[2:] # remove 0b
    bitStr = '0' * (32 - len(bitStr)) + bitStr # add 0's if needed for 32 bits
    byteWriter(bitStr, fo)
 
    # write the encoded data
    for b in byteArr:
        byteWriter(dic[b], fo)
 
    byteWriter('0' * 8, fo) # to write the last remaining bits (if any)
    fo.close()
 
elif mode == 'd': # FILE DECODING
    bitPosition = 0
    n = int(bitReader(8), 2) + 1 # first read the number of encoding tuples
    # print 'Number of encoding tuples:', n
    dic = dict()
    for i in range(n):
        # read the byteValue
        byteValue = int(bitReader(8), 2)
        # read 3-bit(len(encodingBitStr)-1) value
        m = int(bitReader(3), 2) + 1
        # read encodingBitStr
        encodingBitStr = bitReader(m)
        dic[encodingBitStr] = byteValue # add to the dictionary
    # print 'The dictionary of encodingBitStr : byteValue pairs:'
    # print dic
    # print
 
    # read 32-bit file size (number of encoded bytes) value
    numBytes = long(bitReader(32), 2) + 1
    print 'Number of bytes to decode:', numBytes
 
    # read the encoded data, decode it, write into the output file
    fo = open(outputFile, 'wb')
    for b in range(numBytes):
        # read bits until a decoding match is found
        encodingBitStr = ''
        while True:
            encodingBitStr += bitReader(1)
            if encodingBitStr in dic:
                byteValue = dic[encodingBitStr]
                fo.write(chr(byteValue))
                break
    fo.close()

 

Najbardziej interesuje mnie też gdzie Usage: ShannonFano.py [e|d] [path]InputFileName [path]OutputFileName gdzie mam tą linie kodu wstawić ? Jeśli skompiluje program to nie ma błędu i właśnie pojawi mi się to Usage: itd i na dole pojawi mi się "Process finished with exit code 0" czyli program wyłączony i wszystko jest OK

1 odpowiedź

0 głosów
odpowiedź 28 stycznia 2018 przez adrian17 Ekspert (344,860 p.)

Jeśli skompiluje program to nie ma błędu

To nie C, tu nie ma osobnej kompilacji, to się od razu uruchamia.

Najbardziej interesuje mnie też gdzie Usage: ShannonFano.py [e|d] [path]InputFileName [path]OutputFileName

To znaczy: nic nie musisz ręcznie grzebać w kodzie ani nawet otwierać pycharma; wystarczyło w terminalu wpisać na przykład `python ShannonFano.py e wejscie.txt wyjscie.txt`

 

Podobne pytania

0 głosów
2 odpowiedzi 201 wizyt
pytanie zadane 1 września 2017 w C i C++ przez wojtekd09 Początkujący (260 p.)
+1 głos
3 odpowiedzi 3,505 wizyt
+1 głos
1 odpowiedź 3,199 wizyt

92,570 zapytań

141,422 odpowiedzi

319,643 komentarzy

61,958 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...