5various worker functions to manipulate numbers
8__all__ = [
'convert_mainframe',
9 'get_value_from_suspect_exp',
18__author__ =
'Geoffrey Malafsky'
19__email__ =
'gmalafsky@technikinterlytics.com'
25 Checks if string is integer number. Returns bool
29 result= is_int_get(valnum,
"bool")
30 except (RuntimeError, ValueError):
36 Checks if string is real number. Returns bool
40 result= is_real_get(valnum,
"bool")
41 except (RuntimeError, ValueError):
45def is_int_get(valnum:str, typ:str=
"", remove_front_chars:bool=
False):
47 Checks if string is integer number.
49 valnum: input string to check
50 typ: optional return type (string, number, bool)
51 remove_front_chars: optional. bool whether non-numeric chars as prefix will be removed
52 and therefore not declare non-numeric
53 Return depends on typ. Default is bool.
54 number: converted integer or -999999 if error
55 string: string of integer or false:reason if not. Reason will
56 be detected issue such as decimal (has decimal point),
69 typ=typ.lower().strip()
70 if typ
not in [
"bool",
"number",
"string"]:
72 valnum=valnum.lower().strip()
73 if valnum.startswith(
"-"):
76 elif valnum.startswith(
"(")
and valnum.endswith(
")"):
79 elif valnum.startswith(
"+"):
84 elif any(x
in valnum
for x
in [
"e+",
"e-"]):
85 numstr= get_value_from_suspect_exp(valnum)
86 if len(numstr)==0
or numstr.startswith(
"notok:")
or numstr==valnum:
101 elif not remove_front_chars:
103 resultnum=int(valnum)
108 for i
in range(len(valnum)):
109 charstr= valnum[i:i+1]
110 if charstr.isdigit():
118 elif charstr==
"e" and numes==0:
128 if len(reason)==0
and nstart>-1
and (numes==1
or len(numstr)>0):
131 resultnum=int(valnum)
133 resultnum= int(numstr)
138 resultstr =
"false:" + reason
140 elif not remove_front_chars
and nstart>0:
149 resultstr= str(resultnum)
154 except (RuntimeError, ValueError):
155 resultstr=
"false:error"
158def is_real_get(valnum:str, typ:str=
"", remove_front_chars:bool=
False):
160 Checks if string is real number.
162 valnum: input string to check
163 typ: optional return type (string, number, bool)
164 remove_front_chars: optional. bool whether non-numeric chars as prefix will be removed
165 and therefore not declare non-numeric
166 Return depends on typ. Default is bool.
167 number: converted real or -999999 if error
168 string: string of real or false:reason if not. Reason will
169 be detected issue such as empty, non-numeric
173 resultbool:bool=
False
174 resultnum:float=-999999
182 typ=typ.lower().strip()
183 if typ
not in [
"bool",
"number",
"string"]:
185 valnum=valnum.lower().strip()
186 if valnum.startswith(
"-"):
189 elif valnum.startswith(
"(")
and valnum.endswith(
")"):
192 elif valnum.startswith(
"+"):
197 elif any(x
in valnum
for x
in [
"e+",
"e-"]):
198 numstr= get_value_from_suspect_exp(valnum)
199 if len(numstr)==0
or numstr.startswith(
"notok:")
or numstr==valnum:
204 resultnum=float(numstr)
208 elif not remove_front_chars:
210 resultnum=float(valnum)
215 for i
in range(len(valnum)):
216 charstr= valnum[i:i+1]
217 if charstr.isdigit():
227 reason=
"duplicate decimal"
229 elif charstr==
"e" and numes==0:
239 if len(reason)==0
and nstart>-1
and (numes==1
or len(numstr)>0):
242 resultnum=float(valnum)
244 resultnum= float(numstr)
249 resultstr =
"false:" + reason
251 elif not remove_front_chars
and nstart>0:
260 resultstr= str(resultnum)
261 if "." not in resultstr:
267 except (RuntimeError, ValueError):
268 resultstr=
"false:error"
273 Convert MainFrame formatted number string
275 Converts a string representing a main frame formatted number with an encoded last character into a string of a
276 real along with sign reversal if necessary
277 Always makes last 2 digits into decimal portion so no further divide by 100 is necessary. If special char is
278 within input string it becomes the end char and the
279 remaining suffix is discarded. Leading zeros are truncated so 000.12 becomes 0.12 . Codes are:
300 Return result or starts with 'notok:' if error. If no special char found then original string returned
312 str_in= valnum.strip().lower()
314 raise ValueError(
"str_in is empty")
315 if str_in.startswith(
"-"):
361 n1= str_in.find(str1)
365 codechar= str_in[n1:(n1+1)]
420 elif codechar.isdigit():
423 if len(str_out)>=2
and "." not in str_out:
426 str_out +=
"." + str1
433 if (dval := is_real_get(str_out,
"number",
True))!= -999999:
435 if str_out.startswith(
"."):
436 str_out=
"0" + str_out
439 str1= str_out[(n1+1):]
440 str_out=str_out[:(n1+1)]
451 str_out= signtyp + str_out
452 except (RuntimeError,ValueError)
as err:
453 str_out=
"notok:" + str(err)
458 Get Value From Suspected Exponential
460 Check string to see if it is an exponential number
461 which is extracted into real number if so
462 Returns string of number if converted or original string. Starts with notok: if error
481 orignum=valnum.lower()
482 if orignum.startswith(
"-"):
485 elif orignum.startswith(
"(")
and orignum.endswith(
")"):
487 orignum=orignum[1:-1]
491 numstr= orignum[:orignum.find(
"e")]
492 exppart=orignum[orignum.find(
"e")+1:]
493 if len(exppart)>0
and is_real(exppart):
496 if not is_real(numstr):
500 dval= is_real_get(numstr,
"number",
True)
501 if exppart.startswith(
"+")
or exppart.startswith(
"-"):
503 if len(exppart)>0
and (dexp := is_real_get(exppart,
"number",
True))!= -999999:
512 nper=result.find(
".")
513 decpart=result[nper+1:]
514 intpart=result[:nper]
519 elif len(decpart)==0:
520 result = intpart +
".00"
521 elif len(decpart)==1:
522 result = intpart +
"." + decpart +
"0"
525 if result.startswith(
"."):
526 result =
"0" + result
528 if flag
and isnegval:
530 except (RuntimeError, ValueError, OSError)
as err:
531 result=
"notok:" + str(err)
536 Cleans non-numeric prefix and suffix characters from number.
537 Enclosing parens which is interpreted as negative indicator and replaced with -,
538 while leading + is removed.
539 returns string starting with notok: if error
552 valnum=valnum.lower().strip()
553 if valnum.startswith(
"-"):
556 elif valnum.startswith(
"(")
and valnum.endswith(
")"):
559 elif valnum.startswith(
"+"):
571 if not isok
and not resultstr==
"-false-":
572 if any(x
in valnum
for x
in [
"e+",
"e-"]):
573 txt= get_value_from_suspect_exp(valnum)
574 if len(txt)==0
or txt.startswith(
"notok:")
or txt==valnum:
584 for i
in range(len(valnum)):
589 charstr= valnum[i:i+1]
590 if charstr.isdigit():
608 elif charstr==
"e" and numes==0:
615 if not resultstr==
"-false-" and nstart>-1:
622 elif len(resultstr)>0:
624 dval=float(resultstr)
627 if resultstr==
"-false-":
629 elif isneg
and len(resultstr)>0
and not resultstr==
"0" and not resultstr.startswith(
"-"):
630 resultstr=
"-" + resultstr
631 except (RuntimeError,ValueError)
as err:
632 resultstr=
"notok:" + str(err)
str get_value_from_suspect_exp(str valnum)
str convert_mainframe(str valnum)
is_real_get(str valnum, str typ="", bool remove_front_chars=False)
is_int_get(str valnum, str typ="", bool remove_front_chars=False)
str clean_number(str valnum)