KL-Py 0.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. KL_Py/KL_Py.py +4400 -0
  2. KL_Py/__init__.py +1 -0
  3. KL_Py/hindGui/__init__.py +16529 -0
  4. KL_Py/hindGui/_utils.py +140 -0
  5. KL_Py/hindGui/elements/base.py +1055 -0
  6. KL_Py/hindGui/elements/button.py +947 -0
  7. KL_Py/hindGui/elements/calendar.py +222 -0
  8. KL_Py/hindGui/elements/canvas.py +122 -0
  9. KL_Py/hindGui/elements/center.py +44 -0
  10. KL_Py/hindGui/elements/checkbox.py +240 -0
  11. KL_Py/hindGui/elements/column.py +443 -0
  12. KL_Py/hindGui/elements/combo.py +329 -0
  13. KL_Py/hindGui/elements/error.py +47 -0
  14. KL_Py/hindGui/elements/frame.py +273 -0
  15. KL_Py/hindGui/elements/graph.py +817 -0
  16. KL_Py/hindGui/elements/helpers.py +202 -0
  17. KL_Py/hindGui/elements/image.py +324 -0
  18. KL_Py/hindGui/elements/input.py +310 -0
  19. KL_Py/hindGui/elements/list_box.py +392 -0
  20. KL_Py/hindGui/elements/menu.py +192 -0
  21. KL_Py/hindGui/elements/multiline.py +685 -0
  22. KL_Py/hindGui/elements/option_menu.py +168 -0
  23. KL_Py/hindGui/elements/pane.py +127 -0
  24. KL_Py/hindGui/elements/progress_bar.py +304 -0
  25. KL_Py/hindGui/elements/radio.py +252 -0
  26. KL_Py/hindGui/elements/separator.py +64 -0
  27. KL_Py/hindGui/elements/sizegrip.py +34 -0
  28. KL_Py/hindGui/elements/slider.py +199 -0
  29. KL_Py/hindGui/elements/spin.py +252 -0
  30. KL_Py/hindGui/elements/status_bar.py +165 -0
  31. KL_Py/hindGui/elements/stretch.py +26 -0
  32. KL_Py/hindGui/elements/tab.py +697 -0
  33. KL_Py/hindGui/elements/table.py +463 -0
  34. KL_Py/hindGui/elements/text.py +413 -0
  35. KL_Py/hindGui/elements/tree.py +493 -0
  36. KL_Py/hindGui/replace.py +45 -0
  37. KL_Py/hindGui/tray.py +358 -0
  38. KL_Py/hindGui/window.py +2906 -0
  39. KL_Py/requests/__init__.py +184 -0
  40. KL_Py/requests/__version__.py +14 -0
  41. KL_Py/requests/_internal_utils.py +50 -0
  42. KL_Py/requests/adapters.py +719 -0
  43. KL_Py/requests/api.py +157 -0
  44. KL_Py/requests/auth.py +314 -0
  45. KL_Py/requests/certifi/__init__.py +4 -0
  46. KL_Py/requests/certifi/__main__.py +12 -0
  47. KL_Py/requests/certifi/core.py +83 -0
  48. KL_Py/requests/certifi/py.typed +0 -0
  49. KL_Py/requests/certs.py +17 -0
  50. KL_Py/requests/charset_normalizer/__init__.py +48 -0
  51. KL_Py/requests/charset_normalizer/__main__.py +6 -0
  52. KL_Py/requests/charset_normalizer/api.py +671 -0
  53. KL_Py/requests/charset_normalizer/cd.py +421 -0
  54. KL_Py/requests/charset_normalizer/cli/__init__.py +8 -0
  55. KL_Py/requests/charset_normalizer/cli/__main__.py +363 -0
  56. KL_Py/requests/charset_normalizer/constant.py +2031 -0
  57. KL_Py/requests/charset_normalizer/legacy.py +80 -0
  58. KL_Py/requests/charset_normalizer/md.py +744 -0
  59. KL_Py/requests/charset_normalizer/models.py +359 -0
  60. KL_Py/requests/charset_normalizer/py.typed +0 -0
  61. KL_Py/requests/charset_normalizer/utils.py +420 -0
  62. KL_Py/requests/charset_normalizer/version.py +8 -0
  63. KL_Py/requests/compat.py +106 -0
  64. KL_Py/requests/cookies.py +561 -0
  65. KL_Py/requests/exceptions.py +151 -0
  66. KL_Py/requests/help.py +134 -0
  67. KL_Py/requests/hooks.py +33 -0
  68. KL_Py/requests/idna/__init__.py +45 -0
  69. KL_Py/requests/idna/codec.py +122 -0
  70. KL_Py/requests/idna/compat.py +15 -0
  71. KL_Py/requests/idna/core.py +437 -0
  72. KL_Py/requests/idna/idnadata.py +4309 -0
  73. KL_Py/requests/idna/intranges.py +57 -0
  74. KL_Py/requests/idna/package_data.py +1 -0
  75. KL_Py/requests/idna/py.typed +0 -0
  76. KL_Py/requests/idna/uts46data.py +8841 -0
  77. KL_Py/requests/models.py +1039 -0
  78. KL_Py/requests/packages.py +23 -0
  79. KL_Py/requests/sessions.py +831 -0
  80. KL_Py/requests/status_codes.py +128 -0
  81. KL_Py/requests/structures.py +99 -0
  82. KL_Py/requests/urllib3/__init__.py +211 -0
  83. KL_Py/requests/urllib3/_base_connection.py +165 -0
  84. KL_Py/requests/urllib3/_collections.py +487 -0
  85. KL_Py/requests/urllib3/_request_methods.py +278 -0
  86. KL_Py/requests/urllib3/_version.py +34 -0
  87. KL_Py/requests/urllib3/connection.py +1099 -0
  88. KL_Py/requests/urllib3/connectionpool.py +1178 -0
  89. KL_Py/requests/urllib3/contrib/__init__.py +0 -0
  90. KL_Py/requests/urllib3/contrib/emscripten/__init__.py +17 -0
  91. KL_Py/requests/urllib3/contrib/emscripten/connection.py +260 -0
  92. KL_Py/requests/urllib3/contrib/emscripten/fetch.py +726 -0
  93. KL_Py/requests/urllib3/contrib/emscripten/request.py +22 -0
  94. KL_Py/requests/urllib3/contrib/emscripten/response.py +277 -0
  95. KL_Py/requests/urllib3/contrib/pyopenssl.py +564 -0
  96. KL_Py/requests/urllib3/contrib/socks.py +228 -0
  97. KL_Py/requests/urllib3/exceptions.py +335 -0
  98. KL_Py/requests/urllib3/fields.py +341 -0
  99. KL_Py/requests/urllib3/filepost.py +89 -0
  100. KL_Py/requests/urllib3/http2/__init__.py +53 -0
  101. KL_Py/requests/urllib3/http2/connection.py +356 -0
  102. KL_Py/requests/urllib3/http2/probe.py +87 -0
  103. KL_Py/requests/urllib3/poolmanager.py +651 -0
  104. KL_Py/requests/urllib3/py.typed +2 -0
  105. KL_Py/requests/urllib3/response.py +1480 -0
  106. KL_Py/requests/urllib3/util/__init__.py +42 -0
  107. KL_Py/requests/urllib3/util/connection.py +137 -0
  108. KL_Py/requests/urllib3/util/proxy.py +43 -0
  109. KL_Py/requests/urllib3/util/request.py +263 -0
  110. KL_Py/requests/urllib3/util/response.py +101 -0
  111. KL_Py/requests/urllib3/util/retry.py +549 -0
  112. KL_Py/requests/urllib3/util/ssl_.py +527 -0
  113. KL_Py/requests/urllib3/util/ssl_match_hostname.py +159 -0
  114. KL_Py/requests/urllib3/util/ssltransport.py +271 -0
  115. KL_Py/requests/urllib3/util/timeout.py +275 -0
  116. KL_Py/requests/urllib3/util/url.py +469 -0
  117. KL_Py/requests/urllib3/util/util.py +42 -0
  118. KL_Py/requests/urllib3/util/wait.py +124 -0
  119. KL_Py/requests/utils.py +1086 -0
  120. KL_Py/when.py +144 -0
  121. kl_py-0.0.1.dist-info/METADATA +15 -0
  122. kl_py-0.0.1.dist-info/RECORD +125 -0
  123. kl_py-0.0.1.dist-info/WHEEL +5 -0
  124. kl_py-0.0.1.dist-info/licenses/LICENSE +21 -0
  125. kl_py-0.0.1.dist-info/top_level.txt +1 -0
