TSP using genetic algorithm - python-3.x

How do I implement 'insert mutation' and 'cycle recombination' for a TSP problem using genetic algorithm in Python3?
Assume I have done the selection steps and now I have two parents for reproduction.
This is what I have done so far:
# -*- coding: utf-8 -*-
"""
Created on Tue Dec 13 14:15:31 2016
#author: niloo
"""
import pandas as pd
import random
import numpy as np
from geopy.distance import great_circle as gcy
def read(file_name):
data = pd.DataFrame.from_csv(file_name, sep=" ")
data = np.array(data)
return data
def Dist(data):
# distance = []
for i in range(len(data)):
temp = []
for j in range(len(data)):
if j < i:
temp.append(distance[j][i])
elif i == j:
temp.append(0)
else:
temp.append(gcy((data[i][0], data[i][1]), (data[j][0], data[j][1])).km)
distance.append(temp)
#print(distance[1][2])
return distance
def k_fitness():
k = 50
t = 3
first_gener = []
how_fit = []
for i in range(0, k):
temp = np.random.permutation(535)
first_gener.append(temp)
for i in range(len(first_gener)):
sum_dis = 0
for j in range(0, 534):
temp1 = first_gener[i][j]
temp2 = first_gener[i][j + 1]
sum_dis += distance[int(temp1)][int(temp2)]
how_fit.append(sum_dis)
# print(how_fit)
race1 = np.random.randint(k, size=t)
winner1 = 9999999999999999999
for i in range(0, t):
if how_fit[int(race1[i])] < winner1:
winner1 = how_fit[int(race1[i])]
mom = first_gener[int(race1[i])]
#print (mom)
race2 = np.random.randint(k, size=t)
winner2 = 9999999999999999999
for i in range(0, t):
if how_fit[int(race2[i])] < winner2:
winner2 = how_fit[int(race2[i])]
dad = first_gener[int(race2[i])]
return mom, dad
def cross_over(mom , dad):
#mom = [1,2,3,4,5,6,7,8,9]
#dad = [9,3,7,8,2,6,5,1,4]
if len(mom) != len(dad):
print ('error')
else:
child1 = [0] * len(mom)
child2 = [0] * len(mom)
flag = False
index = [0] * len(mom)
while True:
ind = -1
for i in range(len(mom)):
if index[i] == 0:
ind = i
break
if ind == -1:
break
temp = ind
while True:
index[temp] = 1
if flag == False:
child1[temp] = mom[temp]
child2[temp] = dad[temp]
else:
child1[temp] = dad[temp]
child2[temp] = mom[temp]
val = dad[temp]
for i in range(len(dad)):
if mom[i] == val:
temp = i
break
if ind == temp:
break
if flag == False:
flag = True
else:
flag = False
#print child1
#print child2
return [child1 , child2]
def mutation(offspring):
if random.random() <= 0.02:
index1 = random.randint(534)
index2 = random.randint(534)
if index1 != index2:
ind1 = min(index1 , index2)
ind2 = max(index1 , index2)
temp = offspring [ : ind1+1]
temp += offspring [ind2 : ind2+1]
temp += offspring [ind1+1 : ind2]
temp += offspring [ind2+1 : ]
offspring = temp
return offspring
else:
return offspring
dat = read('ali535.tsp')
distance = []
Dist(dat)
k_fitness()

Related

AttibuteError when trying to make configs

