Passing a function to an Object at Instantiation in C# - python

I am currently working on a project where I am trying to make an GUI for programming an I2C device. I have a bunch of register addresses and values in those registers both in hex strings like so:
[Address, Value][0x00, 0x01][0x01, 0xFF][0x02, 0xA0]... //not code, just abstract representation
Each register value represents something different. I have to convert each register value from a hex string to its associated human-understandable representation. My plan for this is to create a dictionary whose keys are the register addresses and whose values are a register object. The register object would contain information about the register like a description and a conversion function which takes in the hex string and outputs a converted value. The conversion function is different for every register since they represent different things. I want to create a generic register class and pass in each register's unique conversion function at instantiation. Passing this function is where I'm not sure if I'm making things more complicated than they need to be.
My code currently looks like this:
private class my_register
{
private string Description;
{get;}
//using delegate to be able to store function specified outside of class
public delegate string convert_del(string reg_val);
public convert_del conversion_func;
//constructor uses a delegate to store the function passed at instantiation
my_register(string desc, func<string, string> convert_func_input)
this.Description = desc;
this.conversion_func = new convert_del(convert_func_input)
}
//Now I can create the object and pass in the function
static void Main()
{
// lambda function is just a simple place holder to show that I can pass a function
my_register first_reg = new my_register("Temp", reg_val => (Convert.ToInt32(reg_val, 16)
+ 10).ToString())
Console.WriteLine(first_reg.conversion_func("0x0A")) //output is 20
}
This code works at least for the minimal testing I ran. This took me a long time to figure out, perhaps because I just didn't understand delegates well, but I am wondering if this is a convoluted way of going about this in C#. I come from a python background, though I'm not particularly skilled in that either. The way I would do this in python is as follows:
class my_register(object):
def __init__(self, desc, conversion):
self.Description = desc
self.conversion = conversion
def temp_convert(reg_val):
return str(int(reg_val, 0) + 10)
first_reg = my_register("Temp", temp_convert)
first_reg.conversion(10) #returns '20'
The pythonic way just seems way simpler, so I'm wondering if there a better more canonical way of achieving this function passing in C# or if there is a way to avoid passing the function all together?

Related

How to dynamically return Object attributes in python, including attributes of objects that are attributes

I am trying to write a testing program for a python program that takes data, does calculations on it, then puts the output in a class instance object. This object contains several other objects, each with their own attributes. I'm trying to access all the attributes and sub-attributes dynamically with a one size fits all solution, corresponding to elements in a dictionary I wrote to cycle through and get all those attributes for printing onto a test output file.
Edit: this may not be clear from the above but I have a list of the attributes I want, so using something to actually get those attributes is not a problem, although I'm aware python has methods that accomplish this. What I need to do is to be able to get all of those attributes with the same function call, regardless of whether they are top level object attributes or attributes of object attributes.
Python is having some trouble with this - first I tried doing something like this:
for string in attr_dictionary:
...
outputFile.print(outputclass.string)
...
But Python did not like this, and returned an AttributeError
After checking SE, I learned that this is a supposed solution:
for string in attr_dictionary:
...
outputFile.print(getattr(outputclass, string))
...
The only problem is - I want to dynamically access the attributes of objects that are attributes of outputclass. So ideally it would be something like outputclass.objectAttribute.attribute, but this does not work in python. When I use getattr(outputclass, objectAttribute.string), python returns an AttributeError
Any good solution here?
One thing I have thought of trying is creating methods to return those sub-attributes, something like:
class outputObject:
...
def attributeIWant(self,...):
return self.subObject.attributeIWant
...
Even then, it seems like getattr() will return an error because attributeIWant() is supposed to be a function call, it's not actually an attribute. I'm not certain that this is even within the capabilities of Python to make this happen.
Thank you in advance for reading and/or responding, if anyone is familiar with a way to do this it would save me a bunch of refactoring or additional code.
edit: Additional Clarification
The class for example is outputData, and inside that class you could have and instance of the class furtherData, which has the attribute dataIWant:
class outputData:
example: furtherData
example = furtherData()
example.dataIWant = someData
...
with the python getattr I can't access both attributes directly in outputData and attributes of example unless I use separate calls, the attribute of example needs two calls to getattr.
Edit2: I have found a solution I think works for this, see below
I was able to figure this out - I just wrote a quick function that splits the attribute string (for example outputObj.subObj.propertyIWant) then proceeds down the resultant array, calling getattr on each subobject until it reaches the end of the array and returns the actual attribute.
Code:
def obtainAttribute(sample, attributeString: str):
baseObj = sample
attrArray = attributeString.split(".")
for string in attrArray:
if(attrArray.index(string) == (len(attrArray) - 1)):
return getattr(baseObj,string)
else:
baseObj = getattr(baseObj,string)
return "failed"
sample is the object and attributeString is, for example object.subObject.attributeYouWant

How to write docstring in python to specify that a parameter can assume only a set of values

Good morning everybody,
I need to know if there is a way, at the moment I say no, for having the behavior I write in JavaScript also in Python.
If in JavaScript, when I have a function with a parameter that can assume only some values, I write the following code
/**
* Set the status of session
* #param {('ACTIVE'|'LOCKED'|'UNAUTHORIZED')} status
*/
function set(status = 'UNAUTHORIZED') {
console.log(status);
}
Writing in this way, calling the function makes my IDE (PHPStorm) to suggest me the list of values I can use as shown in the following image
This is my function in Python
def set(status: str) -> None:
"""
Set the status of session
:param status: ('ACTIVE','LOCKED','UNAUTHORIZED')
:return:
:rtype: None
"""
print(status)
but I can't get the same result with IDE (PYCharm) probably because the syntax of docstring is wrong.
Is there a way to get in Python the same result I have in JavaScript?
For example, if I wrote the same function, how can I define the list of values that the parameter can assume?
Thanks to all of you

