Python中的运行时/资源警告错误



我试图运行此代码并遇到运行时间错误。我无法调试代码。我确实相信错误在于函数Huffman_encode和Huffman_decode。显示的错误是资源警告错误。这是代码:

from linked_list import *
from huffman_bits_io import HuffmanBitsWriter as writer, HuffmanBitsReader as reader
import unittest
class Leaf:
    '''class that implements Leaf'''
    def __init__(self, parent, value, code, frequency):
        self.parent = parent
        self.frequency = frequency
        self.value = value
        self.code = code
    def __eq__(self, other):
        return type(other) == Leaf and self.parent == other.parent and self.frequency ==other.frequency and self.value==other.value and self.code==other.code
    def __repr__(self):
        return "[ {}, frequency = {} ]".format(self.code, self.frequency)

class Node:
    '''class that implements Node'''
    def __init__(self, parent, code, lchild, rchild, frequency):
        self.parent = parent
        self.code = code
        self.frequency = frequency
        self.lchild = lchild
        self.rchild = rchild
    def __eq__(self, other):
        return type(other) == Node and self.parent==other.parent and self.code == other.code and self.frequency == other.frequency and self.lchild == other.lchild and self.rchild == other.rchild
    def __repr__(self):
        return "{}, freq = {}nleft = {}nright = {}".format(self.code, self.frequency, self.lchild.___repr__(), self.rchild.__repr__())

def strip(string, seq):
    '''this function cuts sequence from beginning of string if possible and returns result '''
    if len(seq) > len(string):
        return string
    for i in range(len(seq)):
        if seq[i] != string[i]:
            return string
    else:
        return string[len(seq):]

def find(lst, item):
    '''this function finds index of first occurrence of given element in the list and returns it or raise error if there is no such element'''
    for i in range(lst.length):
        if get(lst, i).value[0] == item:
            return i
    else:
        raise ValueError

def string_traverse(node):
    '''this function returns string representation of tree in pre-order traversal'''
    lst = empty_list()
    traverse(node, lst) #calls traverse
    result_string = ''
    for i in range(lst.length): #accumulate string from lst list
        result_string += chr(get(lst, i).value)
    return result_string

def traverse(node, code):
    '''this function traverse the try and return list of leaf's value(helper for string_traverse)'''
    if type(node) == Leaf:
        code = add(code, node.value, code.length) #if node is Leaf than terminate recursion and return character
    else:
        traverse(node.lchild, code) #recursive call
        traverse(node.rchild, code) #recursive call

def count_occurrences(file_name):
    '''this function returns list that represent occurrence of every character of given string'''
    with open(file_name) as file: #reads file
        data = file.read()
    lst = list()
    for i in range(len(data)): #creates list of integer representation of string
        lst.append(ord(data[i]))
    data = lst
    lst = empty_list()
    for char in data: #this loop calculates occurrences of characters in the string
        try:
            index = find(lst, char)
            lst = set(lst, index, (char, get(lst, index).value[1] + 1))
        except ValueError:
            lst = add(lst, (char, 1), 0)
    lst = sort(lst, lambda x: x.value[1], False) #sorts occurrences
    return lst

def comes_before(el1, el2):
    '''this function returns True if el1 leaf should come before el2 leaf in Huffman tree meaning'''
    if el1[1] < el2[1] or (el1[1] == el2[1] and type(el1[0]) is int and type(el2[0]) is int and el1[0] < el2[0]):
        return True
    else:
        return False