AttributeError: module 'collections' has no attribute 'Sequence'
i get this error everything i try to run my code but there isn't any information about how to use Mothur except for the the documentation.
`# python3
import sys
import queue
import itertools
from collections import deque
from mothur_py import Mothur
import collections.abc as collections
class KmerIdMgmt:
def __init__(self):
self.id = 0
self.ids_map = {}
self.kmers = {}
def insert(self, kmer):
if kmer not in self.ids_map:
self.ids_map[kmer] = self.id
self.kmers[self.id] = kmer
self.id += 1
return self.ids_map[kmer]
class DeBruijnGraph(object):
def __init__(self, k, reads):
self.k = k
self.threshold = self.k + 1
self.kmer_ids = KmerIdMgmt()
self.coverage = {}
self.graph = {}
self.outgoing_num = lambda k: len(self.graph[k][0])
self.incoming_num = lambda k: self.graph[k][1]
self.make_deBruijn_graph(self.break_reads_into_kmers(reads))
def break_reads_into_kmers(self, reads):
break_read = lambda read: [ read[j:j + self.k] for j in range(len(read) - self.k + 1) ]
return [ kmer for read in reads for kmer in break_read(read) ]
def make_deBruijn_graph(self, kmers):
def add_edge(graph, coverage, left, right):
graph.setdefault(left, [set(), 0])
graph.setdefault(right, [set(), 0])
coverage.setdefault((left, right), 0)
coverage[(left, right)] += 1
if right not in graph[left][0]:
graph[left][0].add(right)
graph[right][1] += 1
for kmer in kmers:
left = self.kmer_ids.insert(kmer[:-1])
right = self.kmer_ids.insert(kmer[1:])
if left != right:
add_edge(self.graph, self.coverage, left, right)
def remove_leaves(self):
removable = [ k for k, v in self.graph.items() if len(v[0]) == 0 ]
for k in removable:
del self.graph[k]
def print_graph(self):
for k, v in self.graph.items():
print(k, v)
class TipRemoval(DeBruijnGraph):
def __init__(self, k, reads):
DeBruijnGraph.__init__(self, k, reads)
def remove_tips(self):
for k, v in self.graph.items():
find_and_remove = None
if self.outgoing_num(k) == 1 and self.incoming_num(k) == 0:
find_and_remove = self.find_and_remove_incoming
elif self.outgoing_num(k) > 1:
find_and_remove = self.find_and_remove_outgoing
else: continue
condition = True
while condition:
condition = False
for edge in v[0]:
if find_and_remove(edge, 0):
v[0].remove(edge)
condition = True
break
def find_and_remove_outgoing(self, current, depth):
if self.outgoing_num(current) > 1 or self.incoming_num(current) > 1:
return False
if depth == self.threshold:
return False
if self.outgoing_num(current) == 0:
return True
if self.find_and_remove_outgoing(next(iter(self.graph[current][0])), depth + 1):
to = next(iter(self.graph[current][0]))
self.graph[current][0].pop()
self.graph[to][1] -= 1
return True
return False
def find_and_remove_incoming(self, current, depth):
if self.outgoing_num(current) == 0 or self.incoming_num(current) > 1:
return True
if depth == self.threshold:
return False
if self.find_and_remove_incoming(next(iter(self.graph[current][0])), depth + 1):
to = next(iter(self.graph[current][0]))
self.graph[current][0].pop()
self.graph[to][1] -= 1
return True
return False
class BubbleRemoval(TipRemoval):
def __init__(self, k, reads):
TipRemoval.__init__(self, k, reads)
self.paths = {}
def remove_bubbles(self):
for k, v in self.graph.items():
if self.outgoing_num(k) > 1:
self.dfs(path=[k], current=k, depth=0)
for pair, candidates_list in self.paths.items():
source, target = pair[0], pair[1]
best_path = max(candidates_list, key=lambda item: item[1])[0]
for path, _ in candidates_list:
if best_path == path or not self.bubble_possible(source, target):
continue
if self.paths_disjoint(best_path, path) and self.path_exists(path):
self.remove_path(path)
def bubble_possible(self, source, target):
return len(self.graph[source][0]) > 1 and self.graph[target][1] > 1
def path_exists(self, path):
for j in range(len(path) -1):
if path[j +1] not in self.graph[path[j]][0]:
return False
return True
def remove_path(self, path):
for j in range(len(path) -1):
self.graph[path[j]][0].remove(path[j +1])
self.graph[path[j +1]][1] -= 1
del self.coverage[(path[j], path[j +1])]
def paths_disjoint(self, a, b):
return len(set(a) & set(b)) == 2
def dfs(self, path, current, depth):
if current != path[0] and self.incoming_num(current) > 1:
weight = sum(self.coverage[(path[i], path[i+1])] for i in range(len(path)-1)) / len(path)
self.paths.setdefault((path[0], current), list()).append((path[:], weight))
if depth == self.threshold:
return
for next_ in self.graph[current][0]:
if next_ not in path:
path.append(next_)
self.dfs(path, next_, depth + 1)
path.remove(next_)
class PhiX174GenomeAssembler(BubbleRemoval):
def __init__(self, k, reads):
BubbleRemoval.__init__(self, k, reads)
def make_Euler_cycle(self):
verteces = deque()
path = []
# line 191
current = next(iter(self.graph))
verteces.append(current)
while verteces:
current = verteces[0]
if len(self.graph[current][0]) != 0:
t = next(iter(self.graph[current][0]))
verteces.append(t)
self.graph[current][0].remove(t)
continue
path.append(current)
verteces.popleft()
return path
def assemble(self):
self.remove_tips()
self.remove_leaves()
self.remove_bubbles()
cycle = self.make_Euler_cycle()
circular_genome = self.kmer_ids.kmers[cycle[0]]
for i in range(1, len(cycle) - (self.k - 1)):
circular_genome += self.kmer_ids.kmers[cycle[i]][-1]
return circular_genome
if __name__ == "__main__":
n_kmers = int(input())
for _ in range(n_kmers):
reads = list(input())
reads = str(reads)
with open('reads.fasta', 'w') as read:
read.write(reads)
k = 100
m = Mothur()
contig = m.make.contigs(ffasta = read)
for x in range(n_kmers):
print(">CONTIG", x)
print(contig)
`

