1414 'nested_attr' , 'nested_setdefault' , 'nested_callable' , 'nested_idx' , 'set_nested_idx' , 'val2idx' ,
1515 'uniqueify' , 'loop_first_last' , 'loop_first' , 'loop_last' , 'first_match' , 'last_match' , 'fastuple' , 'bind' ,
1616 'mapt' , 'map_ex' , 'compose' , 'maps' , 'partialler' , 'instantiate' , 'using_attr' , 'copy_func' , 'patch_to' ,
17- 'patch' , 'patch_property' , 'compile_re' , 'ImportEnum' , 'StrEnum' , 'str_enum' , 'Stateful' , 'PrettyString ' ,
18- 'even_mults' , 'num_cpus' , 'add_props' , 'typed' , 'exec_new' , 'exec_import' , 'str2bool' , 'lt' , 'gt' , 'le ' ,
19- 'ge' , 'eq' , 'ne' , 'add' , 'sub' , 'mul' , 'truediv' , 'is_' , 'is_not' ]
17+ 'patch' , 'patch_property' , 'compile_re' , 'ImportEnum' , 'StrEnum' , 'str_enum' , 'Stateful' , 'NotStr ' ,
18+ 'PrettyString' , ' even_mults' , 'num_cpus' , 'add_props' , 'typed' , 'exec_new' , 'exec_import' , 'str2bool' , 'lt' ,
19+ 'gt' , 'le' , ' ge' , 'eq' , 'ne' , 'add' , 'sub' , 'mul' , 'truediv' , 'is_' , 'is_not' ]
2020
2121# %% ../nbs/01_basics.ipynb 1
2222from .imports import *
@@ -1034,36 +1034,53 @@ def _init_state(self):
10341034 self ._state = {}
10351035
10361036# %% ../nbs/01_basics.ipynb 418
1037+ class NotStr (GetAttr ):
1038+ "Behaves like a `str`, but isn't an instance of one"
1039+ _default = 's'
1040+ def __init__ (self , s ): self .s = s
1041+ def __repr__ (self ): return repr (self .s )
1042+ def __str__ (self ): return self .s
1043+ def __add__ (self , b ): return NotStr (self .s + str (b ))
1044+ def __mul__ (self , b ): return NotStr (self .s * b )
1045+ def __len__ (self ): return len (self .s )
1046+ def __eq__ (self , b ): return self .s == b .s if isinstance (b , NotStr ) else b
1047+ def __lt__ (self , b ): return self .s < b
1048+ def __hash__ (self ): return hash (self .s )
1049+ def __bool__ (self ): return bool (self .s )
1050+ def __contains__ (self , b ): return b in self .s
1051+ def __iter__ (self ): return iter (self .s )
1052+
1053+ # %% ../nbs/01_basics.ipynb 420
10371054class PrettyString (str ):
10381055 "Little hack to get strings to show properly in Jupyter."
10391056 def __repr__ (self ): return self
10401057
1041- # %% ../nbs/01_basics.ipynb 424
1058+ # %% ../nbs/01_basics.ipynb 426
10421059def even_mults (start , stop , n ):
10431060 "Build log-stepped array from `start` to `stop` in `n` steps."
10441061 if n == 1 : return stop
10451062 mult = stop / start
10461063 step = mult ** (1 / (n - 1 ))
10471064 return [start * (step ** i ) for i in range (n )]
10481065
1049- # %% ../nbs/01_basics.ipynb 426
1066+ # %% ../nbs/01_basics.ipynb 428
10501067def num_cpus ():
10511068 "Get number of cpus"
10521069 try : return len (os .sched_getaffinity (0 ))
10531070 except AttributeError : return os .cpu_count ()
10541071
10551072defaults .cpus = num_cpus ()
10561073
1057- # %% ../nbs/01_basics.ipynb 428
1074+ # %% ../nbs/01_basics.ipynb 430
10581075def add_props (f , g = None , n = 2 ):
10591076 "Create properties passing each of `range(n)` to f"
10601077 if g is None : return (property (partial (f ,i )) for i in range (n ))
10611078 return (property (partial (f ,i ), partial (g ,i )) for i in range (n ))
10621079
1063- # %% ../nbs/01_basics.ipynb 431
1080+ # %% ../nbs/01_basics.ipynb 433
10641081def _typeerr (arg , val , typ ): return TypeError (f"{ arg } =={ val } not { typ } " )
10651082
1066- # %% ../nbs/01_basics.ipynb 432
1083+ # %% ../nbs/01_basics.ipynb 434
10671084def typed (f ):
10681085 "Decorator to check param and return types at runtime"
10691086 names = f .__code__ .co_varnames
@@ -1080,21 +1097,21 @@ def _f(*args,**kwargs):
10801097 return res
10811098 return functools .update_wrapper (_f , f )
10821099
1083- # %% ../nbs/01_basics.ipynb 440
1100+ # %% ../nbs/01_basics.ipynb 442
10841101def exec_new (code ):
10851102 "Execute `code` in a new environment and return it"
10861103 pkg = None if __name__ == '__main__' else Path ().cwd ().name
10871104 g = {'__name__' : __name__ , '__package__' : pkg }
10881105 exec (code , g )
10891106 return g
10901107
1091- # %% ../nbs/01_basics.ipynb 442
1108+ # %% ../nbs/01_basics.ipynb 444
10921109def exec_import (mod , sym ):
10931110 "Import `sym` from `mod` in a new environment"
10941111# pref = '' if __name__=='__main__' or mod[0]=='.' else '.'
10951112 return exec_new (f'from { mod } import { sym } ' )
10961113
1097- # %% ../nbs/01_basics.ipynb 443
1114+ # %% ../nbs/01_basics.ipynb 445
10981115def str2bool (s ):
10991116 "Case-insensitive convert string `s` too a bool (`y`,`yes`,`t`,`true`,`on`,`1`->`True`)"
11001117 if not isinstance (s ,str ): return bool (s )
0 commit comments