Object instance evocation by provided variable - python-3.4

imagine there is a set of objects, like:
class oven():
pass
class delta_t_pause():
pass
class caliberBox():
pass
class caliberRectl():
pass
class caliberRound():
pass
and so on. There is a class Button(QtWidgets.QPushButton) which receives two variables when evoked by mouse click. On variable carries an id the other data to be stored in the object.
What I want to do is, create an instance of the object matching the id. Assigning the data to it might be done by obj = Object(data), which is no big deal.
Does anyone has some useful ideas how to achieve that? I'm kinda stuck here.
class Button(QtWidgets.QPushButton):
def __init__(self, senderid, items, parent):
super().__init__(senderid, items, parent)
print(senderid)
self.obj = items
def mousePressEvent(self,event):
QtWidgets.QPushButton.mousePressEvent(self, event)
if event.button() == QtCore.Qt.LeftButton:
print(event.button(),' pressed')
is what I have so far...
Something like
if senderid is in list:
obj = Object(data)
but how do I select the right Object
All programming is done in Python-3.4 and PyQt5.5.
cheers,
Christian

You could keep a dictionary that maps ids to classes. Then you can use the dict to create your object.
objects = {4: oven, 8: delta_t_pause, 15: caliberBox}
if senderid in objects:
obj = objects[senderid](data)

Related

Memory corruption for custom class on uWSGI

During development of a new app based on Django, I noticed a memory corruption. I got two functions which use this class:
class ConfigMap():
data = list()
def add(self, entry: CusDeployPhone):
for row in self.data:
if row.phone_var.varid == entry.phone_var.varid:
return self
self.data.append(entry)
return self
def get(self):
return self.data
Function #1
def gen_config_model(request, deploy_phone):
deploy_phone_general = CusDeployPhone.objects.filter(phone_model=7)
config_list_model = ConfigMap()
for entry in deploy_phone:
config_list_model.add(entry)
for entry in deploy_phone_general:
config_list_model.add(entry)
Function #2
def gen_config_endpoint(request):
config_list_endpoint = ConfigMap()
for entry in deploy_model:
config_list_endpoint.add(entry)
for entry in deploy_phone_general:
config_list_endpoint.add(entry)
Both functions return the data in the list. I noticed that when calling the endpoint view, I also see the data when loading the model-one!
Somehow the class gets corrupted or merged with the existing one. Why?
The variable is local to the function.
I know there are issues with lists (references / pointers) but why in this case?
Issue solved:
Python Stack Corruption?
The children variable was declared as a class-level variable so it is
shared amongst all instances of your Nodes. You need to declare it an
instance variable by setting it in the initializer.
Change declaration to initializer.
def __init__(self):
self.children = []
...

Duplicate items in Set

In Kotlin, I have a MutableSet of a data class. The data class does not override equals() or hashCode(). I've been encountering bugs involving duplicate objects in the set, and I noticed that calling foo.containsAll(foo) returns false for the set.
I went through each item in the set and only a handful return false for foo.contains(foo.toList()[i]). For those that do, calling foo.toList()[i] == foo.toList()[i] returns true. So, equality checking works.
What is going on here?
I believe the only way this is possible (short of reflection, etc.) is if your data class contains something mutable and an instance changing state after being added to the set, etc. e.g.
data class Foo(var int: Int = 0)
data class Bar(val string: String, val foo: Foo = Foo())
val bars = mutableSetOf<Bar>()
bars += Bar("")
bars += Bar("")
println(bars.containsAll(bars)) // true
bars.first().foo.int = 12
println(bars.containsAll(bars)) // false
This is because the result of hashCode() is being used in the set to identify it but if the state changes in an instance of your data class then it will likely have a different hash value causing issues like this.
In general elements in sets and keys in maps should be immutable to avoid this issue.

How can I set up a Class containing itself in R (for a tree)?

I need a class that may or may not contain itself, for usage as a tree in R.
Every Node has Side, Analytical_Matrix, MaxChi2 and P and Sons are of type Node too.
The first time a Node is created, I need the Sons to be empty or NULL. But later I create them and asign them as Sons (I have a limit of max 3 sons).
I have tried this for setting up the Class:
setClass(Class = "Node",slots=c(Side="character",Analytical_matrix="data.frame",MaxChi2="data.frame",P="numeric",TerminalNode="logical",LSon="Node",CSon="Node",RSon="Node"),prototype = prototype(LSon=NULL,CSon=NULL,RSon=NULL))
And this for declaring one instance of the new class. I get an error. I need the sons to be empty first because is an infinite loop looking always for Sons of Sons of Sons.
Res=new(Class = "Node",Side=c("A","B"),Analytical_Matrix=data.frame(A=c(1,2)),MaxChi2=data.frame(A=c(3)),P=0.3),NodoTerminal=FALSE)
It is possible to have a class contain itself as one of its slots, via a "class union". Here is a simple example of a class with an id integer slot and a parent slot that we want to be the same class:
setClass("myObject",representation(
parent="myObject_or_NULL",
id="integer"
),prototype=prototype(
parent=NULL
)) -> myObject
setClassUnion("myObject_or_NULL",c("myObject","NULL"))
The above will generate a warning that "myObject_or_NULL" isn't defined, but it's only a warning and not an error.
Now, if we try to make a new one:
myObject()
An object of class "myObject"
Slot "parent":
NULL
Slot "id":
integer(0)
We don't have a recursive loop any more because the default is NULL. After it's instantiated, you can set the slot to whatever you like, of course.