How to find the shortest path

In the function of find_shortest_func, i think if now position isn't "T" which is also known as the terminal or exit, then i will try to find for direction and see if it is "T", if not, check if it is space and i can go there. Besides, tell the next state function now output and dic to tell the place where i visited. But some errors occur and I don't know why.
I think the problem may occur where I tried to deepcopy the output list
import copy
def set_symbol(symbol_name):
def set_symbol_decorator(func):
def wrapper(self, symbol):
setattr(self, symbol_name, symbol)
return wrapper
return set_symbol_decorator
class Maze:
space_symbol = " "
obstacle_symbol = "X"
path_symbol = "•"
output = []
dis = 0
def __init__(self, input_string):
self.maze = []
if input_string.endswith("txt"):
with open(input_string) as f:
count = 0
for line in f.readlines():
self.maze.append([])
for j in line:
if j != '\n':
self.maze[count].append(j)
count += 1
else:
count = 0
for i in input_string.split("\n"):
self.maze.append([])
for j in i:
self.maze[count].append(j)
count += 1
def __str__(self):
output_string = ""
for i in range(20):
for j in range(20):
output_string += self.maze[i][j]
output_string += "\n"
return output_string
#set_symbol("space_symbol")
def set_space_symbol(self, change):
pass
#set_symbol("obstacle_symbol")
def set_obstacle_symbol(self, change):
pass
#set_symbol("path_symbol")
def set_path_symbol(self, change):
pass
def find_shortest_func(self, position: tuple, d: dict, out: list, dis: int):
dic = copy.deepcopy(d)
output = copy.deepcopy(out)
dic[(position[0], position[1])] = 1
output.append((position[0], (position[1])))
dis += 1
if self.maze[position[0]][position[1]] != "T":
if position[0]+1 < 20 and self.maze[position[0]+1][position[1]] == self.space_symbol and (position[0]+1, position[1]) not in dic:
self.find_shortest_func(
(position[0]+1, position[1]), dic, output, dis)
if position[1]+1 < 20 and self.maze[position[0]][position[1]+1] == self.space_symbol and (position[0], position[1]+1) not in dic:
self.find_shortest_func(
(position[0], position[1]+1), dic, output, dis)
if position[0]-1 >= 0 and self.maze[position[0]-1][position[1]] == self.space_symbol and (position[0]-1, position[1]) not in dic:
self.find_shortest_func(
(position[0]-1, position[1]), dic, output, dis)
if position[1]-1 >= 0 and self.maze[position[0]][position[1]-1] == self.space_symbol and (position[0], position[1]-1) not in dic:
self.find_shortest_func(
(position[0], position[1]-1), dic, output, dis)
if self.maze[position[0]][position[1]] == "T":
if dis < self.dis:
self.output = copy.deepcopy(output)
self.dis = dis
return
def find_shortest_path(self):
d = dict()
output = []
dis = -1
self.find_shortest_func((1, 0), d, output, dis)
return self.output, self.dis

