22 transobj: transform.Transform,
24 result_datatype:str=
"",
25 hash_fields:dict=
None,
26 field_values:list=
None,
27 lookup_dicts:list=
None,
28 hash_lookup_dicts:dict=
None,
29 current_record_index:int=0,
30 current_field_index:int=-1
35 Processes a transform and uses LookUpDicts as needed. For lookups and by
36 reference functions, there must also be passed in dict of field titles (lower case) to index in list.
37 Lookups also require pre-processing the LookUp Dictionaries and passing into this function that list as well
38 as the hash dictionary of the titles.
41 transobj: Transform object to be processed
42 initial_value: initial value to begin with. This can be empty string.
43 result_datatype: optional datatype for final value (int,real,string,date,bool) default is string
44 hash_fields: dictionary key=field title lower case, value= array index in fields. This is required for Ref operations that use referenced field_values.
45 field_values: list of record values
46 lookup_dicts: optional list of LookUpDict objects
47 hash_lookup_dicts: dictionary of hashed lookup dict title to index position
48 current_record_index: integer index of record for which this transform is being processed. 0-based. If less than 0 it is ignored.
49 current_field_index: integer index of field in output record for which this transform is being processed. 0-based. If less than 0 it is ignored.
51 Return: If error start with notok: otherwise string of result value
66 if_result_true:bool=
False
67 prior_was_if:bool=
False
93 lkup:lookup.LookUpDict=lookup.LookUpDict()
96 if transobj
is None or not isinstance(transobj, transform.Transform):
97 raise ValueError(
"empty transform supplied")
98 if initial_value
is None:
99 raise ValueError(
"missing initial_value")
100 if field_values
is None:
102 if hash_fields
is None:
104 if lookup_dicts
is None:
106 if hash_lookup_dicts
is None:
112 result_datatype=result_datatype.lower().strip()
114 while i < len(transobj.ops):
134 if_result_true=
False
135 if i>= len(transobj.ops):
138 oper= transobj.ops[i].title.lower()
139 param1=transobj.ops[i].param1
140 param2=transobj.ops[i].param2
141 param3=transobj.ops[i].param3
143 str1= recfuncs.get_math_alias(result)
144 if len(str1)>0
and not str1.startswith(
"notok:"):
145 if not oper.endswith(
"refs"):
146 if oper.startswith(
"mult")
or oper.startswith(
"div")
or oper.startswith(
"add")
or oper.startswith(
"subtract"):
147 doclean= param2.lower()!=
"false"
151 doclean= param3.lower()!=
"false"
153 dval= numfuncs.is_real_get(str1,
"number", doclean)
157 if oper.startswith(
"ifstr")
or oper.startswith(
"ifnotstr"):
160 items= param1.split(
"|")
164 elif oper==
"settovalue":
165 if param1.lower()
in recfuncs.char_aliases:
166 result= recfuncs.char_aliases[param1.lower()]
169 elif oper==
"settoindex":
170 if len(param1)==0
or (lval := numfuncs.is_int_get(param1,
"number",
True)) < 0:
172 lval1 = current_record_index
if current_record_index>=0
else 0
175 elif oper==
"settoref":
176 param1=param1.lower()
177 if param1
in hash_fields:
178 nfld=hash_fields[param1]
179 if nfld<0
or nfld>= len(field_values):
182 result=recfuncs.get_math_alias(field_values[nfld])
185 elif oper==
"settorandom":
187 if len(param3)>0
and (dval := numfuncs.is_real_get(param3,
"number",
True)) != -999999:
189 if random.random()<dval:
195 if len(param1)==0
or (dval := numfuncs.is_real_get(param1,
"number",
True)) == -999999:
197 if len(param2)==0
or (dval2 := numfuncs.is_real_get(param2,
"number",
True)) == -999999:
201 dval1= random.random() * (dval2-dval) + dval
202 result= str(round(dval1,5))
205 elif oper==
"settofreqlist":
207 if len(param1)>0
and len(param2)>0:
208 str_list=param1.split(
"|")
213 if (dval1 := numfuncs.is_real_get(s,
"number",
True))!= -999999:
215 dbl_list.append(dval)
219 if dval==0
or len(dbl_list)==0:
222 str_list=param2.split(
"|")
223 if len(str_list)!=len(dbl_list):
226 for j
in range(len(dbl_list)):
232 if (dval := numfuncs.is_real_get(param3,
"number",
True))!= -999999:
235 elif param3.lower()
in hash_fields:
236 nfld= hash_fields[param3.lower()]
237 str1= recfuncs.get_math_alias(field_values[nfld])
238 if len(str1)>0
and (dval := numfuncs.is_real_get(str1,
"number",
True))== -999999:
241 dval= random.random()
242 for j
in range(len(dbl_list)):
243 if dval< dbl_list[j]:
246 if not flag
or nidx<0:
249 result= recfuncs.get_math_alias(str_list[nidx])
251 if (dval := numfuncs.is_real_get(result,
"number",
True))!= -999999:
253 if len(param1)>0
and numfuncs.is_int(param1):
254 n1=max(0,int(param1))
256 result= str(round(dval,n1))
257 if result_datatype==
"real" and "." not in result:
260 if (dval := numfuncs.is_real_get(result,
"number",
True))!= -999999:
261 result= str(math.floor(dval))
262 if result_datatype==
"real" and "." not in result:
264 elif oper==
"ceiling":
265 if (dval := numfuncs.is_real_get(result,
"number",
True))!= -999999:
266 result= str(math.ceil(dval))
267 if result_datatype==
"real" and "." not in result:
269 elif oper==
"cleannumber":
270 result= numfuncs.clean_number(result)
271 elif oper
in [
"multbyref",
"divbyref",
"addbyref",
"subtractbyref",
"divfromref",
"subtractfromref"]:
272 param1=param1.lower()
273 doclean= param2.lower()!=
"false"
275 if param1
in hash_fields:
276 nfld= hash_fields[param1]
277 str1= recfuncs.get_math_alias(field_values[nfld])
279 str1= numfuncs.clean_number(str1)
280 if (dval1 := numfuncs.is_real_get(str1,
"number",
False))== -999999:
283 if oper.startswith(
"mult"):
285 elif oper.startswith(
"divfrom"):
290 elif oper.startswith(
"div"):
295 elif oper.startswith(
"add"):
297 elif oper.startswith(
"subtractfrom"):
299 elif oper.startswith(
"subtract"):
301 if result_datatype.startswith(
"int"):
302 result= str(round(dval))
305 elif oper
in [
"multrefs",
"addrefs"]:
307 param1 +=
"," + param2
308 param1= param1.lower()
309 doclean= param3.lower()!=
"false"
310 str_list= param1.split(
",")
312 for j
in range(len(str_list)):
314 str1= str_list[j].lower().strip()
315 if str1
in hash_fields:
316 nfld= hash_fields[str1]
317 str1= recfuncs.get_math_alias(field_values[nfld])
319 str1= numfuncs.clean_number(str1)
320 if (dval1 := numfuncs.is_real_get(str1,
"number",
False))== -999999:
327 elif oper==
"addrefs":
329 if result_datatype.startswith(
"int"):
330 result= str(round(dval))
333 elif oper
in [
"mult",
"div",
"divfrom",
"add",
"subtract",
"subtractfrom"]:
336 doclean= param2.lower()!=
"false"
338 result= numfuncs.clean_number(result)
339 if (dval := numfuncs.is_real_get(result,
"number",
False))== -999999:
341 param1= recfuncs.get_math_alias(param1)
343 param1= numfuncs.clean_number(param1)
344 if (dval1 := numfuncs.is_real_get(param1,
"number",
False))== -999999:
353 elif oper==
"divfrom":
362 elif oper==
"subtract":
364 elif oper==
"subtractfrom":
366 if result_datatype.startswith(
"int"):
367 result= str(round(dval))
370 elif oper
in [
"abs",
"negate"]:
371 if result_datatype.startswith(
"int"):
373 if (lval := numfuncs.is_int_get(result,
"number",
True))== -999999:
375 if (dval := numfuncs.is_real_get(result,
"number",
True))!= -999999:
376 lval= math.floor(dval)
384 if (dval := numfuncs.is_real_get(result,
"number",
True))== -999999:
391 elif oper
in [
"log",
"ln"]:
393 if (dval := numfuncs.is_real_get(result,
"number",
True))== -999999:
397 dval1= math.log10(dval)
399 dval1= math.log(dval)
402 if result_datatype.startswith(
"int"):
403 lval= math.floor(dval1)
407 elif oper
in [
"pow10",
"powe"]:
409 if (dval := numfuncs.is_real_get(result,
"number",
True))== -999999:
419 elif oper==
"setdecimal":
430 if numfuncs.is_int(param1):
436 for j
in range(n1-n2):
442 result=result.strip()
444 result=result.lstrip()
446 result=result.rstrip()
447 elif oper==
"tolower":
448 result=result.lower()
449 elif oper==
"toupper":
450 result=result.upper()
451 elif oper==
"totitle":
452 result=result.capwords()
453 elif oper
in [
"front",
"end",
"back",
"before",
"after"]:
455 str1= recfuncs.convert_char_aliases(param1).lower()
456 n1= result.lower().find(str1)
460 result= result[:(n1+n2)]
461 elif oper
in (
"end",
"back"):
466 result=result[(n1+n2):]
467 elif oper
in (
"frontn",
"endn",
"backn"):
468 if numfuncs.is_int(param1):
470 if 0< n1 < len(result):
473 elif oper
in (
"endn",
"backn"):
474 result=result[(len(result)-n1):]
476 str1= recfuncs.convert_char_aliases(param1)
477 str2= recfuncs.convert_char_aliases(param2)
478 n1= result.lower().find(str1.lower())
479 if 0< n1 < len(result):
482 n1= result.lower().find(str2.lower())
483 if 0< n1 < len(result):
486 if numfuncs.is_int(param1):
488 if 0< n1 < len(result):
490 if numfuncs.is_int(param2):
492 if 0< n2 < len(result):
495 if numfuncs.is_int(param1):
497 if 0< n1 < len(result):
498 result=result[n1:n1+1]
499 elif oper==
"setlength":
501 if numfuncs.is_int(param1):
503 param2=param2.lower()
505 if "left" in param2
or "front" in param2:
509 str2= recfuncs.convert_char_aliases(param3)
516 result= result[(len(result)-n1):]
523 result = str2 + result
526 elif oper==
"prepend":
527 str1= recfuncs.convert_char_aliases(param1)
528 result = str1 + result
530 str1= recfuncs.convert_char_aliases(param1)
533 str2= recfuncs.convert_char_aliases(param1).lower()
538 result=result[len(str2):]
539 elif n1==len(result)-len(str2):
540 result=result[:-len(str2)]
543 result=result[(n1+len(str2)):]
544 result= str1 + result
547 elif oper==
"replace":
548 str2= recfuncs.convert_char_aliases(param1).lower()
549 str3= recfuncs.convert_char_aliases(param2)
550 if str2 != str3.lower():
555 result=result[len(str2):] + str3
556 elif n1==len(result)-len(str2):
557 result=result[:-len(str2)] + str3
560 result=result[(n1+len(str2)):]
561 result= str1 + str3 + result
564 elif oper==
"exceldatenumbertoiso":
565 result= datefuncs.convert_excel_date_to_iso(result)
566 elif oper==
"datetoiso":
567 result= datefuncs.convert_date_to_iso(result, param1)
568 elif oper==
"settoisodate":
569 param1=param1.lower().strip()
571 if param1
in [
"today",
"now",
""]:
574 result= datefuncs.get_current_iso_datetime(flag, param2)
578 str1= datefuncs.is_iso_date_str(param1,flag)
579 if str1.startswith(
"true"):
581 result=str1[str1.find(
":")+1:]
586 elif oper==
"convertmainframenumber":
587 result= numfuncs.convert_mainframe(result)
588 elif oper==
"convertfromexp":
589 result= numfuncs.get_value_from_suspect_exp(result)
590 elif oper.startswith((
"ifgte",
"ifgt",
"iflte",
"iflt",
"ifnotgte",
"ifnotgt",
"ifnotlte",
"ifnotlt",
"ifeq",
"ifnoteq")):
594 param1=param1.lower()
596 if oper.endswith(
"ref"):
598 raise ValueError(
"missing reference field title in: " + oper)
599 if param1
in hash_fields:
600 nfld= hash_fields[param1]
601 str1= recfuncs.get_math_alias(field_values[nfld])
602 if (dval1 := numfuncs.is_real_get(str1,
"number",
True))== -999999:
605 raise ValueError(
"reference field title not in fields: " + param1 +
", oper=" + oper)
608 str1= recfuncs.get_math_alias(param1)
609 if (dval1 := numfuncs.is_real_get(str1,
"number",
True))== -999999:
612 if oper
in [
"ifgte",
"ifnotgte"]:
615 elif oper
in [
"ifgt",
"ifnotgt"]:
618 elif oper
in [
"iflte",
"ifnotlte"]:
621 elif oper
in [
"iflt",
"ifnotlt"]:
624 elif oper
in [
"ifeq",
"ifnoteq"]:
627 if oper.startswith(
"ifnot"):
628 if_result_true =
not if_result_true
629 if i== len(transobj.ops)-1:
630 result= str(if_result_true).lower()
631 elif oper
in [
"ifempty",
"ifnotempty"]:
636 if oper.startswith(
"ifnot"):
637 if_result_true=
not if_result_true
638 if i== len(transobj.ops)-1:
639 result= str(if_result_true).lower()
640 elif oper
in [
"ifstreq",
"ifnotstreq"]:
644 if not param2==
"true":
646 for j
in range(len(items)):
647 str2= recfuncs.convert_special_notation(items[j])
648 if not param2==
"true":
653 if oper.startswith(
"ifnot"):
654 if_result_true=
not if_result_true
655 if i== len(transobj.ops)-1:
656 result= str(if_result_true).lower()
657 elif oper
in [
"ifstrstarts",
"ifnotstrstarts"]:
661 if not param2==
"true":
663 for j
in range(len(items)):
664 str2= recfuncs.convert_special_notation(items[j])
665 if not param2==
"true":
667 if str1.startswith(str2):
670 if oper.startswith(
"ifnot"):
671 if_result_true=
not if_result_true
672 if i== len(transobj.ops)-1:
673 result= str(if_result_true).lower()
674 elif oper
in [
"ifstrends",
"ifnotstrends"]:
678 if not param2==
"true":
680 for j
in range(len(items)):
681 str2= recfuncs.convert_special_notation(items[j])
682 if not param2==
"true":
684 if str1.endswith(str2):
687 if oper.startswith(
"ifnot"):
688 if_result_true=
not if_result_true
689 if i== len(transobj.ops)-1:
690 result= str(if_result_true).lower()
691 elif oper
in [
"ifstrcontains",
"ifnotstrcontains"]:
695 if not param2==
"true":
698 str1=str1.replace(
" ",
"")
699 for j
in range(len(items)):
700 str2= recfuncs.convert_special_notation(items[j])
701 if not param2==
"true":
706 if oper.startswith(
"ifnot"):
707 if_result_true=
not if_result_true
708 if i== len(transobj.ops)-1:
709 result= str(if_result_true).lower()
710 elif oper
in [
"ifint",
"ifnotint"]:
714 if numfuncs.is_int(result):
717 if param1==
"positive" and lval<=0:
719 elif param1==
"negative" and lval>=0:
721 if oper.startswith(
"ifnot"):
722 if_result_true=
not if_result_true
723 if i== len(transobj.ops)-1:
724 result= str(if_result_true).lower()
725 elif oper
in [
"ifreal",
"ifnotreal"]:
729 if (dval := numfuncs.is_real_get(result,
"number",
True))== -999999:
733 if param1==
"positive" and dval<=0:
735 elif param1==
"negative" and dval>=0:
737 if oper.startswith(
"ifnot"):
738 if_result_true=
not if_result_true
739 if i== len(transobj.ops)-1:
740 result= str(if_result_true).lower()
741 elif oper.startswith((
"ifmatch",
"ifnotmatch")):
747 param1=param1.lower()
748 if oper.endswith(
"ref"):
750 raise ValueError(
"missing reference field title in: " + oper)
751 if param1
in hash_fields:
752 nfld= hash_fields[param1]
753 str2= recfuncs.get_math_alias(field_values[nfld])
755 raise ValueError(
"reference field title not in fields: " + param1 +
", oper=" + oper)
758 str1=recfuncs.convert_special_notation(str1)
759 str2=recfuncs.convert_special_notation(str2)
763 if str2.startswith(
"*"):
768 elif str2.endswith(
"*"):
771 if wildf
and wildb
and len(str2)==0:
773 elif len(str1)>0
and len(str2)>0:
774 if wildf
and wildb
and str2
in str1:
776 elif wildf
and not wildb
and str1.endswith(str2):
778 elif not wildf
and wildb
and str1.startswith(str2):
780 elif not wildf
and not wildb
and str1==str2:
782 if_result_true=ismatch
783 if oper.startswith(
"ifnot"):
784 if_result_true=
not if_result_true
785 if i== len(transobj.ops)-1:
786 result= str(if_result_true).lower()
787 elif oper
in [
"ifisodate",
"ifnotisodate"]:
790 str1= datefuncs.is_iso_date_str(result,
False)
791 if_result_true= str1.startswith(
"true")
792 if oper.startswith(
"ifnot"):
793 if_result_true=
not if_result_true
794 if i== len(transobj.ops)-1:
795 result= str(if_result_true).lower()
796 elif oper
in [
"ifdateformat",
"ifnotdateformat"]:
798 if_result_true= datefuncs.is_date_format(result, param1)
799 if oper.startswith(
"ifnot"):
800 if_result_true=
not if_result_true
801 if i== len(transobj.ops)-1:
802 result= str(if_result_true).lower()
805 if hash_fields
is None or len(hash_fields)==0:
806 raise ValueError(
"no hash fields defined so cannot do transform:" + transobj.title +
",op index=" + str(i))
807 if lookup_dicts
is None or len(lookup_dicts)==0:
808 raise ValueError(
"no lookupdicts defined, transform:" + transobj.title +
",op index=" + str(i))
809 if hash_lookup_dicts
is None:
810 raise ValueError(
"no hash lookupdicts defined, transform:" + transobj.title +
",op index=" + str(i))
811 param1=param1.lower()
812 if param1
not in hash_lookup_dicts:
813 raise ValueError(
"transform lookupdict not defined:" + param1 +
",transform="\
814 + transobj.title +
",op index=" + str(i))
815 nidx= hash_lookup_dicts[param1]
816 lkup= lookup_dicts[nidx]
824 param2=param2.lower()
827 if "|" in param2
and len(param2)>(1+ n1):
835 if str2
in hash_fields:
836 nfld2=hash_fields[str2]
838 raise ValueError(
"lookup field 2 is not in supplied record fields: " + str2)
840 if str3
in hash_fields:
841 nfld3=hash_fields[str3]
843 raise ValueError(
"lookup field 3 is not in supplied record fields: " + str3)
846 fldval2= field_values[nfld2]
848 fldval3= field_values[nfld3]
849 if not lkup.is_case_sens:
851 fldval2=fldval2.lower()
853 fldval3=fldval3.lower()
855 for j
in range(len(lkup.recs)):
860 for f
in range(nkeys):
862 fldval= recfuncs.convert_special_notation(result)
863 if not lkup.is_case_sens:
864 fldval=fldval.lower()
865 keyand=lkup.recs[j].key1_and
866 keynot=lkup.recs[j].key1_not
869 keyand=lkup.recs[j].key2_and
870 keynot=lkup.recs[j].key2_not
873 keyand=lkup.recs[j].key3_and
874 keynot=lkup.recs[j].key3_not
880 for k
in range(len(keynot)):
883 if not lkup.is_case_sens:
887 wildf=lkup.recs[j].key1_not_front_wild[k]
888 wildb=lkup.recs[j].key1_not_back_wild[k]
890 wildf=lkup.recs[j].key2_not_front_wild[k]
891 wildb=lkup.recs[j].key2_not_back_wild[k]
893 wildf=lkup.recs[j].key3_not_front_wild[k]
894 wildb=lkup.recs[j].key3_not_back_wild[k]
896 if wildf
and wildb
and len(str1)==0:
898 elif len(fldval)>0
and len(str1)>0:
899 if wildf
and wildb
and str1
in fldval:
901 elif wildf
and not wildb
and fldval.endswith(str1):
903 elif not wildf
and wildb
and fldval.startswith(str1):
905 elif not wildf
and not wildb
and fldval==str1:
915 for k
in range(len(keyand)):
918 if not lkup.is_case_sens:
921 wildf=lkup.recs[j].key1_and_front_wild[k]
922 wildb=lkup.recs[j].key1_and_back_wild[k]
924 wildf=lkup.recs[j].key2_and_front_wild[k]
925 wildb=lkup.recs[j].key2_and_back_wild[k]
927 wildf=lkup.recs[j].key3_and_front_wild[k]
928 wildb=lkup.recs[j].key3_and_back_wild[k]
930 if wildf
and wildb
and len(str1)==0:
932 elif len(fldval)>0
and len(str1)>0:
933 if wildf
and wildb
and str1
in fldval:
935 elif wildf
and not wildb
and fldval.endswith(str1):
937 elif not wildf
and wildb
and fldval.startswith(str1):
939 elif not wildf
and not wildb
and fldval==str1:
946 if not ismatch
or isnotmatch:
951 if ismatch
and not isnotmatch:
952 result= lkup.recs[j].result
959 except (RuntimeError,ValueError,OSError)
as err:
960 result=
"notok:" + str(err)