Large table access from c++ functions with boost::python

I'm generating a very large lookup table in C++ and using it from a variety of C++ functions. These functions are exposed to python using boost::python.
When not used as part of a class the desired behaviour is achieved. When I try and use the functions as part of a class written in just python I run in to issues accessing the lookup table.
------------------------------------
C++ for some numerical heavy lifting
------------------------------------
include <boost/python>
short really_big_array[133784630]
void fill_the_array(){
//Do some things which populate the array
}
int use_the_array(std::string thing){
//Lookup a few million things in the array depending on thing
//Return some int dependent on the values found
}
BOOST_PYTHON_MODULE(bigarray){
def("use_the_array", use_the_array)
def("fill_the_array", fill_the_array)
}
---------
PYTHON Working as desired
---------
import bigarray
if __name__ == "__main__"
bigarray.fill_the_array()
bigarray.use_the_array("Some Way")
bigarray.use_the_array("Some Other way")
#All works fine
---------
PYTHON Not working as desired
---------
import bigarray
class BigArrayThingDoer():
"""Class to do stuff which uses the big array,
use_the_array() in a few different ways
"""
def __init__(self,other_stuff):
bigarray.fill_the_array()
self.other_stuff = other_stuff
def use_one_way(thing):
return bigarray.use_the_array(thing)
if __name__ == "__main__"
big_array_thing_doer = BigArrayThingDoer()
big_array_thing_doer.use_one_way(thing)
#Segfaults or random data
I think I am probably not exposing enough to python to make sure the array is accessible at the right times, but im not quite sure exactly what I shoudld be exposing. Equally likely that there is some sort of problem involving ownership of the lookup table.
I dont ever need to manipulate the lookup table except via the other c++ functions.
Missing a self in a definition. Used key word arguments where I should probably have used keyword only arguments so got no error when running.

designing my ticket api

I have a function named getTicket which take two argument id which is a number and format (string)
def getTicket(id, format):
if format == "pdf":
getTicketPDF(id) #some specialized pdf method gets called
elif format == "json":
getTicketJSON(id) #specialized json method
Now if I have to support some new format like "html" then I can create another elif for html.
But I want to generalize this code so that if in future n new method gets added I do not have to change my code
How can I design my getTicket api?
You can create a dictionary that stores the format to function mapping , like "pdf" mapping to function getTicketPDF , etc. And then in your getTicket() function you call the dictionary's value for format and call it by passing id parameter to it. Example -
funcdict = {"pdf":getTicketPDF
"json":getTicketJSON}
def getTicket(id, format):
try:
funcdict[format](id)
except KeyError:
#Handle case where format is not found in dictionary
If later you decide to add a new function for a new format, you just need to add a new mapping to the dictionary.
Your use case calls for a Strategy Pattern Implementation(PDF/JSON/HTML ticket generation strategies) which uses a Factory Pattern to obtain the correct strategy implementation class.
Here are the high-level steps -
Separate the functionality of ticket generation into a class TicketGenerator. Let this be an interface. It will have a single abstract method generateTicket()
Use a TicketGeneratorFactory to get the correct TicketGenerator instance based on the type of ticket i.e. an instance of PDFTicketGenerator, JSONTicketGenerator, HTMLTicketGenerator and so on... Each of these implemention classes have a generateTicket() implementation as per the type i.e. PDF/JSON/HTML.
This instance should be assigned to the base TicketGenerator Type.
TicketGenerator.generateTicket() would then give you the ticket in the desired format - PDF/JSON/HTML.

A more pythonic way to build a class based on a string (how not to use eval)

OK.
So I've got a database where I want to store references to other Python objects (right now I'm using to store inventory information for person stores of beer recipe ingredients).
Since there are about 15-20 different categories of ingredients (all represented by individual SQLObjects) I don't want to do a bunch of RelatedJoin columns since, well, I'm lazy, and it seems like it's not the "best" or "pythonic" solution as it is.
So right now I'm doing this:
class Inventory(SQLObject):
inventory_item_id = IntCol(default=0)
amount = DecimalCol(size=6, precision=2, default=0)
amount_units = IntCol(default=Measure.GM)
purchased_on = DateCol(default=datetime.now())
purchased_from = UnicodeCol(default=None, length=256)
price = CurrencyCol(default=0)
notes = UnicodeCol(default=None)
inventory_type = UnicodeCol(default=None)
def _get_name(self):
return eval(self.inventory_type).get(self.inventory_item_id).name
def _set_inventory_item_id(self, value):
self.inventory_type = value.__class__.__name__
self._SO_set_inventory_item_id(value.id)
Please note the ICKY eval() in the _get_name() method.
How would I go about calling the SQLObject class referenced by the string I'm getting from __class__.__name__ without using eval()? Or is this an appropriate place to utilize eval()? (I'm sort of of the mindset where it's never appropriate to use eval() -- however since the system never uses any end user input in the eval() it seems "safe".)
To get the value of a global by name; Use:
globals()[self.inventory_type]

Categories

Resources