pypipr 1.0.75__py3-none-any.whl → 1.0.77__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.
@@ -0,0 +1,1590 @@
1
+ Metadata-Version: 2.1
2
+ Name: pypipr
3
+ Version: 1.0.77
4
+ Summary: The Python Package Index Project
5
+ Author: ufiapjj
6
+ Author-email: ufiapjj@gmail.com
7
+ Requires-Python: >=3.9
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.9
10
+ Classifier: Programming Language :: Python :: 3.10
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Requires-Dist: colorama
14
+ Requires-Dist: cssselect
15
+ Requires-Dist: django
16
+ Requires-Dist: getch ; platform_system == "Linux"
17
+ Requires-Dist: lxml
18
+ Requires-Dist: pint
19
+ Requires-Dist: pyyaml
20
+ Requires-Dist: requests
21
+ Requires-Dist: tzdata
22
+ Description-Content-Type: text/markdown
23
+
24
+
25
+ # About
26
+ The Python Package Index Project (pypipr)
27
+
28
+ pypi : https://pypi.org/project/pypipr
29
+
30
+
31
+ # Setup
32
+ Install with pip
33
+ ```
34
+ pip install pypipr
35
+ ```
36
+
37
+ Then import pypipr
38
+ ```python
39
+ import pypipr
40
+ ```
41
+
42
+ # CONSTANT
43
+
44
+ `LINUX`
45
+
46
+ `WINDOWS`
47
+
48
+ # FUNCTION
49
+
50
+ ## auto_reload
51
+
52
+ `auto_reload(filename)`
53
+
54
+ Menjalankan file python secara berulang.
55
+ Dengan tujuan untuk melihat perubahan secara langsung.
56
+ Pastikan kode aman untuk dijalankan.
57
+ Jalankan kode ini di terminal console.
58
+
59
+ ```py
60
+ python -m pypipr.iflow.auto_reload file_name.py
61
+ ```
62
+
63
+ ## avg
64
+
65
+ `avg(i)`
66
+
67
+ Simple Average Function karena tidak disediakan oleh python
68
+
69
+ ```python
70
+ n = [1, 22, 2, 3, 13, 2, 123, 12, 31, 2, 2, 12, 2, 1]
71
+ print(avg(n))
72
+ ```
73
+
74
+ Output:
75
+ ```py
76
+ 16.285714285714285
77
+ ```
78
+
79
+ ## basename
80
+
81
+ `basename(path)`
82
+
83
+ Mengembalikan nama file dari path
84
+
85
+ ```python
86
+ print(basename("/ini/nama/folder/ke/file.py"))
87
+ ```
88
+
89
+ Output:
90
+ ```py
91
+ file.py
92
+ ```
93
+
94
+ ## batch_calculate
95
+
96
+ `batch_calculate(pattern)`
97
+
98
+ Analisa perhitungan massal.
99
+ Bisa digunakan untuk mencari alternatif terendah/tertinggi/dsb.
100
+
101
+
102
+ ```python
103
+ print(batch_calculate("{1 10} m ** {1 3}"))
104
+ print(list(batch_calculate("{1 10} m ** {1 3}")))
105
+ ```
106
+
107
+ Output:
108
+ ```py
109
+ <generator object batch_calculate at 0x76ef846200>
110
+ [('1 m ** 1', <Quantity(1, 'meter')>), ('1 m ** 2', <Quantity(1, 'meter ** 2')>), ('1 m ** 3', <Quantity(1, 'meter ** 3')>), ('2 m ** 1', <Quantity(2, 'meter')>), ('2 m ** 2', <Quantity(2, 'meter ** 2')>), ('2 m ** 3', <Quantity(2, 'meter ** 3')>), ('3 m ** 1', <Quantity(3, 'meter')>), ('3 m ** 2', <Quantity(3, 'meter ** 2')>), ('3 m ** 3', <Quantity(3, 'meter ** 3')>), ('4 m ** 1', <Quantity(4, 'meter')>), ('4 m ** 2', <Quantity(4, 'meter ** 2')>), ('4 m ** 3', <Quantity(4, 'meter ** 3')>), ('5 m ** 1', <Quantity(5, 'meter')>), ('5 m ** 2', <Quantity(5, 'meter ** 2')>), ('5 m ** 3', <Quantity(5, 'meter ** 3')>), ('6 m ** 1', <Quantity(6, 'meter')>), ('6 m ** 2', <Quantity(6, 'meter ** 2')>), ('6 m ** 3', <Quantity(6, 'meter ** 3')>), ('7 m ** 1', <Quantity(7, 'meter')>), ('7 m ** 2', <Quantity(7, 'meter ** 2')>), ('7 m ** 3', <Quantity(7, 'meter ** 3')>), ('8 m ** 1', <Quantity(8, 'meter')>), ('8 m ** 2', <Quantity(8, 'meter ** 2')>), ('8 m ** 3', <Quantity(8, 'meter ** 3')>), ('9 m ** 1', <Quantity(9, 'meter')>), ('9 m ** 2', <Quantity(9, 'meter ** 2')>), ('9 m ** 3', <Quantity(9, 'meter ** 3')>), ('10 m ** 1', <Quantity(10, 'meter')>), ('10 m ** 2', <Quantity(10, 'meter ** 2')>), ('10 m ** 3', <Quantity(10, 'meter ** 3')>)]
111
+ ```
112
+
113
+ ## batchmaker
114
+
115
+ `batchmaker(pattern: str)`
116
+
117
+ Alat Bantu untuk membuat teks yang berulang.
118
+ Gunakan `{[start][separator][finish]([separator][step])}`.
119
+ ```
120
+ [start] dan [finish] -> bisa berupa huruf maupun angka
121
+ ([separator][step]) -> bersifat optional
122
+ [separator] -> selain huruf dan angka
123
+ [step] -> berupa angka positif
124
+ ```
125
+
126
+ ```python
127
+ s = "Urutan {1/6/3} dan {10:9} dan {j k} dan {Z - A - 15} saja."
128
+ print(batchmaker(s))
129
+ print(list(batchmaker(s)))
130
+ ```
131
+
132
+ Output:
133
+ ```py
134
+ <generator object batchmaker at 0x76ef8516c0>
135
+ ['Urutan 1 dan 10 dan j dan Z saja.', 'Urutan 1 dan 10 dan j dan K saja.', 'Urutan 1 dan 10 dan k dan Z saja.', 'Urutan 1 dan 10 dan k dan K saja.', 'Urutan 1 dan 9 dan j dan Z saja.', 'Urutan 1 dan 9 dan j dan K saja.', 'Urutan 1 dan 9 dan k dan Z saja.', 'Urutan 1 dan 9 dan k dan K saja.', 'Urutan 4 dan 10 dan j dan Z saja.', 'Urutan 4 dan 10 dan j dan K saja.', 'Urutan 4 dan 10 dan k dan Z saja.', 'Urutan 4 dan 10 dan k dan K saja.', 'Urutan 4 dan 9 dan j dan Z saja.', 'Urutan 4 dan 9 dan j dan K saja.', 'Urutan 4 dan 9 dan k dan Z saja.', 'Urutan 4 dan 9 dan k dan K saja.']
136
+ ```
137
+
138
+ ## calculate
139
+
140
+ `calculate(teks)`
141
+
142
+ Mengembalikan hasil dari perhitungan teks menggunakan modul pint.
143
+ Mendukung perhitungan matematika dasar dengan satuan.
144
+
145
+ Return value:
146
+ - Berupa class Quantity dari modul pint
147
+
148
+ Format:
149
+ - f"{result:~P}" -> pretty
150
+ - f"{result:~H}" -> html
151
+ - result.to_base_units() -> SI
152
+ - result.to_compact() -> human readable
153
+
154
+ ```python
155
+ fx = "3 meter * 10 cm * 3 km"
156
+ res = calculate(fx)
157
+ print(res)
158
+ print(res.to_base_units())
159
+ print(res.to_compact())
160
+ print(f"{res:~P}")
161
+ print(f"{res:~H}")
162
+ ```
163
+
164
+ Output:
165
+ ```py
166
+ 90 centimeter * kilometer * meter
167
+ 900.0 meter ** 3
168
+ 900.0 meter ** 3
169
+ 90 cm·km·m
170
+ 90 cm km m
171
+ ```
172
+
173
+ ## choices
174
+
175
+ `choices(iterator, title=None, prompt='', default=None)`
176
+
177
+ Memudahkan dalam membuat pilihan untuk user dalam tampilan console
178
+
179
+ ```py
180
+ a = choices("ini hanya satu pilihan")
181
+ b = choices(
182
+ {
183
+ "sedan": "audi",
184
+ "suv": "volvo",
185
+ "truck": "tesla",
186
+ },
187
+ title="Car Model",
188
+ prompt="Pilih Mobil : ",
189
+ )
190
+ c = choices(
191
+ iscandir(recursive=False),
192
+ title="List File dan Folder",
193
+ prompt="Pilih File atau Folder : ",
194
+ )
195
+ ```
196
+
197
+ ## chunk_array
198
+
199
+ `chunk_array(array, size, start=0)`
200
+
201
+ Membagi array menjadi potongan-potongan dengan besaran yg diinginkan
202
+
203
+ ```python
204
+ arr = [2, 3, 12, 3, 3, 42, 42, 1, 43, 2, 42, 41, 4, 24, 32, 42, 3, 12, 32, 42, 42]
205
+ print(chunk_array(arr, 5))
206
+ print(list(chunk_array(arr, 5)))
207
+ ```
208
+
209
+ Output:
210
+ ```py
211
+ <generator object chunk_array at 0x76ef874e40>
212
+ [[2, 3, 12, 3, 3], [42, 42, 1, 43, 2], [42, 41, 4, 24, 32], [42, 3, 12, 32, 42], [42]]
213
+ ```
214
+
215
+ ## console_run
216
+
217
+ `console_run(info, command=None, print_info=True, capture_output=False)`
218
+
219
+ Menjalankan command seperti menjalankan command di Command Terminal
220
+
221
+ ```py
222
+ console_run('dir')
223
+ console_run('ls')
224
+ ```
225
+
226
+ ## create_folder
227
+
228
+ `create_folder(folder_name)`
229
+
230
+ Membuat folder.
231
+ Membuat folder secara recursive dengan permission.
232
+
233
+ ```py
234
+ create_folder("contoh_membuat_folder")
235
+ create_folder("contoh/membuat/folder/recursive")
236
+ create_folder("./contoh_membuat_folder/secara/recursive")
237
+ ```
238
+
239
+ ## datetime_from_string
240
+
241
+ `datetime_from_string(iso_string, timezone='UTC')`
242
+
243
+ Parse iso_string menjadi datetime object
244
+
245
+ ```python
246
+ print(datetime_from_string("2022-12-12 15:40:13").isoformat())
247
+ print(datetime_from_string(
248
+ "2022-12-12 15:40:13",
249
+ timezone="Asia/Jakarta"
250
+ ).isoformat())
251
+ ```
252
+
253
+ Output:
254
+ ```py
255
+ 2022-12-12T15:40:13+00:00
256
+ 2022-12-12T15:40:13+07:00
257
+ ```
258
+
259
+ ## datetime_now
260
+
261
+ `datetime_now(timezone=None)`
262
+
263
+ Memudahkan dalam membuat Datetime untuk suatu timezone tertentu
264
+
265
+ ```python
266
+ print(datetime_now("Asia/Jakarta"))
267
+ print(datetime_now("GMT"))
268
+ print(datetime_now("Etc/GMT+7"))
269
+ ```
270
+
271
+ Output:
272
+ ```py
273
+ 2024-04-23 05:00:14.636387+07:00
274
+ 2024-04-22 22:00:14.636697+00:00
275
+ 2024-04-22 15:00:14.637248-07:00
276
+ ```
277
+
278
+ ## dict_first
279
+
280
+ `dict_first(d: dict, remove=False)`
281
+
282
+ Mengambil nilai (key, value) pertama dari dictionary dalam bentuk tuple.
283
+
284
+ ```python
285
+ d = {
286
+ "key2": "value2",
287
+ "key3": "value3",
288
+ "key1": "value1",
289
+ }
290
+ print(dict_first(d, remove=True))
291
+ print(dict_first(d))
292
+ ```
293
+
294
+ Output:
295
+ ```py
296
+ ('key2', 'value2')
297
+ ('key3', 'value3')
298
+ ```
299
+
300
+ ## dirname
301
+
302
+ `dirname(path)`
303
+
304
+ Mengembalikan nama folder dari path.
305
+ Tanpa trailing slash di akhir.
306
+
307
+ ```python
308
+ print(dirname("/ini/nama/folder/ke/file.py"))
309
+ ```
310
+
311
+ Output:
312
+ ```py
313
+ /ini/nama/folder/ke
314
+ ```
315
+
316
+ ## exit_if_empty
317
+
318
+ `exit_if_empty(*args)`
319
+
320
+ Keluar dari program apabila seluruh variabel
321
+ setara dengan empty
322
+
323
+ ```py
324
+ var1 = None
325
+ var2 = '0'
326
+ exit_if_empty(var1, var2)
327
+ ```
328
+
329
+ ## filter_empty
330
+
331
+ `filter_empty(iterable, zero_is_empty=True, str_strip=True)`
332
+
333
+ Mengembalikan iterabel yang hanya memiliki nilai
334
+
335
+ ```python
336
+ var = [1, None, False, 0, "0", True, {}, ['eee']]
337
+ print(filter_empty(var))
338
+ ```
339
+
340
+ Output:
341
+ ```py
342
+ <generator object filter_empty at 0x76ef8463e0>
343
+ ```
344
+
345
+ ## get_class_method
346
+
347
+ `get_class_method(cls)`
348
+
349
+ Mengembalikan berupa tuple yg berisi list dari method dalam class
350
+
351
+ ```python
352
+ class ExampleGetClassMethod:
353
+ def a():
354
+ return [x for x in range(10)]
355
+
356
+ def b():
357
+ return [x for x in range(10)]
358
+
359
+ def c():
360
+ return [x for x in range(10)]
361
+
362
+ def d():
363
+ return [x for x in range(10)]
364
+
365
+ print(get_class_method(ExampleGetClassMethod))
366
+ print(list(get_class_method(ExampleGetClassMethod)))
367
+ ```
368
+
369
+ Output:
370
+ ```py
371
+ <generator object get_class_method at 0x76ef8465c0>
372
+ [<function ExampleGetClassMethod.a at 0x76ef886c00>, <function ExampleGetClassMethod.b at 0x76ef886b60>, <function ExampleGetClassMethod.c at 0x76ef886ca0>, <function ExampleGetClassMethod.d at 0x76ef886f20>]
373
+ ```
374
+
375
+ ## get_filemtime
376
+
377
+ `get_filemtime(filename)`
378
+
379
+ Mengambil informasi last modification time file dalam nano seconds
380
+
381
+ ```python
382
+ print(get_filemtime(__file__))
383
+ ```
384
+
385
+ Output:
386
+ ```py
387
+ 1710697117516083632
388
+ ```
389
+
390
+ ## get_filesize
391
+
392
+ `get_filesize(filename)`
393
+
394
+ Mengambil informasi file size dalam bytes
395
+
396
+ ```python
397
+ print(get_filesize(__file__))
398
+ ```
399
+
400
+ Output:
401
+ ```py
402
+ 465
403
+ ```
404
+
405
+ ## get_from_index
406
+
407
+ `get_from_index(obj, index, on_error=None)`
408
+
409
+ Mendapatkan value dari object berdasarkan indexnya.
410
+ Jika error out of range maka akan mengembalikan on_error.
411
+
412
+ ```python
413
+ l = [1, 3, 5]
414
+ print(get_from_index(l, 7))
415
+ ```
416
+
417
+ Output:
418
+ ```py
419
+ None
420
+ ```
421
+
422
+ ## github_pull
423
+
424
+ `github_pull()`
425
+
426
+ Menjalankan command `git pull`
427
+
428
+ ```py
429
+ github_pull()
430
+ ```
431
+
432
+ ## github_push
433
+
434
+ `github_push(commit_msg=None)`
435
+
436
+ Menjalankan command status, add, commit dan push
437
+
438
+ ```py
439
+ github_push('Commit Message')
440
+ ```
441
+
442
+ ## github_user
443
+
444
+ `github_user(email=None, name=None)`
445
+
446
+ Menyimpan email dan nama user secara global sehingga tidak perlu
447
+ menginput nya setiap saat.
448
+
449
+ ```py
450
+ github_user('my@emil.com', 'MyName')
451
+ ```
452
+
453
+ ## iargv
454
+
455
+ `iargv(key: int, cast=None, on_error=None)`
456
+
457
+ ## idumps
458
+
459
+ `idumps(data, syntax='yaml', indent=4)`
460
+
461
+ Mengubah variabel data menjadi string untuk yang dapat dibaca untuk disimpan.
462
+ String yang dihasilkan berbentuk syntax YAML/JSON/HTML.
463
+
464
+ ```python
465
+ data = {
466
+ 'a': 123,
467
+ 't': ['disini', 'senang', 'disana', 'senang'],
468
+ 'l': (12, 23, [12, 42]),
469
+ }
470
+ print(idumps(data))
471
+ print(idumps(data, syntax='html'))
472
+ ```
473
+
474
+ Output:
475
+ ```py
476
+ a: 123
477
+ l: !!python/tuple
478
+ - 12
479
+ - 23
480
+ - - 12
481
+ - 42
482
+ t:
483
+ - disini
484
+ - senang
485
+ - disana
486
+ - senang
487
+
488
+ <table>
489
+ <tbody>
490
+ <tr>
491
+ <th>a</th>
492
+ <td>
493
+ <span>123</span>
494
+ </td>
495
+ </tr>
496
+ <tr>
497
+ <th>t</th>
498
+ <td>
499
+ <ul>
500
+ <li>
501
+ <span>disini</span>
502
+ </li>
503
+ <li>
504
+ <span>senang</span>
505
+ </li>
506
+ <li>
507
+ <span>disana</span>
508
+ </li>
509
+ <li>
510
+ <span>senang</span>
511
+ </li>
512
+ </ul>
513
+ </td>
514
+ </tr>
515
+ <tr>
516
+ <th>l</th>
517
+ <td>
518
+ <ul>
519
+ <li>
520
+ <span>12</span>
521
+ </li>
522
+ <li>
523
+ <span>23</span>
524
+ </li>
525
+ <li>
526
+ <ul>
527
+ <li>
528
+ <span>12</span>
529
+ </li>
530
+ <li>
531
+ <span>42</span>
532
+ </li>
533
+ </ul>
534
+ </li>
535
+ </ul>
536
+ </td>
537
+ </tr>
538
+ </tbody>
539
+ </table>
540
+
541
+ ```
542
+
543
+ ## idumps_html
544
+
545
+ `idumps_html(data, indent=None)`
546
+
547
+ Serialisasi python variabel menjadi HTML.
548
+ ```
549
+ List -> <ul>...</ul>
550
+ Dict -> <table>...</table>
551
+ ```
552
+
553
+ ```python
554
+ data = {
555
+ 'abc': 123,
556
+ 'list': [1, 2, 3, 4, 5],
557
+ 'dict': {'a': 1, 'b':2, 'c':3},
558
+ }
559
+ print(idumps_html(data))
560
+ ```
561
+
562
+ Output:
563
+ ```py
564
+ <table>
565
+ <tbody>
566
+ <tr>
567
+ <th>abc</th>
568
+ <td>
569
+ <span>123</span>
570
+ </td>
571
+ </tr>
572
+ <tr>
573
+ <th>list</th>
574
+ <td>
575
+ <ul>
576
+ <li>
577
+ <span>1</span>
578
+ </li>
579
+ <li>
580
+ <span>2</span>
581
+ </li>
582
+ <li>
583
+ <span>3</span>
584
+ </li>
585
+ <li>
586
+ <span>4</span>
587
+ </li>
588
+ <li>
589
+ <span>5</span>
590
+ </li>
591
+ </ul>
592
+ </td>
593
+ </tr>
594
+ <tr>
595
+ <th>dict</th>
596
+ <td>
597
+ <table>
598
+ <tbody>
599
+ <tr>
600
+ <th>a</th>
601
+ <td>
602
+ <span>1</span>
603
+ </td>
604
+ </tr>
605
+ <tr>
606
+ <th>b</th>
607
+ <td>
608
+ <span>2</span>
609
+ </td>
610
+ </tr>
611
+ <tr>
612
+ <th>c</th>
613
+ <td>
614
+ <span>3</span>
615
+ </td>
616
+ </tr>
617
+ </tbody>
618
+ </table>
619
+ </td>
620
+ </tr>
621
+ </tbody>
622
+ </table>
623
+
624
+ ```
625
+
626
+ ## ienv
627
+
628
+ `ienv(on_windows=None, on_linux=None)`
629
+
630
+ Mengambalikan hasil berdasarkan environment dimana program dijalankan
631
+
632
+ ```py
633
+ getch = __import__(ienv(on_windows="msvcrt", on_linux="getch"))
634
+
635
+ inherit = ienv(
636
+ on_windows=[BaseForWindows, BaseEnv, object],
637
+ on_linux=[SpecialForLinux, BaseForLinux, BaseEnv, object]
638
+ )
639
+
640
+ class ExampleIEnv(*inherit):
641
+ pass
642
+ ```
643
+
644
+ ## iexec
645
+
646
+ `iexec(python_syntax, import_pypipr=True)`
647
+
648
+ improve exec() python function untuk mendapatkan outputnya
649
+
650
+ ```python
651
+ print(iexec('print(9*9)'))
652
+ ```
653
+
654
+ Output:
655
+ ```py
656
+ 81
657
+
658
+ ```
659
+
660
+ ## ijoin
661
+
662
+ `ijoin(iterable, separator='', start='', end='', remove_empty=False, recursive=True, recursive_flat=False, str_strip=False)`
663
+
664
+ Simplify Python join functions like PHP function.
665
+ Iterable bisa berupa sets, tuple, list, dictionary.
666
+
667
+ ```python
668
+ arr = {'asd','dfs','weq','qweqw'}
669
+ print(ijoin(arr, ', '))
670
+
671
+ arr = '/ini/path/seperti/url/'.split('/')
672
+ print(ijoin(arr, ','))
673
+ print(ijoin(arr, ',', remove_empty=True))
674
+
675
+ arr = {'a':'satu', 'b':(12, 34, 56), 'c':'tiga', 'd':'empat'}
676
+ print(ijoin(arr, separator='</li>\n<li>', start='<li>', end='</li>',
677
+ recursive_flat=True))
678
+ print(ijoin(arr, separator='</div>\n<div>', start='<div>', end='</div>'))
679
+ print(ijoin(10, ' '))
680
+ ```
681
+
682
+ Output:
683
+ ```py
684
+ weq, asd, dfs, qweqw
685
+ ,ini,path,seperti,url,
686
+ ini,path,seperti,url
687
+ <li>satu</li>
688
+ <li>12</li>
689
+ <li>34</li>
690
+ <li>56</li>
691
+ <li>tiga</li>
692
+ <li>empat</li>
693
+ <div>satu</div>
694
+ <div><div>12</div>
695
+ <div>34</div>
696
+ <div>56</div></div>
697
+ <div>tiga</div>
698
+ <div>empat</div>
699
+ 10
700
+ ```
701
+
702
+ ## iloads
703
+
704
+ `iloads(data, syntax='yaml')`
705
+
706
+ Mengubah string data hasil dari idumps menjadi variabel.
707
+ String data adalah berupa syntax YAML.
708
+
709
+ ```python
710
+ data = {
711
+ 'a': 123,
712
+ 't': ['disini', 'senang', 'disana', 'senang'],
713
+ 'l': (12, 23, [12, 42]),
714
+ }
715
+ s = idumps(data)
716
+ print(iloads(s))
717
+ ```
718
+
719
+ Output:
720
+ ```py
721
+ {'a': 123, 'l': (12, 23, [12, 42]), 't': ['disini', 'senang', 'disana', 'senang']}
722
+ ```
723
+
724
+ ## iloads_html
725
+
726
+ `iloads_html(html)`
727
+
728
+ Mengambil data yang berupa list `<ul>`, dan table `<table>` dari html
729
+ dan menjadikannya data python berupa list.
730
+ setiap data yang ditemukan akan dibungkus dengan tuple sebagai separator.
731
+ ```
732
+ list (<ul>) -> list -> list satu dimensi
733
+ table (<table>) -> list[list] -> list satu dimensi didalam list
734
+ ```
735
+ apabila data berupa ul maka dapat dicek type(data) -> html_ul
736
+ apabila data berupa ol maka dapat dicek type(data) -> html_ol
737
+ apabila data berupa dl maka dapat dicek type(data) -> html_dl
738
+ apabila data berupa table maka dapat dicek type(data) -> html_table
739
+
740
+ ```python
741
+ import pprint
742
+ pprint.pprint(iloads_html(iopen("https://harga-emas.org/")), depth=10)
743
+ pprint.pprint(iloads_html(iopen("https://harga-emas.org/1-gram/")), depth=10)
744
+ ```
745
+
746
+ Output:
747
+ ```py
748
+ (['Home', 'Emas 1 Gram', 'History', 'Trend', 'Perak 1 Gram', 'Pluang'],
749
+ [['Harga Emas Hari Ini - Selasa, 23 April 2024'],
750
+ ['Spot Emas USD↓2.325,78 (-4,35) / oz',
751
+ 'Kurs IDR16.280,00 / USD',
752
+ 'Emas IDR↓1.217.346 (-2.277) / gr'],
753
+ ['LM Antam (Jual)↓1.343.000 (-4.000) / gr',
754
+ 'LM Antam (Beli)↓1.238.000 (-4.000) / gr']],
755
+ [['Harga Emas Hari Ini'],
756
+ ['Gram', 'Gedung Antam Jakarta', 'Pegadaian'],
757
+ ['per Gram (Rp)', 'per Batangan (Rp)', 'per Gram (Rp)', 'per Batangan (Rp)'],
758
+ ['1000',
759
+ '1.284 (-4)',
760
+ '1.283.600 (-4.000)',
761
+ '1.043.040 (+8.200)',
762
+ '1.043.040.000 (+8.200.000)'],
763
+ ['500',
764
+ '2.567 (-8)',
765
+ '1.283.640 (-4.000)',
766
+ '1.043.082 (+8.200)',
767
+ '521.541.000 (+4.100.000)'],
768
+ ['250',
769
+ '5.136 (-16)',
770
+ '1.284.060 (-4.000)',
771
+ '1.043.512 (+8.200)',
772
+ '260.878.000 (+2.050.000)'],
773
+ ['100',
774
+ '12.851 (-40)',
775
+ '1.285.120 (-4.000)',
776
+ '1.044.600 (+8.200)',
777
+ '104.460.000 (+820.000)'],
778
+ ['50',
779
+ '25.718 (-80)',
780
+ '1.285.900 (-4.000)',
781
+ '1.045.400 (+8.200)',
782
+ '52.270.000 (+410.000)'],
783
+ ['25',
784
+ '51.499 (-160)',
785
+ '1.287.480 (-4.000)',
786
+ '1.047.040 (+8.200)',
787
+ '26.176.000 (+205.000)'],
788
+ ['10',
789
+ '129.250 (-400)',
790
+ '1.292.500 (-4.000)',
791
+ '1.052.200 (+8.200)',
792
+ '10.522.000 (+82.000)'],
793
+ ['5',
794
+ '259.600 (-800)',
795
+ '1.298.000 (-4.000)',
796
+ '1.057.800 (+8.200)',
797
+ '5.289.000 (+41.000)'],
798
+ ['3',
799
+ '434.889 (-1.333)',
800
+ '1.304.667 (-4.000)',
801
+ '1.064.667 (+8.000)',
802
+ '3.194.000 (+24.000)'],
803
+ ['2',
804
+ '656.500 (-2.000)',
805
+ '1.313.000 (-4.000)',
806
+ '1.073.500 (+8.500)',
807
+ '2.147.000 (+17.000)'],
808
+ ['1',
809
+ '1.343.000 (-4.000)',
810
+ '1.343.000 (-4.000)',
811
+ '1.104.000 (+8.000)',
812
+ '1.104.000 (+8.000)'],
813
+ ['0.5',
814
+ '2.886.000 (-8.000)',
815
+ '1.443.000 (-4.000)',
816
+ '1.208.000 (+8.000)',
817
+ '604.000 (+4.000)'],
818
+ ['Update harga LM Antam :22 April 2024, pukul 08:09Harga pembelian kembali '
819
+ ':Rp. 1.238.000/gram (-4.000)',
820
+ 'Update harga LM Pegadaian :31 Agustus 2023']],
821
+ [['Spot Harga Emas Hari Ini (Market Open)'],
822
+ ['Satuan', 'USD', 'Kurs\xa0Dollar', 'IDR'],
823
+ ['Ounce\xa0(oz)', '2.325,78 (-4,35)', '16.280,00', '37.863.698'],
824
+ ['Gram\xa0(gr)', '74,78', '16.280,00', '1.217.346 (-2.277)'],
825
+ ['Kilogram\xa0(kg)', '74.775,56', '16.280,00', '1.217.346.173'],
826
+ ['Update harga emas :23 April 2024, pukul 05:00Update kurs :22 April 2024, '
827
+ 'pukul 13:10']],
828
+ [['Gram', 'UBS Gold 99.99%'],
829
+ ['Jual', 'Beli'],
830
+ ['/ Batang', '/ Gram', '/ Batang', '/ Gram'],
831
+ ['100', '128.200.000', '1.282.000', '127.085.000', '1.270.850'],
832
+ ['50', '64.250.000', '1.285.000', '63.595.000', '1.271.900'],
833
+ ['25', '32.150.000', '1.286.000', '31.900.000', '1.276.000'],
834
+ ['10', '12.910.000', '1.291.000', '12.810.000', '1.281.000'],
835
+ ['5', '6.480.000', '1.296.000', '6.457.000', '1.291.400'],
836
+ ['1', '1.340.000', '1.340.000', '1.324.000', '1.324.000'],
837
+ ['', 'Update :22 April 2024, pukul 11:58']],
838
+ [['Konversi Satuan'],
839
+ ['Satuan', 'Ounce (oz)', 'Gram (gr)', 'Kilogram (kg)'],
840
+ ['Ounce\xa0(oz)', '1', '31,1034767696', '0,0311034768'],
841
+ ['Gram\xa0(gr)', '0,0321507466', '1', '0.001'],
842
+ ['Kilogram\xa0(kg)', '32,1507466000', '1.000', '1']],
843
+ [['Pergerakan Harga Emas Dunia'],
844
+ ['Waktu', 'Emas'],
845
+ ['Unit', 'USD', 'IDR'],
846
+ ['Angka', '+/-', 'Angka', '+/-'],
847
+ ['Hari Ini', 'Kurs', '', '', '16.280', '%'],
848
+ ['oz', '2.330,13', '-4,35-0,19%', '37.934.516', '-70.818-0,19%'],
849
+ ['gr', '74,92', '-0,14-0,19%', '1.219.623', '-2.277-0,19%'],
850
+ ['30 Hari', 'Kurs', '', '', '15.662', '+618+3,95%'],
851
+ ['oz', '2.165,64', '+160,14+7,39%', '33.918.254', '+3.945.445+11,63%'],
852
+ ['gr', '69,63', '+5,15+7,39%', '1.090.497', '+126.849+11,63%'],
853
+ ['2 Bulan', 'Kurs', '', '', '15.630', '+650+4,16%'],
854
+ ['oz', '2.038,19', '+287,59+14,11%', '31.856.910', '+6.006.789+18,86%'],
855
+ ['gr', '65,53', '+9,25+14,11', '1.024.223', '+193.123+18,86%'],
856
+ ['6 Bulan', 'Kurs', '', '', '15.871', '+409+2,58%'],
857
+ ['oz', '1.984,00', '+341,78+17,23%', '31.488.064', '+6.375.634+20,25%'],
858
+ ['gr', '63,79', '+10,99+17,23%', '1.012.365', '+204.981+20,25%'],
859
+ ['1 Tahun', 'Kurs', '', '', '15.731', '+549+3,49%'],
860
+ ['oz', '1.823,86', '+501,92+27,52%', '28.691.142', '+9.172.557+31,97%'],
861
+ ['gr', '58,64', '+16,14+27,52%', '922.442', '+294.905+31,97%'],
862
+ ['2 Tahun', 'Kurs', '', '', '14.348', '+1.932+13,47%'],
863
+ ['oz', '1.931,96', '+393,82+20,38%', '27.719.762', '+10.143.936+36,59%'],
864
+ ['gr', '62,11', '+12,66+20,38%', '891.211', '+326.135+36,59%'],
865
+ ['3 Tahun', 'Kurs', '', '', '14.530', '+1.750+12,04%'],
866
+ ['oz', '1.777,11', '+548,67+30,87%', '25.821.408', '+12.042.290+46,64%'],
867
+ ['gr', '57,14', '+17,64+30,87%', '830.178', '+387.169+46,64%'],
868
+ ['5 Tahun', 'Kurs', '', '', '14.154', '+2.126+15,02%'],
869
+ ['oz', '1.277,64', '+1.048,14+82,04%', '18.083.717', '+19.779.982+109,38%'],
870
+ ['gr', '41,08', '+33,70+82,04%', '581.405', '+635.941+109,38%']])
871
+ (['Home', 'Emas 1 Gram', 'History', 'Trend', 'Perak 1 Gram', 'Pluang'],
872
+ [[''],
873
+ ['Emas 24 KaratHarga Emas 1 Gram', ''],
874
+ ['USD', '74,78↓', '-0,14-0,19%'],
875
+ ['KURS', '16.238,15↓', '-8,20-0,05%'],
876
+ ['IDR', '1.214.216,82↓', '-2.885,30-0,24%'],
877
+ ['Selasa, 23 April 2024 05:00']],
878
+ [[''],
879
+ ['Emas 1 Gram (IDR)Emas 1 Gram (USD)Kurs USD-IDR',
880
+ 'Hari Ini',
881
+ '1 Bulan',
882
+ '1 Tahun',
883
+ '5 Tahun',
884
+ 'Max',
885
+ '']],
886
+ [['Pergerakkan Harga Emas 1 Gram'],
887
+ ['', 'Penutupan Kemarin', 'Pergerakkan Hari Ini', 'Rata-rata'],
888
+ ['USD', '74,92', '74,78 - 74,92', '74,85'],
889
+ ['KURS', '16.246,35', '16.238,15 - 16.246,35', '16.242,25'],
890
+ ['IDR', '1.217.102,12', '1.214.216,82 - 1.217.102,12', '1.215.659,47'],
891
+ [''],
892
+ ['', 'Awal Tahun', 'Pergerakkan YTD', '+/- YTD'],
893
+ ['USD', '66,32', '64,07 - 77,14', '+8,46 (12,76%)'],
894
+ ['KURS', '15.390,10', '15.390,00 - 16.307,80', '+848,05 (5,51%)'],
895
+ ['IDR', '1.020.729,53', '997.660,12 - 1.256.829,06', '+193.487,29 (18,96%)'],
896
+ [''],
897
+ ['', 'Tahun Lalu / 52 Minggu', 'Pergerakkan 52 Minggu', '+/- 52 Minggu'],
898
+ ['USD', '63,76', '58,43 - 77,14', '+11,02 (17,28%)'],
899
+ ['KURS', '14.936,00', '14.669,40 - 16.307,80', '+1.302,15 (8,72%)'],
900
+ ['IDR', '952.339,68', '912.925,68 - 1.256.829,06', '+261.877,14 (27,50%)']])
901
+ ```
902
+
903
+ ## input_char
904
+
905
+ `input_char(prompt=None, prompt_ending='', newline_after_input=True, echo_char=True, default=None)`
906
+
907
+ Meminta masukan satu huruf tanpa menekan Enter.
908
+
909
+ ```py
910
+ input_char("Input char : ")
911
+ input_char("Input char : ", default='Y')
912
+ input_char("Input Char without print : ", echo_char=False)
913
+ ```
914
+
915
+ ## iopen
916
+
917
+ `iopen(path, data=None, regex=None, css_select=None, xpath=None, file_append=False)`
918
+
919
+ Membaca atau Tulis pada path yang bisa merupakan FILE maupun URL.
920
+
921
+ Baca File :
922
+ - Membaca seluruh file.
923
+ - Jika berhasil content dapat diparse dengan regex.
924
+ - Apabila File berupa html, dapat diparse dengan css atau xpath.
925
+
926
+ Tulis File :
927
+ - Menulis pada file.
928
+ - Jika file tidak ada maka akan dibuat.
929
+ - Jika file memiliki content maka akan di overwrite.
930
+
931
+ Membaca URL :
932
+ - Mengakses URL dan mengembalikan isi html nya berupa teks.
933
+ - Content dapat diparse dengan regex, css atau xpath.
934
+
935
+ Tulis URL :
936
+ - Mengirimkan data dengan metode POST ke url.
937
+ - Jika berhasil dan response memiliki content, maka dapat diparse
938
+ dengan regex, css atau xpath.
939
+
940
+
941
+ ```python
942
+ # FILE
943
+ print(iopen("__iopen.txt", "mana aja"))
944
+ print(iopen("__iopen.txt", regex="(\w+)"))
945
+ # URL
946
+ print(iopen("https://www.google.com/", css_select="a"))
947
+ print(iopen("https://www.google.com/", dict(coba="dulu"), xpath="//a"))
948
+ ```
949
+
950
+ Output:
951
+ ```py
952
+ 8
953
+ ['mana', 'aja']
954
+ [<Element a at 0x76f9498d20>, <Element a at 0x76ef6ba620>, <Element a at 0x76ef701090>, <Element a at 0x76ef701130>, <Element a at 0x76ef701180>, <Element a at 0x76ef7011d0>, <Element a at 0x76ef701220>, <Element a at 0x76ef701270>, <Element a at 0x76ef7012c0>, <Element a at 0x76ef701310>, <Element a at 0x76ef701360>, <Element a at 0x76ef7013b0>, <Element a at 0x76ef701400>, <Element a at 0x76ef701450>, <Element a at 0x76ef7014a0>, <Element a at 0x76ef7014f0>, <Element a at 0x76ef701540>, <Element a at 0x76ef701590>]
955
+ False
956
+ ```
957
+
958
+ ## iprint
959
+
960
+ `iprint(*args, color=None, sort_dicts=False, **kwargs)`
961
+
962
+ Improve print function dengan menambahkan color dan pretty print
963
+ Color menggunakan colorama Fore + Back + Style
964
+
965
+ ```python
966
+ import colorama
967
+ iprint(
968
+ 'yang ini',
969
+ {'12':12,'sdsd':{'12':21,'as':[88]}},
970
+ color=colorama.Fore.BLUE + colorama.Style.BRIGHT
971
+ )
972
+ ```
973
+
974
+ Output:
975
+ ```py
976
+ yang ini {'12': 12, 'sdsd': {'12': 21, 'as': [88]}}
977
+ ```
978
+
979
+ ## irange
980
+
981
+ `irange(start, finish, step=1)`
982
+
983
+ Meningkatkan fungsi range() dari python untuk pengulangan menggunakan huruf
984
+
985
+ ```python
986
+ print(irange('a', 'c'))
987
+ print(irange('z', 'a', 10))
988
+ print(list(irange('a', 'z', 10)))
989
+ print(list(irange(1, '7')))
990
+ print(list(irange(10, 5)))
991
+ ```
992
+
993
+ Output:
994
+ ```py
995
+ <generator object irange at 0x76ef833bc0>
996
+ <generator object irange at 0x76ef833bc0>
997
+ ['a', 'k', 'u']
998
+ [1, 2, 3, 4, 5, 6, 7]
999
+ [10, 9, 8, 7, 6, 5]
1000
+ ```
1001
+
1002
+ ## ireplace
1003
+
1004
+ `ireplace(string: str, replacements: dict, flags=re.IGNORECASE|re.MULTILINE|re.DOTALL)`
1005
+
1006
+ STRing TRanslate mengubah string menggunakan kamus dari dict.
1007
+ Replacement dapat berupa text biasa ataupun regex pattern.
1008
+ Apabila replacement berupa regex, gunakan raw string `r"..."`
1009
+ Untuk regex capturing gunakan `(...)`, dan untuk mengaksesnya
1010
+ gunakan `\1`, `\2`, .., dst.
1011
+
1012
+ ```python
1013
+ text = 'aku ini mau ke sini'
1014
+ replacements = {
1015
+ "sini": "situ",
1016
+ r"(ini)": r"itu dan \1",
1017
+ }
1018
+ print(ireplace(text, replacements))
1019
+ ```
1020
+
1021
+ Output:
1022
+ ```py
1023
+ aku itu dan ini mau ke situ
1024
+ ```
1025
+
1026
+ ## is_empty
1027
+
1028
+ `is_empty(variable, empty=[None, False, 0, 0, '0', '', '-0', '\n', '\t', set(), {}, [], ()])`
1029
+
1030
+ Mengecek apakah variable setara dengan nilai kosong pada empty.
1031
+
1032
+ Pengecekan nilai yang setara menggunakan simbol '==', sedangkan untuk
1033
+ pengecekan lokasi memory yang sama menggunakan keyword 'is'
1034
+
1035
+ ```python
1036
+ print(is_empty("teks"))
1037
+ print(is_empty(True))
1038
+ print(is_empty(False))
1039
+ print(is_empty(None))
1040
+ print(is_empty(0))
1041
+ print(is_empty([]))
1042
+ ```
1043
+
1044
+ Output:
1045
+ ```py
1046
+ False
1047
+ False
1048
+ True
1049
+ True
1050
+ True
1051
+ True
1052
+ ```
1053
+
1054
+ ## is_iterable
1055
+
1056
+ `is_iterable(var, str_is_iterable=False)`
1057
+
1058
+ Mengecek apakah suatu variabel bisa dilakukan forloop atau tidak
1059
+
1060
+ ```python
1061
+ s = 'ini string'
1062
+ print(is_iterable(s))
1063
+
1064
+ l = [12,21,2,1]
1065
+ print(is_iterable(l))
1066
+
1067
+ r = range(100)
1068
+ print(is_iterable(r))
1069
+
1070
+ d = {'a':1, 'b':2}
1071
+ print(is_iterable(d.values()))
1072
+ ```
1073
+
1074
+ Output:
1075
+ ```py
1076
+ False
1077
+ True
1078
+ True
1079
+ True
1080
+ ```
1081
+
1082
+ ## is_valid_url
1083
+
1084
+ `is_valid_url(path)`
1085
+
1086
+ Mengecek apakah path merupakan URL yang valid atau tidak.
1087
+ Cara ini merupakan cara yang paling efektif.
1088
+
1089
+ ```python
1090
+ print(is_valid_url("https://chat.openai.com/?model=text-davinci-002-render-sha"))
1091
+ print(is_valid_url("https://chat.openai.com/?model/=text-dav/inci-002-render-sha"))
1092
+ ```
1093
+
1094
+ Output:
1095
+ ```py
1096
+ True
1097
+ True
1098
+ ```
1099
+
1100
+ ## iscandir
1101
+
1102
+ `iscandir(folder_name='.', glob_pattern='*', recursive=True, scan_file=True, scan_folder=True)`
1103
+
1104
+ Mempermudah scandir untuk mengumpulkan folder dan file.
1105
+
1106
+ ```python
1107
+ print(iscandir())
1108
+ print(list(iscandir("./", recursive=False, scan_file=False)))
1109
+ ```
1110
+
1111
+ Output:
1112
+ ```py
1113
+ <generator object iscandir at 0x76ef875640>
1114
+ [PosixPath('.git'), PosixPath('.vscode'), PosixPath('pypipr'), PosixPath('__pycache__'), PosixPath('dist')]
1115
+ ```
1116
+
1117
+ ## isplit
1118
+
1119
+ `isplit(text, separator='', include_separator=False)`
1120
+
1121
+ Memecah text menjadi list berdasarkan separator.
1122
+
1123
+ ```python
1124
+ t = '/ini/contoh/path/'
1125
+ print(isplit(t, separator='/'))
1126
+ ```
1127
+
1128
+ Output:
1129
+ ```py
1130
+ ['', 'ini', 'contoh', 'path', '']
1131
+ ```
1132
+
1133
+ ## log
1134
+
1135
+ `log(text=None)`
1136
+
1137
+ Decorator untuk mempermudah pembuatan log karena tidak perlu mengubah
1138
+ fungsi yg sudah ada.
1139
+ Melakukan print ke console untuk menginformasikan proses yg sedang
1140
+ berjalan didalam program.
1141
+
1142
+ ```py
1143
+ @log
1144
+ def some_function():
1145
+ pass
1146
+
1147
+ @log()
1148
+ def some_function_again():
1149
+ pass
1150
+
1151
+ @log("Calling some function")
1152
+ def some_function_more():
1153
+ pass
1154
+
1155
+ some_function()
1156
+ some_function_again()
1157
+ some_function_more()
1158
+ ```
1159
+
1160
+ ## password_generator
1161
+
1162
+ `password_generator(length=8, characters='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~')`
1163
+
1164
+ Membuat pssword secara acak
1165
+
1166
+ ```python
1167
+ print(password_generator())
1168
+ ```
1169
+
1170
+ Output:
1171
+ ```py
1172
+ 1,7'~v%p
1173
+ ```
1174
+
1175
+ ## pip_freeze_without_version
1176
+
1177
+ `pip_freeze_without_version(filename=None)`
1178
+
1179
+ Memberikan list dari dependencies yang terinstall tanpa version.
1180
+ Bertujuan untuk menggunakan Batteries Included Python.
1181
+
1182
+ ```py
1183
+ print(pip_freeze_without_version())
1184
+ ```
1185
+
1186
+ ## poetry_publish
1187
+
1188
+ `poetry_publish(token=None)`
1189
+
1190
+ Publish project to pypi,org
1191
+
1192
+ ```py
1193
+ poetry_publish()
1194
+ ```
1195
+
1196
+ ## poetry_update_version
1197
+
1198
+ `poetry_update_version(mayor=False, minor=False, patch=False)`
1199
+
1200
+ Update versi pada pyproject.toml menggunakan poetry
1201
+
1202
+ ```py
1203
+ poetry_update_version()
1204
+ ```
1205
+
1206
+ ## print_colorize
1207
+
1208
+ `print_colorize(text, color='\x1b[32m', bright='\x1b[1m', color_end='\x1b[0m', text_start='', text_end='\n')`
1209
+
1210
+ Print text dengan warna untuk menunjukan text penting
1211
+
1212
+ ```py
1213
+ print_colorize("Print some text")
1214
+ print_colorize("Print some text", color=colorama.Fore.RED)
1215
+ ```
1216
+
1217
+ ## print_dir
1218
+
1219
+ `print_dir(var, colorize=True)`
1220
+
1221
+ Print property dan method yang tersedia pada variabel
1222
+
1223
+ ```python
1224
+ import pathlib
1225
+ p = pathlib.Path("https://www.google.com/")
1226
+ print_dir(p, colorize=False)
1227
+ ```
1228
+
1229
+ Output:
1230
+ ```py
1231
+ __bytes__ : b'https:/www.google.com'
1232
+ __class__ : .
1233
+ __dir__ : ['__module__', '__doc__', '__slots__', '__new__', '_make_child_relpath', '__enter__', '__exit__', 'cwd', 'home', 'samefile', 'iterdir', '_scandir', 'glob', 'rglob', 'absolute', 'resolve', 'stat', 'owner', 'group', 'open', 'read_bytes', 'read_text', 'write_bytes', 'write_text', 'readlink', 'touch', 'mkdir', 'chmod', 'lchmod', 'unlink', 'rmdir', 'lstat', 'rename', 'replace', 'symlink_to', 'hardlink_to', 'link_to', 'exists', 'is_dir', 'is_file', 'is_mount', 'is_symlink', 'is_block_device', 'is_char_device', 'is_fifo', 'is_socket', 'expanduser', '__reduce__', '_parse_args', '_from_parts', '_from_parsed_parts', '_format_parsed_parts', '_make_child', '__str__', '__fspath__', 'as_posix', '__bytes__', '__repr__', 'as_uri', '_cparts', '__eq__', '__hash__', '__lt__', '__le__', '__gt__', '__ge__', 'drive', 'root', 'anchor', 'name', 'suffix', 'suffixes', 'stem', 'with_name', 'with_stem', 'with_suffix', 'relative_to', 'is_relative_to', 'parts', 'joinpath', '__truediv__', '__rtruediv__', 'parent', 'parents', 'is_absolute', 'is_reserved', 'match', '_cached_cparts', '_drv', '_hash', '_parts', '_pparts', '_root', '_str', '__getattribute__', '__setattr__', '__delattr__', '__ne__', '__init__', '__reduce_ex__', '__getstate__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__', '_flavour']
1234
+ __doc__ : Path subclass for non-Windows systems.
1235
+
1236
+ On a POSIX system, instantiating a Path should return this object.
1237
+
1238
+ __enter__ : https:/www.google.com
1239
+ __fspath__ : https:/www.google.com
1240
+ __getstate__ : (None, {'_drv': '', '_root': '', '_parts': ['https:', 'www.google.com'], '_str': 'https:/www.google.com'})
1241
+ __hash__ : -9044097875519772453
1242
+ __init__ : None
1243
+ __init_subclass__ : None
1244
+ __module__ : pathlib
1245
+ __reduce__ : (<class 'pathlib.PosixPath'>, ('https:', 'www.google.com'))
1246
+ __repr__ : PosixPath('https:/www.google.com')
1247
+ __sizeof__ : 72
1248
+ __slots__ : ()
1249
+ __str__ : https:/www.google.com
1250
+ __subclasshook__ : NotImplemented
1251
+ _cached_cparts : ['https:', 'www.google.com']
1252
+ _cparts : ['https:', 'www.google.com']
1253
+ _drv :
1254
+ _flavour : <pathlib._PosixFlavour object at 0x76ffdb35d0>
1255
+ _hash : -9044097875519772453
1256
+ _parts : ['https:', 'www.google.com']
1257
+ _root :
1258
+ _str : https:/www.google.com
1259
+ absolute : /data/data/com.termux/files/home/pypipr/https:/www.google.com
1260
+ anchor :
1261
+ as_posix : https:/www.google.com
1262
+ cwd : /data/data/com.termux/files/home/pypipr
1263
+ drive :
1264
+ exists : False
1265
+ expanduser : https:/www.google.com
1266
+ home : /data/data/com.termux/files/home
1267
+ is_absolute : False
1268
+ is_block_device : False
1269
+ is_char_device : False
1270
+ is_dir : False
1271
+ is_fifo : False
1272
+ is_file : False
1273
+ is_mount : False
1274
+ is_reserved : False
1275
+ is_socket : False
1276
+ is_symlink : False
1277
+ iterdir : <generator object Path.iterdir at 0x76f8d3a340>
1278
+ joinpath : https:/www.google.com
1279
+ name : www.google.com
1280
+ parent : https:
1281
+ parents : <PosixPath.parents>
1282
+ parts : ('https:', 'www.google.com')
1283
+ resolve : /data/data/com.termux/files/home/pypipr/https:/www.google.com
1284
+ root :
1285
+ stem : www.google
1286
+ suffix : .com
1287
+ suffixes : ['.google', '.com']
1288
+ ```
1289
+
1290
+ ## print_log
1291
+
1292
+ `print_log(text)`
1293
+
1294
+ Akan melakukan print ke console.
1295
+ Berguna untuk memberikan informasi proses program yg sedang berjalan.
1296
+
1297
+ ```python
1298
+ print_log("Standalone Log")
1299
+ ```
1300
+
1301
+ Output:
1302
+ ```py
1303
+ >>> Standalone Log
1304
+ ```
1305
+
1306
+ ## print_to_last_line
1307
+
1308
+ `print_to_last_line(text: str)`
1309
+
1310
+ Melakukan print ke konsol tetapi akan menimpa baris terakhir.
1311
+ Berguna untuk memberikan progress secara interaktif.
1312
+
1313
+ ```python
1314
+ c = input("masukkan apa saja : ")
1315
+ print_to_last_line(f"masukkan apa saja : {c} [ok]")
1316
+ ```
1317
+
1318
+ Output:
1319
+ ```py
1320
+ masukkan apa saja : masukkan apa saja : [ok]
1321
+ ```
1322
+
1323
+ ## random_bool
1324
+
1325
+ `random_bool()`
1326
+
1327
+ Menghasilkan nilai random True atau False.
1328
+ Fungsi ini merupakan fungsi tercepat untuk mendapatkan random bool.
1329
+ Fungsi ini sangat cepat, tetapi pemanggilan fungsi ini membutuhkan
1330
+ overhead yg besar.
1331
+
1332
+ ```python
1333
+ print(random_bool())
1334
+ ```
1335
+
1336
+ Output:
1337
+ ```py
1338
+ True
1339
+ ```
1340
+
1341
+ ## set_timeout
1342
+
1343
+ `set_timeout(interval, func, args=None, kwargs=None)`
1344
+
1345
+ Menjalankan fungsi ketika sudah sekian detik.
1346
+ Apabila timeout masih berjalan tapi kode sudah selesai dieksekusi semua, maka
1347
+ program tidak akan berhenti sampai timeout selesai, kemudian fungsi dijalankan,
1348
+ kemudian program dihentikan.
1349
+
1350
+ ```python
1351
+ set_timeout(3, lambda: print("Timeout 3"))
1352
+ x = set_timeout(7, print, args=["Timeout 7"])
1353
+ print(x)
1354
+ print("menghentikan timeout 7")
1355
+ x.cancel()
1356
+ ```
1357
+
1358
+ Output:
1359
+ ```py
1360
+ <Timer(Thread-2, started 510794906864)>
1361
+ menghentikan timeout 7
1362
+ ```
1363
+
1364
+ ## sets_ordered
1365
+
1366
+ `sets_ordered(iterator)`
1367
+
1368
+ Hanya mengambil nilai unik dari suatu list
1369
+
1370
+ ```python
1371
+ array = [2, 3, 12, 3, 3, 42, 42, 1, 43, 2, 42, 41, 4, 24, 32, 42, 3, 12, 32, 42, 42]
1372
+ print(sets_ordered(array))
1373
+ print(list(sets_ordered(array)))
1374
+ ```
1375
+
1376
+ Output:
1377
+ ```py
1378
+ <generator object sets_ordered at 0x76ef89dbe0>
1379
+ [2, 3, 12, 42, 1, 43, 41, 4, 24, 32]
1380
+ ```
1381
+
1382
+ ## str_cmp
1383
+
1384
+ `str_cmp(t1, t2)`
1385
+
1386
+ Membandingakan string secara incase-sensitive menggunakan lower().
1387
+ Lebih cepat dibandingkan upper(), casefold(), re.fullmatch(), len().
1388
+ perbandingan ini sangat cepat, tetapi pemanggilan fungsi ini membutuhkan
1389
+ overhead yg besar.
1390
+
1391
+ ```python
1392
+ print(str_cmp('teks1', 'Teks1'))
1393
+ ```
1394
+
1395
+ Output:
1396
+ ```py
1397
+ True
1398
+ ```
1399
+
1400
+ ## text_colorize
1401
+
1402
+ `text_colorize(text, color='\x1b[32m', bright='\x1b[1m', color_end='\x1b[0m')`
1403
+
1404
+ return text dengan warna untuk menunjukan text penting
1405
+
1406
+ ```py
1407
+ text_colorize("Print some text")
1408
+ text_colorize("Print some text", color=colorama.Fore.RED)
1409
+ ```
1410
+
1411
+ ## to_str
1412
+
1413
+ `to_str(value)`
1414
+
1415
+ Mengubah value menjadi string literal
1416
+
1417
+ ```python
1418
+ print(to_str(5))
1419
+ print(to_str([]))
1420
+ print(to_str(False))
1421
+ print(to_str(True))
1422
+ print(to_str(None))
1423
+ ```
1424
+
1425
+ Output:
1426
+ ```py
1427
+ 5
1428
+
1429
+ False
1430
+ True
1431
+
1432
+ ```
1433
+
1434
+ # CLASS
1435
+
1436
+ ## APIMixinView
1437
+
1438
+ `APIMixinView`
1439
+
1440
+ APIView adalah class view untuk membuat Website API
1441
+ Cara kerjanya adalah dengan menggunakan variabel GET untuk menerima data.
1442
+
1443
+ Class ini tidak bisa digunakan sendiri.
1444
+ Class ini harus menjadi mixin Class View karena perlu trigger untuk
1445
+ memanggil method get().
1446
+
1447
+ ```py
1448
+ class ExampleAPIView(APIMixinView, View):
1449
+ pass
1450
+ ```
1451
+
1452
+ ## ComparePerformance
1453
+
1454
+ `ComparePerformance`
1455
+
1456
+ Menjalankan seluruh method dalam class,
1457
+ Kemudian membandingkan waktu yg diperlukan.
1458
+ Nilai 100 berarti yang tercepat.
1459
+
1460
+ ```python
1461
+ class ExampleComparePerformance(ComparePerformance):
1462
+ # number = 1
1463
+ z = 10
1464
+
1465
+ def a(self):
1466
+ return (x for x in range(self.z))
1467
+
1468
+ def b(self):
1469
+ return tuple(x for x in range(self.z))
1470
+
1471
+ def c(self):
1472
+ return [x for x in range(self.z)]
1473
+
1474
+ def d(self):
1475
+ return list(x for x in range(self.z))
1476
+
1477
+ pprint.pprint(ExampleComparePerformance().compare_result(), depth=100)
1478
+ print(ExampleComparePerformance().compare_performance())
1479
+ print(ExampleComparePerformance().compare_performance())
1480
+ print(ExampleComparePerformance().compare_performance())
1481
+ print(ExampleComparePerformance().compare_performance())
1482
+ print(ExampleComparePerformance().compare_performance())
1483
+ ```
1484
+
1485
+ ## PintUregQuantity
1486
+
1487
+ `PintUregQuantity`
1488
+
1489
+ ## RunParallel
1490
+
1491
+ `RunParallel`
1492
+
1493
+ Menjalankan program secara bersamaan.
1494
+
1495
+ - `class RunParallel` didesain hanya untuk pemrosesan data saja.
1496
+ - Penggunaannya `class RunParallel` dengan cara membuat instance
1497
+ sub class beserta data yg akan diproses, kemudian panggil fungsi
1498
+ yg dipilih `run_asyncio / run_multi_threading / run_multi_processing`,
1499
+ kemudian dapatkan hasilnya.
1500
+ - `class RunParallel` tidak didesain untuk menyimpan data, karena
1501
+ setiap module terutama module `multiprocessing` tidak dapat mengakses
1502
+ data kelas dari proses yg berbeda.
1503
+ - Semua methods akan dijalankan secara paralel kecuali method dengan
1504
+ nama yg diawali underscore `_`
1505
+ - Method untuk multithreading/multiprocessing harus memiliki 2
1506
+ parameter, yaitu: `result: dict` dan `q: queue.Queue`. Parameter
1507
+ `result` digunakan untuk memberikan return value dari method, dan
1508
+ Parameter `q` digunakan untuk mengirim data antar proses.
1509
+ - Method untuk asyncio harus menggunakan keyword `async def`, dan
1510
+ untuk perpindahan antar kode menggunakan `await asyncio.sleep(0)`,
1511
+ dan keyword `return` untuk memberikan return value.
1512
+ - Return Value berupa dictionary dengan key adalah nama function,
1513
+ dan value adalah return value dari setiap fungsi
1514
+ - Menjalankan Multiprocessing harus berada dalam blok
1515
+ `if __name__ == "__main__":` karena area global pada program akan
1516
+ diproses lagi. Terutama pada sistem operasi windows.
1517
+ - `run_asyncio()` akan menjalankan kode dalam satu program, hanya
1518
+ saja alur program dapat berpindah-pindah menggunkan
1519
+ `await asyncio.sleep(0)`.
1520
+ - `run_multi_threading()` akan menjalankan program dalam satu CPU,
1521
+ hanya saja dalam thread yang berbeda. Walaupun tidak benar-benar
1522
+ berjalan secara bersamaan namun bisa meningkatkan kecepatan
1523
+ penyelesaian program, dan dapat saling mengakses resource antar
1524
+ program. Akses resource antar program bisa secara langsung maupun
1525
+ menggunakan parameter yang sudah disediakan yaitu `result: dict`
1526
+ dan `q: queue.Queue`.
1527
+ - `run_multi_processing()` akan menjalankan program dengan beberapa
1528
+ CPU. Program akan dibuatkan environment sendiri yang terpisah dari
1529
+ program induk. Keuntungannya adalah program dapat benar-benar berjalan
1530
+ bersamaan, namun tidak dapat saling mengakses resource secara langsung.
1531
+ Akses resource menggunakan parameter yang sudah disediakan yaitu
1532
+ `result: dict` dan `q: queue.Queue`.
1533
+
1534
+ ```python
1535
+ class ExampleRunParallel(RunParallel):
1536
+ z = "ini"
1537
+
1538
+ def __init__(self) -> None:
1539
+ self.pop = random.randint(0, 100)
1540
+
1541
+ def _set_property_here(self, v):
1542
+ self.prop = v
1543
+
1544
+ def a(self, result: dict, q: queue.Queue):
1545
+ result["z"] = self.z
1546
+ result["pop"] = self.pop
1547
+ result["a"] = "a"
1548
+ q.put("from a 1")
1549
+ q.put("from a 2")
1550
+
1551
+ def b(self, result: dict, q: queue.Queue):
1552
+ result["z"] = self.z
1553
+ result["pop"] = self.pop
1554
+ result["b"] = "b"
1555
+ result["q_get"] = q.get()
1556
+
1557
+ def c(self, result: dict, q: queue.Queue):
1558
+ result["z"] = self.z
1559
+ result["pop"] = self.pop
1560
+ result["c"] = "c"
1561
+ result["q_get"] = q.get()
1562
+
1563
+ async def d(self):
1564
+ print("hello")
1565
+ await asyncio.sleep(0)
1566
+ print("hello")
1567
+
1568
+ result = {}
1569
+ result["z"] = self.z
1570
+ result["pop"] = self.pop
1571
+ result["d"] = "d"
1572
+ return result
1573
+
1574
+ async def e(self):
1575
+ print("world")
1576
+ await asyncio.sleep(0)
1577
+ print("world")
1578
+
1579
+ result = {}
1580
+ result["z"] = self.z
1581
+ result["pop"] = self.pop
1582
+ result["e"] = "e"
1583
+ return result
1584
+
1585
+ if __name__ == "__main__":
1586
+ print(ExampleRunParallel().run_asyncio())
1587
+ print(ExampleRunParallel().run_multi_threading())
1588
+ print(ExampleRunParallel().run_multi_processing())
1589
+ ```
1590
+