From a5184eee9c6552a189b7b61f85a0fafed038b7a7 Mon Sep 17 00:00:00 2001 From: Ann Isaeva Date: Mon, 27 Mar 2023 18:48:39 +0300 Subject: [PATCH] HW2 added --- lesson_2/main1.py | 61 +++++++++++++++++++++++++++++++++++++++++++ lesson_2/main1_dec.py | 45 +++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 lesson_2/main1.py create mode 100644 lesson_2/main1_dec.py diff --git a/lesson_2/main1.py b/lesson_2/main1.py new file mode 100644 index 0000000..6730288 --- /dev/null +++ b/lesson_2/main1.py @@ -0,0 +1,61 @@ +import math +import sys + +def index_to_bytes(value, bits): + n = bits // 8 + if bits % 8 != 0: + n += 1 + return value.to_bytes(n, 'little') + + +if not (2 <= len(sys.argv) <= 3): + print('Usage: python', sys.argv[0], 'input_file (output_file)') + exit(-1) + +with open(sys.argv[1], 'rb') as file: + data = file.read() + +dictionary = {(i,): i for i in range(256)} +sequence = list() + +outpath = sys.argv[2] if len(sys.argv) == 3 else sys.argv[1] + '.lzw' +# cond ? a : b +# a if cond else b +# if len(sys.argv) == 3: +# outpath = sys.argv[2] +# else: +# outpath = sys.argv[1] + '.lzw' +with open(outpath, 'wb') as file: + for sym in data: + sequence.append(sym) + key = tuple(sequence) + if key in dictionary: + continue + + n = math.ceil(math.log2(len(dictionary))) + index_value = dictionary[key[:-1]] + enc_value = index_to_bytes(index_value, n) + file.write(enc_value) + + value = len(dictionary) + dictionary[key] = value + # print(value, '->', key) + + sequence = sequence[-1:] + + n = math.ceil(math.log2(len(dictionary))) + index_value = dictionary[tuple(sequence)] + enc_value = index_to_bytes(index_value, n) + file.write(enc_value) + + # [1, 2, 3] + # [3] + + # a + # a[b] -> [a] (ab) -> dict + # b[e] -> [b] (be) -> dict + # e + + # a + # ab + # ab[c] -> [ab] (abc) -> dict \ No newline at end of file diff --git a/lesson_2/main1_dec.py b/lesson_2/main1_dec.py new file mode 100644 index 0000000..f74e9b3 --- /dev/null +++ b/lesson_2/main1_dec.py @@ -0,0 +1,45 @@ +import sys +import math + + +if not (2 <= len(sys.argv) <= 3): + print('Usage: python', sys.argv[0], 'input_file (output_file)') + exit(-1) + +dictionary = {i: (i,) for i in range(256)} + +inpath = sys.argv[1] +outpath = sys.argv[2] if len(sys.argv) > 2 else sys.argv[1][:-4][:sys.argv[1].find('.')] + '_dec' + \ + sys.argv[1][:-4][sys.argv[1].find('.'):] + +sequence = [] + +with open(inpath, 'rb') as file_in: + with open(outpath, 'wb') as file_out: + bites = math.ceil(math.log2(len(dictionary))) + bytes = bites // 8 + if bytes % 8 == 0: + bytes += 1 + data = file_in.read(bytes) + sym = int.from_bytes(data, 'little') + file_out.write(bytearray(dictionary[sym])) + sequence.append(dictionary[sym][0]) + sequence.append(sym) + sequence = list(dictionary[sym]) + while True: + bites = math.ceil(math.log2(len(dictionary))) + bytes_in_cycle = bites // 8 + bytes_in_cycle += 1 + sym = file_in.read(bytes_in_cycle) + if not sym: + break + sym = int.from_bytes(sym, 'little') + if sym in dictionary: + file_out.write(bytearray(dictionary[sym])) + sequence.append(dictionary[sym][0]) + dictionary[len(dictionary)] = tuple(sequence) + sequence = list(dictionary[sym]) + else: + sequence.append(sequence[0]) + file_out.write(bytearray(sequence)) + dictionary[len(dictionary)] = tuple(sequence) \ No newline at end of file