KL_Py/KL_Py.py ADDED
@@ -0,0 +1,4400 @@
1
+ from types import *
2
+ from typing import Callable, TypeVar, NewType, Any, Optional, Union, get_origin, Final, Self, Generic, Sequence, Iterable, Iterator, Generator, Mapping, List, Tuple, Set, Dict, defaultdict, Counter, Literal, NoReturn, Never
3
+ from abc import abstractmethod, ABCMeta, ABC as AbstractBaseClass
4
+ import functools
5
+ from functools import reduce, lru_cache, cache, wraps, partial, partialmethod
6
+ from dataclasses import dataclass
7
+ # need both math imports for convenience
8
+ from numbers import Number
9
+ from random import randint as old_randint, uniform as old_randflt
10
+ import time
11
+ import time as timer
12
+ from threading import Timer
13
+ import datetime
14
+ from dateutil.parser import parse as parse_date, ParserError
15
+ from math import *
16
+ # need both math imports for convenience
17
+ from copy import deepcopy
18
+ from pathlib import Path
19
+ import builtins, os, sys, argparse, io, asyncio, random, urllib, traceback, time as Time, platform, json, shutil, glob, shlex, signal, site, base64, enum, collections, collections.abc, importlib, functools, cmd, ctypes, stat, math, re, ast, webbrowser, subprocess, requests
20
+ from base64 import b64encode, b64decode
21
+ from urllib.parse import quote_plus as encode_url, quote as encode_url_soft, unquote_plus as normalize_url, unquote as normalize_url_soft
22
+ from contextlib import contextmanager, redirect_stdout, redirect_stderr
23
+ from itertools import product as collective_iter, count
24
+ from re import escape
25
+ import enum # NOTE: to allow enum.auto without making it global
26
+ # both of these imports are needed ^V
27
+ from enum import Enum
28
+ from inspect import *
29
+ from hindGui import *
30
+ from when import *
31
+ encodeurl = urlencode = url_encode = encode_url
32
+ encodeurlsoft = encode_urlsoft = urlencodesoft = url_encode_soft =encode_url_soft
33
+ decodeurl = decode_url = normurl = norm_url = normalizeurl = urldecode = url_decode =normalize_url
34
+ decodeurlsoft = decode_url_soft = normurlsoft = norm_url_soft = normalizeurlsoft = urlencodesoft = url_encode_soft =normalize_url_soft
35
+ base64.encode = base64_encode = base64.b64encode
36
+ base64.decode = base64_decode = base64.b64decode
37
+ Many = Union
38
+ Nullable = Optional
39
+ argv = ARGV = sys.argv[1:]
40
+ # helper regexes
41
+ HEX_RE = HEX_REGEX = r"(?:0x|#)?(?:[a-f0-9]{3}){1,2}"
42
+ PIN_RE = PIN_REGEX = r"^\d{4,64}$"
43
+ MAIL_RE = MAIL_REGEX = EMAIL_RE = EMAIL_REGEX = r"(?P<profile>[\w.+\!\-]+)@(?P<domain>[a-zA-Z0-9](?:[a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?)(?P<suffix>(?:\.[a-zA-Z]{2,})+)"
44
+ STRICT_PWD_RE = STRICT_PWD_REGEX = STRICT_PASSWORD_RE = STRICT_PASSWORD_REGEX = r"(?=.*\d)(?=.*[A-Z])(?=.*[a-z])(?=.*[^\w\d ])(.{8,})"
45
+ PHONE_RE = PHONE_REGEX = r"(?:(?P<start>\+|0{2})?(?P<country>\d{1,3}))?(?:[\-\(]|(?<=\d) )*(?P<A>\d{3})[ \-\)]*(?P<B>\d{3})[ \-\)]*(?P<C>\d{4})"
46
+ HTML_RE = HTML_REGEX = r"\s*(?P<tag>\<\s*(?P<tagName>[\!\/]?\w+)\s*(?P<attributes>(?P<attributeName>[\w\-]+)(?:\s*\=\s*[\"\']?(?P<attributeValue>[^\"\'\<\>]+)?[\"\']?\s*)?\s*)*\s*\/?>)(?P<content>[^\<\>]*)(?P<possibleClosingTag>\<\s*\/\s*(?P<possibleClosingTagName>\w+)\s*\>)?\s*"
47
+ CSS_RE = CSS_REGEX = r"(?P<tag>[\w.\#\:\-\s\,\+\~\>\[\]\=\'\"\\\^\$\~\*]+)\s*\{(?P<pairs>(?:\s*[\w\-]{3,}\:\s*[\w\s\-\,\(\)\\\'\"\#\%.\+\-\*\/]+;\s*)+)\}"
48
+ URL_RE = URL_REGEX = r"(?P<protocol>\w+\:[\\\/]{2,3})?(?:(?P<subDomain>[\w\-]+)\.)?(?P<domain>[\w\-]+)(?P<suffix>(?:\.[a-zA-Z]{2,})+)(?P<port>\:\d{1,5})?(?P<route>\/[^ \?\=\&\#]*)?(?P<query>\?[^ \#]*)?(?P<hash>\#[\w\-]*)?"
49
+ TITLE_CASED_WORD_RE = TITLE_CASED_WORD_REGEX = r"[A-Z][a-z]*(?: +[A-Z][a-z]*)+"
50
+ ALPHA_RE = ALPHA_REGEX = r"[A-Za-z]+"
51
+ LETTERS_WITH_SYMBOLS_RE = LETTERS_WITH_SYMBOLS_REGEX = r"[a-zA-Z (\(\)\{\}\[\]\&\:\;\-\'\"\?\!\,\.)]+"
52
+ TRAILING_SPACE_RE = TRAILING_SPACE_REGEX = r"(^\s+|\s+$)"
53
+ NUM_RE = NUM_REGEX = r"(\-?\d*\.?\d+)"
54
+ NON_NUM_RE: str = r"[^\-\.\d]+"
55
+ INT_RE = INTEGEGER_RE = INT_REGEX = INTEGEGER_REGEX = r"\-?\d+"
56
+ WORD_RE = WORD_REGEX = r"[A-Za-z_\'][\w\']*(?:\-[A-Za-z_\']\w*(?: [A-Za-z_\'][\w\']*){0})*"
57
+ NON_WORD_RE = NON_WORD_REGEX = r"[^A-Za-z_\-]|\-(?![A-Za-z_])"
58
+ def __rgx_is_full_match__(pattern, s): return bool(re.search(f"^{pattern}$", str(s) if s is not None else ""))
59
+ def __rgx_catch__(pattern, s) -> str | list[str]:
60
+ matches: list[str] = re.findall(pattern, str(s) if s is not None else "")
61
+ return matches[0] if len(matches) == 1 else matches
62
+ jumle_me_he = lafz_me_he = lambda y, x: re.search(y, x) or False if isinstance(y, str) and isinstance(x, str) else False
63
+ is_mail = is_email = ismail = isemail = lambda s: __rgx_is_full_match__(MAIL_RE, s)
64
+ he_mail = hemail = he_email = heemail = is_mail
65
+ catch_mail = catch_email = catchmail = catchemail = pakro_mail = pakromail = pakro_email = pakroemail = lambda s: __rgx_catch__(MAIL_RE, s)
66
+ has_mail = has_email = hasmail = hasemail = lambda s: catch_mail(s) != []
67
+ me_he_mail = mehemail = me_he_email = meheemail = has_mail
68
+ is_strict_pwd = is_strictpwd = isstrict_pwd = isstrictpwd = lambda s: __rgx_is_full_match__(STRICT_PWD_RE, s)
69
+ he_strict_pwd = he_strictpwd = hestrict_pwd = hestrictpwd = is_strict_pwd
70
+ catch_strict_pwd = catch_strictpwd = catchstrict_pwd = catchstrictpwd = pakro_strict_pwd = pakro_strictpwd = pakrostrict_pwd = pakrostrictpwd = lambda s: __rgx_catch__(STRICT_PWD_RE, s)
71
+ has_strict_pwd = has_strictpwd = hasstrict_pwd = hasstrictpwd = lambda s: catch_strict_pwd(s) != []
72
+ is_phone = isphone = is_phone_number = isphonenumber = is_phone_nr = isphonenr = lambda s: __rgx_is_full_match__(PHONE_RE, s)
73
+ he_phone = hephone = he_phone_number = hephonenumber = he_phone_nr = hephonenr = is_phone
74
+ catch_phone = catchphone = catch_phone_number = catchphonenumber = catch_phone_nr = catchphonenr = lambda s: __rgx_catch__(PHONE_RE, s)
75
+ pakro_phone = pakrophone = pakro_phone_number = pakrophonenumber = pakro_phone_nr = pakrophonenr = catch_phone
76
+ has_phone = hasphone = has_phone_nr = hasphonenr = has_phone_number = hasphonenumber = lambda s: catch_phone(s) != []
77
+ me_he_phone = mehephone = me_he_phone_nr = mehephonenr = me_he_phone_number = mehephonenumber = has_phone
78
+ is_html = ishtml = he_html = hehtml = lambda s: __rgx_is_full_match__(HTML_RE, s)
79
+ catch_html = catchhtml = pakro_html = pakrohtml = lambda s: __rgx_catch__(HTML_RE, s)
80
+ has_html = hashtml = me_he_html = mehehtml = lambda s: catch_html(s) != []
81
+ is_css = iscss = he_css = hecss = lambda s: __rgx_is_full_match__(CSS_RE, s)
82
+ catch_css = catchcss = lambda s: __rgx_catch__(CSS_RE, s)
83
+ has_css = hascss = lambda s: catch_css(s) != []
84
+ is_url = isurl = he_url = heurl = lambda s: __rgx_is_full_match__(URL_RE, s)
85
+ catch_url = catchurl = pakro_url = pakrourl = lambda s: __rgx_catch__(URL_RE, s)
86
+ has_url = hasurl = me_he_url = mehe_url = meheurl = lambda s: catch_url(s) != []
87
+ is_title_cased_word = is_titlecasedword = lambda s: __rgx_is_full_match__(TITLE_CASED_WORD_RE, s)
88
+ catch_title_cased_word = catchtitle_cased_word = lambda s: __rgx_catch__(TITLE_CASED_WORD_RE, s)
89
+ has_title_cased_word = hastitle_cased_word = lambda s: catch_title_cased_word(s) != []
90
+ is_alpha = isalpha = is_letter = isletter = lambda s: __rgx_is_full_match__(ALPHA_RE, s)
91
+ catch_alpha = catchalpha = catch_letter = catchletter = lambda s: __rgx_catch__(ALPHA_RE, s)
92
+ has_alpha = hasalpha = has_letter = hasletter = lambda s: catch_alpha(s) != []
93
+ is_num_like = isnumlike = he_num_jesa = henumjesa = he_num_jesi = henumjesi = he_parsable_num = heparsablenum = lambda s: __rgx_is_full_match__(NUM_RE, s)
94
+ catch_num = catchnum = pakro_num = pakronum = lambda s: __rgx_catch__(NUM_RE, s)
95
+ has_num = hasnum = me_he_num = mehenum = lambda s: catch_num(s) != []
96
+ catch_non_num = catchnonnum = pakro_non_num = pakrononnum = lambda s: __rgx_catch__(NON_NUM_RE, s)
97
+ has_non_num = hasnonnum = me_he_non_num = mehenonnum = lambda s: catch_non_num(s) != []
98
+ catch_int = catchint = lambda s: __rgx_catch__(INT_RE, s)
99
+ has_int = hasint = ne_he_int = meheint = lambda s: catch_int(s) != []
100
+ is_word = isword = lambda s: __rgx_is_full_match__(WORD_RE, s)
101
+ catch_word = catchword = pakro_word = pakroword = lambda s: __rgx_catch__(WORD_RE, s)
102
+ has_word = hasword = lambda s: catch_word(s) != []
103
+ is_non_word = isnon_word = isnonword = he_non_word = henon_word = henonword = lambda s: __rgx_is_full_match__(NON_WORD_RE, s)
104
+ catch_non_word = catchnon_word = catchnonword = pakro_non_word = pakronon_word = pakrononword = lambda s: __rgx_catch__(NON_WORD_RE, s)
105
+ has_non_word = hasnonword = me_he_non_word = mehenonword = lambda s: catch_non_word(s) != []
106
+ is_hex = ishex = he_hex = hehex = lambda s: __rgx_is_full_match__(HEX_RE, s)
107
+ catch_hex = catchhex = pakro_hex = pakrohex = lambda s: __rgx_catch__(HEX_RE, s)
108
+ has_hex = hashex = me_he_hex = mehehex = lambda s: catch_hex(s) != []
109
+ is_pin = ispin = he_pin = hepin = lambda s: __rgx_is_full_match__(PIN_RE, s)
110
+ catch_pin = catchpin = pakro_pin = pakropin = lambda s: __rgx_catch__(PIN_RE, s)
111
+ has_pin = haspin = me_he_pin = mehepin = lambda s: catch_pin(s) != []
112
+
113
+ # file function aliases
114
+ def make_file(filename: str, content: str = "") -> None:
115
+ if not isinstance(filename, str) or not filename.strip():
116
+ return
117
+ if not isinstance(content, str):
118
+ content = ""
119
+ with open(filename, mode="w", encoding="utf-8") as f:
120
+ f.write(content)
121
+ os.make_file = os.touch = make_file
122
+ os.make_folder = os.create_folder = os.touch_folder = lambda folder_path: os.makedirs(folder_path, exist_ok=True) if isinstance(folder_path, str) and folder_path.strip() else None
123
+ os.copy_file = os.copy = shutil.copy_file = lambda filename, dest: shutil.copy2(filename, dest) if all([isinstance(filename, str), str(filename).strip(), isinstance(dest, str), str(dest).strip()]) else None
124
+ os.move = lambda filename, dest: os.replace(filename, dest) if all([isinstance(filename, str), str(filename).strip(), isinstance(dest, str), str(dest).strip()]) else None
125
+ os.delete_file = os.remove_file = lambda filename: os.remove(filename) if isinstance(filename, str) and filename.strip() else None
126
+ os.remove_folder = os.delete_folder = shutil.remove_folder = shutil.delete_folder = lambda folder_path: shutil.rmtree(folder_path) if isinstance(folder_path, str) and folder_path.strip() else None
127
+ def saare(*args, default=None, n: int | float = 1) -> Any:
128
+ if len(args) >= 1 and isinstance(args[0], (list, tuple, float)):
129
+ if len(args) == 2:
130
+ args, default = [*args]
131
+ elif len(args) == 3:
132
+ args, default, n = [*args]
133
+ else:
134
+ args = args[0]
135
+ if not len(args):
136
+ return default
137
+ if isinstance(n, float):
138
+ n = int(n)
139
+ if type(n) not in (type(None), int):
140
+ n = None
141
+ if isinstance(args, (tuple, set)):
142
+ args = list(args)
143
+ if all(args):
144
+ truthies: list = [arg for arg in args if arg]
145
+ if isinstance(n, int) and n == 1 and len(truthies) >= 1:
146
+ return truthies[-1]
147
+ elif isinstance(n, int) and n >= 2:
148
+ try:
149
+ return truthies[:int(n) if isinstance(n, (int, float)) and 0<=n<=len(args) else len(args)]
150
+ except IndexError:
151
+ ...
152
+ return truthies
153
+ return default
154
+ sab = both = sare = saare
155
+ def either(*args, default=None, n: int | float = 1) -> Any:
156
+ if len(args) >= 1 and isinstance(args[0], (list, tuple, float)):
157
+ if len(args) == 2:
158
+ args, default = [*args]
159
+ elif len(args) == 3:
160
+ args, default, n = [*args]
161
+ else:
162
+ args = args[0]
163
+ if not len(args):
164
+ return default
165
+ if isinstance(n, float):
166
+ n = int(n)
167
+ if type(n) not in (type(None), int):
168
+ n = None
169
+ if isinstance(args, (tuple, set)):
170
+ args = list(args)
171
+ if any(args):
172
+ truthies: list = [arg for arg in args if arg]
173
+ if isinstance(n, int) and n == 1 and len(truthies) >= 1:
174
+ return truthies[0]
175
+ elif isinstance(n, int) and n >= 2:
176
+ try:
177
+ return truthies[:int(n) if isinstance(n, (int, float)) and 0<=n<=len(args) else len(args)]
178
+ except IndexError:
179
+ ...
180
+ return truthies
181
+ return default
182
+ yato = ya_to = kuch = some = chand = either
183
+ def neither(*args, default=[], n: int | float | None = None) -> Any:
184
+ if len(args) >= 1 and isinstance(args[0], (list, tuple, float)):
185
+ if len(args) == 2:
186
+ args, default = [*args]
187
+ elif len(args) == 3:
188
+ args, default, n = [*args]
189
+ else:
190
+ args = args[0]
191
+ if not len(args):
192
+ return default
193
+ if isinstance(n, float):
194
+ n = int(n)
195
+ if type(n) not in (type(None), int):
196
+ n = None
197
+ if isinstance(args, (tuple, set)):
198
+ args = list(args)
199
+ if not any(args):
200
+ try:
201
+ return [arg for arg in args if not arg][:int(n) if isinstance(n, int) and 0<=n<=len(args) else len(args)]
202
+ except IndexError:
203
+ return args
204
+ return default
205
+ nahi = nato = na_to = neither
206
+ def xor(*args: tuple[Any]) -> bool:
207
+ return sum(map(bool, args)) == 1
208
+ # helper placeholders
209
+ OR = YA = NOR = AND = AUR = 0
210
+ EXCL = EXCL_END = EXCL_STOP = EXCLUSIVE = EXCLUSIVE_STOP = EXCLUSIVE_END = EXCLUSIVE_LAST = BAGER = BAGERAKHRI = BAGER_AKHRI = 0
211
+ INCL = INCL_END = INCL_STOP = INCLUSIVE = INCLUSIVE_STOP = INCLUSIVE_END = INCLUSIVE_LAST = SHAMIL = SHAAMIL = SHAMIL_AKHRI = SHAAMIL_AKHRI = 1
212
+ FINCL = FINCL_END = FINCL_STOP = FORCE_INCLUSIVE = FORCE_INCLUSIVE_STOP = FORCE_INCLUSIVE_END = FORCE_INCLUSIVE_LAST = ZABARDASTI_SHAMIL = ZABARDASTI_SHAAMIL = ZABARDASTI_SHAMIL_AKHRI = ZABARDASTI_SHAAMIL_AKHRI = 2
213
+ NO_REVERSE = NON_REVERSE = NOT_REVERSE = DO_NOT_REVERSE = DONT_REVERSE = NO_REVERT = NON_REVERT = NOT_REVERT = DO_NOT_REVERT = DONT_REVERT = NAHI_REVERSE = NAHI_REVERSED = NAHI_REVERT = NOT_REVERSE = NOT_REVERSED = NAHI_ULTA = NAHI_ULTI = NAHI_ULTE = NAHI_ULAT = 0
214
+ ULAT = ULTA = ULTI = ULTE = REVERSE = REVERT = REVERSED = 1
215
+ def _map(array: list | tuple | set, x: Callable, if_: Callable = lambda _: 1) -> list:
216
+ if type(x) not in (Callable, type):
217
+ return array
218
+ was_a_tuple: bool = False
219
+ was_a_set: bool = False
220
+ if type(array) == tuple:
221
+ array = list(array)
222
+ was_a_tuple = True
223
+ if type(array) == set:
224
+ array = list(array)
225
+ was_a_set = True
226
+ if type(array) != list:
227
+ return []
228
+ result = []
229
+ try:
230
+ result = [x(v) for v in array if callable(if_) and if_(v)]
231
+ except (TypeError, ValueError):
232
+ pass
233
+ if was_a_tuple:
234
+ result = tuple(result)
235
+ if was_a_set:
236
+ result = set(result)
237
+ return result
238
+ def pehla(iterable: Iterable) -> Any:
239
+ if not isinstance(iterable, Iterable)\
240
+ or not len(iterable):
241
+ return
242
+ try:
243
+ return iterable[0]
244
+ except IndexError:
245
+ ...
246
+ def dusra(iterable: Iterable) -> Any:
247
+ if not isinstance(iterable, Iterable)\
248
+ or len(iterable) < 1:
249
+ return
250
+ try:
251
+ return iterable[1]
252
+ except IndexError:
253
+ ...
254
+ def tisra(iterable: Iterable) -> Any:
255
+ if not isinstance(iterable, Iterable)\
256
+ or len(iterable) < 2:
257
+ return
258
+ try:
259
+ return iterable[2]
260
+ except IndexError:
261
+ ...
262
+ teesra = tisra
263
+ def tisra_akhri(iterable: Iterable) -> Any:
264
+ if not isinstance(iterable, Iterable)\
265
+ or len(iterable) < 2:
266
+ return
267
+ try:
268
+ return iterable[-3]
269
+ except IndexError:
270
+ ...
271
+ teesra_aakhri = teesra_akhri = tisra_aakhri = tisra_akhri
272
+ def dusra_akhri(iterable: Iterable) -> Any:
273
+ if not isinstance(iterable, Iterable)\
274
+ or len(iterable) < 1:
275
+ return
276
+ try:
277
+ return iterable[-2]
278
+ except IndexError:
279
+ ...
280
+ dusra_aakhri = dusra_akhri
281
+ def akhri(iterable: Iterable) -> Any:
282
+ if not isinstance(iterable, Iterable)\
283
+ or not len(iterable):
284
+ return
285
+ try:
286
+ return iterable[-1]
287
+ except IndexError:
288
+ ...
289
+ aakhri = akhri
290
+ # ATTENTION: No changes to the following function (EVER):
291
+ __old_open__ = builtins.open
292
+ def open(file, mode="r", buffering=-1, encoding=None, *args, **kwargs):
293
+ if isinstance(mode, str) and "b" not in mode.lower():
294
+ encoding = "utf-8"
295
+ return __old_open__(file, mode=mode, buffering=buffering, encoding=encoding, *args, **kwargs)
296
+ builtins.open = open
297
+ # could help make IO a little easier to work with
298
+ # so no more encoding="..." everywhere
299
+ # CATCH: the mode has to stay any of the following non-binary modes:
300
+ # ['w', 'r', 'a', 'w+', 'r+', 'a+']
301
+ # as the original builtins.open does not allow encoding
302
+ # with binary mode
303
+ # ^
304
+ # WARNING
305
+ # NO CHANGED PLEASE!
306
+ # THIS CAN RUIN THE ENTIRE ENVIROMENT
307
+ def try_else(x: Any, y: Any) -> Any|None:
308
+ try:
309
+ if not x:
310
+ raise Exception()
311
+ # if x does not even exist
312
+ # to begin with,
313
+ # let's just skip to the except block right away
314
+ if callable(x):
315
+ x = x()
316
+ # if callable,
317
+ # replace x with its return value from the function call, if possible
318
+ if isinstance(x, str):
319
+ x = x.strip()
320
+ # let's check, AND SEE if the RETURN VALUE is FALSY
321
+ # if it is, head over to the except block, and return y
322
+ # otherwise, return x, as-is
323
+ if not x:
324
+ raise ValueError()
325
+ return x
326
+ except:
327
+ # upon failure,
328
+ # try the fallback
329
+ if y is not None and callable(y):
330
+ y = y()
331
+ # if callable,
332
+ # replace y with its return value from the function call, if possible
333
+ return y
334
+ koshish_nakami = koshish_nakaami = try_else
335
+ def collective_range(*lists: list[list]) -> list[int]:
336
+ lists = list(lists)
337
+ # converting the tuples to actual lists
338
+ # as Python varargs (*args)
339
+ # return a tuple (immutable)
340
+ # not a list
341
+ if not lists:
342
+ return []
343
+ lists = [lst for lst in lists if lst is not None and isinstance(lst, list)]
344
+ # filter
345
+ for i, lst in enumerate(lists):
346
+ if not isinstance(lists[i], list):
347
+ continue
348
+ lists[i] = range(len(lists[i]))
349
+ return collective_iter(*lists)
350
+ # this is going to be an improved version, a replacement of (random.)randint
351
+ # to avoid stack overflow, and cyclic references,
352
+ # let's store the old_randint function
353
+ from random import randint as old_randint, uniform as old_randflt
354
+ def rand_int(x: int = 10, y: int|None = None) -> int:
355
+ """
356
+ Ek random integer generate karta he range `x` (zaruri), aur `y` (kaabile ignore) ke darmyaan.
357
+ A replacement to random.randint
358
+ @param x min (switchable with @param:y)
359
+ :type <int>
360
+ @param y max (switchable with @param:x)
361
+ :type <int, optional>
362
+ @return a random int
363
+ :type <int>
364
+ """
365
+ if isinstance(x, float) and isinstance(y, float): return rand_flt(x, y)
366
+ if isinstance(x, float):
367
+ x = int(x)
368
+ if not isinstance(x, int):
369
+ x = 0
370
+ if y is not None:
371
+ if isinstance(y, float):
372
+ y = int(y)
373
+ if not isinstance(y, int):
374
+ y = 10
375
+ if y is None:
376
+ x, y = 0, x
377
+ # with type checks out of the way
378
+ # there shouldn't be a problem
379
+ # if we do:
380
+ x = int(x)
381
+ y = int(y)
382
+ if x == y:
383
+ return x
384
+ if y < x:
385
+ x, y = y, x
386
+ # let's make the make the function exclusive (of y itself)
387
+ result: int = 0
388
+ if y > x:
389
+ result = old_randint(x, y - 1)
390
+ else:
391
+ result = old_randint(y, x - 1)
392
+ return result
393
+ randint = koiint = koi_int = koinum = koi_num = koi_darmyan = randbetween = rand_between = randbw = rand_bw = randbelow = rand_below = rand_int
394
+ def rand_flt(x: float = 0, y: float|None = None, precision: int|None = None) -> float:
395
+ """
396
+ A replacement to random.uniform
397
+ @param x min (or max if y is None)
398
+ :type <float>
399
+ @param y max (switchable with @param:x)
400
+ :type <float, optional>
401
+ @return a random int
402
+ :type <float>
403
+ """
404
+ if not isinstance(x, (int, float)):
405
+ x = 0
406
+ if y is not None and not isinstance(y, (int, float)):
407
+ y = 1
408
+ x = float(x)
409
+ if y is not None:
410
+ y = float(y)
411
+ if not x and y is None:
412
+ x, y = 0, 1
413
+ if y is None:
414
+ x, y = 0.0, x
415
+ if x == y:
416
+ return x
417
+ if y < x:
418
+ x, y = y, x
419
+ # let's make the make the function exclusive (of y itself)
420
+ if y > 0:
421
+ y -= .1
422
+ else:
423
+ y += .1
424
+ if not precision or not isinstance(precision, int) or precision <= 0:
425
+ precision = 1
426
+ return round(old_randflt(x, y), precision)
427
+ randfloat = rand_float = randflt = koi_flt = koiflt = rand_flt
428
+ def choose(iterable: Iterable, n: int|None= None, koi: int|None=None) -> Any|list[Any]:
429
+ if koi is not None and isinstance(koi, int) and not isinstance(n, int):
430
+ n = abs(koi)
431
+ if isinstance(iterable, int) and isinstance(n, Iterable):
432
+ # cross compatibility: if the arguments
433
+ # are in reverse order
434
+ # order them
435
+ n, iterable = iterable, n
436
+ if not isinstance(iterable, Iterable):
437
+ return []
438
+ iterable = list(iterable)
439
+ if not len(iterable):
440
+ return [] if n != 1 else None
441
+ if isinstance(n, int) and n < 0:
442
+ n = abs(n)
443
+ if not n or not isinstance(n, int):
444
+ n = 1
445
+ if n > len(iterable):
446
+ n = len(iterable)
447
+ items: list[Any] = []
448
+ for _ in range(n):
449
+ items.append(iterable[rand_int(len(iterable))])
450
+ if isinstance(iterable, str):
451
+ return "".join(items)
452
+ if n == 1:
453
+ return items[0]
454
+ return items
455
+ choice = choices = choose_from = random_from = rand_from = rand_item = rand_items = rand_choice = choose_any = chuno = chuno_koi = koi = choose
456
+ def rand_range(start: int = 9, stop: int|None = None) -> list[int]:
457
+ """
458
+ Generate a list of random integers.
459
+ - If stop is provided, generate a list of length abs(stop) with elements between start and stop (exclusive of stop).
460
+ - If stop is not provided, generate a list of length start with elements between 0 and start (exclusive of start)
461
+ - If nothing is provided, generate a list of 10 elements between 0 and 9 (inclusive).
462
+ @param start: The start of the range (inclusive) or length of list if stop is None.
463
+ @param stop: The end of the range (exclusive).
464
+ @return: A list of random integers.
465
+ """
466
+ if not isinstance(start, int):
467
+ start = 9
468
+ if stop is None:
469
+ if start == 0:
470
+ return []
471
+ length = abs(start)
472
+ return [rand_int(0, start+1 if start > 0 else start-1) for _ in range(length)]
473
+ else:
474
+ if not isinstance(stop, int):
475
+ stop = 9
476
+ if stop < start:
477
+ start, stop = stop, start
478
+ length = abs(stop)
479
+ if start == stop:
480
+ return [start] * length # or handle this case differently
481
+ return [rand_int(start, stop) for _ in range(length)]
482
+ randrange = rand_range
483
+ def rand_str(length: int = 16) -> str:
484
+ if not isinstance(length, int) or length < 8:
485
+ length = 8
486
+ if length > 64:
487
+ length = 64
488
+ chars: str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+=_"
489
+ return_value: str = ""
490
+ for i in range(length):
491
+ return_value += chars[randint(0, len(chars)-1)]
492
+ return return_value
493
+ randstr = rand_str
494
+ def rand_hex(length: int = 16) -> str:
495
+ if not isinstance(length, int) or length < 8:
496
+ length = 8
497
+ if length > 64:
498
+ length = 64
499
+ chars: str = "0123456789abcdef"
500
+ return_value: str = ""
501
+ while length := length - 1:
502
+ return_value += chars[randint(0, len(chars)-1)]
503
+ return return_value
504
+ randhex = rand_hex
505
+ def rand_uuid() -> str:
506
+ from uuid import uuid4
507
+ return str(uuid4())
508
+ randuuid = rand_uuid
509
+ haal = filhal = filhaal = bool
510
+ line_break = linebreak = LINE_BREAK = LINEBREAK = "\n"
511
+ tab = TAB = "\t"
512
+ one_dim = two_dim = three_dim = four_dim = five_dim = \
513
+ six_dim = seven_dim = eight_dim = nine_dim = ten_dim = list
514
+ # recognizes all, just set it to `list`
515
+ # besides, the whole point of this
516
+ # is to achieve readability;
517
+ # will fail with `list|tuple|set`,
518
+ # and trust me, it has been tried
519
+ # to allow readable list-in-list, tuple-in-tuple types like the following:
520
+ # list[two_dim], list[three_dim], tuple[two_dim], tuple[three_dim]
521
+ # test:
522
+ # x: list[two_dim[int]] = [[1, 3, 5], [2, 4, 6]]
523
+ # print(x)
524
+ def intersection_of(x: list|dict, y: list|dict) -> list|dict:
525
+ if isinstance(x, tuple):
526
+ x = list(x)
527
+ if isinstance(y, tuple):
528
+ y = list(y)
529
+ if not isinstance(x, (list, dict)) and not isinstance(y, (list, dict)):
530
+ return []
531
+ if all(isinstance(each, list) for each in [x, y]):
532
+ return_val: list[Any] = list(set(x).intersection(y))
533
+ return_val.sort()
534
+ # list.sort returns None
535
+ return return_val
536
+ if all(isinstance(each, dict) for each in [x, y]):
537
+ return dict(x.items() & y.items())
538
+ return []
539
+ intersection = intersection_of
540
+ def if_main(main: Callable[[], None]) -> Callable[[], None]:
541
+ if callable(main) and main.__module__ == "__main__":
542
+ main()
543
+ return main
544
+ _entry = __entry = __entry__ = ifmain = if_main
545
+
546
+
547
+ class Date:
548
+ SEP: str = ", "
549
+ TIME_SEP: str = ":"
550
+ def __init__(self, date_string: Many[str, int, float, datetime.datetime, None] = None) -> None:
551
+ self.date_object: datetime.datetime
552
+ if isinstance(date_string, datetime.datetime):
553
+ self.date_object = date_string
554
+ if isinstance(date_string, (int, float)):
555
+ try:
556
+ self.date_object = datetime.datetime.fromtimestamp(date_string)
557
+ return
558
+ except (OverflowError, OSError, ValueError):
559
+ self.date_object = datetime.datetime.now()
560
+ return
561
+ if not isinstance(date_string, str):
562
+ self.date_object = datetime.datetime.now()
563
+ return
564
+ try:
565
+ date_string = re.sub(r"(?<=\d)\.(?=\d)", ":", date_string)
566
+ # replace is defined further below in the file
567
+ # better use original re.sub for safety
568
+ self.date_object = parse_date(date_string)
569
+ except ParserError:
570
+ print("Not a valid date string. Defaulting to today.")
571
+ self.date_object = datetime.datetime.now()
572
+ def __repr__(self, *args, **kwargs) -> str:
573
+ return self.format(*args, **kwargs)
574
+ __str__ = __repr__
575
+ # getters
576
+ def to_datetime(self) -> None:
577
+ return self.date_object
578
+ get_object = to_datetime
579
+ def format(self, short: bool = False, s: bool = False, short_year: bool = False, sep: str = SEP, time_sep: str = TIME_SEP) -> str:
580
+ if not isinstance(sep, str):
581
+ sep = self.SEP
582
+ if not isinstance(time_sep, str):
583
+ time_sep = self.TIME_SEP
584
+ date: datetime.datetime = self.date_object
585
+ format_for_short_dates: str = f"%I{time_sep}%M %p{sep}%a{sep}%b %d{sep}%{'Y' if not short_year else 'y'}"
586
+ format_for_longer_dates: str = f"%I{time_sep}%M{'' if not s else time_sep + '%S'} %p{sep}%A{sep}%B %d{sep}%{'Y' if not short_year else 'y'}"
587
+ formatted_date: str = ""
588
+ if short:
589
+ formatted_date = date.strftime(format_for_short_dates)
590
+ else:
591
+ formatted_date = date.strftime(format_for_longer_dates)
592
+ return formatted_date.lstrip("0").replace(" 0", " ")
593
+ get = get_long = long_get = get_full = full_get = read = full_read = read_full = long_read = read_long = read_long = long_read = f = _f = f_ = fmt = _str = str_ = _format = format_ = to_str = to_string = full = long = detailed = extended = full_form = long_form = detailed_form = extended_form = format
594
+ short = short_form = get_short = read_short = short_read = get_short = short_get = f_short = _f_short = f_short_ = fmt_short = _str_short = str_short = _format_short = format_short_ = partialmethod(format, short=True)
595
+ super_short = short_super = partialmethod(format, short=True, short_year=True)
596
+ super_super_short = short_super_super = super_duper_short = short_super_duper = lambda self: self.date_object.strftime("%I:%M %p, %a, %b %d, %y").lstrip("0")
597
+ short_almost_unreadable = almost_unreadable = inhuman_short = short_inhuman = inhumanly_short = short_inhumanly = insanely_short = short_insane = short_insanely = almost_unreadable_short = short_computerized = computerized_short = short_robotic = robotic_short = crazy_short = lambda self: self.date_object.strftime("%D")
598
+ def day(self, short: bool = False, short_year: bool = False, sep: str = SEP) -> str:
599
+ if isinstance(short, int)\
600
+ and not isinstance(short, bool)\
601
+ and short not in (True, False):
602
+ # if it's a true int, not a bool disguised as such
603
+ day: int = short
604
+ return self.set_day(day)
605
+ if not isinstance(sep, str):
606
+ sep = self.SEP
607
+ _today: str = self.format(
608
+ short=short,
609
+ short_year=short_year,
610
+ sep=sep
611
+ ).split(sep, 1)[1]
612
+ return _today
613
+ date = d = long_timeless = timeless_long = long_wo_time = long_without_time = long_no_time = day
614
+ date_short = short_date = day_short = short_day = short_without_time = short_wo_time = timeless_short = short_timeless = short_no_time = partialmethod(day, short=True)
615
+ date_super_short = super_short_date = day_super_short = super_short_day = super_short_without_time = super_short_wo_time = timeless_super_short = super_short_timeless = super_short_no_time = partialmethod(day, short=True, short_year=True)
616
+ def day_only(self, short: bool = False) -> str:
617
+ name_of_day: str = self.day(short=short).split(",")[0].strip()
618
+ return name_of_day
619
+ day_name = day_of_week = dow = day_only
620
+ def day_number(self, short: bool = False) -> str:
621
+ day_number: str = self.day().split(",")[1].strip().split(" ")[1]
622
+ return int(day_number)
623
+ d_nr = day_nr = day_num = day_of_month = dom = day_number
624
+ def is_weekend(self) -> bool:
625
+ return self.day_only() in ("Saturday", "Sunday")
626
+ he_weekend = is_weekend
627
+ def is_weekday(self) -> bool:
628
+ return not self.is_weekend()
629
+ he_weekday = is_weekday
630
+ def month_only(self, short: bool = False) -> str:
631
+ if isinstance(short, int)\
632
+ and not isinstance(short, bool)\
633
+ and short not in (True, False):
634
+ # if it's a true int, not a bool disguised as such
635
+ month: int = short
636
+ return self.set_month(month)
637
+ name_of_month: str = self.day(
638
+ short=short
639
+ ).split(", ")[1].split(" ")[0].strip()
640
+ return name_of_month
641
+ month_name = month = mn = month_only
642
+ def year_only(self, short: bool = False) -> str | int:
643
+ if isinstance(short, int)\
644
+ and not isinstance(short, bool)\
645
+ and short not in (True, False):
646
+ # if it's a true int, not a bool disguised as such
647
+ year: int = short
648
+ return self.set_year(year)
649
+ year_string: str = self.day()\
650
+ .split(", ")[-1].strip()
651
+ if short:
652
+ year_string = year_string[-2:]
653
+ # if short,
654
+ # return early
655
+ # so '2002' (str)
656
+ # now shortened into
657
+ # '02' doesn't end up
658
+ # 2 (now int)
659
+ return year_string
660
+ year: int = int(year_string)
661
+ return year
662
+ yr = year = year_only
663
+ def time(self, s: bool = False, time_sep: str = TIME_SEP) -> str:
664
+ if not isinstance(time_sep, str):
665
+ time_sep = self.TIME_SEP
666
+ return self.format(s=s, sep=self.SEP, time_sep=time_sep).split(self.SEP, 1)[0]
667
+ def time_and_day(self, s: bool = False, time_sep: str = TIME_SEP) -> str:
668
+ if not isinstance(time_sep, str):
669
+ time_sep = self.TIME_SEP
670
+ return self.format(s=s, sep=self.SEP, time_sep=time_sep).rsplit(self.SEP, 2)[0]
671
+ @classmethod
672
+ def now(cls) -> str:
673
+ return str(cls())
674
+ @classmethod
675
+ def time_now(cls, s: bool = False, time_sep: str = TIME_SEP) -> str:
676
+ return cls().time(s=s, time_sep=time_sep)
677
+ @classmethod
678
+ def today(cls, short: bool = False, sep: str = SEP) -> str:
679
+ return cls().day(short=short, sep=sep)
680
+ @classmethod
681
+ def day_today(cls, short: bool = False) -> str:
682
+ return cls().day_only(short=short)
683
+ # setters
684
+ def update(self, *args, **kwargs) -> Self:
685
+ self.date_object = self.date_object.replace(*args, **kwargs)
686
+ return self
687
+ replace = change = update
688
+ def set_year(self, year: int) -> Self:
689
+ if not isinstance(year, int) or year <= 0 or year > int(9.9e3):
690
+ raise TypeError("A year is supposed to be an int between 1 and 9999 (both inclusive)")
691
+ self.update(year=year)
692
+ return self
693
+ set_yr = set_year
694
+ def set_month(self, month: int) -> Self:
695
+ if not isinstance(month, int) or month <= 0 or month > 12:
696
+ raise TypeError("A month is supposed to be an int between 1 and 12 (both inclusive)")
697
+ self.update(month=month)
698
+ return self
699
+ set_mn = set_month
700
+ def set_day(self, day: int) -> Self:
701
+ if not isinstance(day, int) or day <= 0 or day > 31:
702
+ raise TypeError("A day is supposed to be an int between 1 and 31 (both inclusive)")
703
+ self.update(day=day)
704
+ return self
705
+ set_d = set_day
706
+
707
+ class Char(str):
708
+ def __new__(cls, value: Any):
709
+ if value is None:
710
+ return ""
711
+ character: str = ""
712
+ if isinstance(value, int|float):
713
+ character = chr(int(value))
714
+ else:
715
+ value = str(value).strip()
716
+ if not len(value):
717
+ return ""
718
+ character = value[0]
719
+ return super().__new__(cls, character)
720
+ char = Char
721
+ Str = lafz = jumla = lambda x: str(x).strip() # trim the string after parsing
722
+ # no one needs additional whitespace
723
+ nr = num = Num = Nr = Number
724
+ INFINITY = Infinity = infinity = Inf = inf
725
+ INT_INFINITY = INTEGER_INFINITY = INTINFINITY = INTEGERINFINITY = IntInfinity = Int_Infinity = int_infinity = intinfinity = int_inf = IntInf = intinf = sys.maxsize
726
+ goto = open_link = link_kholo = kholo_link = webbrowser.open
727
+ link = webbrowser
728
+ _dir = os.getcwd()
729
+ # crucial \/
730
+ class AbstractMethodsRehteHeError(TypeError):
731
+ def __init__(self, name: str):
732
+ self.name = str(name)
733
+ super().__init__(self.name)
734
+ class AbstractBaseClassMeta(ABCMeta):
735
+ def __new__(mcs, name, bases, namespace, **kwargs):
736
+ cls = super().__new__(mcs, name, bases, namespace, **kwargs)
737
+ if ABCMeta in cls.__mro__ and cls.__abstractmethods__:
738
+ return cls
739
+ abstract_methods: set = set()
740
+ for base in bases:
741
+ if isinstance(base, ABCMeta):
742
+ abstract_methods.update(base.__abstractmethods__)
743
+ missing_methods = abstract_methods - set(cls.__dict__)
744
+ for method_name in abstract_methods:
745
+ if not any(method_name in base.__dict__ for base in inspect.getmro(cls)[1:]):
746
+ missing_methods.add(method_name)
747
+ if missing_methods:
748
+ raise AbstractMethodsRehteHeError(
749
+ f"Base class '{name}' ke methods {missing_methods} ko implement karna laazmi he"
750
+ )
751
+ for method_name in abstract_methods:
752
+ if method_name not in cls.__dict__ :
753
+ continue
754
+ subclass_method = cls.__dict__[method_name]
755
+ for base in inspect.getmro(cls)[1:]:
756
+ if method_name not in base.__dict__:
757
+ continue
758
+ base_method = base.__dict__[method_name]
759
+ base_method_type = inspect.signature(base_method)
760
+ subclass_method_type = inspect.signature(subclass_method)
761
+ if base_method_type == subclass_method_type:
762
+ continue
763
+ raise TypeError(
764
+ f"Concrete class '{name}' ke method '{method_name}' ka kism BASE CLASS '{base.__name__}' ke sath match nahi karta"
765
+ )
766
+ return cls
767
+ # preserve the sequence
768
+ # it MATTERS
769
+ def extends_from(_object: Any, target: Any) -> bool:
770
+ """
771
+ checks if @_object extends from (or isinstance of) @super_class
772
+ DIFFERENT FROM regular `__builtins__.isinstance`
773
+ in the sense that `__builtins__.isinstance` only tells you if an object x
774
+ is strictly of type --- or an "instance" initiated directly from class --- y
775
+ @param _object
776
+ ::type Any/type type (class)
777
+ ::desc an object or a class to test if it extends from (or at least belongs to) class @target
778
+ @param target
779
+ ::type Any/type type (class)
780
+ ::desc the target class
781
+ @return
782
+ ::type bool
783
+ ::desc returns True if @_object extends from @target
784
+
785
+ Reads like: 'If X extends_from Y', or 'If X belongs_to Y'
786
+ Handles both instances (isinstance), and classes (issubclass).
787
+ """
788
+ if isinstance(target, (list, tuple, UnionType)):
789
+ sub_targets: list[Any] = target.__args__ if isinstance(target, UnionType) else target
790
+ return any(extends_from(_object, sub_target) for sub_target in sub_targets)
791
+ if isinstance(_object, (list, tuple, set)) and not isinstance(_object, (str, bytes)):
792
+ if len(_object) == 0:
793
+ return False
794
+ return all(extends_from(item, target) for item in _object)
795
+ # kill int-on-bool, bool-on-int false-positive checks
796
+ if target is int and isinstance(_object, bool):
797
+ return False
798
+ if target is int and _object is bool:
799
+ return False
800
+ if isinstance(_object, type) or hasattr(_object, "__origin__"):
801
+ try:
802
+ # Handle Generic Aliases like list[int] which issubclass() can reject
803
+ _object = get_origin(_object) or _object
804
+ target = get_origin(target) or target
805
+ return issubclass(_object, target)
806
+ except TypeError:
807
+ return False
808
+ # if _object is an object, check if it's an instance of target
809
+ try:
810
+ return isinstance(_object, target)
811
+ except TypeError:
812
+ return False
813
+ belongs_to = he_sub_class = sub_class_he = he_kism = extends_from
814
+ # ^^much needed
815
+ def kism(x: Any) -> type:
816
+ return get_origin(x) or type(x)
817
+ he_kism = hekism = is_type = istype = lambda y, x: kism(x) == y
818
+ # keep the order
819
+ def __ltype_helper_fn__(o: object) -> str:
820
+ try:
821
+ cls = o if isinstance(o, type) else type(o)
822
+ name = getattr(cls, "__name__", "unknown")
823
+ name = re.sub(r"^(?:KL(?:_Py)?[\._]|datetime\.|__main\.)", "", name)
824
+ type_normalization = {
825
+ "str_": "str",
826
+ "float64": "float", "float32": "float", "float16": "float",
827
+ "int64": "int", "int32": "int", "int16": "int", "int8": "int",
828
+ "bool_": "bool"
829
+ }
830
+ return type_normalization.get(name, name)
831
+ except Exception:
832
+ return "unknown"
833
+ def ltype(o: object, max_depth: int = 6, _current_depth: int = 0) -> str:
834
+ if _current_depth > max_depth:
835
+ return "..."
836
+ parsed_type = __ltype_helper_fn__(o)
837
+ if (not isinstance(o, Iterable) or
838
+ isinstance(o, (str, bytes, bytearray, memoryview, Generator, Iterator, zip, map, builtins.filter, enumerate))):
839
+ return parsed_type
840
+ try:
841
+ if callable(getattr(o, "__len__", None)) and not len(o):
842
+ return parsed_type
843
+ except Exception:
844
+ pass
845
+ if isinstance(o, Mapping):
846
+ try:
847
+ items_snapshot = list(o.items())
848
+ except (KeyboardInterrupt, SystemExit):
849
+ raise
850
+ except Exception:
851
+ return parsed_type
852
+ filtered_items = [
853
+ (k, v) for k, v in items_snapshot
854
+ if not (isinstance(k, str) and re.search(r"^\b(?:k[aeio]|mese)\b$", k))
855
+ ]
856
+ if not filtered_items:
857
+ return parsed_type
858
+ first_k, first_v = filtered_items[0]
859
+ if id(o) == id(first_v):
860
+ return f"{parsed_type}[{__ltype_helper_fn__(first_k)}, ...]"
861
+ first_k_type, first_v_type = type(first_k), type(first_v)
862
+ supported_key_types = (str, int, float, bool)
863
+ if first_k_type in supported_key_types:
864
+ try:
865
+ if all(type(k) is first_k_type for k, _ in filtered_items):
866
+ if all(type(v) is first_v_type for _, v in filtered_items):
867
+ return f"{parsed_type}[{__ltype_helper_fn__(first_k)}, {ltype(first_v, max_depth, _current_depth + 1)}]"
868
+ except (KeyboardInterrupt, SystemExit):
869
+ raise
870
+ except Exception:
871
+ pass
872
+ return parsed_type
873
+ try:
874
+ iterator = iter(o)
875
+ first_item = next(iterator)
876
+ except (StopIteration, KeyboardInterrupt, SystemExit):
877
+ if isinstance(sys.exc_info()[0], (KeyboardInterrupt, SystemExit)):
878
+ raise
879
+ return parsed_type
880
+ except Exception:
881
+ return parsed_type
882
+ if id(o) == id(first_item):
883
+ return f"{parsed_type}[...]"
884
+ first_type = type(first_item)
885
+ try:
886
+ for item in iterator:
887
+ if type(item) is not first_type:
888
+ return parsed_type
889
+ except (KeyboardInterrupt, SystemExit):
890
+ raise
891
+ except Exception:
892
+ return parsed_type
893
+ return f"{parsed_type}[{ltype(first_item, max_depth, _current_depth + 1)}]"
894
+ pakki_kism = pkism = literal_kism = lkism = literal_type = ltype
895
+ def ltype_old(o: object) -> str:
896
+ try:
897
+ parsed_type: str = re.split(r"[\"\']", str(type(o)))[1]
898
+ except IndexError:
899
+ return "unknown"
900
+ if re.search(r"^(?:KL(?:_Py)?|datetime|__main__)\.(?=[A-Za-z_])", parsed_type):
901
+ parsed_type = parsed_type.split(".", maxsplit=1)[1]
902
+ if not isinstance(o, Iterable) or isinstance(o, (Generator, Iterator, zip, map, builtins.filter, enumerate)) or (callable(getattr(o, "__len__", None)) and not len(o)):
903
+ return parsed_type
904
+ if re.search(r"\b(?:list|tuple|(?:frozen)?set|(?:p(?:an)?d(?:as)?\.)?(?:Custom)?Series|(?:n(?:um)?py?\.)?ndarray|dict_(?:keys|values))\b", parsed_type):
905
+ if all(isinstance(item, list) for item in o):
906
+ parsed_type += "[list]"
907
+ elif all(isinstance(item, tuple) for item in o):
908
+ parsed_type += "[tuple]"
909
+ elif all(isinstance(item, set) for item in o):
910
+ parsed_type += "[set]"
911
+ elif all(isinstance(item, frozenset) for item in o):
912
+ parsed_type += "[frozenset]"
913
+ elif all(isinstance(item, dict) for item in o):
914
+ parsed_type += "[dict]"
915
+ elif all(isinstance(item, str) for item in o):
916
+ parsed_type += "[str]"
917
+ elif all(isinstance(item, int) or re.search(r"(?:n(?:um)?py?)?\.int\d*", str(type(item))) for item in o):
918
+ parsed_type += "[int]"
919
+ elif all(isinstance(item, float) or re.search(r"(?:n(?:um)?py?)?\.float\d*", str(type(item))) for item in o):
920
+ parsed_type += "[float]"
921
+ elif all(isinstance(item, bool) for item in o):
922
+ parsed_type += "[bool]"
923
+ elif all(isinstance(item, datetime.datetime) for item in o):
924
+ parsed_type += "[datetime]"
925
+ elif all(re.search(r"\b(?:KL(?:_Py)?\.)?Date\b", str(type(item))) for item in o):
926
+ parsed_type += "[Date]"
927
+ elif all(isinstance(item, type(None)) for item in o):
928
+ parsed_type += "[None]"
929
+ elif re.search(r"\b(?:dict|(?:KL(?:_Py)?\.)?obj)\b", parsed_type):
930
+ keys = [k for k, v in o.items() if not re.search(r"^\bk[aeio]\b$", str(k))]
931
+ if not len(keys):
932
+ return parsed_type
933
+ if all(isinstance(item, str) for item in keys):
934
+ parsed_type += "[str"
935
+ elif all(isinstance(item, int) for item in keys):
936
+ parsed_type += "[int"
937
+ elif all(isinstance(item, float) for item in keys):
938
+ parsed_type += "[float"
939
+ elif all(isinstance(item, bool) for item in keys):
940
+ parsed_type += "[bool"
941
+ parsed_type += ", "
942
+ values = [v for k, v in o.items() if not re.search(r"^\bk[aeio]\b$", str(k))]
943
+ if all(isinstance(item, list) for item in values):
944
+ parsed_type += "list"
945
+ elif all(isinstance(item, tuple) for item in values):
946
+ parsed_type += "tuple"
947
+ elif all(isinstance(item, set) for item in values):
948
+ parsed_type += "set"
949
+ elif all(isinstance(item, frozenset) for item in values):
950
+ parsed_type += "frozenset"
951
+ elif all(isinstance(item, dict) for item in values):
952
+ parsed_type += "dict"
953
+ elif all(isinstance(item, str) for item in values):
954
+ parsed_type += "str"
955
+ elif all(isinstance(item, int) for item in values):
956
+ parsed_type += "int"
957
+ elif all(isinstance(item, float) for item in values):
958
+ parsed_type += "float"
959
+ elif all(isinstance(item, bool) for item in values):
960
+ parsed_type += "bool"
961
+ elif all(isinstance(item, datetime.datetime) for item in values):
962
+ parsed_type += "datetime"
963
+ elif all(re.search(r"\b(?:KL(?:_Py)?\.)?Date\b", str(type(item))) for item in values):
964
+ parsed_type += "Date"
965
+ elif all(isinstance(item, type(None)) for item in values):
966
+ parsed_type += "None"
967
+ if re.search(r"\[\w+, *$", parsed_type.strip()):
968
+ parsed_type = parsed_type.split("[")[0]
969
+ else:
970
+ parsed_type += "]"
971
+ if re.search(r", *]$", parsed_type.strip()):
972
+ parsed_type = re.sub(r", *]$", "", parsed_type)
973
+ return parsed_type
974
+ # preserve the sequence
975
+ # it MATTERS
976
+ def hissa(item: Any|type, container: Any|type|Iterable, _seen: Optional[set[int]] = None) -> bool:
977
+ try:
978
+ if _seen is None:
979
+ _seen = set()
980
+ container_id = id(container)
981
+ if container_id in _seen:
982
+ return False # Already checked this exact container
983
+ _seen.add(container_id)
984
+ if isinstance(item, str) and isinstance(container, str):
985
+ return match_i(container, item)
986
+ # NOTE: keep the order like this
987
+ # has to be called in reverse
988
+ # the parameters of this function are
989
+ # in reverse for readability
990
+ item_is_type_type: bool = isinstance(item, type) or hasattr(item, "__origin__")
991
+ container_is_type_type: bool = isinstance(container, type) or hasattr(container, "__origin__")
992
+ if item_is_type_type and container_is_type_type:
993
+ return extends_from(container, item)
994
+ if isinstance(container, (list, tuple, set, collections.abc.Iterable)):
995
+ if item_is_type_type:
996
+ return any(extends_from(parent, item) for parent in container if isinstance(parent, type) or hasattr(parent, "__origin__"))
997
+ try:
998
+ # direct membership check first (fast)
999
+ if item in container:
1000
+ return True
1001
+ except TypeError:
1002
+ pass
1003
+ for element in container:
1004
+ if isinstance(element, (list, tuple, set, dict)):
1005
+ if hissa(item, element, _seen=_seen):
1006
+ return True
1007
+ elif item == element:
1008
+ return True
1009
+ return item == container
1010
+ except (TypeError, ValueError, AttributeError):
1011
+ return False
1012
+ # preserve the sequence
1013
+ # it MATTERS
1014
+ def isinstance_each(collection: Any, target: Any) -> bool:
1015
+ """
1016
+ WARNING:
1017
+ this is DIFFERENT from `__builtins__.isinstance`
1018
+ HERE'S HOW: it shortens multiple isinstance checks into one
1019
+ WHERE y is the type to compare each item in x with.
1020
+ So, unlike the original...
1021
+ this one won't return True for
1022
+ `isinstance([1, 2], list)`
1023
+ unlike the original!
1024
+ INSTEAD:
1025
+ this one checks if every item from the @collection on the left
1026
+ matches the type of the @target
1027
+ Here is what it WILL return True for:
1028
+ isinstance_each([1, 2], int) // output: True
1029
+ isinstance_each([1.2, 2.1], float) // output: True
1030
+ isinstance_each([1.2, 2], float) // output: False, since 2 is an int
1031
+
1032
+ :: Checks if every item in @collection belongs_to @target.
1033
+ :: Returns False if the collection is empty.
1034
+ :: Also works with classes: isinstance_each([ValueError, TypeError], Exception) returns True
1035
+ """
1036
+ if not isinstance(collection, (list, tuple, set)):
1037
+ return False
1038
+ return extends_from(collection, target)
1039
+ each_isinstance = each_is_instance = is_instance_each = isinstance_each
1040
+ from bisect import bisect_left
1041
+ def near_get(
1042
+ d: dict,
1043
+ k: Union[str, int, float],
1044
+ default=None
1045
+ ):
1046
+ if not isinstance(d, dict)\
1047
+ or not d\
1048
+ or type(k) not in (
1049
+ str,
1050
+ int,
1051
+ float
1052
+ ):
1053
+ return default
1054
+ if k in d:
1055
+ return d[
1056
+ k
1057
+ ]
1058
+ if isinstance(k, str):
1059
+ k_lower: str = k.lower()
1060
+ str_keys = [
1061
+ str(key)\
1062
+ for key in d\
1063
+ if isinstance(key, str)
1064
+ ]
1065
+ if not str_keys:
1066
+ return default
1067
+ for key in str_keys:
1068
+ if key\
1069
+ .lower() == k_lower:
1070
+ return d[
1071
+ key
1072
+ ]
1073
+ for key in sorted(
1074
+ str_keys
1075
+ ):
1076
+ if key\
1077
+ .lower()\
1078
+ .startswith(
1079
+ k_lower
1080
+ ):
1081
+ return d[
1082
+ key
1083
+ ]
1084
+ for key in sorted(
1085
+ str_keys,
1086
+ key=len,
1087
+ reverse=True
1088
+ ):
1089
+ if k_lower\
1090
+ .startswith(
1091
+ key\
1092
+ .lower()
1093
+ ):
1094
+ return d[
1095
+ key
1096
+ ]
1097
+ else:
1098
+ k_int: int = int(
1099
+ k
1100
+ )
1101
+ if k_int in d:
1102
+ return d[
1103
+ k_int
1104
+ ]
1105
+ num_keys_map = {}
1106
+ for key in d:
1107
+ if isinstance(
1108
+ key,
1109
+ (
1110
+ int,
1111
+ float
1112
+ )
1113
+ ):
1114
+ num_keys_map[
1115
+ int(key)
1116
+ ] = key
1117
+ if not num_keys_map:
1118
+ return default
1119
+ sorted_ints = sorted(
1120
+ num_keys_map\
1121
+ .keys()
1122
+ )
1123
+ if k_int < sorted_ints[
1124
+ 0
1125
+ ]:
1126
+ return d[
1127
+ num_keys_map[
1128
+ sorted_ints[
1129
+ 0
1130
+ ]
1131
+ ]
1132
+ ]
1133
+ if k_int > sorted_ints[
1134
+ -1
1135
+ ]:
1136
+ return d[
1137
+ num_keys_map[
1138
+ sorted_ints[
1139
+ -1
1140
+ ]
1141
+ ]
1142
+ ]
1143
+ pos = bisect_left(
1144
+ sorted_ints,
1145
+ k_int
1146
+ )
1147
+ candidates = [
1148
+ sorted_ints[
1149
+ pos - 1
1150
+ ],
1151
+ sorted_ints[
1152
+ pos
1153
+ ]
1154
+ ]\
1155
+ if pos < len(
1156
+ sorted_ints
1157
+ )\
1158
+ else [
1159
+ sorted_ints[
1160
+ pos - 1
1161
+ ]
1162
+ ]
1163
+ closest_int = min(
1164
+ candidates,
1165
+ key=lambda x:\
1166
+ abs(
1167
+ x - k_int
1168
+ )
1169
+ )
1170
+ if abs(
1171
+ closest_int - k_int
1172
+ ) <= 3:
1173
+ return d[
1174
+ num_keys_map[
1175
+ closest_int
1176
+ ]
1177
+ ]
1178
+ return default
1179
+ def safe_get(
1180
+ data: Any,
1181
+ path: str | list | tuple,
1182
+ default: Any = None,
1183
+ target_type: Any = object,
1184
+ ignore_case: bool = True,
1185
+ use_regex: bool = False,
1186
+ auto_flatten: bool = False,
1187
+ on_match: Optional[Callable[[Any], Any]] = None,
1188
+ deep_search: bool = True,
1189
+ max_depth: int = 20,
1190
+ _seen: Optional[set[int]] = None
1191
+ ) -> Any:
1192
+ if isinstance(data, dict):
1193
+ # add a fallback
1194
+ # if dictionary
1195
+ # get the closest key
1196
+ # if nothing works out
1197
+ default = close_get(d=data, k=path, default=default)
1198
+ if _seen is None:
1199
+ _seen = set()
1200
+ if max_depth < 0:
1201
+ return default
1202
+ if isinstance(path, str) and '.' in path:
1203
+ parts: list[str] = path.split('.')
1204
+ if deep_search:
1205
+ path = parts[-1]
1206
+ else:
1207
+ path = parts[0]
1208
+ if isinstance(path, (list, tuple)) and not deep_search:
1209
+ if len(path) > 0 and any(isinstance(p, (str, list, tuple)) for p in path):
1210
+ is_multi = any(
1211
+ '.' in p\
1212
+ if isinstance(p, str)\
1213
+ else True\
1214
+ for p in path
1215
+ )
1216
+ if is_multi:
1217
+ return [
1218
+ safe_get(
1219
+ data,
1220
+ p,
1221
+ default,
1222
+ target_type,
1223
+ ignore_case,
1224
+ use_regex,
1225
+ auto_flatten,
1226
+ on_match,
1227
+ deep_search,
1228
+ max_depth,
1229
+ _seen.copy()
1230
+ ) for p in path
1231
+ ]
1232
+ if isinstance(
1233
+ data,
1234
+ (
1235
+ list,
1236
+ tuple,
1237
+ dict,
1238
+ set
1239
+ )
1240
+ ):
1241
+ if id(data) in _seen:
1242
+ return default
1243
+ _seen.add(
1244
+ id(data)
1245
+ )
1246
+ def _run_finalize(val):
1247
+ if auto_flatten:
1248
+ def _gen_flatten(items):
1249
+ if isinstance(
1250
+ items,
1251
+ (
1252
+ list,
1253
+ tuple,
1254
+ set
1255
+ )
1256
+ ):
1257
+ for item in items:
1258
+ yield from _gen_flatten(
1259
+ item
1260
+ )
1261
+ else:
1262
+ yield items
1263
+ val = list(
1264
+ _gen_flatten(
1265
+ val
1266
+ )
1267
+ )
1268
+ if on_match\
1269
+ and val is not default:
1270
+ try:
1271
+ val = [
1272
+ on_match(i)\
1273
+ for i in val
1274
+ ]\
1275
+ if auto_flatten\
1276
+ else on_match(val)
1277
+ except:
1278
+ return default
1279
+ if val is not None\
1280
+ and target_type is not object:
1281
+ if auto_flatten:
1282
+ if "isinstance_each" in globals()\
1283
+ and not isinstance_each(
1284
+ val,
1285
+ target_type
1286
+ ):
1287
+ return default
1288
+ else:
1289
+ if "extends_from" in globals()\
1290
+ and not extends_from(
1291
+ val,
1292
+ target_type
1293
+ ):
1294
+ return default
1295
+ return val
1296
+ def _find_key(d, k):
1297
+ if use_regex:
1298
+ try:
1299
+ p = re.compile(
1300
+ str(k),
1301
+ re.IGNORECASE\
1302
+ if ignore_case\
1303
+ else 0
1304
+ )
1305
+ for existing_key in d:
1306
+ if p.search(
1307
+ str(
1308
+ existing_key
1309
+ )
1310
+ ):
1311
+ return d[
1312
+ existing_key
1313
+ ]
1314
+ except re.error:
1315
+ pass
1316
+ elif ignore_case:
1317
+ k_map = {
1318
+ str(key).lower(): key\
1319
+ for key in d.keys()
1320
+ }
1321
+ look = k_map.get(
1322
+ str(k)\
1323
+ .lower()
1324
+ )
1325
+ if look is not None:
1326
+ return d[
1327
+ look
1328
+ ]
1329
+ return d\
1330
+ .get(k)\
1331
+ if isinstance(d, dict)\
1332
+ else None
1333
+ if deep_search:
1334
+ target_key = path\
1335
+ if isinstance(path, (list, tuple))\
1336
+ else str(path)
1337
+ if isinstance(data, dict):
1338
+ found = _find_key(
1339
+ data,
1340
+ target_key
1341
+ )
1342
+ if found is not None:
1343
+ return _run_finalize(
1344
+ found
1345
+ )
1346
+ for v in data.values():
1347
+ res = safe_get(
1348
+ v,
1349
+ path,
1350
+ default,
1351
+ target_type,
1352
+ ignore_case,
1353
+ use_regex,
1354
+ auto_flatten,
1355
+ on_match,
1356
+ True,
1357
+ max_depth - 1,
1358
+ _seen
1359
+ )
1360
+ if res is not default:
1361
+ return res
1362
+ elif isinstance(data, (list, tuple)):
1363
+ for item in data:
1364
+ res = safe_get(
1365
+ item,
1366
+ path,
1367
+ default,
1368
+ target_type,
1369
+ ignore_case,
1370
+ use_regex,
1371
+ auto_flatten,
1372
+ on_match,
1373
+ True,
1374
+ max_depth - 1,
1375
+ _seen
1376
+ )
1377
+ if res is not default:
1378
+ return res
1379
+ return default
1380
+ segments = path.split('.')\
1381
+ if isinstance(path, str)\
1382
+ else path
1383
+ current = data
1384
+ for key in segments:
1385
+ if current is None:
1386
+ return default
1387
+ try:
1388
+ if isinstance(current, dict):
1389
+ current = _find_key(
1390
+ current,
1391
+ key
1392
+ )
1393
+ elif isinstance(current, (list, tuple)):
1394
+ current = current[
1395
+ int(key)
1396
+ ]
1397
+ elif hasattr(current, str(key)):
1398
+ current = getattr(
1399
+ current,
1400
+ str(key),
1401
+ default
1402
+ )
1403
+ else:
1404
+ return default
1405
+ except:
1406
+ return default
1407
+ if current is default\
1408
+ or current is None:
1409
+ return default
1410
+ return _run_finalize(
1411
+ current
1412
+ )
1413
+ deepget = deep_get = safeget = safe_get
1414
+ autoclass = auto_class = dataclass
1415
+ def auto_id(
1416
+ _cls=None,
1417
+ start: int = 1000,
1418
+ field: str = "__id__"
1419
+ ) -> type:
1420
+ if not isinstance(start, int):
1421
+ start = 1000
1422
+ if not isinstance(field, str):
1423
+ field = "__id__"
1424
+ def decorator(cls):
1425
+ counters: dict[str, int] = {
1426
+ field: count(start),
1427
+ "__shanakht__": count(start)
1428
+ }
1429
+ original_init = cls.__init__
1430
+ @wraps(original_init)
1431
+ def new_init(self, *args, **kwargs):
1432
+ setattr(
1433
+ self,
1434
+ field,
1435
+ next(
1436
+ counters[
1437
+ field
1438
+ ]
1439
+ )
1440
+ )
1441
+ setattr(
1442
+ self,
1443
+ "__shanakht__",
1444
+ next(
1445
+ counters[
1446
+ "__shanakht__"
1447
+ ]
1448
+ )
1449
+ )
1450
+ original_init(
1451
+ self,
1452
+ *args,
1453
+ **kwargs
1454
+ )
1455
+ cls.__init__ = new_init
1456
+ return cls
1457
+ if _cls is None:
1458
+ return decorator
1459
+ return decorator(_cls)
1460
+ serialize = autoid = auto_id
1461
+ ______auto_variable_count_helper______: dict = {}
1462
+ class AutoField:
1463
+ def __init__(self, start: int = 0, key:str|None=None, increment: bool=True):
1464
+ self.start = 0 if not isinstance(start, int) else start
1465
+ self.key = object() if key is None else key
1466
+ self.increment = increment
1467
+ ______auto_variable_count_helper______[self.key] = start
1468
+ def __get__(self, instance, owner):
1469
+ if instance is None:
1470
+ return self
1471
+ key = (id(instance), self.key)
1472
+ if key not in ______auto_variable_count_helper______: ______auto_variable_count_helper______[key] = self.start
1473
+ value = ______auto_variable_count_helper______[key]
1474
+ if self.increment:
1475
+ ______auto_variable_count_helper______[key] += 1
1476
+ else: ______auto_variable_count_helper______[key] -= 1
1477
+ return value
1478
+ def __call__(self):
1479
+ value = ______auto_variable_count_helper______[self.key]
1480
+ if self.increment:
1481
+ ______auto_variable_count_helper______[self.key] += 1
1482
+ else: ______auto_variable_count_helper______[self.key] -= 1
1483
+ return value
1484
+ def auto_inc(start: int = 0):
1485
+ if not isinstance(start, int):
1486
+ start = 0
1487
+ return AutoField(start=start)
1488
+ def auto_dec(start: int = 0):
1489
+ if not isinstance(start, int):
1490
+ start = 0
1491
+ return AutoField(start, increment=False)
1492
+ typename = TypeT = typeT = TypeVar("T")
1493
+ def is_active_process(process: str) -> bool:
1494
+ if os.name != "nt" or not isinstance(process, str):
1495
+ return False
1496
+ process = process.strip("\"'").strip()
1497
+ if not process:
1498
+ return False
1499
+ if not process.lower().endswith(".exe"):
1500
+ process_pattern = f"{process}.exe"
1501
+ else:
1502
+ process_pattern = process
1503
+ try:
1504
+ cmd = ["tasklist", "/FI", f"IMAGENAME eq {process_pattern}", "/NH"]
1505
+ result = subprocess.run(
1506
+ cmd,
1507
+ stdout=subprocess.PIPE,
1508
+ stderr=subprocess.DEVNULL,
1509
+ text=True,
1510
+ check=False
1511
+ )
1512
+ if process_pattern.lower() not in result.stdout.lower():
1513
+ return False
1514
+ return True
1515
+ except Exception:
1516
+ return False
1517
+ is_running_process = is_running_app = is_active_process
1518
+ def run_process(
1519
+ command: str | list[str] | tuple[str, ...],
1520
+ new_window: bool = False,
1521
+ max: Optional[int] = None,
1522
+ timeout: Optional[int | float] = None,
1523
+ **kwargs
1524
+ ) -> bool:
1525
+ if isinstance(max, int) and max == 1:
1526
+ if is_running_process(command):
1527
+ return
1528
+ if not command:
1529
+ return False
1530
+ if not new_window\
1531
+ or not isinstance(
1532
+ new_window,
1533
+ bool
1534
+ ):
1535
+ new_window = any(
1536
+ bool(
1537
+ kwargs.pop(k, False)
1538
+ )\
1539
+ for k in [
1540
+ "dont_block",
1541
+ "non_blocking",
1542
+ "detach"
1543
+ ]
1544
+ )
1545
+ is_shell = any(
1546
+ bool(
1547
+ kwargs.pop(k, False)
1548
+ )\
1549
+ for k in [
1550
+ "cmd",
1551
+ "internal",
1552
+ "shell"
1553
+ ]
1554
+ )
1555
+ capture_output = bool(
1556
+ kwargs.pop(
1557
+ "capture_output",
1558
+ False
1559
+ )
1560
+ )
1561
+ print_output = bool(
1562
+ kwargs.pop(
1563
+ "print_output",
1564
+ False
1565
+ )
1566
+ )
1567
+ if print_output:
1568
+ capture_output = True
1569
+ as_text = bool(
1570
+ kwargs.get(
1571
+ "text",
1572
+ kwargs.get(
1573
+ "universal_newlines",
1574
+ False
1575
+ )
1576
+ )
1577
+ ) or print_output
1578
+ kwargs["text"] = as_text
1579
+ kwargs["shell"] = is_shell
1580
+ if isinstance(command, tuple):
1581
+ command = list(command)
1582
+ if isinstance(command, str):
1583
+ if not is_shell\
1584
+ and os.name != 'nt':
1585
+ command = shlex.split(
1586
+ command,
1587
+ posix=True
1588
+ )
1589
+ elif isinstance(command, list)\
1590
+ and is_shell:
1591
+ if os.name == 'nt':
1592
+ command = subprocess\
1593
+ .list2cmdline(
1594
+ command
1595
+ )
1596
+ else:
1597
+ command = shlex.join(
1598
+ command
1599
+ )
1600
+ if os.name == 'nt':
1601
+ creationflags = kwargs.get("creationflags", 0)\
1602
+ | subprocess\
1603
+ .CREATE_NEW_PROCESS_GROUP
1604
+ kwargs["creationflags"] = creationflags
1605
+ empty_buf = "" if as_text else b""
1606
+ stdout, stderr = empty_buf, empty_buf
1607
+ return_code = 1
1608
+ try:
1609
+ if new_window:
1610
+ stdout_pipe = subprocess.PIPE\
1611
+ if capture_output else None
1612
+ stderr_pipe = subprocess.PIPE\
1613
+ if capture_output else None
1614
+ proc = subprocess.Popen(
1615
+ command,
1616
+ stdout=stdout_pipe,
1617
+ stderr=stderr_pipe,
1618
+ **kwargs
1619
+ )
1620
+ if not capture_output:
1621
+ timer.sleep(0.05)
1622
+ return proc.poll() is None or\
1623
+ proc.poll() == 0
1624
+ try:
1625
+ stdout, stderr = proc.communicate(
1626
+ timeout=timeout
1627
+ )
1628
+ return_code = proc.returncode
1629
+ except subprocess.TimeoutExpired:
1630
+ if os.name == "nt":
1631
+ try:
1632
+ proc.send_signal(
1633
+ signal\
1634
+ .CTRL_BREAK_EVENT
1635
+ )
1636
+ except Exception:
1637
+ proc.kill()
1638
+ else:
1639
+ proc.kill()
1640
+ stdout, stderr = proc\
1641
+ .communicate()
1642
+ return_code = 1
1643
+ else:
1644
+ try:
1645
+ proc_res = subprocess.run(
1646
+ command,
1647
+ capture_output=capture_output,
1648
+ timeout=timeout,
1649
+ **kwargs
1650
+ )
1651
+ return_code = proc_res.returncode
1652
+ if capture_output:
1653
+ stdout, stderr = proc_res.stdout, proc_res.stderr
1654
+ else:
1655
+ return return_code == 0
1656
+ except subprocess.TimeoutExpired as e:
1657
+ stdout = e.stdout\
1658
+ if e.stdout is not None\
1659
+ else empty_buf
1660
+ stderr = e.stderr\
1661
+ if e.stderr is not None\
1662
+ else empty_buf
1663
+ return_code = 1
1664
+ if print_output:
1665
+ out = stdout if stdout else stderr
1666
+ if out:
1667
+ msg = out.decode(errors="replace")\
1668
+ if isinstance(out, (bytes, bytearray))\
1669
+ else str(out)
1670
+ if msg.strip():
1671
+ print(msg.strip())
1672
+ return return_code == 0
1673
+ except Exception as e:
1674
+ print(f"Process execution failed, reason: {e}")
1675
+ return False
1676
+ run_command = execute_command = execute_process = run_process
1677
+ def kill_process(process_name: str) -> bool:
1678
+ process_name: str = str(process_name).strip()
1679
+ killed: bool = False
1680
+ if not process_name:
1681
+ return False
1682
+ opsys: str = platform.system().lower()
1683
+ try:
1684
+ if opsys == "windows" or os.name == "nt":
1685
+ if not process_name.lower().endswith(".exe"):
1686
+ process_name += ".exe"
1687
+ # need this
1688
+ run_process(f"taskkill /f /im {process_name}")
1689
+ else:
1690
+ run_process(f"pkill -f {process_name}")
1691
+ killed = True
1692
+ except:
1693
+ killed = False
1694
+ return killed
1695
+ kill_application = kill_app = kill_process
1696
+ def Int(x: str|int|float, base: int = 10) -> int:
1697
+ try:
1698
+ if x is None or\
1699
+ not isinstance(
1700
+ x,
1701
+ (str, int, float, bool)
1702
+ ):
1703
+ return 0
1704
+ if isinstance(x, bool):
1705
+ return 1\
1706
+ if x else 0
1707
+ if not base or\
1708
+ not isinstance(base, int)\
1709
+ or base <= 0\
1710
+ or base >= Infinity:
1711
+ base = 10
1712
+ x = str(x).strip()
1713
+ x = replace(
1714
+ x,
1715
+ r"[^\-\.\d]",
1716
+ ""
1717
+ )
1718
+ # NOTE: keep the dot(.), it's needed for now. keep. the. dot.
1719
+ # ^ allow the dot(.) to pass through, for now, so that 23.5 does NOT become 253
1720
+ if "." in x\
1721
+ and len(x) >= 2:
1722
+ # and later, remove it gracefully
1723
+ x = x.split(".")[0]
1724
+ return int(x, base)
1725
+ except (ValueError, TypeError):
1726
+ return 0
1727
+ def Flt(x: str|int|float) -> float:
1728
+ try:
1729
+ if x is None or\
1730
+ not isinstance(
1731
+ x,
1732
+ (str, int, float, bool)
1733
+ ):
1734
+ return 0.0
1735
+ if isinstance(x, bool):
1736
+ return 1.0\
1737
+ if x else 0.0
1738
+ if isinstance(x, str):
1739
+ x = replace(
1740
+ x.strip(),
1741
+ r"[^e\+\-\.\d]",
1742
+ ""
1743
+ )
1744
+ return float(x)
1745
+ except (ValueError, TypeError):
1746
+ return 0.0
1747
+ def is_pos(n: int|float) -> bool:
1748
+ """agar number ek positive number he to kehta he `Han`,
1749
+ warna `Nahi`"""
1750
+ if not n\
1751
+ or not isinstance(n, (int, float)):
1752
+ return False
1753
+ return n > 0
1754
+ he_positive = he_pos = is_pos
1755
+ def is_neg(n: int|float) -> bool:
1756
+ """agar number ek negative number he to kehta he `Han`,
1757
+ warna `Nahi`"""
1758
+ if not n\
1759
+ or not isinstance(n, (int, float)):
1760
+ return False
1761
+ return n < 0
1762
+ he_negative = he_neg = is_neg
1763
+ def is_even(n: int) -> bool:
1764
+ """agar number ek even number he to kehta he `Han`,
1765
+ warna `Nahi`"""
1766
+ if not isinstance(n, int):
1767
+ return False
1768
+ # allow zero to pass through
1769
+ # might not seem like it,
1770
+ # but it does have the quality OF being even,
1771
+ # or odd, it even... though
1772
+ return n % 2 == 0
1773
+ he_even = is_even
1774
+ def is_odd(n: int) -> bool:
1775
+ """agar number ek odd number he to kehta he `Han`,
1776
+ warna `Nahi`"""
1777
+ if not isinstance(n, int):
1778
+ return False
1779
+ # allow zero to pass through
1780
+ # might not seem like it,
1781
+ # but it does have the quality OF being even,
1782
+ # or odd, it's not odd though
1783
+ return n % 2 != 0
1784
+ he_odd = is_odd
1785
+ char_code = ascii_code = int_code = lambda c: ord(c[0]) if isinstance(c, str) else 0
1786
+ Function = Fc = Pukarne_Layak = Callable
1787
+ def delay(n: int, fn: Callable) -> None:
1788
+ """
1789
+ kism<nr> `n` seconds baad kisi operation ko perform karne ke lie
1790
+ @param
1791
+ n kism<int | float>
1792
+ the delay in seconds
1793
+ @param fn
1794
+ fn kism<Pukarne_Layak / Function>
1795
+ the function to be executed after the delay
1796
+ @return_type
1797
+ kism<KoiNa|NoneType>
1798
+ operation perform karke koi value return nahi karta (koi_na|None)
1799
+ """
1800
+ if not isinstance(n, (int, float)) or n <= 0:
1801
+ n = 1
1802
+ MAX_DELAY: int = int(1e5)
1803
+ if n > MAX_DELAY:
1804
+ n = MAX_DELAY
1805
+ # good practice
1806
+ if not isinstance(fn, Callable):
1807
+ return
1808
+ timed_fn: Timer = Timer(n, fn)
1809
+ timed_fn.start()
1810
+ sec, mint = 1, 60
1811
+ # helpers contants
1812
+ # so we can do delay(5*min, lambda: doSomeThing())
1813
+ # again, helper constants
1814
+ after = baad = delay
1815
+ def blocking_sleep(s: Number = 5) -> None:
1816
+ if not isinstance(s, Number):
1817
+ return
1818
+ from time import sleep
1819
+ sleep(s)
1820
+ wait = rukawat = rukaawat = blocking_sleep
1821
+ def get_platform() -> str:
1822
+ from platform import system
1823
+ return system()
1824
+ get_os = get_platform
1825
+ user_os = user_platform = get_platform()
1826
+ def try_luck(*args, default=None) -> Optional[Any]:
1827
+ import random
1828
+ high = True
1829
+ low = False
1830
+ if args:
1831
+ if len(args) >= 1:
1832
+ if isinstance(args[0], (list, tuple, set)):
1833
+ args = list(args[0])
1834
+ if len(args) >= 2:
1835
+ default = args[1]
1836
+ high = args[0]
1837
+ low = default
1838
+ return random.choice([high, low])
1839
+ Re = re.Re = re.compile
1840
+ re.repl = re.sub
1841
+ def th(n: Number) -> str:
1842
+ if not isinstance(n, Number):
1843
+ return "0th"
1844
+ n = abs(int(n))
1845
+ if 10 <= n % 100 <= 20:
1846
+ suffix = "th"
1847
+ else:
1848
+ suffix = {1: "st", 2: "nd", 3: "rd"}.get(n % 10, "th")
1849
+ return str(n) + suffix
1850
+ def fus(amount: Number) -> str:
1851
+ if amount is None or not isinstance(amount, Number):
1852
+ return ""
1853
+ amount = round(amount, 1)
1854
+ parts = str(amount).split('.')
1855
+ integer_part = '{:,}'.format(int(parts[0]))
1856
+ decimal_part = f".{parts[1]}" if len(parts) > 1 else ''
1857
+ result: str = f"{integer_part}{decimal_part}"
1858
+ result = re.sub(r"\.0+$", "", result)
1859
+ return result
1860
+ def fpk(amount: Number) -> str:
1861
+ if amount is None or not isinstance(amount, Number):
1862
+ return ""
1863
+ amount = round(amount, 1)
1864
+ parts = str(amount).split('.')
1865
+ # Indian formatting for integer part
1866
+ integer_part = parts[0]
1867
+ if len(integer_part) > 3:
1868
+ last_three = integer_part[-3:]
1869
+ rest = integer_part[:-3]
1870
+ rest = ','.join(reversed([rest[max(0, i-2):i] for i in range(len(rest), 0, -2)]))
1871
+ integer_part = f"{rest},{last_three}" if rest else last_three
1872
+ decimal_part = f".{parts[1]}" if len(parts) > 1 else ''
1873
+ format: str = f"{integer_part}{decimal_part}"
1874
+ # fixing a bug...
1875
+ result: str = format.replace("-,", "-")
1876
+ result = re.sub(r"\.0+$", "", result)
1877
+ return result
1878
+ athwa: float = 0.125
1879
+ chotha: float = 0.25
1880
+ adha: float = 0.5
1881
+ dedh: float = 1.5
1882
+ dhai: float = 2.5
1883
+ tin: int = 3
1884
+ chaar: int = 4
1885
+ ath: int = 8
1886
+ aath = ath
1887
+ def number_list_validator(args: tuple[Any]):
1888
+ args = list(args)
1889
+ if len(args) == 1 and isinstance(args[0], (list, tuple)):
1890
+ args = list(args[0])
1891
+ if not all(isinstance(arg, (int, float)) for arg in args):
1892
+ return []
1893
+ return args
1894
+ def mean(*args: tuple[int | float]) -> float:
1895
+ args = number_list_validator(args)
1896
+ if not args:
1897
+ return 0.0
1898
+ return float(sum(args) / len(args))
1899
+ avg = average = math.avg = math.average = math.mean = mean
1900
+ def median(*args: tuple[int | float]) -> float:
1901
+ args = number_list_validator(args)
1902
+ if not args:
1903
+ return 0.0
1904
+ args = sorted(args)
1905
+ mid_of_length: int = len(args) // 2
1906
+ if len(args) % 2 != 0:
1907
+ return float(args[mid_of_length])
1908
+ first_middle: int | float = args[mid_of_length - 1]
1909
+ second_middle: int | float = args[mid_of_length]
1910
+ return float((first_middle + second_middle) / 2)
1911
+ math.find_middle = math.middle_number = math.find_median = math.median = median
1912
+ def arithmode(*args: tuple[int | float]) -> float:
1913
+ args = number_list_validator(args)
1914
+ if not args:
1915
+ return 0.0
1916
+ most_frequent_number: int | float = Counter(args).most_common(1)[0][0]
1917
+ return float(most_frequent_number)
1918
+ math.frequent = math.most_frequent = math.mode = frequent = most_frequent = arith_mode = arithmode
1919
+ def arithrange(*args: tuple[int | float]) -> float:
1920
+ args = number_list_validator(args)
1921
+ if not args:
1922
+ return 0.0
1923
+ return float(max(args) - min(args))
1924
+ math.arith_range = math.arithrange = arith_range = arithrange
1925
+ def IntInput(*args, **kwargs):
1926
+ try:
1927
+ return Int(input(*args, **kwargs))
1928
+ except Exception:
1929
+ return 0
1930
+ def FltInput(*args, **kwargs):
1931
+ try:
1932
+ return Flt(input(*args, **kwargs))
1933
+ except Exception:
1934
+ return 0
1935
+ intInput, fltInput = IntInput, FltInput
1936
+ def flattened(lst: list[Any]) -> list[Any]:
1937
+ if lst is None or not isinstance(lst, list):
1938
+ return []
1939
+ out: list[Any] = []
1940
+ for item in lst:
1941
+ if isinstance(item, Iterable) and not isinstance(item, (str, bytes)):
1942
+ out.extend(flattened(item))
1943
+ else:
1944
+ out.append(item)
1945
+ return out
1946
+ flat = flatten = flattened
1947
+ def clone(item: list|tuple|dict) -> list|tuple|dict:
1948
+ if item is None:
1949
+ return None
1950
+ return deepcopy(item)
1951
+ """
1952
+ __KL_Py.deepcopy__
1953
+
1954
+ @param item
1955
+ @@type (list, tuple, dict)
1956
+ :: object to clone
1957
+ @return
1958
+ @@type (list, tuple, dict)
1959
+ :: a cloned object
1960
+ depending on
1961
+ the type passed
1962
+ in as the argument
1963
+ """
1964
+ def lambai(x: Iterable) -> int:
1965
+ if not isinstance(x, Iterable):
1966
+ return 0
1967
+ return len(x)
1968
+ def barabar(x, y) -> haal:
1969
+ if isinstance(x, str) and isinstance(y, str):
1970
+ return x.lower() == y.lower()
1971
+ return x == y
1972
+ def he(x: Any, y: Any = None) -> bool:
1973
+ """
1974
+ stricter he
1975
+ ONLY EXISTS TO BOOST READABILITY
1976
+ IN HINDGUI-ONLY (non-Klang) PROJECTS
1977
+ different from `barabar`
1978
+ which uses case-insensitivity for strings
1979
+ """
1980
+ if x is not None and y is None:
1981
+ return bool(x)
1982
+ return x == y
1983
+ mojud = bool
1984
+ def yato(x, y) -> bool:
1985
+ return x or y
1986
+ def collect(x, *rest) -> list[list[Any], list[Any]]:
1987
+ if not x or not rest or len(rest) == 0 or not is_iterable(x) or not all(isinstance(item, Iterable) for item in [x, *rest]):
1988
+ return [[], []]
1989
+ args: list = [x, *rest]
1990
+ return list(zip(args))
1991
+ # wraps the old enumerate function
1992
+ # to avoid stack overflow
1993
+ # we'll need this
1994
+ ikhatte = collect
1995
+ old_enumerate = builtins.enumerate
1996
+ def numbered(x: str|list|tuple|dict, *args, **kwargs) -> list[list[Any], list[int]]:
1997
+ if not x or not isinstance(x, (str, list, tuple, dict)):
1998
+ return []
1999
+ kwargs["start"] = kwargs.pop("shuru", kwargs.pop("start", 0))
2000
+ enumeration_object: old_enumerate = old_enumerate(x, *args, **kwargs)
2001
+ if not enumeration_object:
2002
+ return []
2003
+ lst: list = list(enumeration_object)
2004
+ if not lst:
2005
+ return []
2006
+ return [(v, i) for i, v in lst]
2007
+ # WARNING: the `old_enumerate` part
2008
+ # is supposed to be AS/IS
2009
+ # this function overrides
2010
+ # the old enumerate function
2011
+ # for Klang
2012
+ # and replaces it with numbered
2013
+ # also, the swapping is a mandatory step
2014
+ # allowing the following syntax:
2015
+ # for item, i in numbered(arr):
2016
+ # print("{i}. {item}")
2017
+ enumer = numbered
2018
+ __old_list__ = builtins.list
2019
+ class Arr(__old_list__):
2020
+ current_type = Any
2021
+ length_is_final: bool = False
2022
+ def __init__(self, *objs, fixed: bool = False):
2023
+ objs = flattened(__old_list__(objs))
2024
+ if len(objs) > 0 and objs[0] is not None and objs[0] is not Iterable:
2025
+ self.current_type = type(objs[0])
2026
+ super().__init__()
2027
+ self.push(objs)
2028
+ filtered_lst: list = []
2029
+ if self.current_type is not Any:
2030
+ for item in self:
2031
+ if isinstance(item, Number) and not isinstance(item, bool) and self.current_type == str:
2032
+ item = Str(item)
2033
+ if re.search(r"\d|\b(?:True|False)\b", str(item)) and isinstance(item, (str, int, float, bool)) and self.current_type in [int, float]:
2034
+ if self.current_type == int:
2035
+ item = Int(item)
2036
+ else:
2037
+ item = Flt(item)
2038
+ # ^ WARNING (change not needed): refers to `Int` instead of
2039
+ # builtin `int`
2040
+ # FOR A REASON:
2041
+ # forced int-ification (if possible)
2042
+ # applying the type filter on items
2043
+ if type(item) != self.current_type:
2044
+ continue
2045
+ filtered_lst.append(item)
2046
+ self.clear()
2047
+ self[:] = filtered_lst
2048
+ if fixed:
2049
+ self.length_is_final = True
2050
+ def filter_out(self, fn):
2051
+ if not callable(fn):
2052
+ return self
2053
+ self[:] = [x for x in self if not fn(x)]
2054
+ return self
2055
+ def keep_if(self, fn):
2056
+ if not callable(fn):
2057
+ return self
2058
+ self[:] = [x for x in self if fn(x)]
2059
+ return self
2060
+ def map(self, fn):
2061
+ if not callable(fn):
2062
+ return self
2063
+ self[:] = [fn(x) for x in self]
2064
+ return self
2065
+ def unique(self):
2066
+ self[:] = __old_list__(dict.fromkeys(self))
2067
+ return self
2068
+ def has(self, x):
2069
+ return x in self
2070
+ def includes(self, x):
2071
+ return self.has(x)
2072
+ def i(self, i, default=None):
2073
+ if not isinstance(i, int):
2074
+ return self
2075
+ if i < 0:
2076
+ i = len(self) + i
2077
+ if 0 <= i < len(self):
2078
+ return self[i]
2079
+ return default
2080
+ def last(self):
2081
+ if self:
2082
+ return self[-1]
2083
+ return self
2084
+ def last_i(self, n: int = 1):
2085
+ if not isinstance(n, int):
2086
+ return self
2087
+ if n > 0 and n <= len(self):
2088
+ return self[-n]
2089
+ return self
2090
+ def nth(self, n):
2091
+ return self.i(n)
2092
+ def nth_last(self, n):
2093
+ return self.last_i(n)
2094
+ def first(self):
2095
+ if self:
2096
+ return self[0]
2097
+ return None
2098
+ def second(self):
2099
+ return self.i(1)
2100
+ def sec_last(self):
2101
+ return self.last_i(2)
2102
+ def update(self, i, x):
2103
+ if not isinstance(i, int):
2104
+ return self
2105
+ if i < 0:
2106
+ i = len(self) + i
2107
+ if 0 <= i < len(self):
2108
+ self[i] = x
2109
+ return self
2110
+ def replace(self, i, x):
2111
+ return self.update(i, x)
2112
+ def shuffle(self):
2113
+ if len(self) > 1:
2114
+ random.shuffle(self)
2115
+ return self
2116
+ def sort(self, key=None, reverse=False):
2117
+ if len(self) > 1:
2118
+ super().sort(key=key, reverse=reverse)
2119
+ return self
2120
+ def reverse(self):
2121
+ if len(self) > 1:
2122
+ super().reverse()
2123
+ return self
2124
+ def key_array(self):
2125
+ return __old_list__(range(len(self)))
2126
+ def keys(self):
2127
+ return self.key_array()
2128
+ def values(self):
2129
+ return __old_list__(self)
2130
+ def entries(self):
2131
+ return [self.keys(), self.values()]
2132
+ def slice(self, start: int = None, end: int = None):
2133
+ if not isinstance(start, int) or not isinstance(end, int) or start >= len(self) or end > len(self) or start == end:
2134
+ return self[:]
2135
+ return Arr(self[start:end])
2136
+ def slice_keep(self, x):
2137
+ if not isinstance(x, int) or x <= len(self) or x > len(self):
2138
+ return self.copy()
2139
+ return self.slice(0, x)
2140
+ def slice_right(self, x):
2141
+ if not isinstance(x, int):
2142
+ return self.copy()
2143
+ return self.slice(len(self) - x)
2144
+ def slice_end(self, x):
2145
+ if not isinstance(x, int):
2146
+ return self.copy()
2147
+ return self.slice(0, len(self) - x)
2148
+ def random(self):
2149
+ if self:
2150
+ return random.choice(self)
2151
+ return None
2152
+ def empty(self) -> Self:
2153
+ self.clear()
2154
+ return self
2155
+ def eq(self, other):
2156
+ if not isinstance(other, __old_list__):
2157
+ return False
2158
+ return self == other
2159
+ def compare(self, other):
2160
+ if not isinstance(other, __old_list__):
2161
+ return False
2162
+ intersection = Arr(set(self) & set(other))
2163
+ return len(intersection) > len(self) / 2
2164
+ def union(self, *arrays):
2165
+ return self.combine(*arrays)
2166
+ def cat(self, *arrays):
2167
+ return self.combine(*arrays)
2168
+ def concat(self, *arrays):
2169
+ return self.combine(*arrays)
2170
+ def join(self, *arrays):
2171
+ return self.combine(*arrays)
2172
+ def join_str(self, s: str = ""):
2173
+ return str(s).join(map(str, self))
2174
+ def intersection(self, *arrays):
2175
+ for arr in arrays:
2176
+ if isinstance(arr, __old_list__):
2177
+ self[:] = [x for x in self if x in arr]
2178
+ elif isinstance(arr, Arr):
2179
+ self[:] = [x for x in self if x in arr]
2180
+ return self
2181
+ def negative_intersection(self, *arrays):
2182
+ for arr in arrays:
2183
+ if isinstance(arr, __old_list__):
2184
+ self[:] = [x for x in self if x not in arr]
2185
+ elif isinstance(arr, Arr):
2186
+ self[:] = [x for x in self if x not in arr]
2187
+ return self
2188
+ def map_val(self, old_val, new_val) -> Self:
2189
+ for i, x in enumerate(self):
2190
+ if x == old_val:
2191
+ self[i] = new_val
2192
+ return self
2193
+ def sum(self) -> Number:
2194
+ if not len(self):
2195
+ return 0.0
2196
+ nums: __old_list__[Number] = [num for num in self if num is not None and isinstance(num, Number)]
2197
+ # this is a necessary check
2198
+ if not len(nums):
2199
+ return 0.0
2200
+ return sum(nums)
2201
+ def difference(self) -> Number:
2202
+ if not len(self):
2203
+ return 0.0
2204
+ nums: __old_list__[Number] = [num for num in self if num is not None and isinstance(num, Number)]
2205
+ # this is a necessary check
2206
+ if not len(nums):
2207
+ return 0.0
2208
+ diff: Number = nums[0]
2209
+ for i, item in old_enumerate(nums):
2210
+ if i == 0:
2211
+ continue
2212
+ # since we've already taken care of the first item
2213
+ # we don't that
2214
+ if item > 1e9:
2215
+ item = 1e9
2216
+ if item < 1e-9:
2217
+ item = 1e-9
2218
+ diff -= item
2219
+ return diff
2220
+ diff = difference
2221
+ def product(self) -> Number:
2222
+ if not len(self):
2223
+ return 0.0
2224
+ nums: __old_list__[Number] = [num for num in self if num is not None and isinstance(num, Number)]
2225
+ # this is a necessary check
2226
+ if not len(nums):
2227
+ return 0.0
2228
+ prd: Number = nums[0]
2229
+ for i, item in old_enumerate(nums):
2230
+ if i == 0:
2231
+ continue
2232
+ # since we've already taken care of the first item
2233
+ # we don't that
2234
+ if item > 1e9:
2235
+ item = 1e9
2236
+ if item < 1e-9:
2237
+ item = 1e-9
2238
+ prd *= item
2239
+ return prd
2240
+ prd = product
2241
+ def quotient(self) -> Number:
2242
+ if not len(self):
2243
+ return 0.0
2244
+ nums: __old_list__[Number] = [num for num in self if num is not None and isinstance(num, Number)]
2245
+ # this is a necessary check
2246
+ if not len(nums):
2247
+ return 0.0
2248
+ quo: Number = nums[0]
2249
+ for i, item in old_enumerate(nums):
2250
+ if i == 0:
2251
+ continue
2252
+ # since we've already taken care of the first item
2253
+ # we don't that
2254
+ if item == 0:
2255
+ item = 1
2256
+ if item > 1e9:
2257
+ item = 1e9
2258
+ if item < 1e-9:
2259
+ item = 1e-9
2260
+ quo /= item
2261
+ return quo
2262
+ quo = quotient
2263
+ def max(self) -> Number:
2264
+ if not len(self):
2265
+ return 0.0
2266
+ nums: __old_list__[Number] = [num for num in self if num is not None and isinstance(num, Number)]
2267
+ # this is a necessary check
2268
+ if not len(nums):
2269
+ return 0.0
2270
+ return max(nums)
2271
+ def min(self) -> Number:
2272
+ if not len(self):
2273
+ return 0.0
2274
+ nums: __old_list__[Number] = [num for num in self if num is not None and isinstance(num, Number)]
2275
+ # this is a necessary check
2276
+ if not len(nums):
2277
+ return 0.0
2278
+ return min(nums)
2279
+ def combine(self, *args) -> Self:
2280
+ if self.length_is_final:
2281
+ return self
2282
+ if not args:
2283
+ return self
2284
+ for arg in args:
2285
+ if isinstance(arg, tuple):
2286
+ arg = __old_list__(arg)
2287
+ # a tuple?
2288
+ # no thanks,
2289
+ # we need a list
2290
+ if isinstance(arg, __old_list__):
2291
+ arg = flatten(arg)
2292
+ self.extend(arg)
2293
+ return self
2294
+ else:
2295
+ if self.current_type is not Any:
2296
+ if isinstance(arg, Number) and not isinstance(arg, bool) and self.current_type == str:
2297
+ item = Str(arg)
2298
+ if re.search(r"\d|\b(?:True|False)\b", str(arg)) and isinstance(arg, (str, int, float, bool)) and self.current_type in [int, float]:
2299
+ if self.current_type == int:
2300
+ arg = Int(arg)
2301
+ else:
2302
+ arg = Flt(arg)
2303
+ # ^ WARNING (change not needed): refers to `Int` instead of
2304
+ # builtin `int`
2305
+ # FOR A REASON:
2306
+ # forced int-ification (if possible)
2307
+ if type(arg) != self.current_type:
2308
+ continue
2309
+ self.append(arg)
2310
+ return self
2311
+ add = push = me_dalo = combine
2312
+ def push_at(self, i: int, *items) -> Self:
2313
+ if self.length_is_final:
2314
+ return self
2315
+ if not len(items):
2316
+ return self
2317
+ if not isinstance(i, int):
2318
+ i = len(self)
2319
+ if i < 0:
2320
+ i = 0
2321
+ elif i > len(self):
2322
+ i = len(self)
2323
+ #items = flatten(__old_list__(items))
2324
+ items = list(items)
2325
+ if self.current_type is not Any:
2326
+ for i, item in enumerate(items):
2327
+ if isinstance(items[i], Number) and not isinstance(items[i], bool) and self.current_type == str:
2328
+ items[i] = Str(item)
2329
+ if re.search(r"\d|\b(?:True|False)\b", str(items[i])) and isinstance(items[i], (str, int, float, bool)) and self.current_type in [int, float]:
2330
+ if self.current_type == int:
2331
+ items[i] = Int(item)
2332
+ else:
2333
+ items[i] = Flt(item)
2334
+ # ^ WARNING (change not needed): refers to `Int` instead of
2335
+ # builtin `int`
2336
+ # FOR A REASON:
2337
+ # forced int-ification (if possible)
2338
+ # applying the type filter on items
2339
+ if type(items[i]) != self.current_type:
2340
+ items.pop(i)
2341
+ x = self[:i] + items + self[i+len(items)-1:]
2342
+ updated_list: __old_list__ = __old_list__(x)
2343
+ self.clear()
2344
+ self.extend(updated_list)
2345
+ return self
2346
+ def push_start(self, *items) -> Self:
2347
+ self.push_at(0, *items)
2348
+ return self
2349
+ pehla_dalo = ke_pehle_dalo = unshift = push_start
2350
+ def shift(self) -> Any|None:
2351
+ if self.length_is_final:
2352
+ return None
2353
+ if len(self) == 0:
2354
+ return None
2355
+ return self.pop(0)
2356
+ # pop the first item, "shift"ing all to the left by one bit
2357
+ pehla_nikalo = shift
2358
+ # OVERRIDE self.remove
2359
+ old_remove = __old_list__.remove
2360
+ def remove(self, *items) -> Any|None:
2361
+ if self.length_is_final:
2362
+ return None
2363
+ if not len(self):
2364
+ return None
2365
+ if not len(items):
2366
+ return super().pop()
2367
+ items = flatten(__old_list__(items))
2368
+ last_removed: Any = items[-1]
2369
+ for item in items:
2370
+ if not self.contains(item):
2371
+ continue
2372
+ self.old_remove(item)
2373
+ return last_removed
2374
+ rmv = se_nikalo = mese_nikalo = remove
2375
+ # OVERRIDE self.pop
2376
+ old_pop = __old_list__.pop
2377
+ def pop(self, *items) -> Any|None:
2378
+ if self.length_is_final:
2379
+ return None
2380
+ if not len(self):
2381
+ return None
2382
+ if not len(items):
2383
+ return super().pop()
2384
+ items = flatten(__old_list__(items))
2385
+ last_popped: Any = self.old_pop(items[-1])
2386
+ for index in items:
2387
+ if index >= len(self):
2388
+ continue
2389
+ if index < 0:
2390
+ index = len(self) - abs(index)
2391
+ if index < 0 or index >= len(self):
2392
+ continue
2393
+ self.old_pop(index)
2394
+ return last_popped
2395
+ def contains(self, item) -> bool:
2396
+ return self.count(item) > 0
2397
+ has = includes = me_shamil = me_mojud = contains
2398
+ def index_of(self, x: Any) -> int:
2399
+ if not self.contains(x):
2400
+ return -1
2401
+ return self.index(x)
2402
+ find = find_index = index_of
2403
+ no_of = counts_of = __old_list__.count
2404
+ def print_map(self):
2405
+ print(self)
2406
+ def length(self):
2407
+ return len(self)
2408
+ class numlist(list[Number]):
2409
+ def __init__(self, *items: Number|list[Number]):
2410
+ super().__init__()
2411
+ self.push(*items)
2412
+ def __add__(self, other: Number|list[Number]) -> Self:
2413
+ if isinstance(other, list):
2414
+ lst: numlist = numlist()
2415
+ for a, b in zip(self, other):
2416
+ lst.append(a+b)
2417
+ return lst
2418
+ if isinstance(other, Number):
2419
+ self.append(other)
2420
+ return self
2421
+ def __radd__(self, other: Number|list[Number]) -> Self:
2422
+ if isinstance(other, list):
2423
+ lst: numlist = numlist()
2424
+ for a, b in zip(self, other):
2425
+ lst.append(b+a)
2426
+ return lst
2427
+ if isinstance(other, Number):
2428
+ self.insert(0, other)
2429
+ return self
2430
+ def __sub__(self, other: list[Number]) -> Self:
2431
+ lst: numlist = numlist()
2432
+ for a, b in zip(self, other):
2433
+ lst.append(a-b)
2434
+ return lst
2435
+ def __rsub__(self, other: list[Number]) -> Self:
2436
+ lst: numlist = numlist()
2437
+ for a, b in zip(self, other):
2438
+ lst.append(b-a)
2439
+ return lst
2440
+ def __mul__(self, other: list[Number]) -> Self:
2441
+ lst: numlist = numlist()
2442
+ for a, b in zip(self, other):
2443
+ lst.append(a*b)
2444
+ return lst
2445
+ def __truediv__(self, other: list[Number]) -> Self:
2446
+ lst: numlist = numlist()
2447
+ for a, b in zip(self, other):
2448
+ if b == 0:
2449
+ b = 1
2450
+ lst.append(a/b)
2451
+ return lst
2452
+ def __pos__(self) -> Self:
2453
+ return numlist(+x for x in self)
2454
+ def __neg__(self) -> Self:
2455
+ return numlist(-x for x in self)
2456
+ def __abs__(self) -> Self:
2457
+ return numlist(abs(x) for x in self)
2458
+ def __pow__(self, other: list[Number]) -> Self:
2459
+ lst: numlist = numlist()
2460
+ for a, b in zip(self, other):
2461
+ if b == 0:
2462
+ b = 1
2463
+ lst.append(a ** b)
2464
+ return lst
2465
+ def __gt__(self, other: list[Number]) -> bool:
2466
+ return all(a > b for a, b in zip(self, other))
2467
+ def __lt__(self, other: list[Number]) -> bool:
2468
+ return all(a < b for a, b in zip(self, other))
2469
+ def __ge__(self, other: list[Number]) -> bool:
2470
+ return all(a >= b for a, b in zip(self, other))
2471
+ def __le__(self, other: list[Number]) -> bool:
2472
+ return all(a <= b for a, b in zip(self, other))
2473
+ def __eq__(self, other: list[Number]) -> bool:
2474
+ return all(a == b for a, b in zip(self, other))
2475
+ def __ne__(self, other: list[Number]) -> bool:
2476
+ return not all(a == b for a, b in zip(self, other))
2477
+ def __str__(self) -> str:
2478
+ return f"numlist([{', '.join(map(str, self))}])"
2479
+ def __repr__(self) -> str:
2480
+ return f"numlist([{', '.join(map(repr, self))}])"
2481
+ def sum(self) -> Number:
2482
+ if not len(self):
2483
+ return 0
2484
+ return sum(self)
2485
+ def difference(self) -> Number:
2486
+ if not len(self):
2487
+ return 0
2488
+ diff: Number = self[0]
2489
+ for i, item in old_enumerate(self):
2490
+ if i == 0:
2491
+ continue
2492
+ # since we've already taken care of the first item
2493
+ # we don't that
2494
+ if item > 1e9:
2495
+ item = 1e9
2496
+ if item < 1e-9:
2497
+ item = 1e-9
2498
+ diff -= item
2499
+ return diff
2500
+ diff = difference
2501
+ def product(self) -> Number:
2502
+ if not len(self):
2503
+ return 0
2504
+ prd: Number = self[0]
2505
+ for i, item in old_enumerate(self):
2506
+ if i == 0:
2507
+ continue
2508
+ # since we've already taken care of the first item
2509
+ # we don't that
2510
+ if item > 1e9:
2511
+ item = 1e9
2512
+ if item < 1e-9:
2513
+ item = 1e-9
2514
+ prd *= item
2515
+ return prd
2516
+ prd = product
2517
+ def quotient(self) -> Number:
2518
+ if not len(self):
2519
+ return 0
2520
+ quo: Number = self[0]
2521
+ for i, item in old_enumerate(self):
2522
+ if i == 0:
2523
+ continue
2524
+ # since we've already taken care of the first item
2525
+ # we don't that
2526
+ if item == 0:
2527
+ item = 1
2528
+ if item > 1e9:
2529
+ item = 1e9
2530
+ if item < 1e-9:
2531
+ item = 1e-9
2532
+ quo /= item
2533
+ return quo
2534
+ quo = quotient
2535
+ def max(self) -> Number:
2536
+ if not len(self):
2537
+ return 0
2538
+ return max(self)
2539
+ def min(self) -> Number:
2540
+ if not len(self):
2541
+ return 0
2542
+ return min(self)
2543
+ def combine(self, *args: list[Number]) -> Self:
2544
+ if not args:
2545
+ return self
2546
+ for arg in args:
2547
+ if not isinstance(arg, (Number, list)):
2548
+ continue
2549
+ if (isinstance(arg, list) and not all(isinstance(item, Number) for item in arg)):
2550
+ # if it's neither of the supported types
2551
+ # don't push anything
2552
+ continue
2553
+ if isinstance(arg, tuple):
2554
+ arg = list(arg)
2555
+ # a tuple?
2556
+ # no thanks,
2557
+ # we need a list
2558
+ if isinstance(arg, list):
2559
+ self.extend(arg)
2560
+ else:
2561
+ self.append(arg)
2562
+ return self
2563
+ add = push = me_dalo = combine
2564
+ def push_at(self, i: int, *items) -> Self:
2565
+ if not len(items) or not all(isinstance(item, Number) for item in items):
2566
+ return self
2567
+ if not isinstance(i, int):
2568
+ i = len(self)
2569
+ if i < 0:
2570
+ i = 0
2571
+ elif i > len(self):
2572
+ i = len(self)
2573
+ items = flatten(list(items))
2574
+ x = self[:i] + list(items) + self[i+len(items)-1:]
2575
+ updated_list: numlist = numlist(x)
2576
+ self.clear()
2577
+ self.extend(updated_list)
2578
+ return self
2579
+ def push_start(self, *items) -> Self:
2580
+ self.push_at(0, *items)
2581
+ return self
2582
+ unshift = push_start
2583
+ def shift(self) -> Number:
2584
+ if len(self) == 0:
2585
+ return 0
2586
+ return self.pop(0)
2587
+ # OVERRIDE self.remove
2588
+ old_remove = list[Number].remove
2589
+ def remove(self, *items: list[Number]) -> Number:
2590
+ if not len(self) or not all(isinstance(item, (Number, list)) for item in items if item is not None):
2591
+ return 0
2592
+ if not len(items):
2593
+ return super().pop()
2594
+ items = flatten(list(items))
2595
+ last_removed: Number = items[-1]
2596
+ for item in items:
2597
+ if not self.contains(item):
2598
+ continue
2599
+ self.old_remove(item)
2600
+ return last_removed
2601
+ rmv = se_nikalo = remove
2602
+ # OVERRIDE self.pop
2603
+ old_pop = list[Number].pop
2604
+ def pop(self, *items: list[Number]) -> Number:
2605
+ if not len(self) or not all(isinstance(item, (Number, list)) for item in items if item is not None):
2606
+ return 0
2607
+ if not len(items):
2608
+ return super().pop()
2609
+ items = flatten(list(items))
2610
+ last_popped: Number = self.old_pop(items[-1])
2611
+ for index in items:
2612
+ if index >= len(self):
2613
+ continue
2614
+ if index < 0:
2615
+ index = len(self) - abs(index)
2616
+ if index < 0 or index >= len(self):
2617
+ continue
2618
+ self.old_pop(index)
2619
+ return last_popped
2620
+ #def pop_at
2621
+ def contains(self, item) -> bool:
2622
+ return self.count(item) > 0
2623
+ has = includes = me_mojud = contains
2624
+ def index_of(self, x: Number) -> int:
2625
+ if not isinstance(x, Number) or not self.contains(x):
2626
+ return -1
2627
+ return self.index(x)
2628
+ find = find_index = index_of
2629
+ no_of = counts_of = list[Number].count
2630
+ """
2631
+ nlist: numlist = numlist([2, 0, 5])
2632
+ print(nlist.pop(0, -2))
2633
+ print(nlist.quo())
2634
+ print(nlist.find(1))
2635
+ print(nlist)
2636
+ """
2637
+ num_list = numlist
2638
+ class intlist(list[int]):
2639
+ def __init__(self, *items: int):
2640
+ super().__init__(items)
2641
+ def __add__(self, other: list[int]) -> Self:
2642
+ lst: intlist = intlist()
2643
+ for a, b in zip(self, other):
2644
+ lst.append(Int(a)+Int(b))
2645
+ return lst
2646
+ def __radd__(self, other: list[int]) -> Self:
2647
+ lst: intlist = intlist()
2648
+ for a, b in zip(self, other):
2649
+ lst.append(Int(b)+Int(a))
2650
+ return lst
2651
+ def __sub__(self, other: list[int]) -> Self:
2652
+ lst: intlist = intlist()
2653
+ for a, b in zip(self, other):
2654
+ lst.append(Int(a)-Int(b))
2655
+ return lst
2656
+ def __rsub__(self, other: list[int]) -> Self:
2657
+ lst: intlist = intlist()
2658
+ for a, b in zip(self, other):
2659
+ lst.append(Int(b)-Int(a))
2660
+ return lst
2661
+ def __mul__(self, other: list[int]) -> Self:
2662
+ lst: intlist = intlist()
2663
+ for a, b in zip(self, other):
2664
+ lst.append(Int(a)*Int(b))
2665
+ return lst
2666
+ def __truediv__(self, other: list[int]) -> Self:
2667
+ lst: intlist = intlist()
2668
+ for a, b in zip(self, other):
2669
+ if b == 0:
2670
+ b = 1
2671
+ lst.append(Int(a)/Int(b))
2672
+ return lst
2673
+ def __pos__(self) -> Self:
2674
+ return intlist(Int(+x) for x in self)
2675
+ def __neg__(self) -> Self:
2676
+ return intlist(Int(-x) for x in self)
2677
+ def __abs__(self) -> Self:
2678
+ return intlist(Int(abs(x)) for x in self)
2679
+ def __pow__(self, other: list[int]) -> Self:
2680
+ lst: intlist = intlist()
2681
+ for a, b in zip(self, other):
2682
+ if b == 0:
2683
+ b = 1
2684
+ lst.append(Int(a) ** Int(b))
2685
+ return lst
2686
+ def __gt__(self, other: list[int]) -> bool:
2687
+ return all(Int(a) > Int(b) for a, b in zip(self, other))
2688
+ def __lt__(self, other: list[int]) -> bool:
2689
+ return all(Int(a) < Int(b) for a, b in zip(self, other))
2690
+ def __ge__(self, other: list[int]) -> bool:
2691
+ return all(Int(a) >= Int(b) for a, b in zip(self, other))
2692
+ def __le__(self, other: list[int]) -> bool:
2693
+ return all(Int(a) <= Int(b) for a, b in zip(self, other))
2694
+ def __eq__(self, other: list[int]) -> bool:
2695
+ return all(Int(a) == Int(b) for a, b in zip(self, other))
2696
+ def __ne__(self, other: list[int]) -> bool:
2697
+ return not all(Int(a) == Int(b) for a, b in zip(self, other))
2698
+ def __str__(self) -> str:
2699
+ return f"intlist([{', '.join(map(str, self))}])"
2700
+ def __repr__(self) -> str:
2701
+ return f"intlist([{', '.join(map(repr, self))}])"
2702
+ int_list = intlist
2703
+ class fltlist(list[float]):
2704
+ def __init__(self, *items: int):
2705
+ super().__init__(items)
2706
+ def __add__(self, other: list[float]) -> Self:
2707
+ lst: fltlist = fltlist()
2708
+ for a, b in zip(self, other):
2709
+ lst.append(Flt(a)+Flt(b))
2710
+ return lst
2711
+ def __radd__(self, other: list[float]) -> Self:
2712
+ lst: fltlist = fltlist()
2713
+ for a, b in zip(self, other):
2714
+ lst.append(Flt(b)+Flt(a))
2715
+ return lst
2716
+ def __sub__(self, other: list[float]) -> Self:
2717
+ lst: fltlist = fltlist()
2718
+ for a, b in zip(self, other):
2719
+ lst.append(Flt(a)-Flt(b))
2720
+ return lst
2721
+ def __rsub__(self, other: list[float]) -> Self:
2722
+ lst: fltlist = fltlist()
2723
+ for a, b in zip(self, other):
2724
+ lst.append(Flt(b)-Flt(a))
2725
+ return lst
2726
+ def __mul__(self, other: list[float]) -> Self:
2727
+ lst: fltlist = fltlist()
2728
+ for a, b in zip(self, other):
2729
+ lst.append(Flt(a)*Flt(b))
2730
+ return lst
2731
+ def __truediv__(self, other: list[float]) -> Self:
2732
+ lst: fltlist = fltlist()
2733
+ for a, b in zip(self, other):
2734
+ if b == 0:
2735
+ b = 1
2736
+ lst.append(Flt(a)/Flt(b))
2737
+ return lst
2738
+ def __pos__(self) -> Self:
2739
+ return fltlist(Flt(+x) for x in self)
2740
+ def __neg__(self) -> Self:
2741
+ return fltlist(Flt(-x) for x in self)
2742
+ def __abs__(self) -> Self:
2743
+ return fltlist(Flt(abs(x)) for x in self)
2744
+ def __pow__(self, other: list[float]) -> Self:
2745
+ lst: fltlist = fltlist()
2746
+ for a, b in zip(self, other):
2747
+ if b == 0:
2748
+ b = 1
2749
+ lst.append(Flt(a) ** Flt(b))
2750
+ return lst
2751
+ def __gt__(self, other: list[float]) -> bool:
2752
+ return all(Flt(a) > Flt(b) for a, b in zip(self, other))
2753
+ def __lt__(self, other: list[float]) -> bool:
2754
+ return all(Flt(a) < Flt(b) for a, b in zip(self, other))
2755
+ def __ge__(self, other: list[float]) -> bool:
2756
+ return all(Flt(a) >= Flt(b) for a, b in zip(self, other))
2757
+ def __le__(self, other: list[float]) -> bool:
2758
+ return all(Flt(a) <= Flt(b) for a, b in zip(self, other))
2759
+ def __eq__(self, other: list[float]) -> bool:
2760
+ return all(Flt(a) == Flt(b) for a, b in zip(self, other))
2761
+ def __ne__(self, other: list[float]) -> bool:
2762
+ return not all(Flt(a) == Flt(b) for a, b in zip(self, other))
2763
+ def __str__(self) -> str:
2764
+ return f"fltlist([{', '.join(map(str, self))}])"
2765
+ def __repr__(self) -> str:
2766
+ return f"fltlist([{', '.join(map(repr, self))}])"
2767
+ flt_list = fltlist
2768
+ # preserve the sequence
2769
+ T: TypeVar = TypeVar('T')
2770
+ class Stack[T]:
2771
+ def __init__(self, *items: T):
2772
+ self.array: list[T] = []
2773
+ self.length: int = -1
2774
+ if len(items) != 0:
2775
+ for item in items:
2776
+ self.push(item)
2777
+ def push(self, item: T) -> Self:
2778
+ self.array.append(item)
2779
+ self.length += 1
2780
+ return self
2781
+ def pop(self) -> Optional[T]:
2782
+ if self.length == -1:
2783
+ return None
2784
+ popped: T = self.array[self.length]
2785
+ self.length -= 1
2786
+ return popped
2787
+ def top(self) -> Optional[T]:
2788
+ if self.length == -1:
2789
+ return None
2790
+ return self.array[self.length]
2791
+ def len(self) -> int:
2792
+ return self.length + 1
2793
+ def size(self) -> int:
2794
+ return self.len()
2795
+ def __len__(self) -> int:
2796
+ return self.len()
2797
+ def __str__(self) -> str:
2798
+ return str(self.array)
2799
+ def is_valid_regex(text: str) -> bool:
2800
+ if not isinstance(text, str):
2801
+ return False
2802
+ try:
2803
+ re.compile(text)
2804
+ return True
2805
+ except re.error:
2806
+ return False
2807
+ is_valid_re = he_valid_regex = he_valid_re = is_valid_regex
2808
+ def escape_if_not_valid_regex(text: str) -> str:
2809
+ if not isinstance(text, str):
2810
+ return ""
2811
+ escaped_text: str = re.escape(
2812
+ text
2813
+ )
2814
+ if not is_valid_regex(text):
2815
+ return escaped_text
2816
+ return text
2817
+ escape_if_not_valid_re = escape_if_not_valid_regex
2818
+ floor_get = floor_key = near_key = close_get = near_get
2819
+ class obj(dict):
2820
+ def __init__(self, *args, **kwargs):
2821
+ super().__init__(*args, **kwargs)
2822
+ self._convert_nested_dicts(self)
2823
+ def _convert_nested_dicts(self, object):
2824
+ if isinstance(object, dict):
2825
+ for k, v in object.items():
2826
+ if isinstance(v, dict):
2827
+ object[k] = obj(v)
2828
+ elif isinstance(v, (list, tuple)):
2829
+ object[k] = self._convert_nested_collections(v)
2830
+ elif isinstance(object, (list, tuple)):
2831
+ return self._convert_nested_collections(object)
2832
+ return object
2833
+ def _convert_nested_collections(self, collection):
2834
+ converted_collection = []
2835
+ for item in collection:
2836
+ if isinstance(item, dict):
2837
+ converted_collection.append(obj(item))
2838
+ elif isinstance(item, (list, tuple)):
2839
+ converted_collection.append(self._convert_nested_collections(item))
2840
+ else:
2841
+ converted_collection.append(item)
2842
+ return type(collection)(converted_collection)
2843
+ floor_get = floor_key = near_key = close_get = near_get = lambda self, k, default=None: globals().get("floor_get", None)(self, k, default) if callable(globals().get("floor_get", None)) else None
2844
+ def __call__(self, key, default = None, *args, **kwargs):
2845
+ return safe_get(
2846
+ self,
2847
+ path=key,
2848
+ default=default,
2849
+ *args,
2850
+ **kwargs
2851
+ )
2852
+ def __getitem__(self, key) -> Any:
2853
+ default = None
2854
+ if isinstance(key, (list, tuple, set))\
2855
+ and len(key) >= 2:
2856
+ key, default = key[0], key[1]
2857
+ if not all(
2858
+ isinstance(
2859
+ k,
2860
+ (str, int, float)
2861
+ )\
2862
+ for k in self.keys()
2863
+ ):
2864
+ return default
2865
+ if not isinstance(
2866
+ key,
2867
+ (str, int, float)
2868
+ ):
2869
+ return default
2870
+ key_lower = key.lower()\
2871
+ if isinstance(key, str)\
2872
+ else int(key)
2873
+ d_lower : dict = {
2874
+ (k.lower()\
2875
+ if type(k) == str\
2876
+ else int(k))\
2877
+ : v\
2878
+ for k, v\
2879
+ in self.items()
2880
+ }
2881
+ try:
2882
+ if isinstance(key_lower, str):
2883
+ if not any(
2884
+ k.startswith(key_lower)\
2885
+ for k in d_lower\
2886
+ if isinstance(k, str)
2887
+ ):
2888
+ return default
2889
+ for k in d_lower:
2890
+ if isinstance(k, str)\
2891
+ and k.startswith(key_lower):
2892
+ return d_lower[k]
2893
+ elif key_lower not in d_lower:
2894
+ return default
2895
+ return d_lower[key_lower]
2896
+ except Exception as e:
2897
+ print(e)
2898
+ if key not in self:
2899
+ return default
2900
+ return super().__getitem__(key)
2901
+ ka = ki = ke = mese = __getattr__ = __call__
2902
+ def __setattr__(self, key, value) -> None:
2903
+ if isinstance(value, dict):
2904
+ self[key] = obj(value)
2905
+ elif isinstance(value, (list, tuple)):
2906
+ self[key] = self._convert_nested_collections(
2907
+ value
2908
+ )
2909
+ else:
2910
+ self[key] = value
2911
+ def __setitem__(self, key, value) -> None:
2912
+ if isinstance(value, dict):
2913
+ super().__setitem__(
2914
+ key,
2915
+ obj(value)
2916
+ )
2917
+ elif isinstance(value, (list, tuple)):
2918
+ super().__setitem__(
2919
+ key,
2920
+ self.\
2921
+ _convert_nested_collections(
2922
+ value
2923
+ )
2924
+ )
2925
+ else:
2926
+ super().__setitem__(
2927
+ key,
2928
+ value
2929
+ )
2930
+ def keys(self) -> list[Union[str, int, float]]:
2931
+ return list(
2932
+ super()\
2933
+ .keys()
2934
+ )
2935
+ def values(self) -> list[Any]:
2936
+ return list(
2937
+ super()\
2938
+ .values()
2939
+ )
2940
+ def entries(self) -> list[list]:
2941
+ return list(
2942
+ super()\
2943
+ .items()
2944
+ )
2945
+ # allows obj($x=$valueForX, $y=$valueForY)
2946
+ o = Obj = obj
2947
+ # for older dictionaries
2948
+ def keys(dictionary: dict) -> list:
2949
+ if not isinstance(dictionary, dict):
2950
+ return []
2951
+ return list(
2952
+ dictionary.keys()
2953
+ )
2954
+ def values(dictionary: dict) -> list:
2955
+ if not isinstance(dictionary, dict):
2956
+ return []
2957
+ return list(
2958
+ dictionary.values()
2959
+ )
2960
+ def entries(dictionary: dict) -> list:
2961
+ if not isinstance(dictionary, dict):
2962
+ return []
2963
+ return list(
2964
+ dictionary.items()
2965
+ )
2966
+ get_keys = keys_of = keys
2967
+ get_values = values_of = values
2968
+ get_entries = entries_of = entries
2969
+ def remove_duplicates(lst: list) -> list:
2970
+ if not lst or not isinstance(lst, list):
2971
+ return []
2972
+ return list(dict.fromkeys(lst).keys())
2973
+ def swap_keys(_obj: dict[Any, Any]) -> dict[Any, Any]:
2974
+ if not isinstance(_obj, Iterable):
2975
+ return {}
2976
+ return {v: k for k, v in _obj.items()}
2977
+ def Count(itrbl: Iterable) -> dict[int, Any]:
2978
+ if not isinstance(itrbl, Iterable):
2979
+ return {}
2980
+ counted: dict[int, Any] = {}
2981
+ for key in itrbl:
2982
+ counted[key] = counted.get(key, 0) + 1
2983
+ counted = swap_keys(counted)
2984
+ return counted
2985
+ count_occur = Count
2986
+ # ^DIFFERENT FROM collections.count
2987
+ def get_local_declarations() -> obj:
2988
+ """
2989
+ @return
2990
+ <dict>
2991
+ ::a dictionary holding all the local variables, (sub)classes (of classes), and the functions of the local scope of a class/function
2992
+ """
2993
+ [variables, classes, functions] = [{}, {}, {}]
2994
+ frame = currentframe().f_back
2995
+ for name, _obj in frame.f_locals.items():
2996
+ # Exclude built-in names and imported modules
2997
+ if not name.startswith('__'):
2998
+ if isfunction(_obj):
2999
+ functions[name] = _obj
3000
+ elif isclass(_obj):
3001
+ classes[name] = _obj
3002
+ # For variables, we can assume anything else that's not a function or class
3003
+ # and is user-defined in this module is a variable.
3004
+ # This is a simplification; more robust checks might be needed for complex cases.
3005
+ elif not ismodule(_obj): # Exclude imported modules
3006
+ variables[name] = _obj
3007
+ return o(variables=variables, classes=classes, functions=functions)
3008
+ def get_global_declarations() -> obj:
3009
+ """
3010
+ @return
3011
+ <dict>
3012
+ ::a dictionary holding all the local variables, (sub)classes (of classes), and the functions of the local scope of a class/function
3013
+ """
3014
+ [variables, classes, functions] = [{}, {}, {}]
3015
+ for name, _obj in globals().items():
3016
+ # Exclude built-in names and imported modules
3017
+ if not name.startswith('__') and getmodule(_obj) is sys.modules[__name__]:
3018
+ if isfunction(_obj):
3019
+ functions[name] = _obj
3020
+ elif isclass(_obj):
3021
+ classes[name] = _obj
3022
+ # For variables, we can assume anything else that's not a function or class
3023
+ # and is user-defined in this module is a variable.
3024
+ # This is a simplification; more robust checks might be needed for complex cases.
3025
+ elif not ismodule(_obj): # Exclude imported modules
3026
+ variables[name] = _obj
3027
+ return o(variables=variables, classes=classes, functions=functions)
3028
+ Yes = Ha = Han = true = True
3029
+ No = Na = Nahi = false = False
3030
+ none: NoneType = None
3031
+ null = none
3032
+ sort = lambda x: sorted(x) if isinstance(x, Iterable) else []
3033
+ reverse_sort = sort_reverse = lambda x: sorted(x, reverse=True) if isinstance(x, Iterable) else []
3034
+ def sort_mutate(x) -> str | list | tuple:
3035
+ if type(x) not in (str, list, tuple):
3036
+ return x
3037
+ was_a_string: bool = False
3038
+ was_a_tuple: bool = False
3039
+ if isinstance(x, str):
3040
+ x = list(x)
3041
+ was_a_string = True
3042
+ elif isinstance(x, tuple):
3043
+ x = list(x)
3044
+ was_a_tuple = True
3045
+ x.sort()
3046
+ # ^ return None after sorting
3047
+ # let's forcibly return the final x
3048
+ if was_a_string:
3049
+ x = "".join(str(item) for item in x)
3050
+ elif was_a_tuple:
3051
+ x = tuple(x)
3052
+ return x
3053
+ mutate_sort = inplace_sort = sort_inplace = sort_mutate
3054
+ def sort_reverse_mutate(x) -> str | list | tuple:
3055
+ if type(x) not in (str, list, tuple):
3056
+ return x
3057
+ was_a_string: bool = False
3058
+ was_a_tuple: bool = False
3059
+ if isinstance(x, str):
3060
+ x = list(x)
3061
+ was_a_string = True
3062
+ elif isinstance(x, tuple):
3063
+ x = list(x)
3064
+ was_a_tuple = True
3065
+ x.sort(reverse=True)
3066
+ # ^ return None after reverse-sorting
3067
+ # let's forcibly return the final x
3068
+ if was_a_string:
3069
+ x = "".join(str(item) for item in x)
3070
+ elif was_a_tuple:
3071
+ x = tuple(x)
3072
+ return x
3073
+ mutate_sort_reverse = mutate_reverse_sort = sort_mutate_reverse = reverse_mutate_sort = reverse_sort_mutate = inplace_sort_reverse = inplace_reverse_sort = sort_inplace_reverse = reverse_inplace_sort = reverse_sort_inplace = sort_reverse_mutate
3074
+ def reverse(x: Iterable) -> str | list | tuple | dict:
3075
+ if type(x) not in (str, list, tuple, dict):
3076
+ return x
3077
+ if isinstance(x, dict):
3078
+ reversed_kvs: dict = {v: k for k, v in x.items() if type(v) in (str, int, float)}
3079
+ return reversed_kvs
3080
+ return x[::-1]
3081
+ def shuffle(x: Iterable) -> str | list | tuple:
3082
+ if type(x) not in (str, list, tuple):
3083
+ return x
3084
+ was_a_string: bool = False
3085
+ was_a_tuple: bool = False
3086
+ if isinstance(x, str):
3087
+ x = list(x)
3088
+ was_a_string = True
3089
+ elif isinstance(x, tuple):
3090
+ x = list(x)
3091
+ was_a_tuple = True
3092
+ final_x: list = x.copy() # to not mutate the original x
3093
+ random.shuffle(final_x)
3094
+ # ^ return None after shuffling
3095
+ # let's forcibly return the final x
3096
+ if was_a_string:
3097
+ final_x = "".join(str(item) for item in final_x)
3098
+ elif was_a_tuple:
3099
+ final_x = tuple(final_x)
3100
+ return final_x
3101
+ shuffled = shuffle
3102
+ def shuffle_mutate(x: Iterable) -> str | list | tuple:
3103
+ if type(x) not in (str, list, tuple):
3104
+ return x
3105
+ was_a_string: bool = False
3106
+ was_a_tuple: bool = False
3107
+ if isinstance(x, str):
3108
+ x = list(x)
3109
+ was_a_string = True
3110
+ elif isinstance(x, tuple):
3111
+ x = list(x)
3112
+ was_a_tuple = True
3113
+ random.shuffle(x)
3114
+ # ^ return None after shuffling
3115
+ # let's forcibly return the final x
3116
+ final_x: list = x
3117
+ if was_a_string:
3118
+ final_x = "".join(str(item) for item in final_x)
3119
+ elif was_a_tuple:
3120
+ final_x = tuple(final_x)
3121
+ return final_x
3122
+ mutate_shuffle = inplace_shuffle = shuffle_inplace = shuffle_mutate
3123
+ _filter = lambda arr, condition: filter(condition, arr)
3124
+ # test this
3125
+ def rng_old(x: str|list|tuple|Number, y: str|list|tuple|Number|None = None, step: Number = 1, inclusive: bool = True, **kwargs) -> list[int] | list[float] | list[str]:
3126
+ if x is None or not isinstance(x, (str, list, tuple, Number)) or not isinstance(y, (str, list, tuple, Number, NoneType)) or step is None or not isinstance(step, Number):
3127
+ return []
3128
+ x_is_a_parsable_char: bool = False
3129
+ y_is_a_parsable_char: bool = False
3130
+ if isinstance(x, str) and len(str(x).strip()) == 1 and 0 <= ord(x) <= 127:
3131
+ if not y:
3132
+ y = ord(x[0])
3133
+ x = 97 if x[0].lower() == x[0] else 65
3134
+ else:
3135
+ x = ord(x[0])
3136
+ x_is_a_parsable_char = True
3137
+ if isinstance(y, str) and len(str(y).strip()) != 0 and 0 <= ord(y) <= 127:
3138
+ y = ord(y[0])
3139
+ y_is_a_parsable_char = True
3140
+ char_mode: bool = x_is_a_parsable_char and y_is_a_parsable_char
3141
+ if len(kwargs):
3142
+ if "s" in kwargs:
3143
+ step = kwargs.get("s", 1)
3144
+ elif "step" in kwargs:
3145
+ step = kwargs.get("step", 1)
3146
+ if "incl" in kwargs:
3147
+ inclusive = kwargs.get("incl", inclusive)
3148
+ elif "shamil" in kwargs:
3149
+ inclusive = kwargs.get("shamil", inclusive)
3150
+ elif "shamil_akhri" in kwargs:
3151
+ inclusive = kwargs.get("shamil_akhri", inclusive)
3152
+ elif "shaamil" in kwargs:
3153
+ inclusive = kwargs.get("shaamil", inclusive)
3154
+ elif "shaamil_akhri" in kwargs:
3155
+ inclusive = kwargs.get("shaamil_akhri", inclusive)
3156
+ if step <= 0:
3157
+ step = 1
3158
+ if (isinstance(y, Number) and step >= y):
3159
+ step = 1
3160
+ if isinstance(x, (str, list, tuple)) and step >= len(x):
3161
+ step = 1
3162
+ if isinstance(y, (str, list, tuple)) and step >= len(y):
3163
+ step = 1
3164
+ if isinstance(step, Number) and step % 1 == 0:
3165
+ step = int(step)
3166
+ exclusive = not inclusive
3167
+ return_list: list[int] | list[float] = []
3168
+ if y is None:
3169
+ inclusive = False
3170
+ if not isinstance(x, Number) and isinstance(step, (int, float)):
3171
+ if char_mode:
3172
+ step = int(step)
3173
+ i: int = 0
3174
+ while i < len(x):
3175
+ return_list.append(i)
3176
+ i += step
3177
+ if exclusive and len(return_list):
3178
+ return_list = return_list[:-1]
3179
+ return return_list
3180
+ x = abs(x)
3181
+ if isinstance(x, int) and isinstance(step, (int, float)):
3182
+ i: int = 0
3183
+ while i < x:
3184
+ return_list.append(i)
3185
+ i += step
3186
+ if isinstance(x, float):
3187
+ i: float = 0
3188
+ while i < x:
3189
+ return_list.append(i)
3190
+ i += step
3191
+ if inclusive and len(return_list):
3192
+ return_list.append(x)
3193
+ return return_list
3194
+ if (isinstance(x, int) and isinstance(step, (int, float))) and not isinstance(y, Number):
3195
+ if char_mode:
3196
+ step = int(step)
3197
+ y_length: int = len(y)
3198
+ if x < 0 or x >= y_length:
3199
+ return []
3200
+ while x < y_length:
3201
+ return_list.append(x)
3202
+ x += step
3203
+ if exclusive and len(return_list):
3204
+ return_list = return_list[:-1]
3205
+ return return_list
3206
+ elif isinstance(x, int) and isinstance(y, int) and isinstance(step, (int, float)):
3207
+ if char_mode:
3208
+ step = int(step)
3209
+ if x == y:
3210
+ return []
3211
+ if x > y:
3212
+ while x >= y:
3213
+ return_list.append(x)
3214
+ x -= step
3215
+ else:
3216
+ while x <= y:
3217
+ return_list.append(x)
3218
+ x += step
3219
+ elif isinstance(x, float) or isinstance(y, float):
3220
+ if x == y:
3221
+ return []
3222
+ if x > y:
3223
+ while x >= y:
3224
+ return_list.append(x)
3225
+ x -= step
3226
+ else:
3227
+ while x <= y:
3228
+ return_list.append(x)
3229
+ x += step
3230
+ if x_is_a_parsable_char or y_is_a_parsable_char:
3231
+ return_list = [chr(n) for n in return_list]
3232
+ if exclusive and len(return_list):
3233
+ return_list = return_list[:-1]
3234
+ return return_list
3235
+ def rng(
3236
+ x: Union[str, Iterable, Number],
3237
+ y: Union[str, Iterable, Number, None] = None,
3238
+ step: Number = 1,
3239
+ inclusive: int | bool = True,
3240
+ reverse: bool = False,
3241
+ **kwargs
3242
+ ) -> list[str | int | float]:
3243
+ step: int | float = kwargs.get("s", kwargs.get("step", step))
3244
+ incl_flags: list[str] = ["incl", "shamil", "shamil_akhri", "shaamil", "shaamil_akhri"]
3245
+ rev_flags: list[str] = ["reversed", "rev", "ulat", "ulta", "ulti", "ulte"]
3246
+ force_inclusive = isinstance(inclusive, int) and inclusive == 2
3247
+ for flag in incl_flags:
3248
+ if flag in kwargs:
3249
+ val = kwargs[flag]
3250
+ inclusive = isinstance(val, (int, bool)) and val in (1, 2, True)
3251
+ if val == 2:
3252
+ force_inclusive = True
3253
+ break
3254
+ for flag in rev_flags:
3255
+ if flag in kwargs:
3256
+ reverse = bool(kwargs[flag])
3257
+ break
3258
+ if not isinstance(step, Number) or isinstance(step, bool):
3259
+ step = 1
3260
+ try:
3261
+ step_val = float(step)
3262
+ except (ValueError, TypeError):
3263
+ step_val = 1.0
3264
+ if step_val <= 0:
3265
+ step_val = 1.0
3266
+ char_mode = False
3267
+ def get_char_ord(s: str) -> int:
3268
+ if not s:
3269
+ return 0
3270
+ stripped = s.strip()
3271
+ target = stripped[0] if stripped else s[0]
3272
+ return ord(target)
3273
+ if y is None:
3274
+ start_val = 0.0
3275
+ if isinstance(x, str) and len(x) > 0:
3276
+ char_mode = True
3277
+ start_val = 97.0 if x[0].islower() else 65.0
3278
+ end_val = float(get_char_ord(x))
3279
+ elif isinstance(x, Iterable) and not isinstance(x, str):
3280
+ end_val = float(len(x))
3281
+ elif isinstance(x, Number) and not isinstance(x, bool):
3282
+ try:
3283
+ end_val = float(x)
3284
+ except (ValueError, TypeError):
3285
+ return []
3286
+ else:
3287
+ return []
3288
+ if not char_mode and not force_inclusive:
3289
+ inclusive = False
3290
+ else:
3291
+ if isinstance(x, str) and len(x) > 0:
3292
+ char_mode = True
3293
+ start_val = float(get_char_ord(x))
3294
+ elif isinstance(x, Number) and not isinstance(x, bool):
3295
+ start_val = float(x)
3296
+ else:
3297
+ start_val = 0.0
3298
+ if isinstance(y, str) and len(y) > 0:
3299
+ char_mode = True
3300
+ end_val = float(get_char_ord(y))
3301
+ elif isinstance(y, Iterable) and not isinstance(y, str):
3302
+ end_val = float(len(y))
3303
+ if not force_inclusive: inclusive = False
3304
+ if start_val < 0 or start_val >= end_val:
3305
+ return []
3306
+ elif isinstance(y, Number) and not isinstance(y, bool):
3307
+ end_val = float(y)
3308
+ else:
3309
+ return []
3310
+ if force_inclusive:
3311
+ inclusive = True
3312
+ if not (math.isfinite(start_val) and math.isfinite(end_val) and math.isfinite(step_val)):
3313
+ return []
3314
+ result_floats = []
3315
+ if start_val <= end_val:
3316
+ current = start_val
3317
+ while current < end_val or (inclusive and math.isclose(current, end_val, rel_tol=1e-12, abs_tol=1e-12)):
3318
+ result_floats.append(current)
3319
+ current += step_val
3320
+ if current == start_val:
3321
+ break
3322
+ else:
3323
+ current = start_val
3324
+ while current > end_val or (inclusive and math.isclose(current, end_val, rel_tol=1e-12, abs_tol=1e-12)):
3325
+ result_floats.append(current)
3326
+ current -= step_val
3327
+ if current == start_val:
3328
+ break
3329
+ if not result_floats:
3330
+ return []
3331
+ if reverse:
3332
+ result_floats = result_floats[::-1]
3333
+ if char_mode:
3334
+ return [chr(int(round(n))) for n in result_floats if 0 <= int(round(n)) <= 0x10FFFF]
3335
+ result_floats = [round(n, 1) for n in result_floats]
3336
+ if all(n.is_integer() for n in result_floats):
3337
+ return [int(round(n)) for n in result_floats]
3338
+ return result_floats
3339
+ def f(*args) -> str:
3340
+ formatted: str = ""
3341
+ curframe: Optional[FrameType] = currentframe()
3342
+ frames: list[Optional[FrameType]] = []
3343
+ caller_locals: dict[str, Any] = {}
3344
+ while curframe is not None:
3345
+ frames.append(curframe)
3346
+ curframe = curframe.f_back
3347
+ # keep retrieving until you hit the oldest ancestor
3348
+ frames = reversed(frames)
3349
+ # reverse the frames to prioritize the closest local scope first
3350
+ for scope in frames:
3351
+ caller_locals.update(scope.f_globals | scope.f_locals)
3352
+ blacklisted_keywords: list[str] = ['import', '__', 'open', 'exec', 'eval', 'del', 'lambda']
3353
+ blacklisted_functions: list[str] = ['system', 'popen', 'subprocess']
3354
+ blacklisted_items: list[str] = [*blacklisted_keywords, *blacklisted_functions]
3355
+ for arg in args:
3356
+ if isinstance(arg, bool):
3357
+ arg = "Yes" if arg == True else "No"
3358
+ try:
3359
+ ast.parse(f"f'{arg}'")
3360
+ arg_lower: str = arg.lower()
3361
+ for item in blacklisted_items:
3362
+ if item in arg_lower:
3363
+ print(f"Forbidden keyword/function in input: '{item}'")
3364
+ continue
3365
+ # Evaluate the expression
3366
+ arg = re.sub(r"(?<!\\)[\$\{]+([^\s\{\}\(\)\$]+(?:\(([\w\.\-]+(,\s*)?)*\))?)(\}(?!#{4}))?", r"{\1}", arg)
3367
+ # (?<!\\) means recognize escapes, and only match if the dollar '$', and opening_brace '{'' are not precededed by a forward slash '\' (which is the standard pattern for regex escapes)
3368
+ evaluation: str = eval(f"f'{arg}'", {"__builtins__": {}}, caller_locals)
3369
+ WHITESPACE_CHAR = " "
3370
+ # for readability, there should be a whitespace character after each argument, except the last one (though, for the last one, it does not really matter, as it usually goes unnoticed)
3371
+ formatted += evaluation + WHITESPACE_CHAR
3372
+ except Exception as e:
3373
+ ...
3374
+ formatted = formatted.rstrip()
3375
+ return formatted
3376
+ def printf(*args, **kwargs) -> None:
3377
+ print(f(*args), **kwargs)
3378
+ kaho = printf
3379
+ def khali(x: Iterable) -> bool:
3380
+ if x is None:
3381
+ return True
3382
+ if not isinstance(x, Iterable):
3383
+ return not x
3384
+ if isinstance(x, str):
3385
+ return not x.strip()
3386
+ return len(x) == 0
3387
+ is_empty = isempty = khali_he = khali
3388
+ # type checks
3389
+ is_none = isnone = is_null = isnull = lambda x: x is None
3390
+ isnt_none = isntnone = non_none = nonnone = lambda x: not is_none(x)
3391
+ isstr = is_str = isstring = is_string = hestr = he_str = hestring = he_string = lambda x: isinstance(x, str)
3392
+ isnt_string = isntstring = isnt_str = isntstr = non_string = nonstring = non_str = nonstr = lambda x: not is_string(x)
3393
+ isint = is_int = isinteger = is_integer = heint = he_int = heinteger = he_integer = lambda x: isinstance(x, int) and not isinstance(x, bool)
3394
+ isnt_integer = isntinteger = isnt_int = isntint = non_integer = noninteger = non_int = nonint = lambda x: not is_integer(x)
3395
+
3396
+ def is_int_like(x: str) -> bool:
3397
+ if isinstance(x, bool):
3398
+ return True
3399
+ x = str(x)
3400
+ parsed: int = 0
3401
+ try:
3402
+ parsed = int(x)
3403
+ return True
3404
+ except ValueError:
3405
+ ...
3406
+ return False
3407
+ he_int_jesa = he_int_jesi = he_parsable_int = is_parsable_int = is_int_like
3408
+ isflt = is_flt = isfloat = is_float = isdbl = is_dbl = isdouble = is_double = heflt = he_flt = hefloat = he_float = lambda x: isinstance(x, float) and not isinstance(x, bool)
3409
+ isnt_float = isntfloat = isnt_float = isntfloat = non_float = nonfloat = non_flt = nonflt = lambda x: not is_float(x)
3410
+ def is_float_like(x: str) -> bool:
3411
+ x = str(x)
3412
+ parsed: float = 0.0
3413
+ try:
3414
+ parsed = float(x)
3415
+ return True
3416
+ except ValueError:
3417
+ ...
3418
+ return False
3419
+ he_flt_jesa = he_flt_jesi = he_parsable_flt = is_parsable_flt = is_flt_like = he_float_jesa = he_float_jesi = he_parsable_float = is_parsable_float = is_float_like = is_float_like
3420
+ isnr = is_nr = isnum = is_num = isnumber = is_number = henr = he_nr = henum = he_num = henumber = he_number = lambda x: isinstance(x, (int, float))
3421
+ is_boolean = isboolean = is_bool = isbool = hebool = he_bool = heboolean = he_boolean = hehaal = he_haal = lambda x: isinstance(x, bool)
3422
+ isnt_boolean = isntboolean = isnt_bool = isntbool = non_boolean = nonboolean = non_bool = nonbool = lambda x: not is_boolean(x)
3423
+ def is_bool_like(x: str) -> bool:
3424
+ x = str(x)
3425
+ parsed: bool = False
3426
+ if x == "True":
3427
+ parsed = True
3428
+ elif x == "False":
3429
+ parsed = False
3430
+ return parsed
3431
+ islist = is_list = helist = he_list = lambda x: isinstance(x, list)
3432
+ isnt_list = isntlist = lambda x: not is_list(x)
3433
+ is_stringlist = is_stringarr = is_strlist = is_strarr = isstringlist = isstringarr = isstrlist = isstrarr = lambda x: isinstance(x, (list[str], tuple[str, ...]))
3434
+ isnt_stringlist = isnt_stringarr = isnt_strlist = isnt_strarr = isntstringlist = isntstringarr = isntstrlist = isntstrarr = non_stringlist = non_stringarr = non_strlist = non_strarr = nonstringlist = nonstringarr = nonstrlist = nonstrarr = lambda x: not is_stringlist(x)
3435
+ is_integerlist = is_integerarr = is_intlist = is_intarr = isintegerlist = isintegerarr = isintlist = isintarr = lambda x: isinstance(x, (list[int], tuple[int, ...]))
3436
+ isnt_integerlist = isnt_integerarr = isnt_intlist = isnt_intarr = isntintegerlist = isntintegerarr = isntintlist = isntintarr = non_integerlist = non_integerarr = non_intlist = non_intarr = nonintegerlist = nonintegerarr = nonintlist = nonintarr = lambda x: not is_integerlist(x)
3437
+ is_floatlist = is_floatarr = is_fltlist = is_fltarr = isfloatlist = isfloatarr = isfltlist = isfltarr = lambda x: isinstance(x, (list[float], tuple[float, ...]))
3438
+ isnt_floatlist = isnt_floatarr = isnt_fltlist = isnt_fltarr = isntfloatlist = isntfloatarr = isntfltlist = isntfltarr = non_floatlist = non_floatarr = non_fltlist = non_fltarr = nonfloatlist = nonfloatarr = nonfltlist = nonfltarr = lambda x: not is_floatlist(x)
3439
+ is_booleanlist = is_booleanarr = is_boollist = is_boolarr = isbooleanlist = isbooleanarr = isboollist = isboolarr = lambda x: isinstance(x, (list[bool], tuple[bool, ...]))
3440
+ isnt_booleanlist = isnt_booleanarr = isnt_boollist = isnt_boolarr = isntbooleanlist = isntbooleanarr = isntboollist = isntboolarr = non_booleanlist = non_booleanarr = non_boollist = non_boolarr = nonbooleanlist = nonbooleanarr = nonboollist = nonboolarr = lambda x: not is_booleanlist(x)
3441
+ is_iterable = isiterable = lambda x: isinstance(x, Iterable)
3442
+ isnt_iterable = isntiterable = non_iterable = noniterable = lambda x: not is_iterable(x)
3443
+ istuple = is_tuple = hetuple = he_tuple = lambda x: isinstance(x, tuple)
3444
+ isset = is_set = heset = he_set = lambda x: isinstance(x, set)
3445
+ isdict = is_dict = isdictionary = is_dictionary = hedict = he_dict = hedictionary = he_dictionary = lambda x: isinstance(x, dict)
3446
+ is_callable = iscallable = is_function = isfunction = is_func = isfunc = lambda x: callable(x)
3447
+ isnt_callable = isntcallable = non_callable = noncallable = lambda x: not is_callable(x)
3448
+ def split(src: str, regex: str|NoneType = None, maxsplits: int = IntInfinity, flags: int = 0) -> list[str]:
3449
+ if not src or not isinstance(src, str) or not isinstance(regex, (str, NoneType)):
3450
+ # allow regex to be empty, as it sometimes can be
3451
+ return []
3452
+ if regex is None:
3453
+ # if the regex is None, split into words (hyphen, and quote preserved, for max reliability)
3454
+ regex = r"([^\-\w\"\']|(?<!\w)[\-\"\'](?!\w))"
3455
+ regex = str(regex)
3456
+ if not isinstance(maxsplits, int):
3457
+ maxsplits = IntInfinity
3458
+ if maxsplits <= 0:
3459
+ return [src]
3460
+ if not isinstance(flags, int):
3461
+ flags = 0
3462
+ try:
3463
+ regex = re.sub(r"(\?)(<\w+>)", r"\1P\2", regex)
3464
+ raw_list: list[str] = re.split(regex, src, maxsplit=maxsplits, flags=flags)
3465
+ result: list[str] = []
3466
+ for x in raw_list:
3467
+ if not x:
3468
+ continue
3469
+ result.append(x)
3470
+ return result
3471
+ except re.error as e:
3472
+ # fallback to original splitting
3473
+ # if regex splitting fails
3474
+ print(f"re.warning:\n * Bad regex split pattern. Falling back to the original `'string'.split`. *Reason*: {str(e).capitalize()}.")
3475
+ return [x for x in src.split(regex) if x]
3476
+ def joined_words(*args: tuple[Any]) -> str:
3477
+ """
3478
+ @param args
3479
+ :type tuple[Any]
3480
+ :description arguments to join in "x, y, aur z" format
3481
+ @return
3482
+ :type str <blankable, if len(args) == 0>
3483
+ :description the joined arguments (initially of type, Any)
3484
+ """
3485
+ result: list[str] = []
3486
+ for arg in args:
3487
+ if arg is None:
3488
+ continue
3489
+ if isinstance(arg, (list, tuple)):
3490
+ arg = joined_words(*arg)
3491
+ arg = re.sub(r"(?<=, )aur (?=.+$)", "", str(arg))
3492
+ if isinstance(arg, float):
3493
+ arg = round(arg, 1)
3494
+ if isinstance(arg, bool):
3495
+ arg = "Han" if arg else "Nahi"
3496
+ arg = str(arg)
3497
+ if ", " in arg:
3498
+ sub_args: list[str] = arg.split(", ")
3499
+ for sub_arg in sub_args:
3500
+ result.append(sub_arg)
3501
+ continue
3502
+ result.append(arg)
3503
+ if len(result) < 2:
3504
+ return ", ".join(result)
3505
+ last: str = str(result.pop())
3506
+ return ", ".join(result) + ", aur " + last
3507
+ jurewe = joined_words
3508
+ def split_into_words(s: str) -> list[str]:
3509
+ if not isinstance(s, str) or not s.strip(): return ""
3510
+ return re.findall(WORD_RE, s)
3511
+ find_words = findwords = to_words = towords = to_word_list = towordlist = pakro_words = pakrowords = pakro_alfaaz = pakroalfaaz = split_into_words
3512
+ def json_load(filename: str) -> dict | list:
3513
+ if not isinstance(filename, str) or not filename.strip():
3514
+ return {}
3515
+ filename = os.path.normpath(filename)
3516
+ if "." not in filename:
3517
+ filename += ".json"
3518
+ if not os.path.exists(filename):
3519
+ return {}
3520
+ contents: Any = {}
3521
+ try:
3522
+ with open(filename, mode="r") as file:
3523
+ contents = json.load(file)
3524
+ except Exception as e:
3525
+ print(e)
3526
+ # the loaded contents can be a list, too
3527
+ # not always a dictionary
3528
+ if isinstance(contents, dict) and "Obj" in globals():
3529
+ contents = Obj(contents)
3530
+ return contents
3531
+ load_json = loadjson = jsonload = json_load
3532
+ def replace(src: str, to_replace: str|dict|None = None, replacement: str|Callable = "", ignore_case: bool = False, case_insensitive: bool = False, count: int = IntInfinity) -> str:
3533
+ if not src or not isinstance(src, str) or not ((isinstance(to_replace, str)) or (isinstance(to_replace, dict) and not replacement) or isinstance(replacement, (str, Callable))):
3534
+ # allow empty replacement for removals
3535
+ return ""
3536
+ ignore_case = ignore_case or case_insensitive
3537
+ if not ignore_case or not isinstance(ignore_case, bool):
3538
+ ignore_case = False
3539
+ if not isinstance(count, int) or count < 0:
3540
+ count = IntInfinity
3541
+ if isinstance(to_replace, str):
3542
+ if not len(to_replace):
3543
+ return src
3544
+ if not re.search(r"[\(\)]", to_replace):
3545
+ to_replace = f"({to_replace})"
3546
+ to_replace = re.sub(r"(\?)(<\w+>)", r"\1P\2", to_replace)
3547
+ if isinstance(replacement, str):
3548
+ # if it's a string, rather than a callable---usually in the form of a lambda function
3549
+ if re.search(r"[\$\\][&0]", replacement):
3550
+ return src
3551
+ replacement = re.sub(r"\$\{?(\d+)(\}(?!#{4}))?", r"\\\1", replacement) # the function sees and uses 4 hashes (####) as an escape sequence for a replacement regex group's closing brace
3552
+ # achieve JavaScript-like numbered-group convention ^
3553
+ replacement = re.sub(r"\$\{?([A-Za-z]\w*)(\}(?!#{4}))?", r"\\g<\1>", replacement) # the function sees and uses 4 hashes (####) as an escape sequence for a replacement regex group's closing brace
3554
+ # achieve JavaScript-like named-group convention ^
3555
+ flags: int = re.MULTILINE
3556
+ if ignore_case:
3557
+ flags |= re.IGNORECASE
3558
+ result: str = ""
3559
+ if not replacement and isinstance(to_replace, dict):
3560
+ result = src
3561
+ # for now
3562
+ for key, value in to_replace.items():
3563
+ if not key.strip():
3564
+ continue
3565
+ result = replace(result, key, value)
3566
+ return result
3567
+ if not isinstance(to_replace, str):
3568
+ to_replace = ""
3569
+ try:
3570
+ result = re.sub(to_replace, replacement, src, flags=flags, count=count)
3571
+ except re.error as e:
3572
+ src_trunc: str = f"{src[:30]}... ..." if len(src) > 30 else src
3573
+ print(f"re.warning:\n * Bad regex, or replacement pattern '{to_replace}'. Returning the original source string '{src_trunc}' as-is. *Reason*: {str(e).capitalize()}.")
3574
+ result = src
3575
+ return result
3576
+ replacei = ireplace = replace_i = i_replace = functools.partial(replace, ignore_case=True)
3577
+ replaceone = replace_one = functools.partial(replace, count=1)
3578
+ replace_i_one = replace_one_i = replace_ione = replace_onei = replace_ins_first = replace_first_ins = replace_insfirst = functools.partial(replace, ignore_case=True, count=1)
3579
+ def find_matches(src: str, to_find: str) -> list[str]:
3580
+ if not src or not isinstance(src, str) or not to_find or not isinstance(to_find, str):
3581
+ return []
3582
+ to_find = re.sub(r"(\?)(<\w+>)", r"\1P\2", to_find)
3583
+ matches: list[str] = re.findall(to_find, src)
3584
+ return matches
3585
+ def find_matches_i(src: str, to_find: str) -> list[str]:
3586
+ if not src or not isinstance(src, str) or not to_find or not isinstance(to_find, str):
3587
+ return []
3588
+ to_find = re.sub(r"(\?)(<\w+>)", r"\1P\2", to_find)
3589
+ matches: list[str] = re.findall(to_find, src, re.IGNORECASE)
3590
+ return matches
3591
+ def find_matches_as_obj(src: str, to_find: str) -> obj[str, str]:
3592
+ if not src or not isinstance(src, str) or not to_find or not isinstance(to_find, str):
3593
+ return obj()
3594
+ to_find = re.sub(r"(\?)(<\w+>)", r"\1P\2", to_find)
3595
+ matches: obj[str, str] = obj()
3596
+ if matches_found := re.search(to_find, src):
3597
+ matches = matches_found.groupdict()
3598
+ return matches
3599
+ def find_matches_as_obj_i(src: str, to_find: str) -> obj[str, str]:
3600
+ if not src or not isinstance(src, str) or not to_find or not isinstance(to_find, str):
3601
+ return obj()
3602
+ to_find = re.sub(r"(\?)(<\w+>)", r"\1P\2", to_find)
3603
+ matches: obj[str, str] = obj()
3604
+ if matches_found := re.search(to_find, src, flags=re.IGNORECASE):
3605
+ matches = matches_found.groupdict()
3606
+ return matches
3607
+ def find_match(src: str, to_find: str) -> str:
3608
+ if not src or not isinstance(src, str) or not to_find or not isinstance(to_find, str):
3609
+ return ""
3610
+ to_find = re.sub(r"(\?)(<\w+>)", r"\1P\2", to_find)
3611
+ matches: list[str] = find_matches(src, to_find)
3612
+ if len(matches) == 0:
3613
+ return ""
3614
+ return matches[0]
3615
+ def find_match_i(src: str, to_find: str) -> str:
3616
+ if not src or not isinstance(src, str) or not to_find or not isinstance(to_find, str):
3617
+ return ""
3618
+ to_find = re.sub(r"(\?)(<\w+>)", r"\1P\2", to_find)
3619
+ matches: list[str] = find_matches_i(src, to_find)
3620
+ if len(matches) == 0 or not matches[0]:
3621
+ return ""
3622
+ return matches[0]
3623
+ def match(src: str, to_find: str) -> bool:
3624
+ if not src or not isinstance(src, str) or not to_find or not isinstance(to_find, str):
3625
+ return False
3626
+ to_find = re.sub(r"(\?)(<\w+>)", r"\1P\2", to_find)
3627
+ matches: list[str] = find_matches(src, to_find)
3628
+ if len(matches) == 0:
3629
+ return False
3630
+ return True
3631
+ def match_i(src: str, to_find: str) -> bool:
3632
+ if not src or not isinstance(src, str) or not to_find or not isinstance(to_find, str):
3633
+ return False
3634
+ to_find = re.sub(r"(\?)(<\w+>)", r"\1P\2", to_find)
3635
+ matches: list[str] = find_matches_i(src, to_find)
3636
+ if len(matches) == 0:
3637
+ return False
3638
+ return True
3639
+ hasmatch = has_match = match
3640
+ hasmatchi = has_match_i = match_i
3641
+ def find_words(src: Any) -> list[str]:
3642
+ """
3643
+ @param src
3644
+ :type Any
3645
+ :description the source to find the words from
3646
+ @return
3647
+ :type list <blankable, if no words are found>
3648
+ :description a word list containing all the words from the object
3649
+ """
3650
+ if not src:
3651
+ return ""
3652
+ src = str(src).strip()
3653
+ word_list: list[str] = find_matches(src, r"(?:[A-Za-z]+\-)*[A-Za-z]+")
3654
+ return word_list
3655
+ dhundo_alfaaz = dhundo_alfaz = words_of = to_words = find_words
3656
+ def startswith(x: str|list, y: str|list) -> bool:
3657
+ if not isinstance(x, (str, list, tuple)):
3658
+ return False
3659
+ if isinstance_each([x, y], str):
3660
+ try:
3661
+ return re.search(f"^{y}", x)
3662
+ except re.error as e:
3663
+ print(f"re.warning:\n * Bad regex. Switching to default `str.startswith` mode, now that the regex mode failed. *Reason*: {str(e).capitalize()}.")
3664
+ return x.startswith(y)
3665
+ elif isinstance(x, (list, tuple)):
3666
+ if isinstance(x, tuple):
3667
+ x = list(x)
3668
+ if not isinstance(y, (list, tuple)):
3669
+ y = [y]
3670
+ if isinstance(y, tuple):
3671
+ y = list(y)
3672
+ if len(x) < len(y):
3673
+ return False
3674
+ return x[:len(y)] == y
3675
+ return False
3676
+ starts_with = startswith
3677
+ def endswith(x: str|list, y: str|list) -> bool:
3678
+ if not isinstance(x, (str, list, tuple)):
3679
+ return False
3680
+ if isinstance_each([x, y], str):
3681
+ try:
3682
+ return re.search(f"{y}$", x)
3683
+ except re.error as e:
3684
+ print(f"re.warning:\n * Bad regex. Switching to default `str.endswith` mode, now that the regex mode failed. *Reason*: {str(e).capitalize()}.")
3685
+ return x.endswith(y)
3686
+ elif isinstance(x, (list, tuple)):
3687
+ if isinstance(x, tuple):
3688
+ x = list(x)
3689
+ if not isinstance(y, (list, tuple)):
3690
+ y = [y]
3691
+ if isinstance(y, tuple):
3692
+ y = list(y)
3693
+ if len(x) < len(y):
3694
+ return False
3695
+ return x[-len(y):] == y
3696
+ return False
3697
+ ends_with = endswith
3698
+ def upper(src: str) -> str:
3699
+ if not isinstance(src, str):
3700
+ return ""
3701
+ result: str = src.upper()
3702
+ return result
3703
+ def isupper(src: str) -> bool:
3704
+ if not isinstance(src, str):
3705
+ return False
3706
+ return src.isupper()
3707
+ is_upper = isupper
3708
+ def lower(src: str) -> str:
3709
+ if not isinstance(src, str):
3710
+ return ""
3711
+ result: str = src.lower()
3712
+ return result
3713
+ def islower(src: str) -> bool:
3714
+ if not isinstance(src, str):
3715
+ return False
3716
+ return src.islower()
3717
+ is_lower = islower
3718
+ def snake_case(src: str) -> str:
3719
+ if not isinstance(src, str):
3720
+ return ""
3721
+ all_were_upper: bool = False
3722
+ if src.upper() == src:
3723
+ all_were_upper = True
3724
+ result: str = src.casefold()
3725
+ result = re.sub(r"[^\-\.\w\n]+", "_", result).strip("_")
3726
+ if all_were_upper:
3727
+ result = result.upper()
3728
+ return result
3729
+ snakecase = snake_case
3730
+ def is_snake_case(src: str) -> bool:
3731
+ if not isinstance(src, str):
3732
+ return False
3733
+ return src == snake_case(src)
3734
+ issnakecase = is_snakecase = is_snake_case
3735
+ def title_case(src: str) -> str:
3736
+ if not isinstance(src, str):
3737
+ return ""
3738
+ result: str = src.title()
3739
+ return result
3740
+ def is_title_case(src: str) -> bool:
3741
+ if not isinstance(src, str):
3742
+ return False
3743
+ return src.istitle()
3744
+ istitle = is_title = istitlecase = is_titlecase = is_title_case
3745
+ def sentence_case(src: str) -> str:
3746
+ if not isinstance(src, str):
3747
+ return ""
3748
+ result: str = src.capitalize()
3749
+ return result
3750
+ sentcase = sent_case = sentence_case
3751
+ def is_sentence_case(src: str) -> bool:
3752
+ if not isinstance(src, str):
3753
+ return False
3754
+ return src == sentence_case(src)
3755
+ issentcase = is_sentcase = is_sent_case = issentencecase = is_sentencecase = is_sentence_case
3756
+ class Money:
3757
+ def __init__(self, amount=0, currency="Rs. "):
3758
+ self.amount = amount if amount >= 0 else 0
3759
+ self.currency = currency if currency and len(currency) <= 4 else "Rs. "
3760
+ def set_currency(self, currency):
3761
+ if currency and len(currency) <= 4:
3762
+ self.currency = currency
3763
+ return self
3764
+ def set_amount(self, new_amount):
3765
+ if new_amount >= 0:
3766
+ self.amount = new_amount
3767
+ return self
3768
+ def add(self, *nums):
3769
+ self.amount += sum(nums)
3770
+ return self
3771
+ def subtract(self, *nums):
3772
+ self.amount -= sum(nums)
3773
+ return self
3774
+ def multiply(self, *nums):
3775
+ for n in nums:
3776
+ self.amount *= n
3777
+ return self
3778
+ def divide(self, *nums):
3779
+ for n in nums:
3780
+ if n == 0:
3781
+ n = 1
3782
+ self.amount /= n
3783
+ return self
3784
+ def __str__(self):
3785
+ return f"{self.currency}{self.amount:.2f}"
3786
+ def balance(self):
3787
+ return str(self)
3788
+ class Pesa(Money):
3789
+ def __init__(self, amount, currency):
3790
+ super().__init__(amount, currency)
3791
+ pesa = Pesa
3792
+ def open_file_case_ins(filename: str, mode: str = 'r', **kwargs):
3793
+ filename = str(filename)
3794
+ if not mode or not isinstance(mode, str):
3795
+ mode = "r"
3796
+ if not filename or not os.path.isfile(filename):
3797
+ raise FileNotFoundError(f"File '{filename}' doesn't exist")
3798
+ directory, name = os.path.split(filename)
3799
+ directory = directory or '.' # Default to current directory if none specified
3800
+ name_lower = name.lower()
3801
+ for actual_file_name in os.listdir(directory):
3802
+ if actual_file_name.lower() == name_lower:
3803
+ actual_path = os.path.join(directory, actual_file_name)
3804
+ if os.path.isfile(actual_path):
3805
+ return open(actual_path, mode, **kwargs)
3806
+ open_case_ins = open_file_case_ins
3807
+ class File:
3808
+ def __init__(self, path: Union[str, Path]):
3809
+ self.pathname = Path(path)
3810
+ def __str__(self) -> str:
3811
+ return str(self.pathname)
3812
+ def path(self) -> Path:
3813
+ return self.pathname
3814
+ def absolute_path(self) -> str:
3815
+ return str(self.pathname.absolute())
3816
+ def abs_path(self) -> str:
3817
+ return self.absolute_path()
3818
+ def is_file(self) -> bool:
3819
+ return self.pathname.is_file()
3820
+ def is_folder(self) -> bool:
3821
+ return self.pathname.is_dir()
3822
+ def exists(self) -> bool:
3823
+ return self.pathname.exists()
3824
+ def exists_file(self) -> bool:
3825
+ return self.is_file() and self.exists()
3826
+ def exists_folder(self) -> bool:
3827
+ return self.is_folder() and self.exists()
3828
+ mojud_file = mojud_he_file = he_mojud_file = found_file = exists_file
3829
+ exists_directory = exists_dir = found_dir = mojud_folder = mojud_he_folder = he_mojud_folder = mojud_directory = mojud_he_directory = he_mojud_directory = exists_folder
3830
+ mojud = mojud_he = he_mojud = found = exists_path = exists
3831
+ @staticmethod
3832
+ def create(fname: str, content: str = "") -> bool:
3833
+ try:
3834
+ if not fname or not content:
3835
+ raise ValueError("File name, and content are required")
3836
+ if re.search(r"(?<=\\w)\\s*[\\|\\+\\&\\,\\;]\\s*(?=\\w)", fname):
3837
+ for subFileName in re.split(r"\\s*[\\|\\+\\&\\,\\;]\\s*", fname):
3838
+ File.create(subFileName, content)
3839
+ return True
3840
+ with open(fname, 'w') as f:
3841
+ f.write(content)
3842
+ print(f"[KL.file.JobSuccess]:\nFile {fname} created successfully.")
3843
+ return True
3844
+ except ValueError as e:
3845
+ print(f"[KL.file.JobFailed]: {e}")
3846
+ except PermissionError:
3847
+ print(f"[KL.file.JobFailed]: Permission denied to create file {fname}")
3848
+ except OSError as e:
3849
+ print(f"[KL.file.JobFailed]: {e}")
3850
+ except Exception as e:
3851
+ print(f"[KL.file.JobFailed]: {e}")
3852
+ return False
3853
+ @staticmethod
3854
+ def createBlankFile(fname: str) -> bool:
3855
+ try:
3856
+ if not fname:
3857
+ raise ValueError("File name is required")
3858
+ Path(fname).touch()
3859
+ print(f"[KL.file.JobSuccess]:\nBlank file {fname} created successfully.")
3860
+ return True
3861
+ except ValueError as e:
3862
+ print(f"[KL.file.JobFailed]: {e}")
3863
+ except PermissionError:
3864
+ print(f"[KL.file.JobFailed]: Permission denied to create file {fname}")
3865
+ except OSError as e:
3866
+ print(f"[KL.file.JobFailed]: {e}")
3867
+ except Exception as e:
3868
+ print(f"[KL.file.JobFailed]: {e}")
3869
+ return False
3870
+ touch = createBlankFile
3871
+ @staticmethod
3872
+ def createFolder(folderName: str) -> bool:
3873
+ try:
3874
+ if not folderName:
3875
+ raise ValueError("Folder name is required")
3876
+ if re.search(r"(?<=\\w)\\s*[\\|\\+\\&\\,\\;]\\s*(?=\\w)", folderName):
3877
+ for folder in re.split(r"\\s*[\\|\\+\\&\\,\\;]\\s*", folderName):
3878
+ File.createFolder(folder)
3879
+ return True
3880
+ os.makedirs(folderName, exist_ok=True)
3881
+ return True
3882
+ except ValueError as e:
3883
+ print(f"[KL.file.JobFailed]: {e}")
3884
+ except PermissionError:
3885
+ print(f"[KL.file.JobFailed]: Permission denied to create folder {folderName}")
3886
+ except OSError as e:
3887
+ print(f"[KL.file.JobFailed]: {e}")
3888
+ except Exception as e:
3889
+ print(f"[KL.file.JobFailed]: {e}")
3890
+ return False
3891
+ @staticmethod
3892
+ def read(fname: str) -> str:
3893
+ try:
3894
+ if not fname:
3895
+ raise ValueError("File name is required")
3896
+ with open_case_ins(fname, 'r') as f:
3897
+ contents: str = f.read()
3898
+ return contents
3899
+ except ValueError as e:
3900
+ print(f"[KL.file.JobFailed]: {e}")
3901
+ except FileNotFoundError:
3902
+ print(f"[KL.file.JobFailed]: File {fname} does not exist")
3903
+ except PermissionError:
3904
+ print(f"[KL.file.JobFailed]: Permission denied to read file {fname}")
3905
+ except OSError as e:
3906
+ print(f"[KL.file.JobFailed]: {e}")
3907
+ except Exception as e:
3908
+ print(f"[KL.file.JobFailed]: {e}")
3909
+ return ""
3910
+ @staticmethod
3911
+ def get_lines(fname: str) -> list[str]:
3912
+ contents: str = File.read(fname)
3913
+ lines: list[str] = []
3914
+ if not contents.strip():
3915
+ return False
3916
+ if re.search(r"\n", contents):
3917
+ split_content: list[str] = split(contents, r"\n")
3918
+ for line in split_content:
3919
+ lines.append(line)
3920
+ else:
3921
+ lines.append(contents)
3922
+ # no lines found other than the first, append the contents as-is
3923
+ return lines
3924
+ readlines = read_lines = getlines = get_lines
3925
+ @staticmethod
3926
+ def readJson(fname: str) -> Optional[dict]:
3927
+ try:
3928
+ return json.loads(File.read(fname))
3929
+ except json.JSONDecodeError as e:
3930
+ print(f"[KL.file.JobFailed]: {e}")
3931
+ except Exception as e:
3932
+ print(f"[KL.file.JobFailed]: {e}")
3933
+ return None
3934
+ @staticmethod
3935
+ def write(fname: str, content: str) -> bool:
3936
+ try:
3937
+ if not fname or not content:
3938
+ raise ValueError("File name and content are required")
3939
+ with open(fname, 'w') as f:
3940
+ f.write(content)
3941
+ print(f"[KL.file.JobSuccess]:\nFile {fname} written successfully.")
3942
+ return True
3943
+ except ValueError as e:
3944
+ print(f"[KL.file.JobFailed]: {e}")
3945
+ except PermissionError:
3946
+ print(f"[KL.file.JobFailed]: Permission denied to write to file {fname}")
3947
+ except OSError as e:
3948
+ print(f"[KL.file.JobFailed]: {e}")
3949
+ except Exception as e:
3950
+ print(f"[KL.file.JobFailed]: {e}")
3951
+ return False
3952
+ @staticmethod
3953
+ def append(fname: str, content: str) -> bool:
3954
+ try:
3955
+ if not fname or not content:
3956
+ raise ValueError("File name and content are required")
3957
+ if re.search(r"(?<=\\w)\\s*[\\|\\+\\&\\,\\;]\\s*(?=\\w)", fname):
3958
+ for subFileName in re.split(r"\\s*[\\|\\+\\&\\,\\;]\\s*", fname):
3959
+ File.append(subFileName, content)
3960
+ return True
3961
+ with open(fname, 'a') as f:
3962
+ f.write(content)
3963
+ print(f"[KL.file.JobSuccess]:\nAppending to file {fname} was successful.")
3964
+ return True
3965
+ except ValueError as e:
3966
+ print(f"[KL.file.JobFailed]: {e}")
3967
+ except PermissionError:
3968
+ print(f"[KL.file.JobFailed]: Permission denied to append to file {fname}")
3969
+ except OSError as e:
3970
+ print(f"[KL.file.JobFailed]: {e}")
3971
+ except Exception as e:
3972
+ print(f"[KL.file.JobFailed]: {e}")
3973
+ return False
3974
+ @staticmethod
3975
+ def delete(fname: str) -> bool:
3976
+ try:
3977
+ if not fname:
3978
+ return
3979
+ if re.search(r"(?<=\\w)\\s*[\\|\\+\\&\\,\\;]\\s*(?=\\w)", fname):
3980
+ for subFileName in re.split(r"\\s*[\\|\\+\\&\\,\\;]\\s*", fname):
3981
+ File.delete(subFileName)
3982
+ return True
3983
+ if os.path.isdir(fname):
3984
+ shutil.rmtree(fname)
3985
+ else:
3986
+ os.remove(fname)
3987
+ print(f"[KL.file.JobSuccess]:\nFile {fname} deleted successfully.")
3988
+ return True
3989
+ except FileNotFoundError:
3990
+ print(f"[KL.file.JobFailed]: File {fname} does not exist")
3991
+ except PermissionError:
3992
+ print(f"[KL.file.JobFailed]: Permission denied to delete file {fname}")
3993
+ except OSError as e:
3994
+ print(f"[KL.file.JobFailed]: {e}")
3995
+ except Exception as e:
3996
+ print(f"[KL.file.JobFailed]: {e}")
3997
+ return False
3998
+ remove = delete
3999
+ @staticmethod
4000
+ def rename(fname: str, destinationString: str) -> bool:
4001
+ try:
4002
+ if not fname or not destinationString:
4003
+ raise ValueError("File name and destination are required")
4004
+ if re.search(r"(?<=\\w)\\s*[\\|\\+\\&\\,\\;]\\s*(?=\\w)", fname) and re.search(r"[\\\\\\/]", destinationString):
4005
+ for subFileName in re.split(r"\\s*[\\|\\+\\&\\,\\;]\\s*", fname):
4006
+ File.rename(subFileName, destinationString)
4007
+ return True
4008
+ os.replace(fname, destinationString)
4009
+ print(f"[KL.file.JobSuccess]:\nFile {fname} was successfully moved/renamed to {destinationString}")
4010
+ return True
4011
+ except ValueError as e:
4012
+ print(f"[KL.file.JobFailed]: {e}")
4013
+ except FileNotFoundError:
4014
+ print(f"[KL.file.JobFailed]: File {fname} does not exist")
4015
+ except PermissionError:
4016
+ print(f"[KL.file.JobFailed]: Permission denied to rename file {fname}")
4017
+ except OSError as e:
4018
+ print(f"[KL.file.JobFailed]: {e}")
4019
+ except Exception as e:
4020
+ print(f"[KL.file.JobFailed]: {e}")
4021
+ return False
4022
+ move = rename
4023
+ @staticmethod
4024
+ def copy(from_path: str, to_path: str, overwrite: bool = True) -> bool:
4025
+ try:
4026
+ if not from_path or not to_path:
4027
+ raise ValueError("Source and destination paths are required")
4028
+ if re.search(r"(?<=\\w)\\s*[\\|\\+\\&\\,\\;]\\s*(?=\\w)", from_path):
4029
+ for subFileName in re.split(r"\\s*[\\|\\+\\&\\,\\;]\\s*", from_path):
4030
+ File.copy(subFileName, to_path, overwrite)
4031
+ return True
4032
+ shutil.copy2(from_path, to_path)
4033
+ return True
4034
+ except ValueError as e:
4035
+ print(f"[KL.file.JobFailed]: {e}")
4036
+ except FileNotFoundError:
4037
+ print(f"[KL.file.JobFailed]: File {from_path} does not exist")
4038
+ except PermissionError:
4039
+ print(f"[KL.file.JobFailed]: Permission denied to copy file {from_path}")
4040
+ except OSError as e:
4041
+ print(f"[KL.file.JobFailed]: {e}")
4042
+ except Exception as e:
4043
+ print(f"[KL.file.JobFailed]: {e}")
4044
+ return False
4045
+ file: File = File
4046
+ def encode(data: any) -> str:
4047
+ try:
4048
+ return base64.b64encode(str(data).encode()).decode()
4049
+ except TypeError as e:
4050
+ return ""
4051
+ def decode(data: str) -> str:
4052
+ import binascii
4053
+ try:
4054
+ return base64.b64decode(data).decode()
4055
+ except (TypeError, binascii.Error) as e:
4056
+ return ""
4057
+
4058
+ import time
4059
+ def time_it(fn):
4060
+ if not callable(fn):
4061
+ return
4062
+ def wrapper(*args, **kwargs):
4063
+ start: float = timer.time()
4064
+ return_value = fn(*args, **kwargs)
4065
+ # if possible, get the return value
4066
+ end: int = timer.time()
4067
+ duration: int = end - start
4068
+ print(f"@timeit:\n\tFunction `{fn.__name__}` took {duration:.3f} second(s) to fulfil its job")
4069
+ return return_value
4070
+ return wrapper
4071
+ def time_lia(fn):
4072
+ if not callable(fn):
4073
+ return
4074
+ def wrapper(*args, **kwargs):
4075
+ start: float = timer.time()
4076
+ return_value = fn(*args, **kwargs)
4077
+ # if possible, get the return value
4078
+ end: int = timer.time()
4079
+ duration: int = end - start
4080
+ print(f"@timelia:\n\tFunction `{fn.__name__}` ne apna kaam {duration:.1f} second(s) me kia")
4081
+ return return_value
4082
+ return wrapper
4083
+ timeme = time_me = timeit = time_it
4084
+ timelia = time_lia
4085
+ def internet_access() -> bool:
4086
+ try:
4087
+ requests.get("https://www.google.com", timeout=5)
4088
+ return True
4089
+ except requests.ConnectionError:
4090
+ return False
4091
+ def fetch(url: str = "") -> dict|list:
4092
+ if not url or not "requests" in globals():
4093
+ return {}
4094
+ try:
4095
+ response = requests.get(url, timeout=60)
4096
+ response.raise_for_status()
4097
+ if not (response.status_code >= 200 and response.status_code <= 299):
4098
+ return {}
4099
+ return response.json()
4100
+ except Exception as e:
4101
+ print(f"Error fetching data: {e}")
4102
+ return {}
4103
+ def filepath(to_filename: str) -> str:
4104
+ if not isinstance(to_filename, str):
4105
+ return ""
4106
+ if hasattr(sys, '_MEIPASS'):
4107
+ base = Path(sys._MEIPASS)
4108
+ elif getattr(sys, 'frozen', False):
4109
+ base = Path(sys.executable).parent
4110
+ else:
4111
+ base = Path(__file__).resolve().parent
4112
+ target = to_filename.strip().replace("\\", "/")
4113
+ if target.startswith(".."):
4114
+ if not (hasattr(sys, '_MEIPASS') or getattr(sys, 'frozen', False)):
4115
+ base = base.parent
4116
+ target = target[2:].lstrip("/")
4117
+ else:
4118
+ target = target.lstrip("/")
4119
+ full_path: str = os.path.normpath(os.path.join(str(base), target))
4120
+ # normalize the path, and make it cross-platform
4121
+ return full_path
4122
+ file_path = get_path = to_path = path_to = ki_path = ki_location = ki_directory = filepath
4123
+ def asset(to_filename: str) -> str:
4124
+ path: str = ""
4125
+ try:
4126
+ if either(hasattr(sys, '_MEIPASS'), getattr(sys, 'frozen', False)) and both("_filepaths" in globals(), "PROGRAMS_DIR" in dir(globals().get("_filepaths", {}))):
4127
+ from _filepaths import PROGRAMS_DIR
4128
+ path = os.path.join(PROGRAMS_DIR, to_filename)
4129
+ else:
4130
+ path = to_path(f"../{to_filename}")
4131
+ # SEQUENCE IS MANDATORY
4132
+ fallback_dirs: list[str] = [
4133
+ f"../asset/{to_filename}",
4134
+ f"../assets/{to_filename}",
4135
+ f"../files/{to_filename}",
4136
+ f"../data/{to_filename}",
4137
+ f"../res/{to_filename}",
4138
+ f"../resource/{to_filename}",
4139
+ f"../resources/{to_filename}",
4140
+ f"../____programs____/{to_filename}",
4141
+ f"../____programs____/asset/{to_filename}",
4142
+ f"../____programs____/assets/{to_filename}",
4143
+ f"../____programs____/files/{to_filename}",
4144
+ f"../____programs____/data/{to_filename}",
4145
+ f"../____programs____/res/{to_filename}",
4146
+ f"../____programs____/resource/{to_filename}",
4147
+ f"../____programs____/resources/{to_filename}",
4148
+ f"../_execute/{to_filename}",
4149
+ f"../_execute/asset/{to_filename}",
4150
+ f"../_execute/assets/{to_filename}",
4151
+ f"../_execute/files/{to_filename}",
4152
+ f"../_execute/data/{to_filename}",
4153
+ f"../_execute/res/{to_filename}",
4154
+ f"../_execute/resource/{to_filename}",
4155
+ f"../_execute/resources/{to_filename}",
4156
+ f"./{to_filename}",
4157
+ f"./asset/{to_filename}",
4158
+ f"./assets/{to_filename}",
4159
+ f"./files/{to_filename}",
4160
+ f"./data/{to_filename}",
4161
+ f"./res/{to_filename}",
4162
+ f"./resource/{to_filename}",
4163
+ f"./resources/{to_filename}",
4164
+ f"./____programs____/{to_filename}",
4165
+ f"./____programs____/asset/{to_filename}",
4166
+ f"./____programs____/assets/{to_filename}",
4167
+ f"./____programs____/files/{to_filename}",
4168
+ f"./____programs____/data/{to_filename}",
4169
+ f"./____programs____/res/{to_filename}",
4170
+ f"./____programs____/resource/{to_filename}",
4171
+ f"./____programs____/resources/{to_filename}",
4172
+ f"./_execute/{to_filename}",
4173
+ f"./_execute/asset/{to_filename}",
4174
+ f"./_execute/assets/{to_filename}",
4175
+ f"./_execute/files/{to_filename}",
4176
+ f"./_execute/data/{to_filename}",
4177
+ f"./_execute/res/{to_filename}",
4178
+ f"./_execute/resource/{to_filename}",
4179
+ f"./_execute/resources/{to_filename}"
4180
+ ]
4181
+ if not os.path.exists(path):
4182
+ for fallback_dir in fallback_dirs:
4183
+ fallback_dir = to_path(fallback_dir)
4184
+ if os.path.exists(fallback_dir):
4185
+ path = fallback_dir
4186
+ break
4187
+ return os.path.normpath(path)
4188
+ except Exception as e:
4189
+ return ""
4190
+ define_asset = to_asset = get_asset = new_asset = load_asset = naya_asset = asset
4191
+ ## belongs at the bottom of KL_Py.py
4192
+ ## a helper function for def= operator
4193
+ def get_initial_of(x: Any) -> Any:
4194
+ if not x:
4195
+ return None
4196
+ out: Any
4197
+ match x:
4198
+ case "str":
4199
+ out = ""
4200
+ case "int":
4201
+ out = 0
4202
+ case "flt" | "float" | "dbl" | "double" | "Number" | "nr":
4203
+ # a number is both a float, and int
4204
+ # lets just assume its a float
4205
+ out = 0.0
4206
+ case "bool" | "haal":
4207
+ out = False
4208
+ case "list":
4209
+ out = []
4210
+ case "tuple":
4211
+ out = ()
4212
+ case "set":
4213
+ out = {}
4214
+ case "Arr":
4215
+ out = Arr()
4216
+ case "numlist":
4217
+ out = numlist()
4218
+ case "intlist":
4219
+ out = intlist()
4220
+ case "fltlist":
4221
+ out = fltlist()
4222
+ case "dict" | "obj":
4223
+ out = obj()
4224
+ case _:
4225
+ out = None
4226
+ return out
4227
+ from hindGui import Text
4228
+ # ^ an overwrite fix
4229
+ # ^ needed
4230
+ # a helper constant for platform checks
4231
+ WINDOWS: Final[str] = "nt"
4232
+ INTERNAL_JSON: Final[str] = to_asset("json/")
4233
+ JSONS: Final[str] = INTERNAL_JSON
4234
+ def json_load_internal(filename: str) -> dict | list:
4235
+ if not isinstance(filename, str) or not filename.strip():
4236
+ return {}
4237
+ return json_load(to_asset(f"json/{filename}"))
4238
+ load_internal_json = loadinternaljson = jsonloadinternal = json_load_internal
4239
+ colors = COLORS = {}
4240
+ pakistani_names = PAKISTANI_NAMES = {}
4241
+ try:
4242
+ colors = COLORS = load_internal_json("colors")
4243
+ pakistani_names = PAKISTANI_NAMES = load_internal_json("pakistani_names")
4244
+ except Exception:
4245
+ ...
4246
+
4247
+
4248
+
4249
+
4250
+ if __name__ == "__main__":
4251
+ print(Int("100", 2))
4252
+ print(Flt("2.22"))
4253
+ print(Int(2.22))
4254
+ print(Flt(2.22))
4255
+ print(Int(2))
4256
+ print(Flt(2))
4257
+ dictionary: obj = obj(key="value")
4258
+ cloned = clone(dictionary)
4259
+ cloned.key = 4
4260
+ print(dictionary.entries())
4261
+ print(cloned.entries())
4262
+ name: lafz = "Misty"
4263
+ print(name)
4264
+ x: num = 4
4265
+ print(x)
4266
+ printf("$name dont! You are, but a $10+5-8 -year-old kid. $x")
4267
+ print(isstr(""))
4268
+ print(isint(3))
4269
+ print(isflt(""))
4270
+ print(isstr(None))
4271
+ print(isstr(None))
4272
+ print(isstr(None))
4273
+ print(isstr(None))
4274
+ print(isstr(None))
4275
+ print(isstr(None))
4276
+ print(isfunc(internet_access))
4277
+ print(flatten([1, [2, [3, 4, [5, 6]]]]))
4278
+ print(remove_duplicates([1, 3, 1, 5, 6, 3, 7, 8, 9]))
4279
+ print(kism(7.5))
4280
+ print(he_kism(7.5, float))
4281
+ printf("hi, $75000.77778:,")
4282
+ x = 12345.6789
4283
+ print(f("$x", "$x:.2f", f"{x:,}", f"{x:,.2f}"))
4284
+ array = intlist(1.4, 2.9, 3.5)
4285
+ array2 = fltlist(2, 4, 6)
4286
+ result = array * array2
4287
+ print(result)
4288
+ nlist: numlist = numlist(1, 3, 5, 7)
4289
+ print(nlist.push([9, 11]))
4290
+ array = Arr([1.2, 3, 5, 6, None, ""], fixed=False)
4291
+ array.me_dalo("x")
4292
+ array.me_dalo("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx0 xxx")
4293
+ print(f"{array=}")
4294
+ #pprint({"name": "Mike", "age": 17, "hobbies": ["horse riding", "country music", "farming"]})
4295
+ print(Msg, Message, Error, Err)
4296
+ @auto_id
4297
+ @auto_class
4298
+ class Book:
4299
+ name: str
4300
+ author: str
4301
+ release: int
4302
+ book1: Book = Book("To Kill A MockingBird", "Anonymous", 2003)
4303
+ book2: Book = Book("The Subtle Art of Not Caring", "Mark Manson", 2007)
4304
+ print(book1.name, book1.author, book1.release, book1.__id__, book1.__shanakht__)
4305
+ print(book1.name, book1.author, book1.release, book1.__id__, book1.__shanakht__)
4306
+ print(book2.name, book2.author, book2.release, book2.__id__, book2.__shanakht__)
4307
+ print(book2.name, book2.author, book2.release, book2.__id__, book2.__shanakht__)
4308
+ print(belongs_to(book1, Book))
4309
+ print(isinstance_each([IOError, OSError], (Exception | BaseException)))
4310
+ print(hissa(None, ["hello world", None]))
4311
+ print(belongs_to(IOError | OSError, Exception))
4312
+ print(chuno(rng(1, 10), koi=2))
4313
+ my_dict: dict[str, dict[str, str] | int] = {"name": {"first": "Mike", "last": "Dawson"}, "age": 22000}
4314
+ from _klang_builtins import cust_print
4315
+ cust_print(my_dict)
4316
+ print(deep_get(my_dict, "first"))
4317
+ dt: Date = Date("2.44 am, Jan 24, 2002")
4318
+ cust_print(dt.day_name(), dont_format_nums=True)
4319
+ cust_print(dt.month_name(), dont_format_nums=True)
4320
+ cust_print(dt.year(), dont_format_nums=True)
4321
+ cust_print(dt.day_name(True), dont_format_nums=True)
4322
+ cust_print(dt.month_name(True), dont_format_nums=True)
4323
+ cust_print(dt.year(True), dont_format_nums=True)
4324
+ dt.update(year=2021)
4325
+ cust_print(dt.year(True), dont_format_nums=True)
4326
+ print(Date("Jun 15 2026").is_weekend())
4327
+ print(Date("Jun 15 2026").is_weekday())
4328
+ print(obj(my_dict).ke("Name").mese("First", default="Anonymous"))
4329
+ print(rng(10, 100, 10) [4-1])
4330
+ print(Text, Bolo, Text == Bolo)
4331
+ print(has_match("P@$$w0rd", STRICT_PWD_RE))
4332
+ print(split_into_words("what a beautifully-crafted fun art, 'tisnit?"))
4333
+ print(is_mail("abbaskhurram255@gmail.com"))
4334
+ print(has_mail("abbaskhurram255@gmail.com 03012965459"))
4335
+ print(catch_mail("abbaskhurram255@gmail.com 03012965459 abbaskhurram255@yahoo.com"))
4336
+ print(catch_mail("abbaskhurram255@gmail.com 03012965459"))
4337
+ print(catch_phone("abbaskhurram255@gmail.com 03012965459 abbaskhurram255@yahoo.com"))
4338
+ print(is_pin(1535))
4339
+ print(is_pin(153))
4340
+ print(is_pin("1535"))
4341
+ print(is_pin("153"))
4342
+ print(ishex("#68fafe"))
4343
+ countries: dict = load_json(r"json/countries.json")
4344
+ print(countries)
4345
+ arr = (1, 3.8, 7)
4346
+ arr = _map(arr, str, lambda x: type(x) != float)
4347
+ print(arr)
4348
+ print(obj(my_dict).floor_key("NA"))
4349
+ print(ltype(None))
4350
+ print(ltype(Date()))
4351
+ print(ltype(obj({1: "Lucien", 2: lambda: ...})))
4352
+ print(ltype({"x": 1, "y": lambda: ...}))
4353
+ print(ltype({"x": 1, "y": lambda: ...}))
4354
+ print(ltype({"y": lambda: ...}))
4355
+ print(ltype({"y": lambda: ...}))
4356
+ print(ltype({"y": Book("x", "y", 2000)}))
4357
+ print(ltype({"y": Book("x", "y", 2000)}))
4358
+ print(rng("a", "z", shamil=Nahi))
4359
+ print(rng(1, 10, inclusive=globals().get('shamil'.strip().replace(' ', '_').upper(), True)))
4360
+ print(rng(1, 10, step=int('2' or '1'), inclusive=globals().get('shaamil akhri'.strip().replace(' ', '_').upper(), True)))
4361
+ print(rng(1, 10, step=int('2' or '1'), inclusive=globals().get('bager akhri'.strip().replace(' ', '_').upper(), True)))
4362
+ print(rng(1, 10, step=int('' or '1'), inclusive=globals().get('bager_akhri'.strip().replace(' ', '_').upper(), True)))
4363
+ print(rng(20, step=.5, inclusive=globals().get(''.strip().replace(' ', '_').upper(), True)))
4364
+
4365
+ # sucks >>
4366
+ print("\n\nsucks:")
4367
+ print(rng(20))
4368
+ print("\n\n")
4369
+
4370
+ print(rng(1, 10, step=float('2' or '1'), inclusive=globals().get('shaamil akhri'.strip().replace(' ', '_').upper(), True)))
4371
+ print(rng(1, 10, step=float('2' or '1'), inclusive=globals().get('shaamil akhri'.strip().replace(' ', '_').upper(), True)))
4372
+ print(rng(1, 10, step=float('' or '1'), inclusive=globals().get('bager akhri'.strip().replace(' ', '_').upper(), True)))
4373
+ print(rng(1, 10, step=float('.5' or '1'), inclusive=globals().get(''.strip().replace(' ', '_').upper(), True)))
4374
+
4375
+ print(rng('a', 'y', step=.5))
4376
+ print(rng('w', 'y'))
4377
+ print(rng(10))
4378
+ print(rng(10, inclusive=FORCE_INCLUSIVE, step=float('2.5')))
4379
+
4380
+ print(he_parsable_num("5.7"))
4381
+ print(Flt("5.7"))
4382
+ print(Int("5.7"))
4383
+
4384
+ print(rng("b", "z", reverse=REVERSED, step=2))
4385
+ print(rng(1, 44, step=float('5' or '1'), inclusive=globals().get('shamil akhri'.strip().replace(' ', '_').upper(), True), reverse=globals().get('nahi reverse'.strip().replace(' ', '_').upper(), False)))
4386
+ print(rng(10, step=float('2' or '1'), inclusive=globals().get('shamil akhri'.strip().replace(' ', '_').upper(), True), reverse=globals().get('reverse'.strip().replace(' ', '_').upper(), False)))
4387
+ print(rng(10, step=float('5' or '1'), inclusive=globals().get('zabardasti shamil akhri'.strip().replace(' ', '_').upper(), True), reverse=globals().get('reverse'.strip().replace(' ', '_').upper(), False)))
4388
+
4389
+ print(rng('a', 'y', step=float('2' or '1'), inclusive=globals().get('shamil akhri'.strip().replace(' ', '_').upper(), True), reverse=globals().get(''.strip().replace(' ', '_').upper(), False)))
4390
+ arr = rng(1, 10)
4391
+ shuffle_inplace(arr)
4392
+ print(arr)
4393
+ colors["sub"] = {"sub2": {"sub3a": 15, "sub3b": 20, 8.3: 8.0}}
4394
+ print(safe_get(colors, 8, default="Couldn't find"))
4395
+ print(colors.sub.sub3B)
4396
+
4397
+ print(Date("2026-07-22 12.01 am").day_nr())
4398
+ print(Date("2026-07-22 12.01 am").time_and_day())
4399
+ print(Date("2002-07-22 12.01 am").yr(2004).d(21).d(), nahi_format_nums=Han)
4400
+ print(Date.day_today())