AttributeError: module 'curses' has no attribute 'cur_set'

import random
import curses
s = curses.initscr()
curses.cur_set(0)
sh, sw = s.getmaxyx()
w = curses.newwin(sh, sw, 0, 0)
w.keypad(1)
w.timeout(100)
snk_x = sw/4
snk_y = sh/2
snake = [
[snk_y, snk_x],
[snk_y, snk_x-1],
[snk_y, snk_x-2]
]
food = [sh/2, sw/2]
w.addch(food[0], food[1], curses.ACS_PI)
key = curses.KEY_RIGHT
while True:
next_key = w.getch()
key = key if next_key == -1 else next_key
if snake[0][0] in [0, sh] or snake[0][1] in [0, sw] or snake[0] in snake[1:]:
curses.endwin()
quit()
new_head = [snake[0][0], snake[0][1]]
if key == curses.KEY_DOWN:
new_head[0] += 1
if key == curses.KEY_UP:
new_head[0] -= 1
if key == curses.KEY_LEFT:
new_head[0] -= 1
if key == curses.KEY_RIGHT:
new_head[0] += 1
snake.insert(0, new_head)
if snake[0] == food:
food = None
while food is None:
nf = [random.randint(1, sh-1),
random.randint(1, sw-1)
]
food = nf if nf not in snake else None
w.addch(food[0], food[1], curses.ACS_PI)
else:
tail = snake.pop()
w.addch(tail[0], tail[1], '')
w.addch(snake[0][0], snake[0][1], curses.ACS_CKBOARD)
curses doesn't have a cur_set() method, but curs_set().
curses.curs_set(0)

ModuleNotFoundError: No module named 'src'. Python 3 error

