Class attributes in Python objects "erasing" themselves - python-3.x

I'm working with some old Python2 code from a differential power analysis (DPA) contest from way back (http://www.dpacontest.org/home/index.html). The code I'm modifying can be found here (https://svn.comelec.enst.fr/dpacontest/code/reference/)
Current issue that is driving me nuts:
Essentially, Some python objects in this code will "erase" themselves or go to their default values, and I have no idea why. I cannot find any code in the logic flow that does this, and I don't think it's a scope issue.
I've tried rewriting parts of the code to use numpy instead of mapping lambda functions. I've also tried a myriad of different orderings of code and pulling methods out of their classes and trying to run them locally/inline.
main.py:
loc_subkeys = brk.get_subkeys()
des_breaker.py
def get_subkeys(self):
"""
Returns a vector of currently best sboxes subkeys.
This is an array of 8 integers.
"""
sk = np.array([])
for i in range(8):
sk = np.append(sk, self.__sbox_breakers[i].get_key())
return sk
sbox_breaker.py
def get_key(self):
"Gives the current best key"
if self.__best_key is None:
marks = np.array([])
print("p0: ", len(list(self.__key_estimators[0]._key_estimator__p0)))
print("p1: ", len(list(self.__key_estimators[0]._key_estimator__p1)))
print("p0: ", len(list(self.__key_estimators[0]._key_estimator__p0)))
print("p1: ", len(list(self.__key_estimators[0]._key_estimator__p1)))
for i in range(64):
ke = self.__key_estimators[i]
marks = np.append(marks, ke.get_mark())
self.__best_key = np.argmax(marks)
return self.__best_key
key_estimator.py - attributes
class key_estimator:
"""
Provides methods to give a mark to the key relatively to the probability f
the correctness of the key.
"""
__sbox = None
__key = None
__cnt0 = 0 # The accumulated traces count in partition 0
__cnt1 = 0 # The accumulated traces count in partition 1
__p0 = None # The bit=0 estimated partition
__p1 = None # The bit=1 estimated partition
__diff = np.array([]) # The differential trace
Print statements in sbox_breaker are mine. Their output is the only clue I have right now:
p0: 5003 (Good)
p1: 5003 (Good)
p0: 0 (???)
p1: 0
What gives? The second time around the attributes of the key_estimator class have seemed to erase themselves. This happens to all the attributes, not just p0 and p1.
The first loop through this program works, but on the second iteration (starting from main) it fails because the attributes have erased themselves. I can "erase" them manually just by printing the object's attributes.

So I seemed to have fixed the problem after sleeping on it. The class attributes were being created by map which returns a list in Python2, but not Python3. Making them into lists with list() solves the persistence issue. I couldn't tell you why printing a map attribute causes it to clear itself though.

Related

Dictionary of Constraints Python SciPy.Optimize

I'm working on creating a dictionary of constraints for a large SCED power problem for minimization. However, I'm being given a ValueError saying an unknown type is passed despite only using Optimize.LinearConstraints at present. When I change to NonlinearConstraints (shown below), indicating that 'NonlinearConstraint' object has no attribute 'A'.
I have a feeling it's due to recursive elements, as even using a single constraint as I've defined them returns the same error
Any idea how I can create the recursive linear constraints?
##EDIT
I've been told to copy the code and provide a bit more context. "gen_supply_seg" is a three dimensional array that, depending on different points in time, has different constraints
def con2a():
for t in range(len(LOAD)):
for g in range(len(GEN)):
nlc2a = optimize.NonlinearConstraint(gen_supply_seg[t,g,1],lb=0,ub=P2Max[g])
return(nlc2a)
def con2b():
for t in range(len(LOAD)):
for g in range(len(GEN)):
nlc2b = optimize.NonlinearConstraint(gen_supply_seg[t,g,2],lb=0,ub=P3Max[g])
return (nlc2b)
def con2c():
for t in range(len(LOAD)):
for g in range(len(GEN)):
nlc2c = optimize.NonlinearConstraint(gen_supply_seg[t,g,3],lb=0,ub=P4Max[g])
return (nlc2c)
con2a = con2a()
con2b = con2b()
con2c = con2c()
These constraints are then added to a set like shown
cons = (con2a,
con2b,
con2c)

After shifting values in linked list. Changing values in the head alters 2 nodes at once

Description
So I decided to make a snake game in Python using PyGame. For fun I decided to represent the snake using a linked list. Originally I had thought that to move the snake I would have to shift every value toward the head node's new destination location and then subsequently update the head node with it's new destination. I quickly realized this method was overcomplicated and unnecessary. However, in my attempt to implement it by shifting all values in a linked list toward the head and subsequently updating the head with it's new value I ended up breaking my linked list.
Here is what happens after I run the code to shift values and update the head.
The head is the top row of the table.
Original printout of data in linked list
x
y
100
50
90
50
80
50
70
50
Data Printout after shifting values
x
y
100
50
100
50
90
50
80
50
This is what we want. Each row has shifted properly. All that needs to be done is to update the head. In this case the snake is going up and the interval is 10 so we would update y in the head by 10. When done this is what happens.
x
y
100
60
100
60
90
50
80
50
When updating the data in the head the next node is now also updated simultaneously. The same thing happens if I try to update the second node in the same manner after shifting the data. If I try to do this before I shift values everything works fine so there seems to be something that is happening when I shift values. I checked the memory addresses of each node and by print(node) and they were all different.
Also, if I update the data property of the 3rd or 4th node it works fine and others are left unchanged. So this is just characteristic of the first and second node after shifting.
Here is the code I wrote to shift the values in my list
def Move(self, direction):
if(direction == 'UP'):
oldvalue = self.linkedlist.head.data
tempnode = self.linkedlist.head
tempv = None
while(tempnode.nextnode is not None):
tempnode = tempnode.nextnode
tempv = tempnode.data
tempnode.data = oldvalue
oldvalue = tempv
self.linkedlist.printList()
self.linkedlist.head.data[1] += 10
If that is hard to understand I simply use 2 temporary variables to both store the data in the current node and the data in the previous node. Update the next node with the previous nodes data and then store the current nodes data again in tempv.
Just in case I will provide the code for my linked list implementation below.
from Node import Node
class LinkedList:
def __init__(self):
self.head = None
def printList(self):
printnode = self.head
while(printnode is not None):
print(f'{printnode.data}')
printnode = printnode.nextnode
print('')
class Node:
def __init__(self, data = None):
self.data = data
self.nextnode = None
Thank you for any help and I apologize if the solution is simple. I stared for hours and also tried to find a similar post to no avail.
Since you copy ("shift") the data from the head node to its successor node, they both have a reference to the same data. So any manipulation to that data will be visible in both nodes.
This does not happen with other nodes, because the source node -- from which the data is copied -- itself gets the value from its predecessor, so in that case there are no two nodes sharing the same data. But the head node did not get data from its predecessor, because ... it has no predecessor.
So you'll need to create a new data list from the data you read from the head node. This you can do by replacing:
oldvalue = self.linkedlist.head.data
with:
oldvalue = self.linkedlist.head.data[:]
Then it will work.
I am not completely sure if I understand what is going on. But I suspect there is something going wrong when copying the data. Please note that in Python, if you set a variable to another object (class), it is passed by reference and not by value.
For example:
class ExampleClass:
def __init__(self, value):
self.value = value
A = ExampleClass(5)
B = A
B.value = 3
print(A.value) # prints 3
Not only classes are passed by reference, but lists as well. It seems like you are passing/setting the data (which I think is a list?) of the previous node to the next node. You are not copying the contents of the data, but passing a reference to this data list. This might cause the behavior you are seeing. You could mitigate this by using copy() or by slicing a list. For example:
b = a.copy()
new_l = l[:]
Also, see the Python FAQ on copying an object.

Merging uneven Corresponding Elements from a method returning value in Dictionaries

How to sort the data that are stored in a global list after inserting them within a method; so that before they are stacked into another list in accordance to their inserted elements? Or is this a bad practice and complicate things in storing data inside of a global list instead of seperated ones within a method; and finally sorting them thereafter ?
Below is the example of the scenario
list= []
dictionary = {}
def MethodA(#returns title):
#searches for corresponding data using beautifulsoup
#adds data into dictionary
# list.append(dictionary)
# returns list
def MethodB(#returns description):
#searches for corresponding data using beautifulsoup
#adds data into dictionary
# list.append(dictionary)
# returns list
Example of Wanted output
MethodA():[title] #scraps(text.title) data from the web
MethodB():[description] #scraps(text.description) from the web
#print(list)
>>>list=[{title,description},{title.description},{title,description},{title.description}]
Actual output
MethodA():[title] #scraps(text.title) data from the web
MethodB():[description] #scraps(text.description) from the web
#print(list)
>>>list =[{title},{title},{description},{description}]
There are a few examples I've seen; such as using Numpy and sorting them in an Array;-
arraylist = np.array(list)
arraylist[:, 0]
#but i get a 'too many indices for array'-
#because I have too much data loading in; including that some of them
#do not have data and are replaced as `None`; so there's an imbalance of indexes.
Im trying to keep it as modulated as possible. I've tried using the norm of iteration;
but it's sort of complicated because I have to indent more loops in it;
I've tried Numpy and Enumerate, but I'm not able to understand how to go about with it. But because it's an unbalanced list; meaning that some value are returned as Nonegives me the return error that; all the input array dimensions except for the concatenation axis must match exactly
Example : ({'Toy Box','Has a toy inside'},{'Phone', None }, {'Crayons','Used for colouring'})
Update; code sample of methodA
def MethodA(tableName, rowName, selectedLink):
try:
for table_tag in selectedLink.find_all(tableName, {'class': rowName}):
topic_title = table_tag.find('a', href=True)
if topic_title:
def_dict1 = {
'Titles': topic_title.text.replace("\n", "")}
global_list.append(def_dict1 )
return def_dict1
except:
def_dict1 = None
Assuming you have something of the form:
x = [{'a'}, {'a1'}, {'b'}, {'b1'}, {'c'}, {None}]
you can do:
dictionary = {list(k)[0]: list(v)[0] for k, v in zip(x[::2], x[1::2])}
or
dictionary = {s.pop(): v.pop() for k, v in zip(x[::2], x[1::2])}
The second method will clear your sets in x

Doc2Vec.infer_vector keeps giving different result everytime on a particular trained model

I am trying to follow the official Doc2Vec Gensim tutorial mentioned here - https://github.com/RaRe-Technologies/gensim/blob/develop/docs/notebooks/doc2vec-lee.ipynb
I modified the code in line 10 to determine best matching document for the given query and everytime I run, I get a completely different resultset. My new code iin line 10 of the notebook is:
inferred_vector = model.infer_vector(['only', 'you', 'can', 'prevent', 'forest', 'fires'])
sims = model.docvecs.most_similar([inferred_vector], topn=len(model.docvecs))
rank = [docid for docid, sim in sims]
print(rank)
Everytime I run the piece of code, I get different set of documents that are matching with this query: "only you can prevent forest fires". The difference is stark and just does not seem to match.
Is Doc2Vec not a suitable match for querying and information extraction? Or are there bugs?
Look into the code, in infer_vector you are using parts of the algorithm that is non-deterministic. Initialization of word vector is deterministic - see the code of seeded_vector, but when we look further, i.e., random sampling of words, negative sampling (updating only sample of word vector per iteration) could cause non-deterministic output (thanks #gojomo).
def seeded_vector(self, seed_string):
"""Create one 'random' vector (but deterministic by seed_string)"""
# Note: built-in hash() may vary by Python version or even (in Py3.x) per launch
once = random.RandomState(self.hashfxn(seed_string) & 0xffffffff)
return (once.rand(self.vector_size) - 0.5) / self.vector_size
Set negative=0 to avoid randomization:
import numpy as np
from gensim.models.doc2vec import Doc2Vec, TaggedDocument
documents = [list('asdf'), list('asfasf')]
documents = [TaggedDocument(doc, [i]) for i, doc in enumerate(documents)]
model = Doc2Vec(documents, vector_size=20, window=5, min_count=1, negative=0, workers=6, epochs=10)
a = list('test sample')
b = list('testtesttest')
for s in (a, b):
v1 = model.infer_vector(s)
for i in range(100):
v2 = model.infer_vector(s)
assert np.all(v1 == v2), "Failed on %s" % (''.join(s))

Abaqus Python script -- Reading 'TENSOR_3D_FULL' data from *.odb file

What I want: strain values LE11, LE22, LE12 at nodal points
My script is:
#!/usr/local/bin/python
# coding: latin-1
# making the ODB commands available to the script
from odbAccess import*
import sys
import csv
odbPath = "my *.odb path"
odb = openOdb(path=odbPath)
assembly = odb.rootAssembly
# count the number of frames
NumofFrames = 0
for v in odb.steps["Step-1"].frames:
NumofFrames = NumofFrames + 1
# create a variable that refers to the reference (undeformed) frame
refFrame = odb.steps["Step-1"].frames[0]
# create a variable that refers to the node set ‘Region Of Interest (ROI)’
ROINodeSet = odb.rootAssembly.nodeSets["ROI"]
# create a variable that refers to the reference coordinate ‘REFCOORD’
refCoordinates = refFrame.fieldOutputs["COORD"]
# create a variable that refers to the coordinates of the node
# set in the test frame of the step
ROIrefCoords = refCoordinates.getSubset(region=ROINodeSet,position= NODAL)
# count the number of nodes
NumofNodes =0
for v in ROIrefCoords.values:
NumofNodes = NumofNodes +1
# looping over all the frames in the step
for i1 in range(NumofFrames):
# create a variable that refers to the current frame
currFrame = odb.steps["Step-1"].frames[i1+1]
# looping over all the frames in the step
for i1 in range(NumofFrames):
# create a variable that refers to the strain 'LE'
Str = currFrame.fieldOutputs["LE"]
ROIStr = Str.getSubset(region=ROINodeSet, position= NODAL)
# initialize list
list = [[]]
# loop over all the nodes in each frame
for i2 in range(NumofNodes):
strain = ROIStr.values [i2]
list.insert(i2,[str(strain.dataDouble[0])+";"+str(strain.dataDouble[1])+\
";"+str(strain.dataDouble[3]))
# write the list in a new *.csv file (code not included for brevity)
odb.close()
The error I get is:
strain = ROIStr.values [i2]
IndexError: Sequence index out of range
Additional info:
Details for ROIStr:
ROIStr.name
'LE'
ROIStr.type
TENSOR_3D_FULL
OIStr.description
'Logarithmic strain components'
ROIStr.componentLabels
('LE11', 'LE22', 'LE33', 'LE12', 'LE13', 'LE23')
ROIStr.getattribute
'getattribute of openOdb(r'path to .odb').steps['Step-1'].frames[1].fieldOutputs['LE'].getSubset(position=INTEGRATION_POINT, region=openOdb(r'path to.odb').rootAssembly.nodeSets['ROI'])'
When I use the same code for VECTOR objects, like 'U' for nodal displacement or 'COORD' for nodal coordinates, everything works without a problem.
The error happens in the first loop. So, it is not the case where it cycles several loops before the error happens.
Question: Does anyone know what is causing the error in the above code?
Here the reason you get an IndexError. Strains are (obviously) calculated at the integration points; according to the ABQ Scripting Reference Guide:
A SymbolicConstant specifying the position of the output in the element. Possible values are:
NODAL, specifying the values calculated at the nodes.
INTEGRATION_POINT, specifying the values calculated at the integration points.
ELEMENT_NODAL, specifying the values obtained by extrapolating results calculated at the integration points.
CENTROID, specifying the value at the centroid obtained by extrapolating results calculated at the integration points.
In order to use your code, therefore, you should get the results using position= ELEMENT_NODAL
ROIrefCoords = refCoordinates.getSubset(region=ROINodeSet,position= ELEMENT_NODAL)
With
ROIStr.values[0].data
You will then get an array containing the 6 independent components of your tensor.
Alternative Solution
For reading time series of results for a nodeset, you can use the function xyPlot.xyDataListFromField(). I noticed that this function is much faster than using odbread. The code also is shorter, the only drawback is that you have to get an abaqus license for using it (in contrast to odbread which works with abaqus python which only needs an installed version of abaqus and does not need to get a network license).
For your application, you should do something like:
from abaqus import *
from abaqusConstants import *
from abaqusExceptions import *
import visualization
import xyPlot
import displayGroupOdbToolset as dgo
results = session.openOdb(your_file + '.odb')
# without this, you won't be able to extract the results
session.viewports['Viewport: 1'].setValues(displayedObject=results)
xyList = xyPlot.xyDataListFromField(odb=results, outputPosition=NODAL, variable=((
'LE', INTEGRATION_POINT, ((COMPONENT, 'LE11'), (COMPONENT, 'LE22'), (
COMPONENT, 'LE33'), (COMPONENT, 'LE12'), )), ), nodeSets=(
'ROI', ))
(Of course you have to add LE13 etc.)
You will get a list of xyData
type(xyList[0])
<type 'xyData'>
Containing the desired data for each node and each output. It size will therefore be
len(xyList)
number_of_nodes*number_of_requested_outputs
Where the first number_of_nodes elements of the list are the LE11 at each nodes, then LE22 and so on.
You can then transform this in a NumPy array:
LE11_1 = np.array(xyList[0])
would be LE11 at the first node, with dimensions:
LE.shape
(NumberTimeFrames, 2)
That is, for each time step you have time and output variable.
NumPy arrays are also very easy to write on text files (check out numpy.savetxt).

Resources