Hash table implementation python - python-3.x

I was implementing my hash table function in python, how do I modify the put() and delete() functions so that the variable count is altered appropriated whenever a key-data pair is added to or deleted from the hash table.
and also how to change the len() function so that it returns this count.
I have no idea about modifying the code.....
class HashTable:
def __init__(self):
self.__size = 5
self.__slots = [None] * self.__size
self.__data = [None] * self.__size
self.__deleted = "\0"
def hash_function(self, key, size):
return key % size
def rehash(self, old_hash,size):
return (old_hash + 1) % size
def get(self, key):
start_slot = self.hash_function(key,len(self.__slots))
position = start_slot
while self.__slots[position] != None:
if self.__slots[position] == key:
return self.__data[position]
else:
position = self.rehash(position, len(self.__slots))
if position == start_slot:
return None
return None
def put(self,key,data):
hash_value = self.hash_function(key,len(self.__slots))
if self.__slots[hash_value] == None or \
self.__slots[hash_value] == self.__deleted:
self.__slots[hash_value] = key
self.__data[hash_value] = data
elif self.__slots[hash_value] == key:
self.__data[hash_value] = data
else:
next_slot = self.rehash(hash_value, len(self.__slots))
while self.__slots[next_slot] != None\
and self.__slots[next_slot] != self.__deleted \
and self.__slots[next_slot] != key:
next_slot = self.rehash(next_slot,len(self.__slots))
if next_slot == hash_value:
return
if self.__slots[next_slot] == None or \
self.__slots[next_slot] == self.__deleted:
self.__slots[next_slot] = key
self.__data[next_slot] = data
else:
self.__data[next_slot] = data
def delete(self, key):
start_slot = self.hash_function(key, len(self.__slots))
position = start_slot
key_in_slot = self.__slots[position]
while key_in_slot != None:
if key_in_slot == key:
self.__slots[position] = self.__deleted
self.__data[position] = self.__deleted
return None
else:
position = self.rehash(position, len(self.__slots))
key_in_slot = self.__slots[position]
if position == start_slot:
return None
def __delitem__(self, key):
return self.delete(key)
def __setitem__(self,key,data):
self.put(key,data)
def __getitem__(self,key):
return self.get(key)
def __len__(self):
count = 0
for value in self.__slots:
if value != None and value != self.__deleted:
count += 1
return count
def __contains__(self, key):
return self.get(key) != None
def __repr__(self):
str_rep = "["
for i in range(len(self.__slots)):
key = self.__slots[i]
data = self.__data[i]
info = ""
if key == None or key == self.__deleted:
info = ""
else:
if data == None:
info = str(key) + ":None"
else:
info = str(key) + ":" + str(data)
str_rep += info + ", "
return str_rep[:-2] + "]"

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

Trying to implement a hashMap using an array from LeetCode

I can't seem to pass all the tests that leetcode gives. I can pass 35/36 test cases and the one error that it has is the get key 623 on one of the test cases gives the wrong number. I have the test case that it didn't pass but it is really long so I don't want to post it on the question.
class pairValue:
def __init__(self, key, value):
self.key = key
self.value = value
class MyHashMap(object):
def __init__(self):
self.size = 0
self.capacity = 2
self.hashMap = [None, None]
def hash(self, key):
return key % self.capacity
def put(self, key, value):
"""
:type key: int
:type value: int
:rtype: None
"""
# if key == 623:
# print(value)
if self.size >= self.capacity //2:
self.rehash()
index = self.hash(key)
while self.hashMap[index] != None and self.hashMap[index].key != -1:
if self.hashMap[index].key == key:
self.hashMap[index].value = value
# print(self.hashMap[index].key,value)
return
index += 1
index %= self.capacity
self.hashMap[index] = pairValue(key, value)
if self.hashMap[index].key != -1:
self.size += 1
def rehash(self):
self.capacity *= 2
newMap = [None] * self.capacity
oldMap = self.hashMap
self.hashMap = newMap
self.size = 0
for x in range(len(oldMap)):
if oldMap[x] != None:
self.put(oldMap[x].key, oldMap[x].value)
# print(self.hashMap)
def get(self, key):
"""
:type key: int
:rtype: int
"""
index = self.hash(key)
# print(self.hashMap[index].key, self.hashMap[index].value)
while self.hashMap[index] != None:
if self.hashMap[index].key == 623:
print(self.hashMap[index].value)
if self.hashMap[index].key == key:
return self.hashMap[index].value
index += 1
index %= self.capacity
# print(self.hashMap)
return -1
def remove(self, key):
"""
:type key: int
:rtype: None
"""
index = self.hash(key)
while self.hashMap[index] != None:
if self.hashMap[index].key == key:
self.hashMap[index].key = -1
self.hashMap[index].value = None
self.size -= 1
index += 1
index %= self.capacity
There are five functions which are to put, get, remove, hash, and rehash, along with the initialization.

Why doesn't the window update in curses?

