Comments by "Dr Gamma D" (@DrDeuteron) on "Tech With Tim"
channel.
-
13
-
10
-
7
-
7
-
for me, when I'm reading 545 data fields of space craft telemetry, which is a helluva dunder init. Instead I just cut and paste the attributes from an excel file into a data class and it calls for a single mouse click. Moreover, dataclass comes with "fields", which can be used to describe the fields, the LaTex formulas for them. expected ranges, alarm ranges, broke ranges, and there is an astuple functions, which can be stuck in dunder iter, possible zip with the fields, and in about 3 lines of executable code, you can flag out-of-range telemetry. Very little dynamic code, and lots of static could is much simpler and less bug prone.
3
-
3
-
3
-
3
-
2
-
2
-
2
-
2
-
2
-
2
-
2
-
2
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
@nirajraut9408 so it calls new and returns a class, otherwise it calls object.__new__() and then tries to instantiate with __init__. His example is bit too simple, in that it just wraps type to show functionality (which needs to be done), but in a real life use case, you may want to choose a class based on the inputs...and only type can do that.
For instance, I have spacecraft telemetry in classes: Current, Voltage, Temperature, and I can tell which one I want by the filename. So I'll do something like:
class Telemetry(type):
klasses = dict(current=Current, voltage=Voltage, temperature=Temperature)
def __new__(cls, name):
return cls.klasses[name].fromfile(name)
Here fromfile are a class method (constructor helpers) that reads the file (in a context manager), and instantiates the object with values.
So in use, I just say:
>>>telemetry = Telemetry(filename)
and get the data unpacked according to protocol w/o having to worry about picking the right object to put it in.
Then I just just say:
>>>telemetry.plot()
and a house keeping plot is generated, without the code explicitly worrying about what kind of telemetry I need to look at.
Note that the whole thing is accomplished with ZERO if/then clauses, reducing cyclomatic complexity.
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
Here's how it goes, for a module:
"""docstring"""
import [python standard library]
import [public 3rd party libs]
import [private 3rd party (your other packages)
from package import module (local package imports)
from . import stuff (relative imports)
CONSTANTS = "module constants"
def func():
"""module functions: pure function with no state and no side effects"""
class Noun
"""classes in the module. Classes are Nouns, they respect things"""
class_attrs = "class attribute 1st""
@classmethod
def from_other_information(cls, ....)
"""constructor helpers, iff WORK needs to be done to convert args to instance attributes""
return cls(..., attr)
def __init__(self, ..., attr):
"""though shalt not do work in init!"""
super().__init__(...) # call super 1st, if needed
self.attr = attr # just set attrs in init, Do. Not. Do. Work.
@property
def derived_attr(self):...
"""now include properties, if needed"""
def __magic_methods__(self...)
"""1st define unary, then binary, ternary magic methods"""
def _protected_method(self....):
"""...from lowest level on up. Alway push work up the method chain as far as possible"""
def public_method(self...):
"""here and only here will you change the state of self, or further up in a protected method""""
def the_single_responsibilty_method(self..):
"""since your class has a single responsibility, only one reason to change, the raison detre will be
in the last method that calls all other methods"""
unit_test() # if you do that.
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
I use meta classes not only to make classes, but also to choose classes. Say I have a Euclid class to do vectors in R3, and a Gibbs class to do vectors in C3. I don’t want the user to decide which class to call, I want a meta class to decide based on the components being real or complex:
class Vector(type):
klasses = {True: Gibbs, False: Euclid}
def __new__(cls, x, y, z):
return cls.klasses[any([isinstance(item, complex) for item in (x, y, z)])](x, y, z)
I mean I could do that in a function, but that hides the internals. The point is, the user just defines Vectors and does operations on them without worrying about how to define an inner product properly. I may also do this if I have vectors in different numbers of dimensions, with a look-up table based on the number of parameters passes to dunder new.
1
-
1
-
1
-
1
-
that's because you have a length 1 array of generators, not of the generator''s In
[17]: x1 = array(i**2 for i in range(10))
In [18]: x1
Out[18]: array(<generator object <genexpr> at 0x7f95cd5c4be0>, dtype=object)
In [19]: x2 = array([i**2 for i in range(10)])
In [20]: x2
Out[20]: array([ 0, 1, 4, 9, 16, 25, 36, 49, 64, 81])
1
-
1