def build_tree(occurrences):
    '''this function returns Huffman tree based on given list of occurrences'''
    if occurrences.length == 1: #if we have only one character returns Leaf with this character and code '0'
        return Leaf(None, get(occurrences, 0).value[0], '0', get(occurrences, 0).value[1])
    while occurrences.length != 1: #algorith described in the task
        el1, occurrences = remove(occurrences, 0)
        el2, occurrences = remove(occurrences, 0)
        el1, el2 = el1.value, el2.value
        if not comes_before(el1, el2): #finds order of elements in the tree
            el1, el2 = el2, el1
        new = Node(None, '', None, None, el1[1] + el2[1]) #creates new node
        if type(el1[0]) is Node:
            el1[0].code = '0' #sets up code for node
            el1[0].parent = new
            new.lchild = el1[0]
        else:
            new.lchild = Leaf(new, el1[0], '0', el1[1]) #if el1 is character not Node we will create leaf for that character
        if type(el2[0]) is Node:
            el2[0].code = '1' #sets up code for node
            el2[0].parent = new
            new.rchild = el2[0]
        else:
            new.rchild = Leaf(new, el2[0], '1', el2[1]) #if el2 is character not Node we will create leaf for that character
        occurrences = insert_sorted(occurrences, (new, new.frequency), comes_before) #inserts new node
    return get(occurrences, 0).value[0]

def collect_code(node, code = ''):
    '''this function traverse Huffman tree and collect code for each leaf and returns them as nested list(helper for create_code)'''
    if type(node) == Leaf:
        lst = empty_list()
        return add(lst, (node.value, code + node.code), 0) #if node is Leaf terminates recursion and returns code for the leaf
    else:
        lst = empty_list()
        lst = add(lst, collect_code(node.lchild, code + node.code), 0) #recursive call
        lst = add(lst, collect_code(node.rchild, code + node.code), 0) #recursive call
        return lst

def create_code(tree):
    '''this function unpack result of calling collect_code and return Huffman code as a list of tuples'''
    code = collect_code(tree) #calls collect code
    i = 0
    while i < code.length: #this loop unpacks list
        if type(get(code, i).value) is not tuple:
            item, code = remove(code, i)
            for j in range(item.value.length):
                code = add(code, get(item.value, j).value, i)
            continue
        i += 1
    return code

def huffman_encode(input_file, output_file):
    '''task describe this function'''
    occurrences = count_occurrences(input_file)
    tree = build_tree(occurrences)
    string = empty_list()
    t = traverse(tree, string)
    code = create_code(tree)
    with open(input_file) as file:
        string = file.read()
    result_string = ''
    for i in range(len(string)): #this loop encodes string using code produced by create_code function
        for j in range(code.length):
            temp = get(code, j).value
            if string[i] == chr(temp[0]):
                result_string += temp[1]
                break
    for i in range(occurrences.length):
        temp = get(occurrences, i).value
        occurrences = set(occurrences, i, (chr(temp[0]), temp[1]))
    occurrences = sort(occurrences, lambda x: x.value[0], False)
    file = writer(output_file)
    file.write_int(code.length)
    for i in range(occurrences.length):
        temp = get(occurrences, i).value
        file.write_byte(ord(temp[0]))
        file.write_int(temp[1])
    file.write_code(result_string)
    file.close()
    return string_traverse(tree)

def huffman_decode(input_file, output_file):
    '''task describe this function'''
    file = reader(input_file)
    number_of_codes = file.read_int()
    occurrences = empty_list()
    for i in range(number_of_codes):
        char = file.read_byte()
        number = file.read_int()
        occurrences = add(occurrences, (char, number), 0)
    occurrences = sort(occurrences, lambda x: x.value[1], False)
    tree = build_tree(occurrences)
    code = sort(create_code(tree), lambda x: x.value[0], False)
    occurrences = sort(occurrences, lambda x: x.value[0], False)
    quantity_of_bits = 0
    for i in range(code.length):
        quantity_of_bits += get(occurrences, i).value[1]*len(get(code, i).value[1])
    occurrences = sort(occurrences, lambda x: x.value[1], False)
    bit_string = ''
    for i in range(quantity_of_bits):
        bit_string = bit_string + ('1' if file.read_bit() else '0')
    result_string = ''
    while bit_string: #this loop decodes string using code produced by create_code function
        for j in range(code.length):
            temp = get(code, j).value
            stripped = strip(bit_string, temp[1])
            if len(stripped) < len(bit_string):
                result_string += chr(temp[0])
                bit_string = stripped
                break
        with open(output_file, 'w') as file:
            file.write(result_string)
            file.close()