I took this nice example of a simple curses application with a list. I wanted to make it scrollable, so I changed the part of the list that gets shown. However, I can scroll down and back up, but the contents shown doesn't change (only the highlighted line, not the lines shown).
What am I doing wrong?
MVCE
#!/usr/bin/env python
import curses
from curses import panel
class Menu(object):
def __init__(self, items, stdscreen):
self.window = stdscreen.subwin(0, 0)
self.window.keypad(1)
self.panel = panel.new_panel(self.window)
self.panel.hide()
panel.update_panels()
self.position = 0
self.items = items
def navigate(self, n):
self.position += n
if self.position < 0:
self.position = 0
elif self.position >= len(self.items):
self.position = len(self.items) - 1
def display(self):
self.panel.top()
self.panel.show()
self.window.clear()
while True:
self.window.refresh()
curses.doupdate()
start = 0
# The next 3 lines seem not to work as intended
while start + (curses.LINES - 1) < self.position:
start += curses.LINES
for index, item in enumerate(self.items[start:curses.LINES - 1], start=start):
if index == self.position:
mode = curses.A_REVERSE
else:
mode = curses.A_NORMAL
msg = "%d. %s" % (index, item[0])
self.window.addstr(1 + index, 1, msg, mode)
key = self.window.getch()
if key in [curses.KEY_ENTER, ord("\n"), curses.KEY_RIGHT]:
self.items[self.position][1]()
elif key == curses.KEY_UP:
self.navigate(-1)
elif key == curses.KEY_DOWN:
self.navigate(1)
elif key == curses.KEY_LEFT:
break
self.window.clear()
self.panel.hide()
panel.update_panels()
curses.doupdate()
class MyApp(object):
def __init__(self, stdscreen):
self.screen = stdscreen
curses.curs_set(0)
submenu_items = [("beep", curses.beep), ("flash", curses.flash)]
submenu = Menu(submenu_items, self.screen)
main_menu_items = [
("beep", curses.beep),
("flash", curses.flash),
("submenu", submenu.display),
]
for i in range(200):
main_menu_items.append((f"flash {i}", curses.flash))
main_menu = Menu(main_menu_items, self.screen)
main_menu.display()
if __name__ == "__main__":
curses.wrapper(MyApp)
Basically that's because you're not updating the upper limit on the slice used in this loop:
for index, item in enumerate(self.items[start:curses.LINES - 1], start=start):
Here's a better version
MVCE
#!/usr/bin/env python
import curses
from curses import panel
class Menu(object):
def __init__(self, items, stdscreen):
self.window = stdscreen.subwin(0, 0)
self.window.keypad(1)
self.panel = panel.new_panel(self.window)
self.panel.hide()
panel.update_panels()
self.position = 0
self.items = items
def navigate(self, n):
self.position += n
if self.position < 0:
self.position = 0
elif self.position >= len(self.items):
self.position = len(self.items) - 1
def display(self):
self.panel.top()
self.panel.show()
self.window.clear()
while True:
start = 0
self.window.clear()
while start + (curses.LINES - 1) < self.position:
start += curses.LINES
myrow = self.position - start
mycol = 0
for index, item in enumerate(self.items[start:start + curses.LINES - 1], start=start):
if index == self.position:
mode = curses.A_REVERSE
else:
mode = curses.A_NORMAL
msg = "%d. %s" % (index, item[0])
self.window.addstr(index - start, 0, msg, mode)
if index == self.position:
(myrow, mycol) = self.window.getyx()
self.window.move(myrow, mycol)
key = self.window.getch()
if key in [curses.KEY_ENTER, ord("\n"), curses.KEY_RIGHT]:
self.items[self.position][1]()
elif key == curses.KEY_UP:
self.navigate(-1)
elif key == curses.KEY_DOWN:
self.navigate(1)
elif key == curses.KEY_LEFT:
break
self.window.clear()
self.panel.hide()
panel.update_panels()
curses.doupdate()
class MyApp(object):
def __init__(self, stdscreen):
self.screen = stdscreen
curses.curs_set(1)
submenu_items = [("beep", curses.beep), ("flash", curses.flash)]
submenu = Menu(submenu_items, self.screen)
main_menu_items = [
("beep", curses.beep),
("flash", curses.flash),
("submenu", submenu.display),
]
for i in range(200):
main_menu_items.append((f"flash {i}", curses.flash))
main_menu = Menu(main_menu_items, self.screen)
main_menu.display()
if __name__ == "__main__":
curses.wrapper(MyApp)

Why is my if statement throwing TypeError: 'int' object is not callable?

In the research I've been doing, I've seen a lot of cases where the same word is used as a variable name and a function name or something like that, and as far as I can tell I don't have any of that. But I have the following code:
operators = "['^', '*', '/', '+', '-']"
def shuntParse(infix):
print("shunting")
output = ""
operatorStack = Stack()
for token in infix:
print(token)
try:
float(token)
output + ' ' + token
except ValueError:
if ((token in operators) and (operatorStack.capacity() > 0)):
while((operators.index(operatorStack.top()) > operators.index(token)) or (operators.index(operatorStack.top()) == operators.index(token))):
output + ' ' + operatorStack.pop()
operatorStack.push(token)
elif ((token == '(') or (token in operators)):
operatorStack.push(token)
elif (token == ')'):
while (operatorStack.top() != '('):
# If stack runs out without finding a left paren, parentheses are not matched
output + ' ' + operatorStack.pop()
operatorStack.pop()
else:
pass
while (operatorStack.capacity() != 0):
output + ' ' + operatorStack.pop()
return output
And when it runs, the following error is thrown:
if ((token in operators) and (operatorStack.capacity() > 0)):
TypeError: 'int' object is not callable
I'm really stuck on why this is coming up, and would love some help. Thank you!
Edit: Here is the code used for the operatorStack
class Stack:
def __init__(self):
self.head = None
self.capacity = 0
def push(self, data):
if (self.head == None):
self.head = Node(data)
capacity += 1
else:
newNode = Node(data)
newNode.nextNode(self.head)
self.head = newNode
capacity += 1
def pop(self):
if (self.head == None):
pass
else:
newHead = self.head.nextNode
oldData = self.head.data
del self.head
self.head = newHead
capacity -= 1
return oldData
def top(self):
return self.head.data
def capacity(self):
return self.capacity

Resources