I am implementing LinkedList in Python 3.6.5. I am stuck with deleting a node from the end:
Here's the code:
class Node(object):
def __init__(self, data):
self.data = data
self.nextNode = None
class LinkedList(object):
def __init__(self):
self.head = None
self.counter = 0
def print_list(self):
current = self.head
while current is not None:
print(current.data)
current = current.nextNode
def size(self):
print(self.counter)
def insert_end(self,data):
newNode = Node(data)
current = self.head
if self.head is None:
self.head = newNode
self.counter+=1
else:
while current.nextNode is not None:
current = current.nextNode
current.nextNode = newNode
self.counter+=1
def insert_end(self,data):
newNode = Node(data)
current = self.head
if self.head is None:
self.head = newNode
self.counter+=1
else:
while current.nextNode is not None:
current = current.nextNode
current.nextNode = newNode
self.counter+=1
def insert_beg(self,data):
newNode = Node(data)
if self.head is None:
self.head = newNode
self.counter+=1
else:
newNode.nextNode = self.head
self.head = newNode
self.counter+=1
def remove_beg(self):
if self.head is None:
print("Linked List is already empty")
else:
currentNode = self.head
self.head = self.head.nextNode
self.counter-=1
del currentNode
def remove_end(self):
if self.head is None:
print("Linked List is already empty")
else:
current_head = self.head
while current_head.nextNode is not None:
current_head = current_head.nextNode
current_node = current_head
current_head.nextNode = None
del current_node.nextNode
self.counter-=1
linkedlist = LinkedList()
linkedlist.remove_beg()
linkedlist.insert_end(1)
linkedlist.insert_end(2)
linkedlist.insert_end(3)
linkedlist.insert_end(4)
print("printing list")
linkedlist.print_list()
linkedlist.insert_beg(22)
print("printing list after addition of 22 in the beginning")
linkedlist.print_list()
linkedlist.remove_beg()
print("printing list")
linkedlist.print_list()
print("printing size")
linkedlist.size()
linkedlist.insert_end(55)
linkedlist.print_list()
linkedlist.remove_end()
linkedlist.print_list()
Everything works fine except removing the node from the end.
Output:
Traceback (most recent call last):
File "intermediate.py", line 84, in
linkedlist.remove_end()
File "intermediate.py", line 61, in remove_end
current_head.nextNode = None
AttributeError: 'NoneType' object has no attribute 'nextNode'
To delete a node from the last, we need to create a link between the second-last node and None
def remove_end(self):
if self.head is None:
print('List is empty!')
else:
current_head = self.head
current_node = None
while current_head.nextNode is not None:
previous = current_head
current_head = current_head.nextNode
previous.nextNode = None
del current_head
Related
Trying to implement the reaserch paper:
https://ieeexplore.ieee.org/document/9479786/
Training a Monotone Network with architechture:
class Model(nn.Module):
def __init__(self, q, s):
self.layer_s_list = [nn.Linear(5, s) for _ in range(q)]
self.inv_w, self.inv_b = self.get_layer_weights()
def forward(self, x):
# print(inv_w[0].shape, inv_b[0].shape)
output_lst = []
for layer in self.layer_s_list:
v, id = torch.max(layer(x), 1)
output_lst.append(v.detach().numpy())
output_lst = np.array(output_lst)
output_lst = torch.from_numpy(output_lst)
out, _ = torch.min(output_lst, 0)
allo_out = F.softmax(out)
pay_out = nn.ReLU(inplace = True)(out)
inv_out_lst = []
for q_idx in range(len(self.inv_w)):
# print(inv_w[q_idx].shape, pay_out.shape, inv_b[q_idx].shape)
y, _ = torch.min(torch.linalg.pinv(self.inv_w[q_idx]) * (pay_out - self.inv_b[q_idx]), 0)
inv_out_lst.append(y.detach().numpy())
final_out = np.array(inv_out_lst)
final_out = torch.from_numpy(final_out)
final_out, _ = torch.max(final_out, 1)
return final_out, allo_out
def get_layer_weights(self):
weights_lst = []
bias_lst = []
for layer in self.layer_s_list:
weights_lst.append(layer.state_dict()['weight'])
bias_lst.append(layer.state_dict()['bias'])
return weights_lst, bias_lst
When I initialise the network and run for random inputs:
q = 5
s = 10
x = torch.rand((10, 5), requires_grad = True)
net = Model(q, s)
y, z = net(x)`
It gives the following error:
AttributeError Traceback (most recent call last)
<ipython-input-3-aac6d239df1f> in <module>
1 x = torch.rand((10, 5), requires_grad = True)
2 net = Model(5, 10)
----> 3 y = net(x)
1 frames
/usr/local/lib/python3.7/dist-packages/torch/nn/modules/module.py in __getattr__(self, name)
1206 return modules[name]
1207 raise AttributeError("'{}' object has no attribute '{}'".format(
-> 1208 type(self).__name__, name))
1209
1210 def __setattr__(self, name: str, value: Union[Tensor, 'Module']) -> None:
AttributeError: 'Model' object has no attribute '_backward_hooks'
Please help me understand what this error is and how to fix it.
You forgot to initialize your model with __init__ method of its parent class nn.Module. A simple solution is to add one line in your Model.__init__:
class Model(nn.Module):
def __init__(self, q, s):
super(Model, self).__init__()
self.layer_s_list = [nn.Linear(5, s) for _ in range(q)]
self.inv_w, self.inv_b = self.get_layer_weights()
I have a grid network (like a maze) and I want to find the shortest route from the source node to the destination node.
I've coded that and it works well. It finds the shortest route for a network of dimensions x*y and with the specific nodes as the source and destination nodes which are determined as inputs to the environment. env = netEnv(3, 4, 1, 8) means my env is a 3*4 grid network with node 1 as the source node and node 8 as the destination node.
The question is how to train the model for any destination? I mean the model works well if the destination is say node 8. But I want it to be trained so that it will find the answer if the destination is a different node in the environment. I don't want the destination to be always fixed.
How can I do that?
Here is my code:
#import dependecies
import gym
from gym import Env
from gym.spaces import Discrete
from stable_baselines3 import DQN
from stable_baselines3 import PPO
from stable_baselines3.common.vec_env import DummyVecEnv
from stable_baselines3.common.evaluation import evaluate_policy
import os
#building the environment
class netEnv(Env):
def __init__(self, x, y, sourceNode, destinationNode):
self.action_space = Discrete(4) #0, 1, 2, 3 => up, down, right, left
self.observation_space = Discrete(x*y)
self.sourceNode = sourceNode
self.destinationNode = destinationNode
self.x = x
self.y = y
self.state = self.sourceNode
self.episodeLength = 20
def step(self, action):
#set actions and rewards
if action == 0: #up
if self.state >= self.y:
self.state = self.state - self.y
#print(self.state)
reward = 0.1
else:
reward = 0
elif action == 1: #down
if self.state < (self.x-1)*self.y:
self.state = self.state + self.y
#print(self.state)
reward = 0.1
else:
reward = 0
elif action == 2: #right
if (self.state % self.y) != self.y-1:
self.state += 1
#print(self.state)
reward = 0.1
else:
reward = 0
else: #left
if (self.state % self.y) != 0:
self.state -= 1
#print(self.state)
reward = 0.1
else:
reward = 0
#decrease the remaining time
self.episodeLength -=1
#reward in termination state
if self.state == self.destinationNode:
reward += self.episodeLength
#set done
if self.episodeLength <= 0 or self.state == self.destinationNode:
done = True
else:
done = False
#set info
info = {}
return self.state, reward, done, info
def render(self):
pass
def reset(self):
self.state = self.sourceNode
self.episodeLength = 20
return self.state
env = netEnv(3, 4, 1, 8)
#training
log_path = os.path.join('Training', 'Logs')
model = PPO('MlpPolicy', env, verbose = 1, tensorboard_log = log_path)
model.learn(total_timesteps=15000)
net_path = os.path.join('Training', 'Saved_models', 'net_PPO_15000')
model.save(net_path)
#delete and reload the model
del model
model = PPO.load(net_path, env)
#evaluate the model
print(evaluate_policy(model, env, n_eval_episodes = 10, render = False))
I want to perform PCA on a list of dataframes, such as cna. My code raised ValueError: Found array with 0 feature(s) (shape=(54, 0)) while a minimum of 1 is required.
class StringConverter(dict):
def __contains__(self, item):
return True
def __getitem__(self, item):
return str
def get(self, default=None):
return str
def get_pathways():
pathways = []
with open(dir + "hsa.txt", newline='') as csvfile:
freader = csv.reader(csvfile, delimiter='\t')
for row in freader:
pathways.append(row)
return pathways
class DataProcessing:
def __init__(self, data, header=0):
self.df = pd.read_csv(data, sep="\t", header=header)
def split_data(self):
X = self.df.iloc[:, :-1]
y = self.df.iloc[:, -1]
return X, y
def pca(self):
pca = PCA()
if np.any(np.isnan(self.df)):
pass
elif np.all(np.isfinite(self.df)):
pass
else:
pca.fit(self.df.iloc[1:, 3:])
self.pca_components = pca.components_
return self.pca_components
def main():
cna = DataProcessing(dir + "data_linear_cna.txt")
patients_source = DataProcessing(dir + "data_clinical_patient_reduced.txt", 0)
patients = {}
# get list of allowed patients
for index, row in patients_source.df.iterrows():
if row.OS_MONTHS != '[Not Available]':
if float(row.OS_MONTHS) > 2 * 12:
patients[row.PATIENT_ID] = 1
pathways = get_pathways()
#### Process the CNA data
q = 5
C = []
G = []
M = []
# find common samples
n = cna.df.shape[1]
common_samples = {}
cna_sample_index = {}
for i in range(2, n):
sample_name = list(cna.df)[i][0:-3]
if sample_name in patients:
common_samples[sample_name] = 1
cna_sample_index[sample_name] = i
ordered_common_samples = list(common_samples.keys())
ordered_common_samples.sort()
process_cna = True
if process_cna:
C = []
for i, p in enumerate(pathways):
allowed_symbols = {}
first = True
for s in p:
if first:
first = False
else:
if s != 'NA':
allowed_symbols[s] = 1
# going through each sample
B = []
allowed_columns = []
for s in ordered_common_samples:
B.append([])
allowed_columns.append(cna_sample_index[s])
Bi = 0
for index, row in cna.df.iterrows():
if row[0].upper() in allowed_symbols:
Bi2 = Bi
for c in allowed_columns:
B[Bi2].append(cna.df.iloc[index, c])
Bi2 = Bi2 + 1
pca_B = PCA()
pca_B.fit(B)
C.append(pca_B.transform(B)[:, 0:q])
cna.pca()
main()
Traceback:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-59-d61a65bf4d9e> in <module>()
248
249
--> 250 main()
4 frames
/usr/local/lib/python3.7/dist-packages/sklearn/utils/validation.py in check_array(array, accept_sparse, accept_large_sparse, dtype, order, copy, force_all_finite, ensure_2d, allow_nd, ensure_min_samples, ensure_min_features, estimator)
815 "Found array with %d feature(s) (shape=%s) while"
816 " a minimum of %d is required%s."
--> 817 % (n_features, array.shape, ensure_min_features, context)
818 )
819
ValueError: Found array with 0 feature(s) (shape=(54, 0)) while a minimum of 1 is required.
I'm trying to parse a text with the Shunting-yard algorithm but I've come across a problem. I don't know where to start parsing functions.
This is my goal: print('Hello ' + in())
The current tokens:
[ID print, LPAREN, STRING "Hello ", PLUS, ID in, LPAREN, RPAREN, RPAREN]
My current parser:
class Parser:
def __init__(self, tokens:list, variables:dict):
self.tokens = tokens
self.idx = -1
self.tok = None
self.variables = variables
self.value_stack = []
self.operator_stack = []
self.next_token()
def next_token(self):
self.idx += 1
self.tok = self.tokens[self.idx] if self.idx < len(self.tokens) else None
def pop(self):
newop = self.operator_stack.pop()
val1 = self.value_stack.pop()
val2 = self.value_stack.pop()
self.value_stack.append(eval_(val1, val2, newop))
def parse(self):
while self.tok:
if self.tok.type in VALUE_TYPE:
self.value_stack.append(self.tok.value)
elif self.tok.type == TT_ID:
self.id()
continue
elif self.tok.type == TT_LPAREN:
self.operator_stack.append(TT_LPAREN)
elif self.tok.type in OPERATORS:
op = self.tok.type
while self.operator_stack and PRESCEDENCE.get(self.operator_stack[-1], 0) >= PRESCEDENCE.get(op, 0):
self.pop()
self.operator_stack.append(op)
elif self.tok.type == TT_RPAREN:
while self.operator_stack and self.operator_stack[-1] != TT_LPAREN:
self.pop()
self.operator_stack.pop()
self.next_token()
while self.operator_stack:
self.pop()
return self.value_stack[-1] if self.value_stack else None
def id(self):
tok = self.tok
self.next_token()
if not self.tok: return
if self.tok.type == TT_EQUALS:
self.next_token()
self.variables[tok.value] = self.parse()
elif self.tok.type == TT_LPAREN:
self.operator_stack.append(tok.value)
else:
self.value_stack.append(self.variables.get(tok.value, 'null'))
How would I implement function handling? Every time I try to execute a function I get this error:
Traceback (most recent call last):
File "lang.py", line 19, in <module>
out = evaluate(text, variables)
File "lang.py", line 10, in evaluate
parser.parse()
File "parsing.py", line 85, in parse
self.pop()
File "parsing.py", line 52, in pop
val2 = self.value_stack.pop()
IndexError: pop from empty list
Any help is appreciated.
Merge Sort functions with only some inputs when run on a linked list. If I include 0 in the list of inputs, only 0 is returned from the final print() call. I don't know what I'm doing wrong
class StackNode(object):
def __init__(self, data):
self.data = data
self.prev = None
class Stack(object):
def __init__(self):
self.head = None
self.count = 0
def push(self, data):
if (self.head == None):
self.head = StackNode(data)
self.count += 1
return
node = StackNode(data)
node.prev = self.head
self.head = node
self.count += 1
return
def pop(self):
node = self.head
self.head = self.head.prev
self.count -= 1
return node
def print(self):
node = self.head
if(node == None):
return
print(node.data)
while(node.prev):
node = node.prev
print(node.data)
def MergeSort(self, h):
if h == None or h.prev == None:
return h
middle = self.GetMiddle(h)
nextToMiddle = middle.prev
middle.prev = None
left = self.MergeSort(h)
right = self.MergeSort(nextToMiddle)
sortedList = self.SortedMerge(left, right)
return sortedList
def SortedMerge(self, a, b):
if a is None:
return b
if b is None:
return a
if(a.data > b.data):
result = a
a.prev = self.SortedMerge(a.prev, b)
else:
result = b
b.prev = self.SortedMerge(b.prev, a)
return result
def GetMiddle(self, head):
if head == None:
return head
slow = head
fast = head
while(fast.prev != None and fast.prev.prev != None):
slow = slow.prev
fast = fast.prev.prev
return slow
a = Stack()
a.push(2)
a.push(5)
a.push(1)
a.push(4)
a.push(3)
a.push(7)
a.print()
a.MergeSort(a.head)
print("after: ")
a.print()
I transcribed my code directly from the linked list merge sort example given on geeksforgeeks.com, with the only difference being that my code creates a stack instead of a queue
MergeSort returns the head of a sorted list, so the call in the main code should be:
a.head = a.MergeSort(a.head)
For a sorted stack, it would seem that the result of doing successive list.pop() should return the nodes in data order, but the code is using ">" instead of "<=" in the compare, reversing the order.
Python 2.7 complained about using the name print for the class print function, and also complained about the 5 (instead of 4) spaces before "def SortedMerge(self, a, b):"
SortedMerge() does one level of recursion for every node merged. For a large list, the program will get stack overflow. Since the list class includes a count, the code could use list.count//2 to determine the number of nodes to advance to reach the midpoint, then use (count//2) for the size of the left half and (count-(count//2)) for the size of the right half. A bottom up merge sort is faster still. However, with python, the overhead of interpreting code is so large that I don't know if it will make a difference. Here is a link to both top down and bottom up merge sort for a linked list, in java, that use a common merge function:
Merge Sort for Singly Linked List seems to remove any numbers larger than the final number I input into the list
I converted the code to python. The merge function is the same for both examples. Note the sort logic is the same, only the push and pop functions result in the linked list acting as a stack. Merge function:
def Merge(self, a, b):
if a is None:
return b
if b is None:
return a
r = StackNode(0) # dummy node
d = r
while(True):
if(a.data <= b.data):
d.prev = a
d = a
a = a.prev
if(a == None):
d.prev = b
break
else:
d.prev = b
d = b
b = b.prev
if(b == None):
d.prev = a
break
return r.prev
Top down example:
def MergeSort(self):
if(self.count < 2):
return
self.head = self.MergeSortR(self.head, self.count)
def MergeSortR(self, h, n):
if(n < 2):
return h
n2 = n//2
t = self.Scan(h, n2-1)
m = t.prev
t.prev = None
h = self.MergeSortR(h, n2)
m = self.MergeSortR(m, n-n2)
h = self.Merge(h, m)
return h
def Scan(self, h, n):
while(n > 0):
h = h.prev
n = n-1
return h
Bottom up example:
def MergeSort(self):
if(self.count < 2):
return
an = [None] * 32
node = self.head
while(node != None):
prev = node.prev
node.prev = None
i = 0
while((i < 32) and (an[i] != None)):
node = self.Merge(an[i], node)
an[i] = None
i = i+1
if(i == 32):
i = i-1
an[i] = node
node = prev
for i in xrange (0, 32):
node = self.Merge(an[i], node)
self.head = node
Test code for 512K nodes. On my system, top down takes about 4.5 seconds, bottom up about 3.9 seconds. To get an idea of the overhead of Python, bottom up in C takes about 0.06 seconds.
import random
from time import time
p = [random.randint(0, 2147483647) for r in xrange(512*1024)]
a = Stack()
for i in xrange (0, len(p)):
a.push(p[i])
s = time()
a.MergeSort()
e = time()
print e - s
for i in xrange (0, len(p)):
p[i] = a.pop().data
for i in xrange (1, len(p)):
if(p[i-1] > p[i]):
print("error")
break