class Test(unittest.TestCase):

    def test_strip1(self):
        self.assertEqual(strip('123456', '123'), '456')
    def test_strip2(self):
        self.assertEqual(strip('123', '4567'), '123')
    def test_strip3(self):
        self.assertEqual(strip('123', '456'), '123')
    def test_find(self):
        lst = empty_list()
        lst = add(lst, (1, 'b'), 0)
        lst = add(lst, (2, 'a'), 1)
        self.assertEqual(find(lst, 2), 1)

    def test_find_raise(self):
        lst = empty_list()
        lst = add(lst, (1, 'b'), 0)
        lst = add(lst, (2, 'a'), 1)
        self.assertRaises(ValueError, find, lst, 5)

    def test_occurrences(self):
        lst = empty_list()
        lst = add(lst, (97, 5), 0)
        lst = add(lst, (98, 3), 0)
        lst = add(lst , (99, 7), 2)
        self.assertEqual(str(count_occurrences(r'test2.txt')), str(lst))

    def test_create_code_and_tree_build(self):
        occurrences = count_occurrences(r'test2.txt')
        tree = build_tree(occurrences)
        code = create_code(tree)
        code = sort(code, lambda x: x.value[0], False)
        self.assertEqual(str(code), "[(97, '11'), (98, '10'), (99, '0')]")

    def test_huffman_encode_decode(self):
        string = huffman_encode(r'test1.txt', r'test_out.txt')
        huffman_decode(r'test_out.txt', r'test_decode.txt')
        self.assertEqual(string, 'a')
        with open(r'test1.txt') as file1:
            with open(r'test_decode.txt') as file2:
                self.assertEqual(file1.read(), file2.read())
                file2.close()
            file1.close()
    def test_huffman_encode_decode3(self):
        string = huffman_encode(r'test2.txt', r'test2_out.txt')
        huffman_decode(r'test2_out.txt', r'test2_decode.txt')
        self.assertEqual(string, 'cba')
        with open(r'test2.txt') as file1:
            with open(r'test2_decode.txt') as file2:
                self.assertEqual(file1.read(), file2.read())
                file2.close()
            file1.close()

    def test_huffman_encode_decode2(self):
        string = huffman_encode(r'test3.txt', r'test3_out.txt')
        huffman_decode(r'test3_out.txt', r'test3_decode.txt')
        self.assertEqual(string, 'edcba')
        with open(r'test3.txt') as file1:
            with open(r'test3_decode.txt') as file2:
                self.assertEqual(file1.read(), file2.read())
                file2.close()
            file1.close()


if __name__ == '__main__':
    unittest.main()

和以下是错误:

...
Warning (from warnings module):
  File "C:UsersVikasDocumentsfwdregardingprojectdevelopmenthuffman.py", line 212
    with open(output_file, 'w') as file:
ResourceWarning: unclosed file <_io.BufferedReader name='test_out.txt'>
.
Warning (from warnings module):
  File "C:UsersVikasDocumentsfwdregardingprojectdevelopmenthuffman.py", line 212
    with open(output_file, 'w') as file:
ResourceWarning: unclosed file <_io.BufferedReader name='test3_out.txt'>
.
Warning (from warnings module):
  File "C:UsersVikasDocumentsfwdregardingprojectdevelopmenthuffman.py", line 212
    with open(output_file, 'w') as file:
ResourceWarning: unclosed file <_io.BufferedReader name='test2_out.txt'>
.....
----------------------------------------------------------------------
Ran 10 tests in 0.272s
OK

似乎打开了代码文件'out_file'的某个地方查找打开的位置并关闭它:

out_file.close()

最新更新