I'm facing the dreaded ModuleNotFoundError: No module named 'src' error. I've done quite some extensive reading into this problem and see that this is a common problem. I can't seem to wrap my head around this.
You can pull my repo at https://github.com/mustafahoda/data-structures-and-algos
Here is what my current project directory looks like.
I'm using pipenv and running commands from after entering the env shell.
I'm using python 3
DSandAlgoBenchmarkSuite
src
|---CommonProblems
|---DataStructures
|---SortingAlgorithms
|--sorting_algos.py
test
|---test_bubble_sort_1.py
.gitignore
.benchmarks
.pytest_cache
Pipfile
Pipfile.lock
test.py
test_bubble_sort_2.py
I have two files that I'd like to run:
test/test_bubble_sort_1.py
test_bubble_sort_2.py
Contents of each file.
# test/test_bubble_sort_1.py
from src.SortingAlgorithms import sorting_algos
import pytest
# test_bubble_sort_2.py
from src.SortingAlgorithms import sorting_algos
import pytest
# src/SortingAlgorithms/sorting_algos.py
# ---------BUBBLE SORT-------------
def bubble_sort(A: list) -> list:
sorted = len(A)
for i in range(len(A)):
L = 0
R = 1
while R != len(A) :
# if L > R, then swap
if A[L] > A[R]:
temp = A[L]
A[L] = A[R]
A[R] = temp
L = L + 1
R = R + 1
return A
# -----------------INSERTION SORT----------------------
def shift_items_to_right(B, start, stop):
for i in range(stop, start, -1):
B[i] = B[i - 1]
return B
def insertion_sort(A : list) -> list:
sorted = 0
while sorted != len(A):
hole = 0
for i in A[:sorted + 1]:
value = A[sorted]
if value < A[hole]:
# move all items to the right from the hole onwards
shift_items_to_right(A, hole, sorted)
# store the value in the hole
A[hole] = value
else:
hole = hole + 1
sorted = sorted + 1
return A
# ---------------------MERGE SORT--------------------------------------
def merge(A: list, B: list) -> list:
ptr_A = 0
ptr_B = 0
C = []
while ptr_A <= len(A) - 1 and ptr_B <= len(B) - 1:
if A[ptr_A] >= B[ptr_B]:
C.append(B[ptr_B])
ptr_B = ptr_B + 1
else:
C.append(A[ptr_A])
ptr_A = ptr_A + 1
if ptr_A == len(A):
for i in B[ptr_B:]:
C.append(i)
else:
for i in A[ptr_A:]:
C.append(i)
return C
def merge_sort(A: list) -> list:
print("A: %s" % A)
if len(A) == 1:
return A
# STEP 1: Divide
mid = len(A) // 2
L = A[:mid]
R = A[mid:]
if L is not None:
L = merge_sort(L)
if R is not None:
R = merge_sort(R)
merged = merge(L, R)
print("Merged: %s" % merged)
return merged
# ---------------------QUICK SORT--------------------------------------
def quicksort(A: list) -> list:
return _quicksort(A, 0, len(A) - 1)
def _quicksort(A: list, start: int, end: int) -> list:
if start >= end:
return A
print("A before partition: %s" % A)
pIndex = partition(A, start, end)
print("A after partition: %s" % A)
print("_____________________________")
_quicksort(A, start, pIndex - 1)
_quicksort(A, pIndex, end)
return A
def partition(A, start: int, end: int):
# set_trace()
pivot = A[end]
i = start
pIndex = start
# set_trace()
while i < end:
# set_trace()
if pivot >= A[i]:
# implement swap between pIndex and A[i]
temp = A[i]
A[i] = A[pIndex]
A[pIndex] = temp
pIndex = pIndex + 1
i = i + 1
# once we reach the element before the pivot, we swap pivot into pIndex
temp = A[pIndex]
A[pIndex] = pivot
A[end] = temp
# set_trace()
print(A)
return pIndex
# ---------------------SELECTION SORT-------------------------------------
def find_min_not_in_place(A: list, visited) -> int:
for i in A:
if visited[i] == False:
min = i
break
for i in A[1:]:
# set_trace()
if i < min and visited[i] == False:
# set_trace()
min = i
# visited[min] = True
return min
def selection_sort_not_in_place(A: list) -> list:
B = []
# construct a dictionary that will keep track of visited numbers
visited = dict()
for i in A:
visited[i] = False
# keep repeating the process until theere are no values in dictionary with False
while False in visited.values():
for i in A:
min = find_min_not_in_place(A, visited)
# set_trace()
B.append(min)
visited[min] = True
print(B)
return B
def find_min_in_place(A: list, sorted_index: int) -> int:
min_index = sorted_index
min = A[sorted_index]
# for i in A[sorted_index:]:
for i in range(sorted_index, len(A)):
if A[i] < min:
min = A[i]
min_index = i
return (min, min_index)
def selection_sort_in_place(A: list) -> list:
sorted = 0
while sorted != len(A):
# min, min_index = find_min_in_place(A[sorted + 1:])
min, min_index = find_min_in_place(A, sorted)
# implement swapping
temp = A[sorted]
A[sorted] = min
A[min_index] = temp
sorted = sorted + 1
return A
Ideally, I want pytest-benchmark suite to work but I've isolated the problem to being an import error.
When I run test_bubble_sort_2.py from the main project directory, it works fine!
However, when I run test/test_bubble_sort_1.py from the main project directory, it doesn't work and throws the exception: ModuleNotFoundError: No module named 'src'
I'd like to run test/test_bubble_sort_1.py in order to maintain the project structure and access the functions from my sorting_algos.py file so I can benchmark them.

Runtime/Resource Warning error in Python

I was trying to run this code and encountered a run time error. I am not able to debug the code. I do believe that the error lies in functions huffman_encode and huffman_decode. The error showing is the resource warning error. Here is the code:
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 = {}\n\left = {}\n\right = {}".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()
And following is the error:
...
Warning (from warnings module):
File "C:\Users\Vikas\Documents\fwdregardingprojectdevelopment\huffman.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:\Users\Vikas\Documents\fwdregardingprojectdevelopment\huffman.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:\Users\Vikas\Documents\fwdregardingprojectdevelopment\huffman.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
it seems somewhere in your code file 'out_file' is opened and not closed
find where it is opened and close it :
out_file.close()

Resources