@@ -142,7 +142,9 @@ def __delattr__(self, name):
142
142
if name in self ._sets :
143
143
del self ._sets [name ]
144
144
else :
145
- raise FuzzyWarning ("Trying to delete a regular attr, this needs extra care." )
145
+ raise FuzzyWarning (
146
+ "Trying to delete a regular attr, this needs extra care."
147
+ )
146
148
147
149
@property
148
150
def range (self ):
@@ -156,7 +158,9 @@ def range(self):
156
158
if int (self ._res ) == self ._res :
157
159
return np .arange (self ._low , self ._high + self ._res , int (self ._res ))
158
160
else :
159
- return np .linspace (self ._low , self ._high , int ((self ._high - self ._low ) / self ._res ) + 1 )
161
+ return np .linspace (
162
+ self ._low , self ._high , int ((self ._high - self ._low ) / self ._res ) + 1
163
+ )
160
164
161
165
def min (self , x ):
162
166
"""Standard way to get the min over all membership funcs.
@@ -387,25 +391,12 @@ def center_of_gravity(self) -> np.floating | float:
387
391
def __repr__ (self ) -> str :
388
392
"""
389
393
Return a string representation of the Set that reconstructs the set with eval().
394
+ """
390
395
391
- *******
392
- Current implementation does NOT work correctly.
393
-
394
- This is harder than expected since all functions are (recursive!) closures which
395
- can't simply be pickled. If this functionality really is needed, all functions
396
- would have to be peppered with closure-returning overhead such as
397
-
398
- def create_closure_and_function(*args):
399
- func = None
400
- def create_function_closure():
401
- return func
402
-
403
- closure = create_function_closure.__closure__
404
- func = types.FunctionType(*args[:-1] + [closure])
405
- return func
396
+ # experimental
397
+ # x = f"{self.func.__qualname__.split('.')[0]}({self.func.__closure__[0].cell_contents.__code__.co_nlocals}))"
398
+ # print(x)
406
399
407
- probably best realized by AST-analysis and code generation...
408
- """
409
400
if self .domain is not None :
410
401
return f"{ self .domain ._name } .{ self .name } "
411
402
return f"Set({ __name__ } ({ self .func .__qualname__ } )"
@@ -459,12 +450,18 @@ def __eq__(self, other: T):
459
450
def __getitem__ (self , key ):
460
451
return self .conditions [frozenset (key )]
461
452
462
- def __call__ (self , values : dict [Domain , float | int ], method = "cog" ) -> np .floating | float | None :
453
+ def __call__ (
454
+ self , values : dict [Domain , float | int ], method = "cog"
455
+ ) -> np .floating | float | None :
463
456
"""Calculate the infered value based on different methods.
464
457
Default is center of gravity (cog).
465
458
"""
466
- assert isinstance (values , dict ), "Please make sure to pass a dict[Domain, float|int] as values."
467
- assert len (self .conditions ) > 0 , "No point in having a rule with no conditions, is there?"
459
+ assert isinstance (values , dict ), (
460
+ "Please make sure to pass a dict[Domain, float|int] as values."
461
+ )
462
+ assert len (self .conditions ) > 0 , (
463
+ "No point in having a rule with no conditions, is there?"
464
+ )
468
465
match method :
469
466
case "cog" :
470
467
# iterate over the conditions and calculate the actual values and weights contributing to cog
@@ -473,7 +470,9 @@ def __call__(self, values: dict[Domain, float | int], method="cog") -> np.floati
473
470
assert target_domain is not None , "Target domain must be defined."
474
471
for if_sets , then_set in self .conditions .items ():
475
472
actual_values : list [Number ] = []
476
- assert then_set .domain == target_domain , "All target sets must be in the same Domain."
473
+ assert then_set .domain == target_domain , (
474
+ "All target sets must be in the same Domain."
475
+ )
477
476
for s in if_sets :
478
477
assert s .domain is not None , "Domains must be defined."
479
478
actual_values .append (s (values [s .domain ]))
@@ -488,13 +487,17 @@ def __call__(self, values: dict[Domain, float | int], method="cog") -> np.floati
488
487
sum_weighted_cogs += then_set .center_of_gravity () * weight
489
488
sum_weights += weight
490
489
index = sum_weighted_cogs / sum_weights
491
-
492
- return (target_domain ._high - target_domain ._low ) / len (
490
+ res = (target_domain ._high - target_domain ._low ) / len (
493
491
target_domain .range
494
492
) * index + target_domain ._low
495
-
496
- case "centroid" : # centroid == center of mass == center of gravity for simple solids
497
- raise NotImplementedError ("actually the same as 'cog' if densities are uniform." )
493
+ return res
494
+
495
+ case (
496
+ "centroid"
497
+ ): # centroid == center of mass == center of gravity for simple solids
498
+ raise NotImplementedError (
499
+ "actually the same as 'cog' if densities are uniform."
500
+ )
498
501
case "bisector" :
499
502
raise NotImplementedError ("Bisector method not implemented yet." )
500
503
case "mom" :
0 commit comments