Can I insert into a map by key in F#?

I'm messing around a bit with F# and I'm not quite sure if I'm doing this correctly. In C# this could be done with an IDictionary or something similar.
type School() =
member val Roster = Map.empty with get, set
member this.add(grade: int, studentName: string) =
match this.Roster.ContainsKey(grade) with
| true -> // Can I do something like this.Roster.[grade].Insert([studentName])?
| false -> this.Roster <- this.Roster.Add(grade, [studentName])
Is there a way to insert into the map if it contains a specified key or am I just using the wrong collection in this case?
The F# Map type is a mapping from keys to values just like ordinary .NET Dictionary, except that it is immutable.
If I understand your aim correctly, you're trying to keep a list of students for each grade. The type in that case is a map from integers to lists of names, i.e. Map<int, string list>.
The Add operation on the map actually either adds or replaces an element, so I think that's the operation you want in the false case. In the true case, you need to get the current list, append the new student and then replace the existing record. One way to do this is to write something like:
type School() =
member val Roster = Map.empty with get, set
member this.Add(grade: int, studentName: string) =
// Try to get the current list of students for a given 'grade'
let studentsOpt = this.Roster.TryFind(grade)
// If the result was 'None', then use empty list as the default
let students = defaultArg studentsOpt []
// Create a new list with the new student at the front
let newStudents = studentName::students
// Create & save map with new/replaced mapping for 'grade'
this.Roster <- this.Roster.Add(grade, newStudents)
This is not thread-safe (because calling Add concurrently might not update the map properly). However, you can access school.Roster at any time, iterate over it (or share references to it) safely, because it is an immutable structure. However, if you do not care about that, then using standard Dictionary would be perfectly fine too - depends on your actual use case.

QSortFilterProxyModel and filter by integers, booleans

I have a QSortFilterProxyModel which is connected to a QSqlQueryModel. In the underlying query there are boolean and integer fields. I would like to filter by these boolean, integers, etc. values. Surprisingly enough (or maybe I'm wrong) QSortFilterProxyModel only filters by strings. This is for instance a "problem" if you want to filter IDs (which are normally integers). If you try for instance to filter an ID=22, you get all the IDs with "22" inside (122, 222, 322, etc.). See this link for a non very elegant solution.
But how would you filter by boolean fields? Can someone give some hint? I suppose I have to subclass QSortFilterProxyModel, or is there another method?
A bit late, but it could be useful to others (and maybe some true expert might add precision/corrections) !
A QSortFilterProxyModel instance uses the method
bool QSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex & source_parent)
to determine if the given row should be kept or not.
By default it will simply test that the string returned by
myProxyModel.data(source_row, QtCore.Qt.DisplayRole)
matches the regular expression you might have set earlier using
myProxyModel.setFilterRegExp(myRegex)
Since you are subclassing this QSortFilterProxyModel you can easily define a new way to filter your items.
Add a method to set the ID you want to check
myProxyModel.setFilterID(myRefId)
then override the filterAcceptsRow to do the test against the ID instead of the regular expression !
You could also want to keep both method (or more) available. To do so, in your filterAcceptsRow method read the data from
myProxyModel.data(source_row, QtCore.Qt.UserRole)
instead of DisplayRole. When setting the UserRole you can store any data, not just string.
Here is an exemple (in python, it's shorter to write, but it works the same in any language) where we store a custom proxy object into the model:
from PyQt4 import QtGui
from PyQt4 import QtCore
class MyDummyObj(object):
def __init__(self, objLabel, objID, hidden=False)
self.__label = objLabel
self.__id = objLabel
self.__hidden = hidden
def getLabel(self):
return self.__label
def getID(self):
return self.__id
def isSecret(self):
return self.__hidden
class MyProxyModel(QtGui.QSortFilterProxyModel):
def __init__(self):
super(MyProxyModel, self).__init__()
self.__testID = None
self.__showHidden = False
def setFilterID(self, filterID):
self.__testID = filterID
def showHiddenRows(self, showHidden=False)
self.__showHidden = showHidden
def filterAcceptsRow(self, sourceRow, sourceParent):
model = self.sourceModel()
myObject = model.data(model.index(sourceRow, 0, sourceParent),
QtCore.Qt.UserRole).toPyObject()
if not self.__showHidden:
if myObject.isSecret():
return False
if self.__testID is not None:
return self.__testID == myObject.getID()
return self.getFilterRegExp().exactMatch(myObject.getLabel())
You can quite explicitly filter boolean roles with setFilterFixedString: filterModel->setFilterFixedString("false")
or filterModel->setFilterFixedString("true") as needed.
a simple solution is to use regexp with start and end anchor :
proxyModel->setFilterRegExp(QString("^%1$").arg(id));

Resources