├── static ├── .nojekyll ├── CNAME └── img │ ├── favicon.png │ ├── favicon-v1.png │ ├── logo_small.png │ ├── cover ebook rust.png │ ├── cover_media_share.png │ ├── logo_small_dark.png │ ├── logo_small_light.png │ ├── cover ebook golang.png │ └── cover ebook python.png ├── README.md ├── docs-wip ├── wip-generic.md ├── wip-unit-test.md ├── wip-string-formatting.md ├── wip-pengelanan-python-programming.md ├── wip-standard-library.md ├── wip-async-io.md └── wip-type-metaclass.md ├── CHANGELOG.md ├── .github ├── FUNDING.yml └── workflows │ ├── ci.yaml │ └── cd.yaml ├── CNAME ├── .gitattributes ├── etc ├── logo.psd ├── cover ebook.pdf ├── cover ebook.psd ├── cover media share.psd └── cover media share square.psd ├── docs ├── installation │ ├── _category_.json │ ├── img │ │ └── instalasi-python.png │ ├── python-editor-plugin.md │ └── instalasi-python.md ├── basic │ ├── _category_.json │ ├── img │ │ ├── csv-1.png │ │ ├── csv-2.png │ │ ├── csv-3.png │ │ ├── csv-4.png │ │ ├── del-1.png │ │ ├── set-1.png │ │ ├── set-2.png │ │ ├── file-1.png │ │ ├── file-2.png │ │ ├── file-3.png │ │ ├── file-4.png │ │ ├── file-5.png │ │ ├── file-6.png │ │ ├── json-1.png │ │ ├── list-1.png │ │ ├── list-2.png │ │ ├── list-3.png │ │ ├── list-4.png │ │ ├── slice-1.png │ │ ├── slice-2.png │ │ ├── slice-3.png │ │ ├── slice-4.png │ │ ├── slice-5.png │ │ ├── slice-6.png │ │ ├── slice-7.png │ │ ├── slice-8.png │ │ ├── string-1.png │ │ ├── string-2.png │ │ ├── template.psd │ │ ├── tuple-1.png │ │ ├── tuple-2.png │ │ ├── tuple-3.png │ │ ├── while-1.png │ │ ├── while-2.png │ │ ├── while-3.png │ │ ├── closure-1.png │ │ ├── function-1.png │ │ ├── function-2.png │ │ ├── function-3.png │ │ ├── function-4.png │ │ ├── komentar-1.png │ │ ├── modules-1.png │ │ ├── modules-2.png │ │ ├── operator-1.png │ │ ├── operator-2.png │ │ ├── packages-1.png │ │ ├── packages-2.png │ │ ├── dataclass-1.png │ │ ├── decorator-1.png │ │ ├── decorator-2.png │ │ ├── dictionary-1.png │ │ ├── dictionary-2.png │ │ ├── dictionary-3.png │ │ ├── dictionary-4.png │ │ ├── docstring-1.png │ │ ├── docstring-2.png │ │ ├── docstring-3.png │ │ ├── docstring-4.png │ │ ├── docstring-5.png │ │ ├── docstring-6.png │ │ ├── for-range-1.png │ │ ├── for-range-10.png │ │ ├── for-range-11.png │ │ ├── for-range-2.png │ │ ├── for-range-3.png │ │ ├── for-range-4.png │ │ ├── for-range-5.png │ │ ├── for-range-6.png │ │ ├── for-range-7.png │ │ ├── for-range-8.png │ │ ├── for-range-9.png │ │ ├── konstanta-1.png │ │ ├── variables-1.png │ │ ├── variables-2.png │ │ ├── class-method-1.png │ │ ├── class-object-1.png │ │ ├── class-object-2.png │ │ ├── class-object-3.png │ │ ├── class-object-4.png │ │ ├── class-object-5.png │ │ ├── hello-python-1.png │ │ ├── hello-python-2.png │ │ ├── hello-python-3.png │ │ ├── hello-python-4.png │ │ ├── hello-python-5.png │ │ ├── if-elif-else-1.png │ │ ├── if-elif-else-2.png │ │ ├── if-elif-else-3.png │ │ ├── if-elif-else-4.png │ │ ├── if-elif-else-5.png │ │ ├── special-names-1.png │ │ ├── special-names-2.png │ │ ├── special-names-3.png │ │ ├── abstract-method-1.png │ │ ├── abstract-method-2.png │ │ ├── abstract-method-3.png │ │ ├── break-continue-1.png │ │ ├── break-continue-2.png │ │ ├── error-exception-1.png │ │ ├── error-exception-2.png │ │ ├── error-exception-3.png │ │ ├── error-exception-4.png │ │ ├── error-exception-5.png │ │ ├── instance-method-1.png │ │ ├── instance-method-2.png │ │ ├── instance-method-3.png │ │ ├── instance-method-4.png │ │ ├── local-global-var-1.png │ │ ├── local-global-var-2.png │ │ ├── number-bilangan-1.png │ │ ├── number-bilangan-2.png │ │ ├── number-bilangan-3.png │ │ ├── number-bilangan-4.png │ │ ├── number-bilangan-5.png │ │ ├── pattern-matching-1.png │ │ ├── pattern-matching-2.png │ │ ├── pattern-matching-3.png │ │ ├── pattern-matching-4.png │ │ ├── pattern-matching-5.png │ │ ├── pattern-matching-6.png │ │ ├── pattern-matching-7.png │ │ ├── pattern-matching-8.png │ │ ├── class-inheritance-1.png │ │ ├── class-inheritance-2.png │ │ ├── class-inheritance-3.png │ │ ├── class-inheritance-4.png │ │ ├── cli-arguments-flags-1.png │ │ ├── cli-arguments-flags-2.png │ │ ├── cli-arguments-flags-3.png │ │ ├── cli-arguments-flags-4.png │ │ ├── cli-arguments-flags-5.png │ │ ├── cli-arguments-flags-6.png │ │ ├── object-id-reference-1.png │ │ ├── object-id-reference-10.png │ │ ├── object-id-reference-11.png │ │ ├── object-id-reference-2.png │ │ ├── object-id-reference-3.png │ │ ├── object-id-reference-4.png │ │ ├── object-id-reference-5.png │ │ ├── object-id-reference-6.png │ │ ├── object-id-reference-7.png │ │ ├── object-id-reference-8.png │ │ ├── object-id-reference-9.png │ │ ├── pack-unpack-elements-1.png │ │ ├── property-visibility-1.png │ │ ├── property-visibility-2.png │ │ ├── duck-typing-vs-structural-typing-1.png │ │ ├── instance-attribute-class-attribute-1.png │ │ ├── positional-optional-keyword-argument-1.png │ │ ├── positional-optional-keyword-argument-2.png │ │ ├── exception-handling-try-except-else-finally-1.png │ │ ├── exception-handling-try-except-else-finally-2.png │ │ ├── exception-handling-try-except-else-finally-3.png │ │ ├── exception-handling-try-except-else-finally-4.png │ │ ├── exception-handling-try-except-else-finally-5.png │ │ ├── exception-handling-try-except-else-finally-6.png │ │ └── exception-handling-try-except-else-finally-7.png │ ├── run-program-python.md │ ├── komentar.md │ ├── hello-python.md │ ├── konstanta.md │ ├── none.md │ ├── break-continue.md │ ├── del.md │ ├── while.md │ ├── generator-yield.md │ ├── list-comprehension.md │ ├── property-visibility.md │ ├── error-exception.md │ ├── variabel.md │ ├── eval-exec.md │ ├── unicode.md │ ├── abstract-method.md │ ├── enum.md │ ├── local-global-var.md │ ├── tipe-data.md │ ├── slice.md │ ├── iterable-iterator.md │ ├── static-method.md │ ├── dataclass.md │ ├── closure.md │ ├── docstring.md │ └── duck-typing-vs-structural-typing.md ├── download-pdf.md ├── LICENSE.md ├── CHANGELOG.md ├── CONTRIBUTING.md └── index.md ├── babel.config.js ├── .gitmodules ├── .vscode └── settings.json ├── .gitignore ├── src-local └── css │ └── custom.css ├── docusaurus.config.js ├── sidebars.js └── package.json /static/.nojekyll: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | docs/index.md -------------------------------------------------------------------------------- /docs-wip/wip-generic.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs-wip/wip-unit-test.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | docs/CHANGELOG.md -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: novalagung 2 | -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | dasarpemrogramanpython.novalagung.com -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.* linguist-language=Python 2 | -------------------------------------------------------------------------------- /static/CNAME: -------------------------------------------------------------------------------- 1 | dasarpemrogramanpython.novalagung.com -------------------------------------------------------------------------------- /etc/logo.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/etc/logo.psd -------------------------------------------------------------------------------- /docs/installation/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Persiapan dan Instalasi", 3 | "position": 6 4 | } 5 | -------------------------------------------------------------------------------- /etc/cover ebook.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/etc/cover ebook.pdf -------------------------------------------------------------------------------- /etc/cover ebook.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/etc/cover ebook.psd -------------------------------------------------------------------------------- /docs/basic/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Pemrograman Python Dasar", 3 | "position": 7 4 | } 5 | -------------------------------------------------------------------------------- /static/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/static/img/favicon.png -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')], 3 | }; 4 | -------------------------------------------------------------------------------- /docs/basic/img/csv-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/csv-1.png -------------------------------------------------------------------------------- /docs/basic/img/csv-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/csv-2.png -------------------------------------------------------------------------------- /docs/basic/img/csv-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/csv-3.png -------------------------------------------------------------------------------- /docs/basic/img/csv-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/csv-4.png -------------------------------------------------------------------------------- /docs/basic/img/del-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/del-1.png -------------------------------------------------------------------------------- /docs/basic/img/set-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/set-1.png -------------------------------------------------------------------------------- /docs/basic/img/set-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/set-2.png -------------------------------------------------------------------------------- /docs/basic/img/file-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/file-1.png -------------------------------------------------------------------------------- /docs/basic/img/file-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/file-2.png -------------------------------------------------------------------------------- /docs/basic/img/file-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/file-3.png -------------------------------------------------------------------------------- /docs/basic/img/file-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/file-4.png -------------------------------------------------------------------------------- /docs/basic/img/file-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/file-5.png -------------------------------------------------------------------------------- /docs/basic/img/file-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/file-6.png -------------------------------------------------------------------------------- /docs/basic/img/json-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/json-1.png -------------------------------------------------------------------------------- /docs/basic/img/list-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/list-1.png -------------------------------------------------------------------------------- /docs/basic/img/list-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/list-2.png -------------------------------------------------------------------------------- /docs/basic/img/list-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/list-3.png -------------------------------------------------------------------------------- /docs/basic/img/list-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/list-4.png -------------------------------------------------------------------------------- /docs/basic/img/slice-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/slice-1.png -------------------------------------------------------------------------------- /docs/basic/img/slice-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/slice-2.png -------------------------------------------------------------------------------- /docs/basic/img/slice-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/slice-3.png -------------------------------------------------------------------------------- /docs/basic/img/slice-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/slice-4.png -------------------------------------------------------------------------------- /docs/basic/img/slice-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/slice-5.png -------------------------------------------------------------------------------- /docs/basic/img/slice-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/slice-6.png -------------------------------------------------------------------------------- /docs/basic/img/slice-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/slice-7.png -------------------------------------------------------------------------------- /docs/basic/img/slice-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/slice-8.png -------------------------------------------------------------------------------- /docs/basic/img/string-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/string-1.png -------------------------------------------------------------------------------- /docs/basic/img/string-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/string-2.png -------------------------------------------------------------------------------- /docs/basic/img/template.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/template.psd -------------------------------------------------------------------------------- /docs/basic/img/tuple-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/tuple-1.png -------------------------------------------------------------------------------- /docs/basic/img/tuple-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/tuple-2.png -------------------------------------------------------------------------------- /docs/basic/img/tuple-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/tuple-3.png -------------------------------------------------------------------------------- /docs/basic/img/while-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/while-1.png -------------------------------------------------------------------------------- /docs/basic/img/while-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/while-2.png -------------------------------------------------------------------------------- /docs/basic/img/while-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/while-3.png -------------------------------------------------------------------------------- /etc/cover media share.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/etc/cover media share.psd -------------------------------------------------------------------------------- /static/img/favicon-v1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/static/img/favicon-v1.png -------------------------------------------------------------------------------- /static/img/logo_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/static/img/logo_small.png -------------------------------------------------------------------------------- /docs/basic/img/closure-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/closure-1.png -------------------------------------------------------------------------------- /docs/basic/img/function-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/function-1.png -------------------------------------------------------------------------------- /docs/basic/img/function-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/function-2.png -------------------------------------------------------------------------------- /docs/basic/img/function-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/function-3.png -------------------------------------------------------------------------------- /docs/basic/img/function-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/function-4.png -------------------------------------------------------------------------------- /docs/basic/img/komentar-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/komentar-1.png -------------------------------------------------------------------------------- /docs/basic/img/modules-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/modules-1.png -------------------------------------------------------------------------------- /docs/basic/img/modules-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/modules-2.png -------------------------------------------------------------------------------- /docs/basic/img/operator-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/operator-1.png -------------------------------------------------------------------------------- /docs/basic/img/operator-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/operator-2.png -------------------------------------------------------------------------------- /docs/basic/img/packages-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/packages-1.png -------------------------------------------------------------------------------- /docs/basic/img/packages-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/packages-2.png -------------------------------------------------------------------------------- /docs/basic/img/dataclass-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/dataclass-1.png -------------------------------------------------------------------------------- /docs/basic/img/decorator-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/decorator-1.png -------------------------------------------------------------------------------- /docs/basic/img/decorator-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/decorator-2.png -------------------------------------------------------------------------------- /docs/basic/img/dictionary-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/dictionary-1.png -------------------------------------------------------------------------------- /docs/basic/img/dictionary-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/dictionary-2.png -------------------------------------------------------------------------------- /docs/basic/img/dictionary-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/dictionary-3.png -------------------------------------------------------------------------------- /docs/basic/img/dictionary-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/dictionary-4.png -------------------------------------------------------------------------------- /docs/basic/img/docstring-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/docstring-1.png -------------------------------------------------------------------------------- /docs/basic/img/docstring-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/docstring-2.png -------------------------------------------------------------------------------- /docs/basic/img/docstring-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/docstring-3.png -------------------------------------------------------------------------------- /docs/basic/img/docstring-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/docstring-4.png -------------------------------------------------------------------------------- /docs/basic/img/docstring-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/docstring-5.png -------------------------------------------------------------------------------- /docs/basic/img/docstring-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/docstring-6.png -------------------------------------------------------------------------------- /docs/basic/img/for-range-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/for-range-1.png -------------------------------------------------------------------------------- /docs/basic/img/for-range-10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/for-range-10.png -------------------------------------------------------------------------------- /docs/basic/img/for-range-11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/for-range-11.png -------------------------------------------------------------------------------- /docs/basic/img/for-range-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/for-range-2.png -------------------------------------------------------------------------------- /docs/basic/img/for-range-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/for-range-3.png -------------------------------------------------------------------------------- /docs/basic/img/for-range-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/for-range-4.png -------------------------------------------------------------------------------- /docs/basic/img/for-range-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/for-range-5.png -------------------------------------------------------------------------------- /docs/basic/img/for-range-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/for-range-6.png -------------------------------------------------------------------------------- /docs/basic/img/for-range-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/for-range-7.png -------------------------------------------------------------------------------- /docs/basic/img/for-range-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/for-range-8.png -------------------------------------------------------------------------------- /docs/basic/img/for-range-9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/for-range-9.png -------------------------------------------------------------------------------- /docs/basic/img/konstanta-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/konstanta-1.png -------------------------------------------------------------------------------- /docs/basic/img/variables-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/variables-1.png -------------------------------------------------------------------------------- /docs/basic/img/variables-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/variables-2.png -------------------------------------------------------------------------------- /etc/cover media share square.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/etc/cover media share square.psd -------------------------------------------------------------------------------- /static/img/cover ebook rust.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/static/img/cover ebook rust.png -------------------------------------------------------------------------------- /static/img/cover_media_share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/static/img/cover_media_share.png -------------------------------------------------------------------------------- /static/img/logo_small_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/static/img/logo_small_dark.png -------------------------------------------------------------------------------- /static/img/logo_small_light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/static/img/logo_small_light.png -------------------------------------------------------------------------------- /docs/basic/img/class-method-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/class-method-1.png -------------------------------------------------------------------------------- /docs/basic/img/class-object-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/class-object-1.png -------------------------------------------------------------------------------- /docs/basic/img/class-object-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/class-object-2.png -------------------------------------------------------------------------------- /docs/basic/img/class-object-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/class-object-3.png -------------------------------------------------------------------------------- /docs/basic/img/class-object-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/class-object-4.png -------------------------------------------------------------------------------- /docs/basic/img/class-object-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/class-object-5.png -------------------------------------------------------------------------------- /docs/basic/img/hello-python-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/hello-python-1.png -------------------------------------------------------------------------------- /docs/basic/img/hello-python-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/hello-python-2.png -------------------------------------------------------------------------------- /docs/basic/img/hello-python-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/hello-python-3.png -------------------------------------------------------------------------------- /docs/basic/img/hello-python-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/hello-python-4.png -------------------------------------------------------------------------------- /docs/basic/img/hello-python-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/hello-python-5.png -------------------------------------------------------------------------------- /docs/basic/img/if-elif-else-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/if-elif-else-1.png -------------------------------------------------------------------------------- /docs/basic/img/if-elif-else-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/if-elif-else-2.png -------------------------------------------------------------------------------- /docs/basic/img/if-elif-else-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/if-elif-else-3.png -------------------------------------------------------------------------------- /docs/basic/img/if-elif-else-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/if-elif-else-4.png -------------------------------------------------------------------------------- /docs/basic/img/if-elif-else-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/if-elif-else-5.png -------------------------------------------------------------------------------- /docs/basic/img/special-names-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/special-names-1.png -------------------------------------------------------------------------------- /docs/basic/img/special-names-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/special-names-2.png -------------------------------------------------------------------------------- /docs/basic/img/special-names-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/special-names-3.png -------------------------------------------------------------------------------- /static/img/cover ebook golang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/static/img/cover ebook golang.png -------------------------------------------------------------------------------- /static/img/cover ebook python.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/static/img/cover ebook python.png -------------------------------------------------------------------------------- /docs/basic/img/abstract-method-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/abstract-method-1.png -------------------------------------------------------------------------------- /docs/basic/img/abstract-method-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/abstract-method-2.png -------------------------------------------------------------------------------- /docs/basic/img/abstract-method-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/abstract-method-3.png -------------------------------------------------------------------------------- /docs/basic/img/break-continue-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/break-continue-1.png -------------------------------------------------------------------------------- /docs/basic/img/break-continue-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/break-continue-2.png -------------------------------------------------------------------------------- /docs/basic/img/error-exception-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/error-exception-1.png -------------------------------------------------------------------------------- /docs/basic/img/error-exception-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/error-exception-2.png -------------------------------------------------------------------------------- /docs/basic/img/error-exception-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/error-exception-3.png -------------------------------------------------------------------------------- /docs/basic/img/error-exception-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/error-exception-4.png -------------------------------------------------------------------------------- /docs/basic/img/error-exception-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/error-exception-5.png -------------------------------------------------------------------------------- /docs/basic/img/instance-method-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/instance-method-1.png -------------------------------------------------------------------------------- /docs/basic/img/instance-method-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/instance-method-2.png -------------------------------------------------------------------------------- /docs/basic/img/instance-method-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/instance-method-3.png -------------------------------------------------------------------------------- /docs/basic/img/instance-method-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/instance-method-4.png -------------------------------------------------------------------------------- /docs/basic/img/local-global-var-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/local-global-var-1.png -------------------------------------------------------------------------------- /docs/basic/img/local-global-var-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/local-global-var-2.png -------------------------------------------------------------------------------- /docs/basic/img/number-bilangan-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/number-bilangan-1.png -------------------------------------------------------------------------------- /docs/basic/img/number-bilangan-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/number-bilangan-2.png -------------------------------------------------------------------------------- /docs/basic/img/number-bilangan-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/number-bilangan-3.png -------------------------------------------------------------------------------- /docs/basic/img/number-bilangan-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/number-bilangan-4.png -------------------------------------------------------------------------------- /docs/basic/img/number-bilangan-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/number-bilangan-5.png -------------------------------------------------------------------------------- /docs/basic/img/pattern-matching-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/pattern-matching-1.png -------------------------------------------------------------------------------- /docs/basic/img/pattern-matching-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/pattern-matching-2.png -------------------------------------------------------------------------------- /docs/basic/img/pattern-matching-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/pattern-matching-3.png -------------------------------------------------------------------------------- /docs/basic/img/pattern-matching-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/pattern-matching-4.png -------------------------------------------------------------------------------- /docs/basic/img/pattern-matching-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/pattern-matching-5.png -------------------------------------------------------------------------------- /docs/basic/img/pattern-matching-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/pattern-matching-6.png -------------------------------------------------------------------------------- /docs/basic/img/pattern-matching-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/pattern-matching-7.png -------------------------------------------------------------------------------- /docs/basic/img/pattern-matching-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/pattern-matching-8.png -------------------------------------------------------------------------------- /docs/basic/img/class-inheritance-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/class-inheritance-1.png -------------------------------------------------------------------------------- /docs/basic/img/class-inheritance-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/class-inheritance-2.png -------------------------------------------------------------------------------- /docs/basic/img/class-inheritance-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/class-inheritance-3.png -------------------------------------------------------------------------------- /docs/basic/img/class-inheritance-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/class-inheritance-4.png -------------------------------------------------------------------------------- /docs/basic/img/cli-arguments-flags-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/cli-arguments-flags-1.png -------------------------------------------------------------------------------- /docs/basic/img/cli-arguments-flags-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/cli-arguments-flags-2.png -------------------------------------------------------------------------------- /docs/basic/img/cli-arguments-flags-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/cli-arguments-flags-3.png -------------------------------------------------------------------------------- /docs/basic/img/cli-arguments-flags-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/cli-arguments-flags-4.png -------------------------------------------------------------------------------- /docs/basic/img/cli-arguments-flags-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/cli-arguments-flags-5.png -------------------------------------------------------------------------------- /docs/basic/img/cli-arguments-flags-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/cli-arguments-flags-6.png -------------------------------------------------------------------------------- /docs/basic/img/object-id-reference-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/object-id-reference-1.png -------------------------------------------------------------------------------- /docs/basic/img/object-id-reference-10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/object-id-reference-10.png -------------------------------------------------------------------------------- /docs/basic/img/object-id-reference-11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/object-id-reference-11.png -------------------------------------------------------------------------------- /docs/basic/img/object-id-reference-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/object-id-reference-2.png -------------------------------------------------------------------------------- /docs/basic/img/object-id-reference-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/object-id-reference-3.png -------------------------------------------------------------------------------- /docs/basic/img/object-id-reference-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/object-id-reference-4.png -------------------------------------------------------------------------------- /docs/basic/img/object-id-reference-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/object-id-reference-5.png -------------------------------------------------------------------------------- /docs/basic/img/object-id-reference-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/object-id-reference-6.png -------------------------------------------------------------------------------- /docs/basic/img/object-id-reference-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/object-id-reference-7.png -------------------------------------------------------------------------------- /docs/basic/img/object-id-reference-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/object-id-reference-8.png -------------------------------------------------------------------------------- /docs/basic/img/object-id-reference-9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/object-id-reference-9.png -------------------------------------------------------------------------------- /docs/basic/img/pack-unpack-elements-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/pack-unpack-elements-1.png -------------------------------------------------------------------------------- /docs/basic/img/property-visibility-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/property-visibility-1.png -------------------------------------------------------------------------------- /docs/basic/img/property-visibility-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/property-visibility-2.png -------------------------------------------------------------------------------- /docs/installation/img/instalasi-python.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/installation/img/instalasi-python.png -------------------------------------------------------------------------------- /docs/basic/img/duck-typing-vs-structural-typing-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/duck-typing-vs-structural-typing-1.png -------------------------------------------------------------------------------- /docs/basic/img/instance-attribute-class-attribute-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/instance-attribute-class-attribute-1.png -------------------------------------------------------------------------------- /docs/basic/img/positional-optional-keyword-argument-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/positional-optional-keyword-argument-1.png -------------------------------------------------------------------------------- /docs/basic/img/positional-optional-keyword-argument-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/positional-optional-keyword-argument-2.png -------------------------------------------------------------------------------- /docs/basic/img/exception-handling-try-except-else-finally-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/exception-handling-try-except-else-finally-1.png -------------------------------------------------------------------------------- /docs/basic/img/exception-handling-try-except-else-finally-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/exception-handling-try-except-else-finally-2.png -------------------------------------------------------------------------------- /docs/basic/img/exception-handling-try-except-else-finally-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/exception-handling-try-except-else-finally-3.png -------------------------------------------------------------------------------- /docs/basic/img/exception-handling-try-except-else-finally-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/exception-handling-try-except-else-finally-4.png -------------------------------------------------------------------------------- /docs/basic/img/exception-handling-try-except-else-finally-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/exception-handling-try-except-else-finally-5.png -------------------------------------------------------------------------------- /docs/basic/img/exception-handling-try-except-else-finally-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/exception-handling-try-except-else-finally-6.png -------------------------------------------------------------------------------- /docs/basic/img/exception-handling-try-except-else-finally-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/novalagung/dasarpemrogramanpython/HEAD/docs/basic/img/exception-handling-try-except-else-finally-7.png -------------------------------------------------------------------------------- /docs-wip/wip-string-formatting.md: -------------------------------------------------------------------------------- 1 | https://docs.python.org/3/library/string.html#format-specification-mini-language 2 | https://stackoverflow.com/questions/699866/convert-int-to-binary-string-in-python -------------------------------------------------------------------------------- /docs-wip/wip-pengelanan-python-programming.md: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /docs-wip/wip-standard-library.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs-wip/wip-async-io.md: -------------------------------------------------------------------------------- 1 | https://docs.python.org/3/library/asyncio.html 2 | 3 | High-level APIs 4 | 5 | Runners 6 | Coroutines and Tasks 7 | Streams 8 | Synchronization Primitives 9 | Subprocesses 10 | Queues 11 | Exceptions -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "examples"] 2 | path = examples 3 | url = https://github.com/novalagung/dasarpemrogramanpython-example.git 4 | branch = master 5 | [submodule "src"] 6 | path = src 7 | url = https://github.com/novalagung/my-docusaurus-global-src.git 8 | branch = master 9 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "spellright.language": [ 3 | "en" 4 | ], 5 | "spellright.documentTypes": [ 6 | "latex", 7 | "plaintext" 8 | ], 9 | "python.analysis.autoImportCompletions": true, 10 | "python.analysis.typeCheckingMode": "basic" 11 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | 4 | # Production 5 | /build 6 | 7 | # Generated files 8 | .docusaurus 9 | .cache-loader 10 | 11 | # Misc 12 | .DS_Store 13 | .env.local 14 | .env.development.local 15 | .env.test.local 16 | .env.production.local 17 | 18 | npm-debug.log* 19 | yarn-debug.log* 20 | yarn-error.log* 21 | -------------------------------------------------------------------------------- /docs/download-pdf.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 4 3 | title: Download versi PDF 4 | sidebar_label: Download versi PDF 5 | --- 6 | 7 | Ebook Dasar Pemrograman Python bisa di-download dalam bentuk file PDF, silakan gunakan link berikut: 8 | 9 | > [Dasar Pemrograman Python.pdf](https://github.com/novalagung/dasarpemrogramanpython/raw/ebooks/dasarpemrogramanpython.pdf?v=beta1.20231011) 10 | -------------------------------------------------------------------------------- /src-local/css/custom.css: -------------------------------------------------------------------------------- 1 | /* You can override the default Infima variables here. */ 2 | :root { 3 | --ifm-color-primary: #e16021; 4 | --ifm-color-primary-dark: #d65618; 5 | --ifm-color-primary-darker: #c4490e; 6 | --ifm-color-primary-darkest: #ac3a04; 7 | --ifm-color-primary-light: #ec6e30; 8 | --ifm-color-primary-lighter: #f77b3e; 9 | --ifm-color-primary-lightest: #f7834a; 10 | --ifm-code-font-size: 95%; 11 | --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); 12 | --doc-sidebar-width: 360px !important; 13 | --ifm-blockquote-border-left-width: 4px; 14 | --ifm-blockquote-border-color: #e16021; 15 | } 16 | 17 | /* custom css */ 18 | 19 | .theme-code-block[class*="language-"] { 20 | background: #FF874B !important; 21 | } 22 | -------------------------------------------------------------------------------- /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: 'continous integration' 2 | 3 | on: 4 | pull_request: 5 | types: 6 | - opened 7 | - synchronize 8 | branches: 9 | - master 10 | 11 | jobs: 12 | test: 13 | name: 'test' 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v3 17 | with: 18 | submodules: recursive 19 | - uses: actions/setup-node@v3 20 | with: 21 | node-version: 16 22 | check-latest: true 23 | - run: npm install 24 | - name: test build 25 | run: | 26 | npm run build 27 | rm -rf build/index.html 28 | cp build/intro.html build/index.html 29 | sed -i 's#https://dasarpemrogramanpython.novalagung.com/intro#https://dasarpemrogramanpython.novalagung.com/#g' build/index.html 30 | -------------------------------------------------------------------------------- /docusaurus.config.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | // Note: type annotations allow type checking and IDEs autocompletion 3 | 4 | const { buildConfig } = require('./src/config'); 5 | 6 | const config = buildConfig({ 7 | title: 'Dasar Pemrograman Python', 8 | tagline: 'Panduan Ringkas untuk Cepat Belajar Pemrograman Python, Gratis!', 9 | url: 'https://dasarpemrogramanpython.novalagung.com', 10 | projectName: 'dasarpemrogramanpython', 11 | seoKeywords: 'python, belajar python, pemrograman python, noval agung, data analytics, fundamental python, contoh python, data science, machine learning', 12 | googleTrackingID: 'G-JLWG9B72SF', 13 | facebookAppID: '875100400724859', 14 | algoliaAppID: 'GTSLZ9HJP5', 15 | algoliaApiKey: 'd4cb065e748f1f0bde373e31b8f155a0', 16 | algoliaIndexName: 'dasarpemrogramanpython-novalagung', 17 | }); 18 | 19 | module.exports = config; 20 | -------------------------------------------------------------------------------- /sidebars.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Creating a sidebar enables you to: 3 | - create an ordered group of docs 4 | - render a sidebar for each doc of that group 5 | - provide next/previous navigation 6 | 7 | The sidebars can be generated from the filesystem, or explicitly defined here. 8 | 9 | Create as many sidebars as you want. 10 | */ 11 | 12 | // @ts-check 13 | 14 | /** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ 15 | const sidebars = { 16 | // By default, Docusaurus generates a sidebar from the docs folder structure 17 | tutorialSidebar: [{type: 'autogenerated', dirName: '.'}], 18 | 19 | // But you can create a sidebar manually 20 | /* 21 | tutorialSidebar: [ 22 | 'intro', 23 | 'hello', 24 | { 25 | type: 'category', 26 | label: 'Tutorial', 27 | items: ['tutorial-basics/create-a-document'], 28 | }, 29 | ], 30 | */ 31 | }; 32 | 33 | module.exports = sidebars; 34 | -------------------------------------------------------------------------------- /docs/LICENSE.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 5 3 | title: Lisensi & Distribusi Konten 4 | sidebar_label: Lisensi & Distribusi Konten 5 | --- 6 | 7 | Ebook Dasar Pemrograman Python gratis untuk disebarluaskan secara bebas, dengan catatan sesuai dengan aturan lisensi CC BY-SA 4.0 yang kurang lebih sebagai berikut: 8 | 9 | - Diperbolehkan menyebar, mencetak, dan menduplikasi material dalam konten ini ke siapapun. 10 | - Diperbolehkan memodifikasi, mengubah, atau membuat konten baru menggunakan material yang ada dalam ebook ini untuk keperluan komersil maupun tidak. 11 | 12 | Dengan catatan: 13 | 14 | - Harus ada credit sumber aslinya, yaitu Dasar Pemrograman Python atau novalagung 15 | - Tidak mengubah lisensi aslinya, yaitu CC BY-SA 4.0 16 | - Tidak ditambahi restrictions baru 17 | - Lebih jelasnya silakan cek https://creativecommons.org/licenses/by-sa/4.0/. 18 | 19 | [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fnovalagung%2Fdasarpemrogramanpython.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fnovalagung%2Fdasarpemrogramanpython?ref=badge_large) 20 | -------------------------------------------------------------------------------- /docs/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | title: Version Changelogs & Updates 4 | sidebar_label: Version Changelogs & Updates 5 | --- 6 | 7 | ## 📝 Release v1.2.20240923 (2024-09-23) 8 | 9 | #### ◉ Chapter update 10 | 11 | - Perbaikan typo dan/atau kesalahan kode 12 | - [A.10. Perulangan ➜ while](/basic/while) 13 | - [A.11. Perulangan ➜ break, continue](/basic/break-continue) 14 | - [A.12. List](/basic/list) 15 | - [A.15. Set](/basic/while) 16 | - [A.16. Python Dictionary](/basic/dictionary) 17 | - [A.17. String](/basic/string) 18 | - [A.18. String ➜ Unicode](/basic/unicode) 19 | - [A.19. Number](/basic/number-bilangan) 20 | - [A.21. Object ID & Reference](/basic/object-id-reference) 21 | - [A.22. Function](/basic/function) 22 | - [A.23. Function ➜ Positional, Optional, Keyword Arguments](/basic/positional-optional-keyword-argument) 23 | - [A.26. Function ➜ Lambda](/basic/lambda) 24 | - [A.27. Modules](/basic/modules) 25 | - [A.48. DocString](/basic/docstring) 26 | - [A.49. File I/O](/basic/file) 27 | - [A.50. CLI Arguments & Flags](/basic/cli-arguments-flags) 28 | - [A.51. File/Data Format ➜ CSV](/basic/csv) 29 | - [A.52. File/Data Format ➜ JSON](/basic/json) 30 | - [A.53. Date, Time, DateTime, Timezone](/basic/datetime-timezone) 31 | - [A.54. DateTime ➜ Parsing & Formatting](/basic/datetime-parsing-formatting) 32 | - Perbaikan kesalahan kode 33 | 34 | #### ◉ General update 35 | 36 | - Penambahan halaman changelogs 37 | - Update landing page untuk optimasi SEO 38 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dasarpemrogramanpython", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "docusaurus": "docusaurus", 7 | "start": "docusaurus start", 8 | "build": "docusaurus build", 9 | "swizzle": "docusaurus swizzle", 10 | "deploy": "docusaurus deploy", 11 | "clear": "docusaurus clear", 12 | "serve": "docusaurus serve", 13 | "write-translations": "docusaurus write-translations", 14 | "write-heading-ids": "docusaurus write-heading-ids" 15 | }, 16 | "dependencies": { 17 | "@docusaurus/core": "^2.2.0", 18 | "@docusaurus/plugin-content-docs": "^2.2.0", 19 | "@docusaurus/plugin-google-gtag": "^2.2.0", 20 | "@docusaurus/plugin-sitemap": "^2.2.0", 21 | "@docusaurus/preset-classic": "^2.2.0", 22 | "@docusaurus/theme-search-algolia": "^2.2.0", 23 | "@mdx-js/react": "^1.6.22", 24 | "@stackql/docusaurus-plugin-structured-data": "adamstudiogh/docusaurus-plugin-structured-data", 25 | "clsx": "^1.2.1", 26 | "disqus-react": "^1.1.5", 27 | "prism-react-renderer": "^1.3.5", 28 | "react": "^17.0.2", 29 | "react-dom": "^17.0.2" 30 | }, 31 | "devDependencies": { 32 | "@docusaurus/module-type-aliases": "2.4.0" 33 | }, 34 | "browserslist": { 35 | "production": [ 36 | ">0.5%", 37 | "not dead", 38 | "not op_mini all" 39 | ], 40 | "development": [ 41 | "last 1 chrome version", 42 | "last 1 firefox version", 43 | "last 1 safari version" 44 | ] 45 | }, 46 | "engines": { 47 | "node": ">=16.14" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /docs/installation/python-editor-plugin.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | title: Python Editor & Plugin 4 | sidebar_label: Python Editor & Plugin 5 | --- 6 | 7 | ## Editor/IDE 8 | 9 | Ada cukup banyak pilihan editor dan IDE untuk development menggunakan Python, diantaranya: 10 | 11 | - [Eclipse](http://www.eclipse.org/), dengan tambahan plugin [PyDev](https://www.pydev.org/) 12 | - [GNU Emacs](https://www.gnu.org/s/emacs/) 13 | - [JetBrains PyCharm](https://www.jetbrains.com/pycharm/) 14 | - [Spyder](https://www.spyder-ide.org/) 15 | - [Sublime Text](http://www.sublimetext.com/), dengan tambahan package [Python](https://realpython.com/python-modules-packages/) 16 | - [Vim](https://www.vim.org/) 17 | - [Visual Studio](https://visualstudio.microsoft.com/vs/features/python/) 18 | - [Visual Studio Code (VSCode)](https://code.visualstudio.com/), dengan tambahan extension [Python](https://marketplace.visualstudio.com/items?itemName=ms-python.python) dan [Jupyter](https://marketplace.visualstudio.com/items?itemName=ms-toolsai.jupyter) 19 | 20 | Selain list di atas, ada juga editor lainnya yang bisa digunakan, contohnya seperti: 21 | 22 | - [Python standard shell (REPL)](https://www.python.org/shell/) 23 | - [Jupyter](https://jupyter.org/) 24 | 25 | ## Preferensi editor penulis 26 | 27 | Penulis menggunakan editor [Visual Studio Code](https://code.visualstudio.com/) dengan tambahan: 28 | 29 | - Extension [Python](https://marketplace.visualstudio.com/items?itemName=ms-python.python), untuk mendapatkan benefit API doc, autocompletion, linting, run feature, dan lainnya. 30 | - Extension [Jupyter](https://marketplace.visualstudio.com/items?itemName=ms-toolsai.jupyter), untuk interactive run program via editor. 31 | -------------------------------------------------------------------------------- /docs/basic/run-program-python.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | title: A.2. Run Python di VSCode 4 | sidebar_label: A.2. Run Python di VSCode 5 | description: Tutorial cara menjalankan program Python 6 | keywords: [python interpreter, python compiler, run program di python, run python] 7 | --- 8 | 9 | Chapter ini membahas tentang pilihan opsi cara run program Python di Visual Studio Code. 10 | 11 | ## A.2.1. Cara run program Python di VSCode 12 | 13 | ### ◉ Menggunakan command `python` 14 | 15 | Command ini sudah kita terapkan pada chapter [Program Pertama ➜ Hello Python](/basic/hello-python), cara penggunaannya cukup mudah, tinggal jalankan saja command di terminal. 16 | 17 | ```bash 18 | # python 19 | python main.py 20 | ``` 21 | 22 | ### ◉ Menggunakan tombol run `▶` 23 | 24 | Cara run program ini lebih praktis karena tingal klik-klik saja. Di toolbar VSCode sebelah kanan atas ada tombol `▶`, gunakan tombol tersebut untuk menjalankan program. 25 | 26 | ![hello world python](img/hello-python-3.png) 27 | 28 | ### ◉ Menggunakan jupyter `code cells` 29 | 30 | Untuk menerapkan cara ini, tambahkan kode `#%%` atau `# %%` pada baris di atas statement `print("hello python")` agar blok kode di bawahnya dianggap sebagai satu `code cell`. 31 | 32 | ![hello world python](img/hello-python-4.png) 33 | 34 | Setelah itu, muncul tombol `Run Cell`, klik untuk run program. 35 | 36 | ![hello world python](img/hello-python-5.png) 37 | 38 | --- 39 | 40 |
41 | 42 | ## Catatan chapter 📑 43 | 44 | ### ◉ Chapter relevan lainnya 45 | 46 | - [Program Pertama ➜ Hello Python](/basic/hello-python) 47 | 48 | ### ◉ Referensi 49 | 50 | - https://code.visualstudio.com/docs/python/python-tutorial 51 | - https://code.visualstudio.com/docs/datascience/jupyter-notebooks 52 | - https://docs.python.org/3/using/cmdline.html 53 | 54 |
55 | -------------------------------------------------------------------------------- /docs/installation/instalasi-python.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | title: Instalasi Python 4 | sidebar_label: Instalasi Python 5 | --- 6 | 7 | Ada banyak cara yang bisa dipilih untuk instalasi Python, silakan pilih sesuai preferensi dan kebutuhan. 8 | 9 | ## Instalasi Python 10 | 11 | ### ◉ Instalasi di Windows 12 | 13 | - Via [Microsoft Store Package](https://apps.microsoft.com/store/detail/python-310/9PJPW5LDXLZ5?hl=en-id&gl=id&rtc=1) 14 | - Via [Official Python installer](https://www.python.org/downloads/release/python-3106/) 15 | - Via [Chocolatey package manager](https://community.chocolatey.org/packages/python/3.10.6) 16 | - Via [Windows Subsystem for Linux (WSL)](https://learn.microsoft.com/en-us/windows/python/web-frameworks) 17 | 18 | ### ◉ Instalasi di MacOS 19 | 20 | - Via [Homebrew](https://docs.brew.sh/Homebrew-and-Python) 21 | - Via [Official Python installer](https://www.python.org/downloads/release/python-3106/) 22 | 23 | ### ◉ Instalasi di OS lainnya 24 | 25 | - Via package manager masing-masing sistem operasi 26 | 27 | ### ◉ Instalasi via source code 28 | 29 | - Tarball source code bisa diunduh di [situs official Python](https://www.python.org/downloads/release/python-3106/) 30 | 31 | ### ◉ Instalasi via Anaconda 32 | 33 | - File installer bisa diunduh di [situs official Anaconda](https://www.anaconda.com/download/) 34 | 35 | ## Konfigurasi path Python 36 | 37 | 1. Pastikan untuk mendaftarkan path dimana Python ter-install ke OS environment variable, agar nantinya mudah dalam pemanggilan binary `python`. 38 | 2. Jika diperlukan, set juga variabel `PYTHONHOME` yang mengarah ke base folder dimana Python terinstall. Biasanya editor akan mengacu ke environment variabel ini untuk mencari dimana path Python berada. 39 | 3. Kemudian, jalankan command `python --version` untuk memastikan binary sudah terdaftar di `$PATH` variable. 40 | 41 | ![instalasi python](img/instalasi-python.png) 42 | -------------------------------------------------------------------------------- /.github/workflows/cd.yaml: -------------------------------------------------------------------------------- 1 | name: 'continous deployment' 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | generate_webbook: 10 | name: 'generate webbook' 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v3 14 | with: 15 | submodules: recursive 16 | - uses: actions/setup-node@v3 17 | with: 18 | node-version: 16 19 | check-latest: true 20 | - run: npm install 21 | - name: generate assets 22 | run: | 23 | npm run build 24 | - name: publish webbook 25 | uses: peaceiris/actions-gh-pages@v3 26 | with: 27 | github_token: ${{ secrets.GITHUB_TOKEN }} 28 | publish_dir: ./build 29 | publish_branch: gh-pages 30 | 31 | generate_ebook: 32 | needs: generate_webbook 33 | name: 'generate ebook' 34 | runs-on: ubuntu-latest 35 | steps: 36 | - name: sleep for 30 seconds 37 | run: sleep 30s 38 | shell: bash 39 | - uses: actions/checkout@v3 40 | with: 41 | submodules: recursive 42 | - name: install prince 43 | run: | 44 | curl https://www.princexml.com/download/prince-14.2-linux-generic-x86_64.tar.gz -O 45 | tar zxf prince-14.2-linux-generic-x86_64.tar.gz 46 | cd prince-14.2-linux-generic-x86_64 47 | yes "" | sudo ./install.sh 48 | - name: build pdf 49 | run: npx docusaurus-prince-pdf -u https://dasarpemrogramanpython.novalagung.com --include-index 50 | - name: install pdftk 51 | run: sudo apt install pdftk 52 | - name: join cover and pdf 53 | run: | 54 | pdftk "etc/cover ebook.pdf" pdf/dasarpemrogramanpython.novalagung.com.pdf cat output pdf/dasarpemrogramanpython.pdf 55 | rm -f pdf/dasarpemrogramanpython.novalagung.* 56 | - name: publish ebook 57 | uses: peaceiris/actions-gh-pages@v3 58 | with: 59 | github_token: ${{ secrets.GITHUB_TOKEN }} 60 | publish_dir: ./pdf 61 | publish_branch: ebooks 62 | -------------------------------------------------------------------------------- /docs/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | title: Contribution & Tech Stack 4 | sidebar_label: Contribution & Tech Stack 5 | --- 6 | 7 | Ebook Dasar Pemrograman Python adalah project open source. Siapapun bebas untuk berkontribusi di sini, bisa dalam bentuk perbaikan typo, update kalimat, maupun submit tulisan baru. 8 | 9 | Bagi kawan-kawan yang berminat untuk berkontribusi, silakan fork [github.com/novalagung/dasarpemrogramanpython](https://github.com/novalagung/dasarpemrogramanpython), kemudian langsung saja cek/buat issue kemudian submit relevan pull request untuk issue tersebut 😊 10 | 11 | ## Checkout project 12 | 13 | ``` 14 | git clone https://github.com/novalagung/dasarpemrogramanpython.git 15 | git submodule update --init --recursive --remote 16 | ``` 17 | 18 | ## Maintainer 19 | 20 | E-book ini di-inisialisasi dan di-maintain oleh Noval Agung Prayogo. 21 | 22 | ## Contributors 23 | 24 | Berikut merupakan hall of fame kontributor yang sudah berbaik hati menyisihkan waktunya untuk membantu pengembangan e-book ini. 25 | 26 | 1. [Arsy Opraza Akma](https://github.com/arasopraza) 27 | 1. [Barep Bimo Pangestu](https://github.com/bosmobosmo) 28 | 1. [Mohammad Safri Dwi Rizky](https://github.com/safridwirizky) 29 | 1. [Muhammad Saleh Solahudin](https://github.com/ZihxS) 30 | 1. [V1337Q](https://github.com/V1337Q) 31 | 1. ... anda 🚀 32 | 33 | ## Ebook/webhook techstack & architecture 34 | 35 | Jika pembaca tertarik untuk membuat konten ebook berbasis web sekaligus versi PDF file-nya, bisa menggunakan link berikut sebagai referensi: 36 | 37 | > https://medium.com/geekculture/serverless-e-book-web-book-using-docusaurus-v2-github-pages-actions-and-pdf-tools-4fef54847b85 38 | 39 | Tools yang digunakan: 40 | 41 | - Web-book engine ➜ [Docusaurus v2](https://docusaurus.io/) 42 | - PDF generator ➜ [Prince XML](https://www.princexml.com/) + [docusaurus-prince-pdf](https://github.com/signcl/docusaurus-prince-pdf) + [PDFtk](https://www.pdflabs.com/tools/pdftk-the-pdf-toolkit/) 43 | - Source code repository ➜ [GitHub](https://github.com/) 44 | - Hosting ➜ [GitHub Pages](https://pages.github.com/) 45 | - CI/CD pipeline ➜ [GitHub Actions](https://github.com/features/actions) 46 | - Content Search ➜ [Algolia DocSearch](https://docsearch.algolia.com/) 47 | 48 | Desain arsitektur: 49 | 50 | ![Dasar pemrograman python](https://raw.githubusercontent.com/novalagung/dasarpemrogramanrust/master/etc/base%20architecture.jpg) 51 | -------------------------------------------------------------------------------- /docs-wip/wip-type-metaclass.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 99 3 | title: A.99. Python Metaclass 4 | sidebar_label: A.99. Metaclass (WIP) 5 | --- 6 | 7 | Chapter ini membahas tentang tipe data `type` pembahasan lebih mendetail mengenai tipe data yang 8 | Pada chapter ini kita akan belajar tentang object special bernama `None`. 9 | 10 | ## A.99.1. Pengenalan `Type` 11 | 12 | `None` merupakan object bawaan Python yang digunakan untuk merepresentasikan nilai kosong atau *null*. 13 | 14 | Penggunaannya cukup sederhana, ketika suatu data nilainya bisa kosong, umumnya sebelum data tersebut diproses dilakukan pengecekan terlebih dahulu menggunakan seleksi kondisi. 15 | 16 | Sebagai contoh, pada kode berikut, dipersiapkan sebuah fungsi bernama `inspect_data()`, tugasnya mengecek apakah variabel memiliki nilai atau tidak. 17 | 18 | ```python 19 | def inspec_data(data): 20 | if data == None: 21 | print("data is empty. like very empty") 22 | else: 23 | print(f"data: {data}, type: {type(data).__name__}") 24 | 25 | data = 0 26 | inspec_data(data) 27 | # output ➜ data: 0, type: int 28 | 29 | data = "" 30 | inspec_data(data) 31 | # output ➜ data: , type: str 32 | 33 | data = None 34 | inspec_data(data) 35 | # output ➜ data is empty. like very empty 36 | 37 | class Car: 38 | def __init__(self): 39 | self.name = "" 40 | 41 | data = Car() 42 | inspec_data(data) 43 | # output ➜ data: <__main__.Car object at 0x000001E6B38F60F0>, type: Car 44 | ``` 45 | 46 | Bisa dilihat pada program di atas output tiap statement adalah berbeda-beda sesuai tipe datanya. 47 | 48 | - Ketika variabel `data` berisi `0` maka variabel tersebut tidak benar-benar kosong, melainkan berisi angka `0`. 49 | 50 | - Karakteristik yang sama juga berlaku ketika variabel berisi string kosong `""`, meskipun ketika di-print tidak muncul apa-apa, variabel tersebut sebenarnya berisi tipe data string namun tanpa isi. maka variabel tersebut tidak benar-benar kosong, melainkan berisi angka `""`. 51 | 52 | - Ketika variabel isinya data `None` maka variabel tersebut dianggap benar-benar kosong. 53 | 54 | --- 55 | 56 |
57 | 58 | ## Catatan chapter 📑 59 | 60 | ### ◉ Source code praktik 61 | 62 |
63 |     
64 |         github.com/novalagung/dasarpemrogramanpython-example/../none
65 |     
66 | 
67 | 68 | ### ◉ Chapter relevan lainnya 69 | 70 | - [Tipe Data](/basic/tipe-data) 71 | - [Special Names](/basic/special-names) 72 | 73 | ### ◉ Referensi 74 | 75 | - https://docs.python.org/3/c-api/none.html 76 | 77 |
78 | -------------------------------------------------------------------------------- /docs/basic/komentar.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | title: A.3. Python Komentar 4 | sidebar_label: A.3. Komentar 5 | description: Tutorial belajar penerapan komentar di Python 6 | keywords: [komentar python, multi line komentar python] 7 | faqs: 8 | - question: Apa itu komentar di Python? 9 | answer: Komentar adalah sebuah statement yang tidak akan dijalankan oleh interpreter. Biasanya digunakan untuk menambahkan keterangan atau men-disable statements agar tidak dieksekusi saat run program. 10 | - question: Komentar di Python 11 | answer: Di Python, komentar menggunakan karakter \# untuk jenis komentar 1 baris, dan karakter """ untuk jenis komentar multi baris. 12 | --- 13 | 14 | Komentar adalah sebuah statement yang tidak akan dijalankan oleh interpreter. Biasanya digunakan untuk menambahkan keterangan atau men-disable statements agar tidak dieksekusi saat run program. 15 | 16 | Python mengenal dua jenis komentar, yaitu komentar satu baris dan multi-baris. 17 | 18 | ## A.3.1. Komentar satu baris 19 | 20 | Karakter `#` digunakan untuk menuliskan komentar, contoh: 21 | 22 | ```python 23 | # ini adalah komentar 24 | print("halo,") 25 | print("selamat pagi!") # ini juga komentar 26 | 27 | # println("statement ini tidak akan dipanggil") 28 | ``` 29 | 30 | Jika di-run, outputnya: 31 | 32 | ![komentar di python](img/komentar-1.png) 33 | 34 | Bisa dilihat statement yang diawali dengan tanda `#` tidak dieksekusi. 35 | 36 | ## A.3.2. Komentar multi-baris 37 | 38 | Komentar multi-baris bisa diterapkan melalui dua cara: 39 | 40 | ### ◉ Komentar menggunakan `#` dituliskan 41 | 42 | ```python 43 | # ini adalah komentar 44 | # ini juga komentar 45 | # komentar baris ke-3 46 | ``` 47 | 48 | ### ◉ Komentar menggunakan `"""` atau `'''` 49 | 50 | Karakter `"""` atau `'''` sebenarnya digunakan untuk membuat *multiline string* atau string banyak baris. Selain itu, bisa juga dipergunakan sebagai penanda komentar multi baris. Contoh penerapannya: 51 | 52 | ```python 53 | """ 54 | ini adalah komentar 55 | ini juga komentar 56 | komentar baris ke-3 57 | """ 58 | ``` 59 | 60 | Atau bisa juga ditulis seperti ini untuk komentar satu baris: 61 | 62 | ```python 63 | """ini adalah komentar""" 64 | ``` 65 | 66 | > - Pembahasan detail mengenai string ada di chapter [String](/basic/string) 67 | > - Pembahasan detail mengenai DocString ada di chapter [DocString](/basic/docstring) 68 | 69 | --- 70 | 71 |
72 | 73 | ## Catatan chapter 📑 74 | 75 | ### ◉ Source code praktik 76 | 77 |
78 |     
79 |         github.com/novalagung/dasarpemrogramanpython-example/../komentar
80 |     
81 | 
82 | 83 | ### ◉ Chapter relevan lainnya 84 | 85 | - [String](/basic/string) 86 | 87 | ### ◉ Referensi 88 | 89 | - https://docs.python-guide.org/writing/documentation/ 90 | 91 |
92 | -------------------------------------------------------------------------------- /docs/basic/hello-python.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | title: A.1. Python Hello World 4 | sidebar_label: A.1. Program Pertama ➜ Hello World 5 | description: Tutorial belajar python, membuat program hello world di python 6 | keywords: [tutorial python, belajar python, hello world python, pemrograman python, bahasa python] 7 | --- 8 | 9 | Bahasa pemrograman Python sangat sederhana dan mudah untuk dipelajari. Pada chapter ini kita akan langsung mempraktikannya dengan membuat program hello world. 10 | 11 | ## A.1.1. Program Hello Python 12 | 13 | Siapkan sebuah folder dengan isi satu file program Python bernama `main.py`. 14 | 15 | ![hello world python](img/hello-python-1.png) 16 | 17 | Pada file `main.py`, tuliskan kode berikut: 18 | 19 | ```python 20 | print("hello python") 21 | ``` 22 | 23 | Run program menggunakan command berikut: 24 | 25 | ```bash 26 | # python 27 | python main.py 28 | ``` 29 | 30 | ![hello world python](img/hello-python-2.png) 31 | 32 | Selamat, secara official sekarang anda adalah programmer Python! 🎉 Mudah bukan!? 33 | 34 | ## A.1.2. Penjelasan program 35 | 36 | Folder `hello-python` bisa disebut dengan folder **project**, dimana isinya adalah file-file program Python berekstensi `.py`. 37 | 38 | File `main.py` adalah file program python. Nama file program bisa apa saja, tapi umumnya pada pemrograman Python, file program utama bernama `main.py`. 39 | 40 | Command `python ` digunakan untuk menjalankan program. Cukup ganti `` dengan nama file program (yang pada contoh ini adalah `main.py`) maka kode program di dalam file tersebut akan di-run oleh Python interpreter. 41 | 42 | Statement `print("")` adalah penerapan dari salah satu fungsi *built-in* yang ada dalam Python stdlib (standard library), yaitu fungsi bernama `print()` yang kegunaannya adalah untuk menampilkan pesan string (yang disipkan pada argument pemanggilan fungsi `print()`). Pesan tersebut akan muncul ke layar output stdout (pada contoh ini adalah terminal milik editor penulis). 43 | 44 | > - Pembahasan detail mengenai fungsi ada di chapter [Function](/basic/function) 45 | > - Pembahasan detail mengenai Python standard library (stdlib) ada di chapter [Python standard library (stdlib)](#) 46 | > 47 | > Untuk sekarang, penulis tidak anjurkan untuk lompat ke pembahasan tersebut. Silakan ikuti pembelajaran chapter per chapter secara berurutan. 48 | 49 | --- 50 | 51 |
52 | 53 | ## Catatan chapter 📑 54 | 55 | ### ◉ Source code praktik 56 | 57 |
58 |     
59 |         github.com/novalagung/dasarpemrogramanpython-example/../hello-python
60 |     
61 | 
62 | 63 | ### ◉ Referensi 64 | 65 | - https://www.learnpython.org/en/Hello,_World! 66 | - https://docs.python.org/3/library/functions.html 67 | 68 |
69 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | title: Tutorial Belajar Python (Gratis!) 4 | sidebar_label: Dasar Pemrograman Python 5 | --- 6 | 7 | Python adalah bahasa pemrograman high-level yang sangat *powerful*, sintaksnya sederhana dan mudah dipelajari, juga memiliki performa yang bagus. Python memiliki komunitas yang besar, bahasa ini dipakai di berbagai platform diantaranya: web, data science, infrastructure tooling, dan lainnya. 8 | 9 | Website/ebook tutorial Dasar Pemrograman Python ini cocok untuk pembaca yang ingin mempelajari pemrograman python dalam kurun waktu yang relatif cepat, dan gratis. Konten pembelajaran pada ebook ini disajikan secara ringkas tidak bertele-tele tapi tetap mencakup point penting yang harus dipelajari. 10 | 11 | Selain topik fundamental python programming, nantinya akan disedikan juga pembahasan *advance* lainnya, **stay tuned!** 12 | 13 | > Versi website/ebook: **v1.2.20240923**, dan versi [Python 3.12.0](https://www.python.org/downloads/release/python-3120/). 14 | 15 | ## Update Konten & Versi Terbaru 16 | 17 | Setiap perubahan pada website/ebook bisa dilihat di halaman berikut: 18 | 19 | > [Version Changelogs & Updates](CHANGELOG) 20 | 21 | ## Download Ebook File (pdf) 22 | 23 | Versi ebook bisa di-download dalam bentuk file di link berikut: 24 | 25 | > PDF/Ebook file: [Dasar Pemrograman Python.pdf](https://github.com/novalagung/dasarpemrogramanpython/raw/ebooks/dasarpemrogramanpython.pdf?v=v1.2.20240923) 26 | 27 | ## Source Code Praktik 28 | 29 | Source code website/ebook & praktik program bisa diunduh di link berikut: 30 | 31 | > - Source code website/ebook ➡️ https://github.com/novalagung/dasarpemrogramanpython 32 | > - Source code praktik ➡️ https://github.com/novalagung/dasarpemrogramanpython-example 33 | 34 | Dianjurkan untuk sekedar tidak copy-paste dari source code dalam proses belajar, usahakan tulis sendiri kode program agar cepat terbiasa dengan bahasa Python. 35 | 36 | ## Kontribusi 37 | 38 | Website/ebook ini merupakan project open source, teruntuk siapapun yang ingin berkontribusi silakan langsung saja cek [github.com/novalagung/dasarpemrogramanpython](https://github.com/novalagung/dasarpemrogramanpython). Cek juga halaman kontributor berikut untuk melihat list kontributor. 39 | 40 | > [Contribution & Tech Stack][/CONTRIBUTING] 41 | 42 | ## Lisensi dan Status FOSSA 43 | 44 | Website/ebook tutorial Dasar Pemrograman Python gratis untuk disebarluaskan secara bebas, baik untuk komersil maupun tidak, dengan catatan harus disertakan credit sumber aslinya (yaitu Dasar Pemrograman Python atau novalagung) dan tidak mengubah lisensi aslinya (yaitu CC BY-SA 4.0). Lebih jelasnya silakan cek halaman [lisensi dan distribusi konten](/LICENSE). 45 | 46 | > [Lisensi dan Distribusi Konten](/LICENSE) 47 | 48 | FOSSA Status: 49 | 50 | [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fnovalagung%2Fdasarpemrogramanpython.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fnovalagung%2Fdasarpemrogramanpython?ref=badge_large) 51 | 52 | ## Author & Maintainer 53 | 54 | Ebook ini dibuat oleh Noval Agung Prayogo. Untuk pertanyaan, kritik, dan saran, silakan drop email ke hello@novalagung.com. 55 | -------------------------------------------------------------------------------- /docs/basic/konstanta.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 5 3 | title: A.5. Python Konstanta 4 | sidebar_label: A.5. Konstanta 5 | description: Tutorial belajar konstanta di Python 6 | keywords: [konstanta python] 7 | faqs: 8 | - question: Apa itu konstanta di Python? 9 | answer: Konstanta adalah sebuah variabel yang nilainya dideklarasikan di awal dan tidak bisa diubah 10 | - question: Cara membuat konstanta di Python 11 | answer: Konstanta di Python versi 3 bisa dibuat menggunakan bantuan module typing.Final. 12 | --- 13 | 14 | Konstanta (atau nilai konstan) adalah sebuah variabel yang nilainya dideklarasikan di awal dan tidak bisa diubah setelahnya. 15 | 16 | Pada chapter ini kita akan mempelajari tentang penerapan Konstanta di Python. 17 | 18 | ## A.5.1. Konstanta di Python 19 | 20 | Deklarasi konstanta di Python dilakukan menggunakan bantuan tipe *class* bernama `typing.Final`. 21 | 22 | Untuk menggunakannya, `typing.Final` perlu di-import terlebih dahulu menggunakan keyword `from` dan `import`. 23 | 24 | ```python 25 | from typing import Final 26 | 27 | PI: Final = 3.14 28 | print("pi: %f" % (PI)) 29 | ``` 30 | 31 | ![konstanta python](img/konstanta-1.png) 32 | 33 | ### ◉ Module import 34 | 35 | Keyword `import` digunakan untuk meng-import sesuatu, sedangkan keyword `from` digunakan untuk menentukan dari module mana sesuatu tersebut akan di-import. 36 | 37 | > Pembahasan detail mengenai `import` dan `from` ada di chapter [Modules](/basic/modules) 38 | 39 | Statement `from typing import Final` artinya adalah meng-import tipe `Final` dari module `typing` yang dimana module ini merupakan bagian dari Python standard library (stdlib). 40 | 41 | > Pembahasan detail mengenai Python standard library (stdlib) ada di chapter [Python standard library (stdlib)](#) 42 | 43 | ## A.5.2. Tipe *class* `typing.Final` 44 | 45 | Tipe `Final` digunakan untuk menandai suatu variabel adalah tidak bisa diubah nilainya (konstanta). Cara penerapan `Final` bisa dengan dituliskan tipe data konstanta-nya secara eksplisit, atau boleh tidak ditentukan (tipe akan diidentifikasi oleh interpreter berdasarkan tipe data nilainya). 46 | 47 | ```python 48 | # tipe konstanta PI tidak ditentukan secara explisit, 49 | # melainkan didapat dari tipe data nilai 50 | PI: Final = 3.14 51 | 52 | # tipe konstanta TOTAL_MONTH ditentukan secara explisit yaitu `int` 53 | TOTAL_MONTH: Final[int] = 12 54 | ``` 55 | 56 | > Pembahasan detail mengenai tipe data ada di chapter [Tipe Data](/basic/tipe-data) 57 | 58 | ## A.5.3. *Naming convention* konstanta 59 | 60 | Mengacu ke dokumentasi [PEP 8 – Style Guide for Python Code](https://peps.python.org/pep-0008/), nama konstanta harus dituliskan dalam huruf besar (UPPER_CASE). 61 | 62 | --- 63 | 64 |
65 | 66 | ## Catatan chapter 📑 67 | 68 | ### ◉ Source code praktik 69 | 70 |
71 |     
72 |         github.com/novalagung/dasarpemrogramanpython-example/../konstanta
73 |     
74 | 
75 | 76 | ### ◉ Chapter relevan lainnya 77 | 78 | - [Variabel](/basic/variabel) 79 | - [Tipe Data](/basic/tipe-data) 80 | - [Modules](/basic/modules) 81 | - [Python standard library (stdlib)](#) 82 | 83 | ### ◉ Referensi 84 | 85 | - https://docs.python.org/3/library/typing.html#typing.Final 86 | - https://peps.python.org/pep-0008/ 87 | 88 |
89 | -------------------------------------------------------------------------------- /docs/basic/none.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 31 3 | title: A.31. Python None 4 | sidebar_label: A.31. None 5 | --- 6 | 7 | Pada chapter ini kita akan belajar tentang object special bernama `None`. 8 | 9 | ## A.31.1. Pengenalan `None` 10 | 11 | `None` merupakan object bawaan Python yang umumnya digunakan untuk merepresentasikan nilai kosong atau *null*. 12 | 13 | Ketika suatu variabel berisi data yang nilainya bisa kosong, umumnya sebelum variabel tersebut digunakan, dilakukan pengecekan terlebih dahulu menggunakan seleksi kondisi untuk memastikan apakah nilainya benar-benar kosong atau tidak. 14 | 15 | Sebagai contoh, pada kode berikut, dipersiapkan sebuah fungsi bernama `inspect_data()`, tugasnya mengecek apakah variabel memiliki nilai atau tidak. 16 | 17 | ```python 18 | def inspect_data(data): 19 | if data is None: 20 | print("data is empty. like very empty") 21 | else: 22 | print(f"data: {data}, type: {type(data).__name__}") 23 | 24 | data = 0 25 | inspect_data(data) 26 | # output ➜ data: 0, type: int 27 | 28 | data = "" 29 | inspect_data(data) 30 | # output ➜ data: , type: str 31 | 32 | data = None 33 | inspect_data(data) 34 | # output ➜ data is empty. like very empty 35 | 36 | class Car: 37 | def __init__(self): 38 | self.name = "" 39 | 40 | data = Car() 41 | inspect_data(data) 42 | # output ➜ data: <__main__.Car object at 0x000001E6B38F60F0>, type: Car 43 | ``` 44 | 45 | Bisa dilihat pada program di atas output tiap statement adalah berbeda-beda sesuai tipe datanya. 46 | 47 | - Ketika variabel `data` berisi `0` maka variabel tersebut tidak benar-benar kosong, melainkan berisi angka `0`. 48 | 49 | - Karakteristik yang sama juga berlaku ketika variabel berisi string kosong `""`, meskipun ketika di-print tidak muncul apa-apa, variabel tersebut sebenarnya berisi tipe data string namun tanpa isi (string dengan panjang nol). Maka variabel tersebut sebenarnya tidak benar-benar kosong. 50 | 51 | - Barulah ketika variabel isinya data `None` maka dianggap benar-benar kosong. 52 | 53 | > Kode di atas berisi penerapan salah satu special name, yaitu attribute `__name__` milik class `type`. 54 | > 55 | > Pembahasan detail mengenai special name ada di chapter [Special Names ➜ Attribute __name__ milik class type](/basic/special-names#a294-attribute-__name__-milik-class-type) 56 | 57 | ## A.31.2. Penggunaan operator `is` terhadap `None` 58 | 59 | Ketika memeriksa apakah sebuah objek bernilai `None` atau tidak, disarankan untuk menggunakan operator `is` dibanding `==`, karena sifat dari operator `==` memanggil special method `__eq__()` dari objek yang diperiksa dan pada praktiknya tidak semua class menggunakan implementasi default method `__eq__()`. Dari sini maka potensi penggunaan operator `==` menghasilkan nilai yg berbeda dibanding yang diharapkan adalah ada (meskipun sangat kecil). 60 | 61 | Serta, operator `is` lebih cepat dibanding `==` untuk pengecekan data `None`. 62 | 63 | --- 64 | 65 |
66 | 67 | ## Catatan chapter 📑 68 | 69 | ### ◉ Source code praktik 70 | 71 |
72 |     
73 |         github.com/novalagung/dasarpemrogramanpython-example/../none
74 |     
75 | 
76 | 77 | ### ◉ Chapter relevan lainnya 78 | 79 | - [Tipe Data](/basic/tipe-data) 80 | - [Special Names](/basic/special-names) 81 | 82 | ### ◉ Referensi 83 | 84 | - https://docs.python.org/3/c-api/none.html 85 | - https://stackoverflow.com/questions/3257919/what-is-the-difference-between-is-none-and-none 86 | - https://stackoverflow.com/questions/26595/is-there-any-difference-between-foo-is-none-and-foo-none/26611#26611 87 | 88 |
89 | -------------------------------------------------------------------------------- /docs/basic/break-continue.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 11 3 | title: A.11. Perulangan Python ➜ break, continue 4 | sidebar_label: A.11. Perulangan ➜ break, continue 5 | # description: 6 | # keywords: [] 7 | # faqs: 8 | # - question: Seleksi kondisi di Python 9 | # answer: Seleksi kondisi di python dilakukan menggunakan if, elif (untuk else if), dan else 10 | # - question: Ternary di Python 11 | # answer: Contoh ternary di python ➜ "passed the exam" if grade >= 65 else "below the passing grade" 12 | --- 13 | 14 | Keyword `break` dan `continue` sering dipergunakan dalam perulangan untuk alterasi flow secara paksa, seperti memberhentikan perulangan atau memaksa perulangan untuk lanjut ke iterasi berikutnya. 15 | 16 | Pada chapter ini kita akan mempelajarinya. 17 | 18 | ## A.11.1. Keyword `break` 19 | 20 | Pengaplikasian `break` biasanya dikombinasikan dengan seleksi kondisi. Sebagai contoh program sederhana berikut, yaitu program dengan spesifikasi: 21 | 22 | - Berisi perulangan yang sifatnya berjalan terus-menerus tanpa henti (karena menggunakan nilai `True` sebagai kontrol). 23 | - Perulangan hanya berhenti jika nilai `n` (yang didapat dari inputan user) adalah tidak bisa dibagi dengan angka `3`. 24 | 25 | ```python 26 | while True: 27 | n = int(input("enter a number divisible by 3: ")) 28 | if n % 3 != 0: 29 | break 30 | 31 | print("%d is divisible by 3" % (n)) 32 | ``` 33 | 34 | ![perulangan break continue](img/break-continue-1.png) 35 | 36 | ## A.11.2. Keyword `continue` 37 | 38 | Keyword `continue` digunakan untuk memaksa perulangan lanjut ke iterasi berikutnya (seperti proses skip). 39 | 40 | Contoh penerapannya bisa dilihat pada program berikut, yang spesifikasinya: 41 | 42 | - Program berisi perulangan dengan kontrol adalah data *range* sebanyak 10 (dimana isinya adalah angka numerik `0` hingga `9`). 43 | - Ketika nilai variabel counter `i` adalah dibawah `3` atau di atas `7` maka iterasi di-skip. 44 | 45 | ```python 46 | for i in range(10): 47 | if i < 3 or i > 7: 48 | continue 49 | print(i) 50 | ``` 51 | 52 | Efek dari `continue` adalah semua statement setelahnya akan di-skip. Pada program di atas, statement `print(i)` tidak dieksekusi ada `continue`. 53 | 54 | Hasilnya bisa dilihat pada gambar berikut, nilai yang di-print adalah angka `3` hingga `7` saja. 55 | 56 | ![perulangan break continue](img/break-continue-2.png) 57 | 58 | ## A.11.3. Label perulangan 59 | 60 | Python tidak mengenal konsep perulangan yang memiliki label. 61 | 62 | Teknik menamai perulangan dengan label umumnya digunakan untuk mengontrol flow pada perulangan bercabang / *nested*, misalnya untuk menghentikan perulangan terluar secara paksa ketika suatu kondisi terpenuhi. 63 | 64 | Di Python, algoritma seperti ini bisa diterapkan namun menggunakan tambahan kode. Contoh penerapannya bisa dilihat pada kode berikut: 65 | 66 | ```python 67 | max = int(input("jumlah bintang: ")) 68 | 69 | outer_loop = True 70 | for i in range(max): 71 | if not outer_loop: 72 | break 73 | 74 | for j in range(i + 1): 75 | print("*", end=" ") 76 | if j >= 7: 77 | outer_loop = False 78 | break 79 | print() 80 | ``` 81 | 82 | Penjelasan: 83 | 84 | - Program yang memiliki perulanga *nested* dengan jumlah perulangan ada 2. 85 | - Disiapkan sebuah variabel `bool` bernama `outer_loop` untuk kontrol perulangan terluar. 86 | - Ketika nilai `j` (yang merupakan variabel counter perulangan terdalam) adalah lebih dari atau sama dengan `7`, maka variabel `outer_loop` di set nilainya menjadi `False`, dan perulangan terdalam di-`break` secara paksa. 87 | - Dengan ini maka perulangan terluar akan terhenti. 88 | 89 | --- 90 | 91 |
92 | 93 | ## Catatan chapter 📑 94 | 95 | ### ◉ Source code praktik 96 | 97 |
 98 |     
 99 |         github.com/novalagung/dasarpemrogramanpython-example/../break-continue
100 |     
101 | 
102 | 103 | ### ◉ Chapter relevan lainnya 104 | 105 | - [Perulangan ➜ for & range](/basic/for-range) 106 | - [Perulangan ➜ while](/basic/while) 107 | 108 | ### ◉ Referensi 109 | 110 | - https://docs.python.org/3/tutorial/controlflow.html 111 | 112 |
113 | -------------------------------------------------------------------------------- /docs/basic/del.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 55 3 | title: A.55. Python Delete Object 4 | sidebar_label: A.55. Delete Object 5 | --- 6 | 7 | Pada sekian chapter yang lalu kita telah belajar tentang object [None](/basic/none), fungsinya untuk menandai variabel agar bernilai kosong. 8 | 9 | Kali ini yang kita pelajari adalah keyword `del` untuk operasi delete object. Hasil penggunaan keyword `del` benar-benar menghapus variabel beserta isinya, jadi tidak hanya mengosongkan nilainya. 10 | 11 | ## A.55.1. Keyword `del` 12 | 13 | Penggunaan `None` sebagai nilai suatu variabel menjadikan variabel tersebut tetap ada tapi nilainya berubah menjadi `None`. Jadi penggunaan `None` disini berguna untuk mengosongkan variabel tanpa menghapus variabel itu sendiri. 14 | 15 | Bagaimana jika kita ingin benar-benar menghapus suatu variabel? Caranya menggunakan keyword `del`. Contoh penggunaannya bisa dilihat di bawah ini: 16 | 17 | ```python 18 | name = "Noval Agung" 19 | print(name) 20 | 21 | del name 22 | print(name) 23 | ``` 24 | 25 | Operasi print pertama memunculkan nilai variabel `name` tanpa kendala. Namun di statement print ke-2, variabel `name` tidak dikenal dan menghasilkan error karena variabel tersebut telah dihapus menggunakan keyword `del`. 26 | 27 | ![python delete object](img/del-1.png) 28 | 29 | Jadi keyword `del` ini benar-benar menghapus variabel ya. 30 | 31 | Tak hanya ke variabel saja, keyword ini bisa digunakan untuk menghapus attribute, item list, class, fungsi, dan banyak lainnya! 32 | 33 | ### ◉ Delete list item 34 | 35 | ```python 36 | obj = ["Noval", "Malang", "Chad"] 37 | print(obj) 38 | # output ➜ ['Noval', 'Malang', 'Chad'] 39 | 40 | del obj[1] 41 | print(obj) 42 | # output ➜ ['Noval', 'Chad'] 43 | ``` 44 | 45 | ### ◉ Delete dictionary item 46 | 47 | ```python 48 | obj = { 49 | "name": "Noval", 50 | "city": "Malang", 51 | "gender": "Chad" 52 | } 53 | print(obj) 54 | # output ➜ {'name': 'Noval', 'city': 'Malang', 'gender': 'Chad'} 55 | 56 | del obj["city"] 57 | print(obj) 58 | # output ➜ {'name': 'Noval', 'gender': 'Chad'} 59 | 60 | del obj["gender"] 61 | print(obj) 62 | # output ➜ {'name': 'Noval'} 63 | ``` 64 | 65 | ### ◉ Delete class/object property 66 | 67 | Keyword `del` dalam penggunaannya terhadap property class/object membuat property tersebut menjadi tidak ada. 68 | 69 | Pada contoh berikut statement delete dibungkus block `try` untuk menangkap error yang muncul karena mencoba mengakses property yang tidak terdaftar. 70 | 71 | ```python 72 | class Person: 73 | def __init__(self, name, city, gender): 74 | self.name = name 75 | self.city = city 76 | self.gender = gender 77 | 78 | p = Person("Noval", "Malang", "Chad") 79 | print(p.name, p.city, p.gender) 80 | # output ➜ Noval Malang Chad 81 | 82 | try: 83 | del p.city 84 | print(p.name, p.city, p.gender) 85 | # raise exception ⬇️ 86 | 87 | except Exception as err: 88 | print(err) 89 | # output ➜ 'Person' object has no attribute 'city' 90 | ``` 91 | 92 | ### ◉ Delete function 93 | 94 | Tak hanya object, fungsi juga bisa dihapus. 95 | 96 | ```python 97 | def say_hello(): 98 | print("hello world") 99 | 100 | say_hello() 101 | # output ➜ hello world 102 | 103 | try: 104 | del say_hello 105 | say_hello() 106 | # raise exception ⬇️ 107 | 108 | except Exception as err: 109 | print(err) 110 | # output ➜ name 'say_hello' is not defined 111 | ``` 112 | 113 | ### ◉ Delete class 114 | 115 | ```python 116 | class Person: 117 | def __init__(self, name, city, gender): 118 | self.name = name 119 | self.city = city 120 | self.gender = gender 121 | 122 | p = Person("Noval", "Malang", "Chad") 123 | print(p.name, p.city, p.gender) 124 | # output ➜ Noval Malang Chad 125 | 126 | try: 127 | del Person 128 | p = Person("Noval", "Malang", "Chad") 129 | # raise exception ⬇️ 130 | 131 | except Exception as err: 132 | print(err) 133 | # output ➜ name 'Person' is not defined 134 | ``` 135 | 136 | --- 137 | 138 |
139 | 140 | ## Catatan chapter 📑 141 | 142 | ### ◉ Source code praktik 143 | 144 |
145 |     
146 |         github.com/novalagung/dasarpemrogramanpython-example/../del
147 |     
148 | 
149 | 150 | ### ◉ Chapter relevan lainnya 151 | 152 | - [None](/basic/none) 153 | 154 | ### ◉ Referensi 155 | 156 | - https://docs.python.org/3/tutorial/datastructures.html#the-del-statement 157 | - https://docs.python.org/3/reference/simple_stmts.html#del 158 | 159 |
160 | -------------------------------------------------------------------------------- /docs/basic/while.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 10 3 | title: A.10. Perulangan Python ➜ while 4 | sidebar_label: A.10. Perulangan ➜ while 5 | description: Tutorial perulangan while di python 6 | keywords: [while, perulangan, python while, looping] 7 | faqs: 8 | - question: Perulangan di Python 9 | answer: Perulangan di Python bisa dilakukan menggunakan while, for range, dan juga kombinasi for dengan tipe data sequence seperti list, tuple, dan lainnya. 10 | - question: While di Python 11 | answer: 'Contoh perulanga di Python menggunakan keyword while ➜ while i < n: print("index:", i)' 12 | --- 13 | 14 | Di Python, selain keyword `for` ada juga keyword `while` yang fungsinya kurang lebih sama yaitu untuk perulangan. Bedanya, perulangan menggunakan `while` terkontrol via operasi logika atau nilai `bool`. 15 | 16 | Pada chapter ini kita akan mempelajari cara penerapannya. 17 | 18 | ## A.10.1. Keyword `while` 19 | 20 | Cara penerapan perulangan ini adalah dengan menuliskan keyword `while` kemudian diikuti dengan nilai `bool` atau operasi logika. Contoh: 21 | 22 | ```python 23 | should_continue = True 24 | 25 | while should_continue: 26 | n = int(input("enter an even number greater than 0: ")) 27 | 28 | if n <= 0 or n % 2 == 1: 29 | print(n, "is not an even number greater than 0") 30 | should_continue = False 31 | else: 32 | print("number:", n) 33 | ``` 34 | 35 | ![perulangan while](img/while-1.png) 36 | 37 | Program di atas memunculkan *prompt* inputan `enter an even number greater than 0:` yang dimana akan terus muncul selama user tidak menginputkan angka ganjil atau angka dibawah sama dengan `0`. 38 | 39 | Contoh lain penerapan `while` dengan kontrol adalah operasi logika: 40 | 41 | ```python 42 | n = int(input("enter max data: ")) 43 | i = 0 44 | 45 | while i < n: 46 | print("number", i) 47 | i += 1 48 | ``` 49 | 50 | ![perulangan while](img/while-2.png) 51 | 52 | ### ◉ Operasi *increment* dan *decrement* 53 | 54 | Python tidak mengenal operator *unary* `++` dan `--`. Solusi untuk melakukan operasi *increment* maupun *decrement* bisa menggunakan cara berikut: 55 | 56 | | Operasi | Cara 1 | Cara 2 | 57 | | :-: | :-: | :-: | 58 | | *Increment* | `i += 1` | `i = i + 1` | 59 | | *Decrement* | `i -= 1` | `i = i - 1` | 60 | 61 | ## A.10.2. Perulangan `while` vs `for` 62 | 63 | Operasi `while` cocok digunakan untuk perulangan yang dimana kontrolnya adalah operasi logika atau nilai boolean yang tidak ada kaitannya dengan *sequence*. 64 | 65 | Pada program yang sudah di tulis di atas, perulangan akan menjadi lebih ringkas dengan pengaplikasian keyword `for`, silakan lihat perbandingannya di bawah ini: 66 | 67 | - Dengan keyword `while`: 68 | 69 | ```python 70 | n = int(input("enter max data: ")) 71 | i = 0 72 | 73 | while i < n: 74 | print("number", i) 75 | i += 1 76 | ``` 77 | 78 | - Dengan keyword `for`: 79 | 80 | ```python 81 | n = int(input("enter max data: ")) 82 | 83 | for i in range(n): 84 | print("number", i) 85 | ``` 86 | 87 | Sedangkan keyword `for` lebih pas digunakan pada perulangan yang kontrolnya adalah data *sequence*, contohnya seperti range dan list. 88 | 89 | ## A.10.3. Perulangan bercabang / *nested* `while` 90 | 91 | Contoh perulangan bercabang bisa dilihat pada kode program berikut ini. Caranya cukup tulis saja keyword `while` di dalam block kode `while`. 92 | 93 | ```python 94 | n = int(input("enter max data: ")) 95 | i = 0 96 | 97 | while i < n: 98 | j = 0 99 | 100 | while j < n - i: 101 | print("*", end=" ") 102 | j += 1 103 | 104 | print() 105 | i += 1 106 | ``` 107 | 108 | ![perulangan while](img/while-3.png) 109 | 110 | ## A.10.4. Kombinasi `while` dan `for` 111 | 112 | Kedua keyword perulangan yang sudah dipelajari, yaitu `for` dan `while` bisa dikombinasikan untuk membuat suatu *nested loop* atau perulangan bercabang. 113 | 114 | Pada contoh berikut, kode program di atas diubah menggunakan kombinasi keyword `for` dan `while`. 115 | 116 | ```python 117 | n = int(input("enter max data: ")) 118 | i = 0 119 | 120 | for i in range(n): 121 | j = 0 122 | 123 | while j < n - i: 124 | print("*", end=" ") 125 | j += 1 126 | 127 | print() 128 | ``` 129 | 130 | --- 131 | 132 |
133 | 134 | ## Catatan chapter 📑 135 | 136 | ### ◉ Source code praktik 137 | 138 |
139 |     
140 |         github.com/novalagung/dasarpemrogramanpython-example/../while
141 |     
142 | 
143 | 144 | ### ◉ Referensi 145 | 146 | - https://docs.python.org/3/tutorial/controlflow.html 147 | 148 |
149 | -------------------------------------------------------------------------------- /docs/basic/generator-yield.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 59 3 | title: A.59. Python Generator & Yield 4 | sidebar_label: A.59. Generator & Yield 5 | --- 6 | 7 | Pada chapter ini kita akan belajar tentang konsep generator serta pengaplikasiannya menggunakan keyword `yield` dan *generator expression*. 8 | 9 | ## A.59.1. Generator object 10 | 11 | Generator object adalah object iterator yang dibuat via fungsi generator (menggunakan keyword `yield`) atau via *generator expression*. 12 | 13 | > Mengenai apa itu iterator, pembahasannya ada di chapter sebelumnya, yaitu [Iterable & Iterator](/basic/iterable-iterator) 14 | 15 | ## A.59.2. Generator function 16 | 17 | Generator function adalah salah satu cara pembuatan generator object. Ciri khasnya di dalam fungsi ada statement berisi keyword `yield`. 18 | 19 | Mari praktekan. Di bawah ini, fungsi `random_messages()` didesain untuk mengembalikan generator object. 20 | 21 | ```python 22 | def random_messages(): 23 | yield "hello python" 24 | yield "how are you" 25 | yield "nice to meet you" 26 | 27 | messages = random_messages() 28 | print(messages) 29 | # 30 | ``` 31 | 32 | Variabel `messages` menampung nilai balik pemanggilan fungsi `random_messages()` (data generator object), ketika di-print nilainya yang muncul adalah *generator object*. 33 | 34 | Selayaknya iterator, generator (yang juga merupakan iterator) pengaksesan itemnya dilakukan via perulangan `for in`, atau menggunakan fungsi `next()`. 35 | 36 | Pada contoh berikutnya ini, generator `random_messages()` digunakan pada perulangan. Hasilnya, di setiap iterasi `for in`, data yang dikembalikan via keyword `yield` di-print. 37 | 38 | ```python 39 | def random_messages(): 40 | yield "hello python" 41 | yield "how are you" 42 | yield "nice to meet you" 43 | 44 | for message in random_messages(): 45 | print(message) 46 | # output ↓ 47 | # 48 | # hello python 49 | # how are you 50 | # nice to meet you 51 | ``` 52 | 53 | Karena ada 3 statement `yield` disitu, maka generator ketika digunakan di perulangan hasilnya iterasi sebanyak 3x. 54 | 55 | - Iterasi ke-1, variabel `message` berisi statement yield ke-1, yaitu `hello python` 56 | - Iterasi ke-2, variabel `message` berisi statement yield ke-2, yaitu `how are you` 57 | - Iterasi ke-3, variabel `message` berisi statement yield ke-3, yaitu `nice to meet you` 58 | 59 | Contoh implementasi penerapan generator via fungsi `next()`: 60 | 61 | ```python 62 | gen = random_messages() 63 | 64 | message = next(gen) 65 | print(f"message 1: {message}") 66 | # output ➜ message 1: hello python 67 | 68 | message = next(gen) 69 | print(f"message 2: {message}") 70 | # output ➜ message 2: how are you 71 | 72 | message = next(gen) 73 | print(f"message 3: {message}") 74 | # output ➜ message 3: nice to meet you 75 | ``` 76 | 77 | Berikut adalah 2 contoh tambahan penerapan fungsi generator dan keyword `yield`. 78 | 79 | ### ◉ Infinite counter 80 | 81 | Keyword `yield` bisa dikombinasikan dengan perulangan `while` untuk membuat logic *infinite counter*. 82 | 83 | ```python 84 | def infinite_counter(): 85 | i = 0 86 | while True: 87 | yield i 88 | i = i + 1 89 | 90 | c = infinite_counter() 91 | print(next(c)) 92 | # output ➜ 0 93 | 94 | print(next(c)) 95 | # output ➜ 1 96 | 97 | print(next(c)) 98 | # output ➜ 2 99 | 100 | # ... 101 | ``` 102 | 103 | ### ◉ Operasi baca file 104 | 105 | Contoh operasi baca file yang setiap baris konten file dikembalikan sebagai data iterasi via keyword `yield`. 106 | 107 | ```python 108 | def file_reader(file_name): 109 | for row in open(file_name, "r"): 110 | yield row 111 | 112 | for row in open('content.txt'): 113 | print(row.strip()) 114 | ``` 115 | 116 | ## A.59.3. Generator expression 117 | 118 | Generator comprehension (atau yang umumnya dikenal sebagai generator expression) adalah ekspresi statement yang ditulis dalam format tertentu yang otomatis terdeteksi sebagai *generator object*. 119 | 120 | Penulisan ekspresi generator mirip seperti penulisan *list comprehension*, perbedaannya ada pada karakter yang digunakan untuk membungkus ekspresi. Pada list comprehension menggunakan tanda `[ ]`, pada generator comprehension/expression menggunakan tanda `( )`. 121 | 122 | Contoh penerapan: 123 | 124 | ```python 125 | exp1 = [num**2 for num in range(5)] 126 | print(exp1) 127 | # output ➜ [0, 1, 4, 9, 16] 128 | 129 | exp2 = (num**2 for num in range(5)) 130 | print(exp2) 131 | # output ➜ at 0x00000...> 132 | 133 | for d in exp2: 134 | print(d) 135 | # output ↓ 136 | # 137 | # 0 138 | # 1 139 | # 4 140 | # 9 141 | # 16 142 | ``` 143 | 144 | --- 145 | 146 |
147 | 148 | ## Catatan chapter 📑 149 | 150 | ### ◉ Source code praktik 151 | 152 |
153 |     
154 |         github.com/novalagung/dasarpemrogramanpython-example/../generator-yield
155 |     
156 | 
157 | 158 | ### ◉ Chapter relevan lainnya 159 | 160 | - [List Comprehension](/basic/list-comprehension) 161 | - [Iterable & Iterator](/basic/iterable-iterator) 162 | 163 | ### ◉ Referensi 164 | 165 | - https://docs.python.org/3/reference/expressions.html#generator-expressions 166 | - https://docs.python.org/3/reference/expressions.html#yield-expressions 167 | 168 |
169 | -------------------------------------------------------------------------------- /docs/basic/list-comprehension.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 13 3 | title: A.13. Python List Comprehension 4 | sidebar_label: A.13. List Comprehension 5 | description: List comprehension adalah metode ringkas pembuatan list selain menggunakan literal `[]`. Cara ini lebih banyak diterapkan untuk operasi list yang menghasilkan struktur baru. 6 | keywords: [list comprehension, python list comprehension, shortcut list] 7 | faqs: 8 | - question: Apa itu list comprehension di Python? 9 | answer: List comprehension adalah metode ringkas pembuatan list selain menggunakan literal `[]`. Cara ini lebih banyak diterapkan untuk operasi list yang menghasilkan struktur baru 10 | --- 11 | 12 | *List comprehension* adalah metode ringkas pembuatan list (selain menggunakan literal `[]` atau menggunakan fungsi `list()`). Cara ini lebih banyak diterapkan untuk operasi list yang menghasilkan struktur baru. 13 | 14 | Pada chapter ini kita akan mempelajarinya. 15 | 16 | ## A.13.1. Pengenalan list comprehension 17 | 18 | Metode penulisan list comprehension membuat kode menjadi sangat ringkas, dengan konsekuensi agak sedikit membingungkan untuk yang belum terbiasa. Jadi penulis sarankan gunakan sesuai kebutuhan. 19 | 20 | Silakan pelajari contoh berikut agar lebih mudah memahami seperti apa itu *list comprehension*. 21 | 22 | ### ◉ Contoh #1 23 | 24 | Perulangan berikut: 25 | 26 | ```python 27 | seq = [] 28 | for i in range(5): 29 | seq.append(i * 2) 30 | 31 | print(seq) 32 | # output ➜ [0, 2, 4, 6, 8] 33 | ``` 34 | 35 | ... bisa dituliskan lebih ringkas menggunakan *list comprehension*, menjadi seperti berikut: 36 | 37 | ```python 38 | seq = [i * 2 for i in range(5)] 39 | 40 | print(seq) 41 | # output ➜ [0, 2, 4, 6, 8] 42 | ``` 43 | 44 | ### ◉ Contoh #2 45 | 46 | Perulangan berikut: 47 | 48 | ```python 49 | seq = [] 50 | for i in range(10): 51 | if i % 2 == 1: 52 | seq.append(i) 53 | 54 | print(seq) 55 | # output ➜ [1, 3, 5, 7, 9] 56 | ``` 57 | 58 | ... bisa dituliskan lebih ringkas menjadi seperti berikut: 59 | 60 | ```python 61 | seq = [i for i in range(10) if i % 2 == 1] 62 | 63 | print(seq) 64 | # output ➜ [1, 3, 5, 7, 9] 65 | ``` 66 | 67 | ### ◉ Contoh #3 68 | 69 | Perulangan berikut: 70 | 71 | ```python 72 | seq = [] 73 | for i in range(1, 10): 74 | if i % 2 == 0: 75 | seq.append(i * 2) 76 | else: 77 | seq.append(i * 3) 78 | 79 | print(seq) 80 | # output ➜ [3, 4, 9, 8, 15, 12, 21, 16, 27] 81 | ``` 82 | 83 | ... bisa dituliskan lebih ringkas menjadi dengan bantuan *ternary* menjadi seperti ini: 84 | 85 | ```python 86 | seq = [] 87 | for i in range(1, 10): 88 | seq.append(i * (2 if i % 2 == 0 else 3)) 89 | 90 | print(seq) 91 | # output ➜ [3, 4, 9, 8, 15, 12, 21, 16, 27] 92 | ``` 93 | 94 | ... dan bisa dijadikan lebih ringkas lagi menggunakan *list comprehension*: 95 | 96 | ```python 97 | seq = [(i * (2 if i % 2 == 0 else 3)) for i in range(1, 10)] 98 | 99 | print(seq) 100 | # output ➜ [3, 4, 9, 8, 15, 12, 21, 16, 27] 101 | ``` 102 | 103 | ### ◉ Contoh #4 104 | 105 | Perulangan berikut: 106 | 107 | ```python 108 | list_x = ['a', 'b', 'c'] 109 | list_y = ['1', '2', '3'] 110 | 111 | seq = [] 112 | for x in list_x: 113 | for y in list_y: 114 | seq.append(x + y) 115 | 116 | print(seq) 117 | # output ➜ ['a1', 'a2', 'a3', 'b1', 'b2', 'b3', 'c1', 'c2', 'c3'] 118 | ``` 119 | 120 | ... bisa dituliskan lebih ringkas menjadi seperti berikut: 121 | 122 | ```python 123 | seq = [x + y for x in list_x for y in list_y] 124 | 125 | print(seq) 126 | # output ➜ ['a1', 'a2', 'a3', 'b1', 'b2', 'b3', 'c1', 'c2', 'c3'] 127 | ``` 128 | 129 | ### ◉ Contoh #5 130 | 131 | Perulangan berikut: 132 | 133 | ```python 134 | matrix = [ 135 | [1, 2, 3, 4], 136 | [5, 6, 7, 8], 137 | [9, 10, 11, 12], 138 | ] 139 | 140 | transposed = [] 141 | for i in range(4): 142 | tr = [] 143 | for row in matrix: 144 | tr.append(row[i]) 145 | transposed.append(tr) 146 | 147 | print(transposed) 148 | # output ➜ [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]] 149 | ``` 150 | 151 | ... bisa dituliskan lebih ringkas menjadi seperti ini: 152 | 153 | ```python 154 | matrix = [ 155 | [1, 2, 3, 4], 156 | [5, 6, 7, 8], 157 | [9, 10, 11, 12], 158 | ] 159 | 160 | transposed = [] 161 | for i in range(4): 162 | transposed.append([row[i] for row in matrix]) 163 | 164 | print(transposed) 165 | # output ➜ [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]] 166 | ``` 167 | 168 | ... dan bisa dijadikan lebih ringkas lagi menggunakan *list comprehension*: 169 | 170 | ```python 171 | matrix = [ 172 | [1, 2, 3, 4], 173 | [5, 6, 7, 8], 174 | [9, 10, 11, 12], 175 | ] 176 | 177 | transposed = [[row[i] for row in matrix] for i in range(4)] 178 | 179 | print(transposed) 180 | # output ➜ [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]] 181 | ``` 182 | 183 | --- 184 | 185 |
186 | 187 | ## Catatan chapter 📑 188 | 189 | ### ◉ Source code praktik 190 | 191 |
192 |     
193 |         github.com/novalagung/dasarpemrogramanpython-example/../list-comprehension
194 |     
195 | 
196 | 197 | ### ◉ Chapter relevan lainnya 198 | 199 | - [Perulangan ➜ for & range](/basic/for-range) 200 | - [List](/basic/list) 201 | - [Generator & Yield](/basic/generator-yield) 202 | 203 | ### ◉ TBA 204 | 205 | - Stack vs Queue 206 | 207 | ### ◉ Referensi 208 | 209 | - https://docs.python.org/3/tutorial/datastructures.html 210 | - https://docs.python.org/3/library/stdtypes.html#typesseq 211 | 212 |
213 | -------------------------------------------------------------------------------- /docs/basic/property-visibility.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 35 3 | title: A.36. Python OOP ➜ Property Visibility 4 | sidebar_label: A.36. OOP ➜ Property Visibility 5 | --- 6 | 7 | Visibility atau privacy dalam konteks OOP merujuk pada penentuan apakah property (baik itu attribute atau method) dapat diakses secara public atau hanya bisa diakses dari dalam class (private). 8 | 9 | Di bab ini, kita akan membahas implementasinya di Python. 10 | 11 | ## A.36.1. Pengenalan visibility/privacy 12 | 13 | Python, dari segi API kode yang tersedia, sebenarnya tidak secara eksplisit mendukung implementasi visibility property instance class. Semua attribute dan method secara default bersifat public di Python. 14 | 15 | > Property public berarti property tersebut dapat diakses melalui instance object atau dari luar block `class`. 16 | 17 | Meskipun demikian, ada beberapa praktik umum untuk menandai bahwa suatu method atau attribute adalah private. Salah satunya adalah menggunakan teknik *name mangling*, di mana nama attribute atau method ditulis dengan diawali 2 karakter underscore, misalnya `__name`, `__list_items`, dan sejenisnya. 18 | 19 | Penamaan tersebut tidak benar-benar membuat visibility property menjadi private, melainkan hanya sebagai penanda saja. Property sendiri tetap bisa diakses secara publik. 20 | 21 | Mari kita coba praktekan. Pertama siapkan project baru dengan struktur seperti ini: 22 | 23 |
24 | 25 | ```bash title="Project structure" 26 | property-visibility/ 27 | │─── models/ 28 | | │─── __init__.py 29 | | │─── company.py 30 | | └─── product.py 31 | └─── main.py 32 | ``` 33 | 34 |
35 | 36 | Package `models` berisi module `company` dan `product`, masing-masing berisi deklarasi class domain model `Company` dan `Product`. Sedangkan file `main.py` merupakan file entrypoint program. 37 | 38 | Isi kedua tersebut dengan kode berikut: 39 | 40 | ```python title="models/product.py" 41 | class Product: 42 | 43 | def __init__(self, name, category): 44 | self.name = name 45 | self.category = category 46 | self.__version = 1.0 47 | ``` 48 | 49 | ```python title="models/product.py" 50 | class Company: 51 | 52 | def __init__(self, name = "", products =[]): 53 | self.name = name 54 | self.products = products 55 | self.__version = 1.0 56 | 57 | def __print_name(self): 58 | print(f"company name: {self.name}") 59 | 60 | def __print_products(self): 61 | print(f"products:") 62 | for p in self.products: 63 | print(f" -> {p.name} ({p.category})") 64 | 65 | def info(self): 66 | self.__print_name() 67 | self.__print_products() 68 | ``` 69 | 70 | Class `Company` memiliki 4 buah fungsi: 71 | 72 | - Constructor `__init__()` yang memiliki parameter `name` dan `products`. Argument parameter tersebut datanya disimpan ke attribute. 73 | 74 | - Fungsi `__print_name()`, tugasnya memunculkan isi attribute `name`. Dari namanya (yang diawali karakter `__`) bisa disimpulkan bahwa fungsi ini didesain hanya untuk digunakan secara private (digunakan dalam blok class saja) dan tidak diperuntukan untuk public. 75 | 76 | - Fungsi `__print_products()`, tugasnya memunculkan isi data produk. Fungsi ini sama seperti `__print_name()` yaitu di-desain memiliki visibility private. 77 | 78 | - Method `info()` yang didalamnya memanggil method `__print_name()` dan `__print_products()`. 79 | 80 | Selain yang telah disebutkan di atas, class `Company` dan `Product` memiliki 1 property private bernama `__version` dimana property ini kita isi dengan informasi versi class. 81 | 82 | Selanjutnya, buka `main.py`, import kedua class tersebut, kemudian buat beberapa data, lalu print isinya. 83 | 84 | ```python title="main.py" 85 | from models import company 86 | from models import product 87 | 88 | if __name__ == "__main__": 89 | data = [] 90 | 91 | c1 = company.Company(name="Microsoft", products=[ 92 | product.Product(name="Windows", category="Operating system"), 93 | product.Product(name="Office 365", category="Productivity software") 94 | ]) 95 | data.append(c1) 96 | 97 | c2 = company.Company(name="Mattel", products=[ 98 | product.Product(name="Hot Wheels", category="Car toys"), 99 | product.Product(name="Uno", category="Card game") 100 | ]) 101 | data.append(c2) 102 | 103 | for d in data: 104 | d.info() 105 | ``` 106 | 107 | Output program: 108 | 109 | ![Property visibility Python](img/property-visibility-1.png) 110 | 111 | ## A.36.2. Property dengan prefix `__` 112 | 113 | Sebelumnya telah disebutkan bahwa prefix `__` dalam penerapannya tidak benar-benar membuat property menjadi private. Silakan test dengan autocompletion editor, property private masih muncul, menandakan bahwa property tersebut tidak benar-benar private. 114 | 115 | ![Property visibility Python](img/property-visibility-2.png) 116 | 117 | Meskipun demikian, solusi ini cukup efektif untuk memberi petunjuk kepada programmer bahwa property tersebut tidak didesain untuk konsumsi publik. 118 | 119 | --- 120 | 121 |
122 | 123 | ## Catatan chapter 📑 124 | 125 | ### ◉ Source code praktik 126 | 127 |
128 |     
129 |         github.com/novalagung/dasarpemrogramanpython-example/../property-visibility
130 |     
131 | 
132 | 133 | ### ◉ Chapter relevan lainnya 134 | 135 | - [OOP ➜ Class & Object](/basic/class-object) 136 | - [OOP ➜ Instance Attribute & Class Attribute](/basic/instance-attribute-class-attribute) 137 | 138 | ### ◉ Referensi 139 | 140 | - https://docs.python.org/3/tutorial/classes.html#private-variables 141 | 142 |
143 | -------------------------------------------------------------------------------- /docs/basic/error-exception.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 46 3 | title: A.46. Python Error & Exception 4 | sidebar_label: A.46. Error & Exception 5 | --- 6 | 7 | Secara teknis Python interpreter mengenal dua jenis error, yaitu *syntax error* dan *exception*. Sebenarnya ada lagi satu jenis error lainnya, yaitu yang munculnya hanya di level linter (di editor) namun tidak membuat eksekusi program menjadi gagal. 8 | 9 | Pada chapter ini kita akan membahas tentang topik tersebut. 10 | 11 | ## A.46.1. Syntax error 12 | 13 | Syntax error adalah salah satu jenis error yang ada di Python, yang jika muncul maka bisa dipastikan eksekusi program adalah gagal atau terhenti. Syntax error disebabkan oleh kesalahan penulisan. 14 | 15 | Misalnya ada typo pada pemanggilan fungsi print yang tidak sengaja tertulis sebagai `prind()`, sedangkan di source code sendiri tidak ada fungsi lain yang dideklarasikan dengan nama itu, maka pada situasi seperti ini terjadi syntax error. 16 | 17 | ```python 18 | prind("hello world") 19 | ``` 20 | 21 | Output program: 22 | 23 | ![Python syntax error](img/error-exception-1.png) 24 | 25 | Satu-satunya solusi untuk mengatasi syntax error adalah dengan memperbaiki kode, memastikan semua penulisannya benar sesuai aturan di Python. 26 | 27 | ## A.46.2. Exception 28 | 29 | Exception adalah jenis error yang muncul saat *runtime* (saat program dijalankan). Berbeda dengan syntax error yang munculnya saat proses eksekusi program (sebelum program benar-benar running). 30 | 31 | Salah satu exception yang umumnya ada di bahasa pemrograman adalah **zero division error**. Error ini muncul ketika ada operasi aritmatika pembagian suatu bilangan numerik terhadap bilangan `0`. 32 | 33 | Contoh kasus exception: 34 | 35 | ```python 36 | n1 = int(input("Enter the 1st number: ")) 37 | n2 = int(input("Enter the 2nd number: ")) 38 | 39 | res = n1 / n2 40 | print(f"{n1} / {n2} = {res}") 41 | ``` 42 | 43 | Output program: 44 | 45 | ![Python exception](img/error-exception-2.png) 46 | 47 | Exception bisa diantisipasi dengan menambahkan validasi, misalnya untuk kasus di atas bisa dengan ditambahkan seleksi kondisi pengecekan nilai `n2`. Jika nilainya adalah `0`, maka program dihentikan dan pesan peringatan dimunculkan. 48 | 49 | ```python 50 | n1 = int(input("Enter the 1st number: ")) 51 | n2 = int(input("Enter the 2nd number: ")) 52 | 53 | if n2 == 0: 54 | print("we do not allow the value of 0 on the 2nd number") 55 | else: 56 | res = n1 / n2 57 | print(f"{n1} / {n2} = {res}") 58 | ``` 59 | 60 | Output program: 61 | 62 | ![Python exception](img/error-exception-3.png) 63 | 64 | Alternatif solusi lainnya untuk mengatasi exception adalah dengan pengaplikasian kombinasi keyword `try` dan `catch`. Lebih detailnya akan dibahas di chapter berikutnya, di chapter [Exception Handling (try, catch, finally)](#). 65 | 66 | ## A.46.3. Throw exception 67 | 68 | Di atas kita belajar salah satu cara antisipasi exception, yaitu dengan penambahan validasi sesuai kebutuhan, jika kondisi berpotensi menghasilkan exception maka pesan custom error dimunculkan. 69 | 70 | Selanjutnya, kita akan belajar cara untuk dengan sengaja membuat atau melempar exception (istilah umumnya *throwing exception*). Dengan melempar exception, program akan terhenti secara paksa. 71 | 72 | Pada program berikut ini, sejumlah baris angka dimunculkan sesuai inputan. Jika inputannya `0` atau bilangan negatif maka exception dilempar, membuat program terhenti. 73 | 74 | ```python 75 | print("this program prints number from 0 to N") 76 | n = int(input("enter the value of N: ")) 77 | 78 | if n <= 0: 79 | raise Exception("we do not allow 0 or negative number") 80 | 81 | for d in range(0, n): 82 | print(d + 1) 83 | ``` 84 | 85 | Outputnya: 86 | 87 | ![Python exception](img/error-exception-4.png) 88 | 89 | Cara membuat exception adalah dengan menggunakan keyword `raise` diikuti dengan pemanggilan class `Exception()` yang argument-nya diisi dengan custom error. 90 | 91 | Pada contoh di atas, exception dimunculkan dengan pesan error `we do not allow 0 or negative number`. 92 | 93 | ## A.46.4. Linter error / warning 94 | 95 | Linter adalah suatu program utilitas yang berguna untuk melakukan pengecekan kualitas kode saat pengembangan (penulisan kode). Linter akan memunculkan error atau warning jika ditemukan pada beberapa bagian kode yang ditulis adalah kurang baik. 96 | 97 | Di Python, jika pembaca menggunakan VSCode editor dan sudah meng-install extension Python, linter akan otomatis bekerja saat menulis kode. 98 | 99 | Linter error adalah warning yang muncul di editor saat kode tidak sesuai baik secara *syntactic* maupun secara *semantic*. Error yang muncul karena alasan semantik tidak akan membuat program terhenti atau gagal running. Program tetap bisa jalan normal saat di-run. 100 | 101 | Salah satu contoh linter error adalah ketika ada suatu fungsi yang saat pemanggilannya diisi oleh tipe data dengan tipe yang tidak sesuai dibanding dengan yang sudah dideklarasikan. Pada situasi seperti ini error muncul di editor, ada highlight merah di situ. 102 | 103 | ![Python exception](img/error-exception-5.png) 104 | 105 | Meskipun tidak membuat program terhenti saat running, ada baiknya untuk selalu menulis kode dengan baik dan benar sesuai aturan. 106 | 107 | --- 108 | 109 |
110 | 111 | ## Catatan chapter 📑 112 | 113 | ### ◉ Source code praktik 114 | 115 |
116 |     
117 |         github.com/novalagung/dasarpemrogramanpython-example/../error-exception
118 |     
119 | 
120 | 121 | ### ◉ Chapter relevan lainnya 122 | 123 | - [Exception Handling ➜ try, except, else, finally](/basic/exception-handling-try-except-else-finally) 124 | 125 | ### ◉ Referensi 126 | 127 | - https://docs.python.org/3/tutorial/errors.html 128 | 129 |
130 | -------------------------------------------------------------------------------- /docs/basic/variabel.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 4 3 | title: A.4. Python Variabel 4 | sidebar_label: A.4. Variabel 5 | description: Tutorial belajar penerapan variabel di Python 6 | keywords: [variabel python] 7 | faqs: 8 | - question: Apa itu variabel di Python? 9 | answer: Dalam konsep programming, variabel adalah suatu nama yang dikenali komputer sebagai penampung suatu nilai/data yang disimpan di memory. Sebagai contoh nilai 3.14 disimpan di variabel bernama PI 10 | - question: Cara deklarasi variabel di Python 11 | answer: Deklarasi variabel di Python cukup sederhana, caranya tinggal tulis saja nama variabel kemudian diikuti operator *assignment* beserta nilai yang ingin dimasukan ke variabel tersebut. Contoh ➜ nama = "noval" 12 | - question: Naming convention atau aturan penamaan variabel di Python 13 | answer: Mengacu ke dokumentasi https://peps.python.org/pep-0008/, nama variabel dianjurkan untuk ditulis menggunakan snake_case. Contoh ➜ pesan = 'halo, selamat pagi' 14 | --- 15 | 16 | Dalam konsep programming, variabel adalah suatu nama yang dikenali komputer sebagai penampung nilai/data yang disimpan di memory. Sebagai contoh nilai `3.14` disimpan di variabel bernama `PI`. 17 | 18 | Pada chapter ini kita akan belajar tentang penerapan variabel di Python. 19 | 20 | ## A.4.1. Deklarasi variabel 21 | 22 | Agar dikenali oleh komputer, variabel harus dideklarasikan. Deklarasi variabel di Python cukup sederhana, caranya tinggal tulis saja nama variabel kemudian diikuti operator *assignment* beserta nilai awal yang ingin dimasukan ke variabel tersebut. Contoh: 23 | 24 | ```python 25 | nama = "noval" 26 | hobi = 'makan' 27 | umur = 18 28 | laki = True 29 | ``` 30 | 31 | Karakter `=` adalah **operator assignment**, digunakan untuk operasi penugasan. Nilai yang ada di sebelah kanan `=` ditugaskan untuk ditampung oleh variabel yang berada di sebelah kiri `=`. Contoh pada statement `nama = "noval"`, nilai `"nama"` ditugaskan untuk ditampung oleh variabel `nama`. 32 | 33 | > Nilai string bisa dituliskan dengan menggunakan literal `"` ataupun `'` 34 | 35 | Ok. Selanjutnya, coba kita munculkan nilai ke-empat variabel di atas ke layar menggunakan fungsi `print()`. Caranya: 36 | 37 | ```python 38 | print("==== biodata ====") 39 | print("nama: %s" % (nama)) 40 | print("hobi: %s, umur: %d, laki: %r" % (hobi, umur, laki)) 41 | ``` 42 | 43 | ![variabel python](img/variables-1.png) 44 | 45 | Penjelasan mengenai program di atas bisa dilihat di bawah ini: 46 | 47 | ### ◉ *String formatting* `print` 48 | 49 | Di program yang sudah ditulis, ada statement berikut: 50 | 51 | ```python 52 | print("==== biodata ====") 53 | ``` 54 | 55 | Statement tersebut adalah contoh cara memunculkan string ke layar output (`stdout`): 56 | 57 | Lalu di bawahnya ada statement ini, yang merupakan contoh penerapan teknik *string formatting* atau *output formatting* untuk mem-format string ke layar output: 58 | 59 | ```python 60 | print("nama: %s" % (nama)) 61 | # output ➜ "nama: noval" 62 | ``` 63 | 64 | Karakter `%s` disitu akan di-replace dengan nilai variabel `nama` sebelum dimunculkan. Dan `%s` disini menandakan bahwa data yang akan me-replace-nya bertipe data `string`. 65 | 66 | Selain `%s`, ada juga `%d` untuk data bertipe numerik integer, dan `%r` untuk data bertipe `bool`. Contoh penerapannya bisa dilihat pada statement ke-3 program yang sudah di tulis. 67 | 68 | ```python 69 | print("hobi: %s, umur: %d, laki: %r" % (hobi, umur, laki)) 70 | # output ➜ "hobi: makan, umur: 18, laki: True" 71 | ``` 72 | 73 | > Pembahasan detail mengenai string formatting ada di chapter [String ➜ formatting](/basic/string#a173-string-formatting) 74 | 75 | ## A.4.2. *Naming convention* variabel 76 | 77 | Mengacu ke dokumentasi [PEP 8 – Style Guide for Python Code](https://peps.python.org/pep-0008/), nama variabel dianjurkan untuk ditulis menggunakan [`snake_case`](https://en.wikipedia.org/wiki/Snake_case). 78 | 79 | ```python 80 | pesan = 'halo, selamat pagi' 81 | nilai_ujian = 99.2 82 | ``` 83 | 84 | ## A.4.3. Operasi *assignment* 85 | 86 | Di pemrograman Python, deklarasi variabel adalah pasti operasi assignment. Variabel dideklarasikan dengan ditentukan langsung nilai awalnya. 87 | 88 | ```python 89 | nama = "noval" 90 | umur = 18 91 | nama = "noval agung" 92 | umur = 21 93 | ``` 94 | 95 | ## A.4.4. Deklarasi variabel beserta tipe data 96 | 97 | Tipe data variabel bisa ditentukan secara eksplisit, penulisannya bisa dilihat pada kode berikut: 98 | 99 | ```python 100 | nama: str = "noval" 101 | hobi: str = 'makan' 102 | umur: int = 18 103 | laki: bool = True 104 | nilai_ujian: float = 99.2 105 | ``` 106 | 107 | > Pembahasan detail mengenai tipe data ada di chapter [Tipe Data](/basic/tipe-data) 108 | 109 | ## A.4.5. Deklarasi banyak variabel sebaris 110 | 111 | Contoh penulisan deklarasi banyak variabel dalam satu baris bisa dilihat pada kode berikut: 112 | 113 | ```python 114 | nilai1, nilai2, nilai3, nilai4 = 24, 25, 26, 21 115 | nilai_rata_rata = (nilai1 + nilai2 + nilai3 + nilai4) / 4 116 | 117 | print("rata-rata nilai: %f" % (nilai_rata_rata)) 118 | ``` 119 | 120 | > Karakter `%f` digunakan untuk mem-format nilai `float` 121 | 122 | Output program di atas: 123 | 124 | ![variabel python](img/variables-2.png) 125 | 126 | --- 127 | 128 |
129 | 130 | ## Catatan chapter 📑 131 | 132 | ### ◉ Source code praktik 133 | 134 |
135 |     
136 |         github.com/novalagung/dasarpemrogramanpython-example/../variables
137 |     
138 | 
139 | 140 | ### ◉ Chapter relevan lainnya 141 | 142 | - [Tipe Data](/basic/tipe-data) 143 | - [String](/basic/string) 144 | - [Number](/basic/number-bilangan) 145 | 146 | ### ◉ Referensi 147 | 148 | - https://www.w3schools.com/python/python_datatypes.asp 149 | - https://peps.python.org/pep-0008/ 150 | - https://en.wikipedia.org/wiki/Snake_case 151 | - https://www.learnpython.org/en/String_Formatting 152 | 153 |
154 | -------------------------------------------------------------------------------- /docs/basic/eval-exec.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 57 3 | title: A.57. Python Eval & Exec 4 | sidebar_label: A.57. Eval & Exec 5 | --- 6 | 7 | Pada chapter ini kita akan mempelajari fungsi `eval()` untuk eksekusi *expression*, fungsi `exec()` untuk eksekusi syntax Python, dan fungsi `compile()`. 8 | 9 | ## A.57.1. Fungsi `eval()` 10 | 11 | String berisi ekspresi seperti `PI * r * r` bisa dieksekusi kemudian diambil hasilnya menggunakan fungsi `eval()`. Cara penggunaannya sangat mudah, tulis saja ekspresi sebagai argument pemanggilan fungsi. Misalnya: 12 | 13 | ```python 14 | a = 10 15 | b = 5 16 | c = 8 17 | area = eval('(a + b) / 20 + (c * c)') 18 | print(area) 19 | # output ➜ 64.75 20 | ``` 21 | 22 | Variabel `a`, `b`, dan `c` di ekspresi `'(a + b) / 20 + (c * c)'` nilainya terisi oleh nilai variabel `a`, `b`, dan `c` yang sudah dideklarasikan sebelumnya. 23 | 24 | Ekspresi string berisi apapun bisa digunakan pada fungsi `eval()` ini, asalkan ekspresinya hanya 1 baris. 25 | 26 | Jika ekspresi tidak valid, maka eksekusi fungsi `eval()` menghasilkan error, dan ketika itu terjadi ada baiknya di-handle dengan baik. Contoh: 27 | 28 | ```python 29 | try: 30 | area = eval('(a + b asd / 20 + (c * c)') 31 | except Exception as err: 32 | print(f"error: {err}") 33 | 34 | # output ➜ error: '(' was never closed (, line 1) 35 | ``` 36 | 37 | By default, variabel dalam ekspresi terisi oleh nilai variabel yang sudah dideklarasikan. Selain itu, nilai variabel juga bisa ditentukan secara eksplisit via parameter ke-2 atau ke-3 fungsi `eval()`. 38 | 39 | - Jika ekspresi berisi variabel yang kesemuanya ditentukan secara eksplisit, bisa gunakan parameter ke-2. 40 | 41 | ```python 42 | area = eval('PI * r * r', { "PI": 3.14, "r": 10 }) 43 | print(area) 44 | # output ➜ 314.0 45 | ``` 46 | 47 | - Jika eskresi berisi variabel yang hanya sebagaian saja yang nilainya ditentukan secara eksplisit, maka gunakan `globals()` sebagai argument parameter ke-2 dan tulis variabel pada parameter ke-3. 48 | 49 | ```python 50 | PI = 3.14 51 | area = eval('PI * r * r', globals(), { "r": 10 }) 52 | print(area) 53 | # output ➜ 314.0 54 | ``` 55 | 56 | > Pemanggilan `eval('expr')` tanpa parameter ke-2 dan ke-3 adalah ekuivalen dengan statement `eval('expr', globals(), locals())` 57 | 58 | ## A.57.2. Fungsi `exec()` 59 | 60 | Fungsi `exec()` berguna untuk eksekusi string berisi kode Python. Cara penggunaannya mirip seperti `eval()`. Contoh: 61 | 62 | - Eksekusi statement dengan operasi *assignment* 63 | 64 | ```python 65 | a = 10 66 | b = 5 67 | c = 8 68 | res = 0 69 | exec('res = (a + b) / 20 + (c * c)') 70 | print(res) 71 | # output ➜ 64.75 72 | ``` 73 | 74 | Eksekusi `(a + b) / 20 + (c * c)` nilainya disimpan ke variabel `res` yang efeknya mengubah nilai variabel `res` yang telah dideklarasikan. 75 | 76 | - Eksekusi perulangan 77 | 78 | ```python 79 | r = 4 80 | stmt = """ 81 | for x in range(r): 82 | print(x) 83 | """ 84 | exec(stmt) 85 | # output ↓ 86 | # 87 | # 0 88 | # 1 89 | # 2 90 | # 3 91 | ``` 92 | 93 | - Eksekusi kode berisi statement import dan fungsi 94 | 95 | ```python 96 | r = 10 97 | res = 0 98 | stmt = """ 99 | from typing import Final 100 | 101 | PI: Final = 3.14 102 | 103 | def calculate_area_of_circle(): 104 | print(f"calculating area of circle with r: {r}") 105 | return PI * r * r 106 | 107 | res = calculate_area_of_circle() 108 | """ 109 | exec(stmt) 110 | print(res) 111 | # output ↓ 112 | # 113 | # calculating area of circle with r: 10 114 | # 314.0 115 | ``` 116 | 117 | Selama string berisi kode Python dengan syntax valid, maka bisa dijalankan via fungsi `exec()` ini. 118 | 119 | ## A.57.3. Fungsi `compile()` 120 | 121 | Fungsi `compile()` digunakan untuk kompilasi expression maupun kode Python, untuk kemudian digunakan pada fungsi `eval()`, `exec()`, ataupun untuk keperluan lainnya (seperti parse AST dan lainnya). 122 | 123 | Fungsi ini memiliki 3 parameter yang harus diisi saat pemanggilan: 124 | 125 | - Parameter ke-1 diisi dengan nilai string *expression* atau kode Python 126 | - Parameter ke-2 diisi string `''` 127 | - Parameter ke-3 diisi `eval` atau `exec` 128 | 129 | Dengan mengkompilasi string terlebih dahulu, kita bisa mengantisipasi syntax error ataupun expression error yang ada dalam string tanpa harus mengeksekusinya terlebih dahulu. 130 | 131 | Pengaplikasian fungsi `compile()` dalam penggunaannya dibedakan berdasarkan isi string yang di-compile. 132 | 133 | ### ◉ Compile *expression* 134 | 135 | Penggunaan fungsi `compile()` untuk *expression*, parameter ke-3 perlu diisi nilai `'eval'`. 136 | 137 | ```python 138 | compiled = compile('expr', '', 'eval') 139 | res = eval(compiled) 140 | ``` 141 | 142 | Contoh: 143 | 144 | ```python 145 | a = 10 146 | b = 5 147 | c = 8 148 | compiled = compile('(a + b) / 20 + (c * c)', '', 'eval') 149 | area = eval(compiled) 150 | print(area) 151 | # output ➜ 64.75 152 | ``` 153 | 154 | ### ◉ Compile *Python source code* 155 | 156 | Sedangkan untuk eksekusi kode Python, parameter ke-3 diisi nilai `'exec'`. 157 | 158 | ```python 159 | compiled = compile(stmt, '', 'exec') 160 | res = exec(compiled) 161 | ``` 162 | 163 | Contoh: 164 | 165 | ```python 166 | r = 10 167 | res = 0 168 | stmt = """ 169 | from typing import Final 170 | 171 | PI: Final = 3.14 172 | 173 | def calculate_area_of_circle(): 174 | print(f"calculating area of circle with r: {r}") 175 | return PI * r * r 176 | 177 | res = calculate_area_of_circle() 178 | """ 179 | compiled = compile(stmt, '', 'exec') 180 | area = exec(compiled) 181 | print(res) 182 | # output ↓ 183 | # 184 | # calculating area of circle with r: 10 185 | # 314.0 186 | ``` 187 | 188 | --- 189 | 190 |
191 | 192 | ## Catatan chapter 📑 193 | 194 | ### ◉ Source code praktik 195 | 196 |
197 |     
198 |         github.com/novalagung/dasarpemrogramanpython-example/../eval-exec
199 |     
200 | 
201 | 202 | ### ◉ Referensi 203 | 204 | - https://stackoverflow.com/questions/2220699/whats-the-difference-between-eval-exec-and-compile 205 | 206 |
207 | 208 | 209 | 210 | 211 | 212 | -------------------------------------------------------------------------------- /docs/basic/unicode.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 18 3 | title: A.18. Python Unicode String 4 | sidebar_label: A.18. String ➜ Unicode 5 | --- 6 | 7 | Python mengadopsi aturan standar [Unicode](https://www.unicode.org/) dalam pengelolaan karakter pada string. Benefitnya Python mendukung dan mengenali berbagai macam jenis karakter, termasuk diantaranya adalah huruf Arab, Jepang, emoji, symbol, dan banyak jenis karakter lainnya. 8 | 9 | > Unicode sendiri adalah suatu aturan standar untuk *encoding* text yang di-maintain oleh Unicode Consortium. Standarisasi ini diciptakan untuk mendukung semua jenis penulisan yang ada di bumi. 10 | 11 | Pada chapter ini kita akan membahas tentang bagaimana implementasi Unicode di Python. 12 | 13 | ## A.18.1. Pengenalan Unicode String 14 | 15 | Dalam dunia per-Unicode-an, ada yang disebut dengan **code point** yaitu suatu angka numerik (bisa desimal maupun hexadecimal) yang merepresentasikan karakter tertentu. Jadi bisa diibaratkan *identifier* dari suatu karakter. Semua karakter ada *code point*-nya, termasuk huruf A, B, C, maupun karakter lainnya (angka, tulisan romawi, symbol, dll). 16 | 17 | Cara penulisan karakter unicode sendiri bisa dengan langsung menuliskan karakternya, atau bisa juga dengan menuliskan *code point* dalam notasi tertentu. 18 | 19 | - Contoh penulisan text dengan langsung menuliskan karakternya: 20 | 21 | ```python 22 | message = "안녕하세요 😀" 23 | print(message) 24 | # output ➜ 안녕하세요 😀 25 | ``` 26 | 27 | - Menggunakan notasi special character `\uXXXX`, dimana `XXXX` diisi dengan *code point* dalam encoding 16-bit. 28 | 29 | ```python 30 | message = "\uC548\uB155\uD558\uC138\uC694" 31 | print(message) 32 | # output ➜ 안녕하세요 33 | ``` 34 | 35 |
    36 |
  • Code point 16-bit C548 merepresentasikan karakter
  • 37 |
  • Code point 16-bit B155 merepresentasikan karakter
  • 38 |
  • Code point 16-bit D558 merepresentasikan karakter
  • 39 |
  • Code point 16-bit C548 merepresentasikan karakter
  • 40 |
  • Code point 16-bit C694 merepresentasikan karakter
  • 41 |
42 | 43 | Untuk memunculkan emoji menggunakan kode encoding 16-bit butuh tambahan effort karena code point emoji tidak cukup jika direpresentasikan oleh *code point* yang lebarnya hanya 16-bit. 44 | 45 | - Menggunakan notasi special character `\UXXXXXXXX`, dimana `XXXXXXXX` diisi *code point* dalam encoding 32-bit. 46 | 47 | ```python 48 | message = "\U0000C548\U0000B155\U0000D558\U0000C138\U0000C694 \U0001F600" 49 | print(message) 50 | # output ➜ 안녕하세요 😀 51 | ``` 52 | 53 | - *Code point* 32-bit `0000C548` merepresentasikan karakter `안` 54 | - *Code point* 32-bit `0000B155` merepresentasikan karakter `녕` 55 | - *Code point* 32-bit `0000D558` merepresentasikan karakter `하` 56 | - *Code point* 32-bit `0000C138` merepresentasikan karakter `세` 57 | - *Code point* 32-bit `0000C694` merepresentasikan karakter `요` 58 | - *Code point* 32-bit `0001F600` merepresentasikan emoji `😀` 59 | 60 | - Atau menggunakan notasi special character `\N{NAME}`, dimana `NAME` diisi dengan nama karakter unicode dalam huruf besar. 61 | 62 | ```python 63 | message = "\N{HANGUL SYLLABLE AN}\N{HANGUL SYLLABLE NYEONG} \N{GRINNING FACE}" 64 | print(message) 65 | # output ➜ 안녕 😀 66 | ``` 67 | 68 | - Nama karakter Unicode `HANGUL SYLLABLE AN` merepresentasikan karakter `안` 69 | - Nama karakter Unicode `HANGUL SYLLABLE NYEONG` merepresentasikan karakter `녕` 70 | - Nama karakter Unicode `GRINNING FACE` merepresentasikan emoji `😀` 71 | 72 | > Salah satu website yang berguna untuk mencari informasi nama dan *code point* karakter Unicode: https://www.compart.com/en/unicode/ 73 | 74 | ## A.18.2. Fungsi utilitas pada *Unicode* 75 | 76 | ### ◉ Fungsi `ord()` 77 | 78 | Fungsi `ord()` digunakan untuk mengambil nilai code point dari suatu karakter. Nilai baliknya adalah numerik berbasis desimal. 79 | 80 | ```python 81 | text = "N" 82 | codePoint = ord(text) 83 | print(f'code point of {text} in decimal: {codePoint}') 84 | # output ➜ code point of N in decimal: 78 85 | 86 | text = "안" 87 | codePoint = ord(text) 88 | print(f'code point of {text} in decimal: {codePoint}') 89 | # output ➜ code point of 안 in decimal: 50504 90 | ``` 91 | 92 | Untuk menampilkan code point dalam notasi heksadesimal, cukup bungkus menggunakan fungsi `hex()`. 93 | 94 | ```python 95 | text = "안" 96 | codePoint = ord(text) 97 | 98 | print(f'code point of {text} in decimal: {codePoint}') 99 | # output ➜ code point of 안 in decimal: 50504 100 | 101 | print(f'code point of {text} in hex: {hex(codePoint)}') 102 | # output ➜ code point of 안 in hex: 0xc548 103 | ``` 104 | 105 | Bisa dilihat dari program di atas, unicode code point dari karakter `안` dalam bentuk heksadesimal adalah `c548`. Jika dicek pada praktek sebelumnya, kode heksadesimal yang sama kita gunakan juga dalam penulisan karakter unicode menggunakan notasi `\uXXXX` (yaitu `\uc548`). 106 | 107 | ### ◉ Fungsi `chr()` 108 | 109 | Fungsi `chr()` adalah kebalikan dari fungsi `ord()`, kegunaannya adalah untuk menampilkan string sesuai code point. 110 | 111 | Pada contoh dibawah ini fungsi `chr()` digunakan untuk memunculkan karakter dengan code point desimal `50504` dan juga heksadesimal `C548`, yang keduanya adalah merepresentasikan karakter yang sama, yaitu `안`. 112 | 113 | ```python 114 | codePoint = chr(50504) 115 | print(codePoint) 116 | # output ➜ 안 117 | 118 | codePoint = chr(0xC548) 119 | print(codePoint) 120 | # output ➜ 안 121 | ``` 122 | 123 | --- 124 | 125 |
126 | 127 | ## Catatan chapter 📑 128 | 129 | ### ◉ Source code praktik 130 | 131 |
132 |     
133 |         github.com/novalagung/dasarpemrogramanpython-example/../unicode
134 |     
135 | 
136 | 137 | ### ◉ Chapter relevan lainnya 138 | 139 | - [String](/basic/string) 140 | 141 | ### ◉ Referensi 142 | 143 | - https://docs.python.org/3/howto/unicode.html#:~:text=Python's%20string%20type%20uses%20the,character%20its%20own%20unique%20code. 144 | - https://docs.python.org/3/howto/unicode.html?highlight=unicode%20howto#the-string-type 145 | 146 |
147 | -------------------------------------------------------------------------------- /docs/basic/abstract-method.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 42 3 | title: A.42. Python OOP ➜ Abstract Method 4 | sidebar_label: A.42. OOP ➜ Abstract Method 5 | --- 6 | 7 | Pada chapter ini kita akan mempelejari tentang apa itu abstract method beserta bagaimana penerapannya pada pemrograman OOP menggunakan Python. 8 | 9 | ## A.42.1. Pengenalan abstract method 10 | 11 | Abstract method merupakan jenis method yang dideklarasikan dengan isi tidak melakukan apa-apa, hanya statement `pass`. Nantinya ketika class (dimana method tersebut berada) di-inherit ke sub class lain, maka sub-class harus meng-override method milik super class tersebut. 12 | 13 | Abstract method umum digunakan pada situasi dimana ada beberapa class yang memiliki method yang sama, namun isinya berbeda satu sama lain. Agar seragam, maka beberapa class tersebut harus menjadi sub class dari sebuah super class yang sama. Super class sendiri berisi abstract method, dibuat sebagai acuan spesifikasi untuk sub class. 14 | 15 | > Pada pemrograman secara umum, fungsi tanpa isi biasa disebut dengan *header function* 16 | 17 | Agar lebih mudah untuk memahami konsep dan penerapan abstract method, kita akan mulai pembelajaran dengan praktek tanpa penerapan abstract method terlebih dahulu. 18 | 19 | Ok, siapkan sebuah class bernama `Object2D` dengan isi satu buah method bernama `calculate_area()`. Kemudian class tersebut diturunkan ke dua class baru bernama `Triangle` dan `Circle`. 20 | 21 | Class `Triangle` dan `Circle` keduanya memiliki bentuk implementasi `calculate_area()` berbeda satu sama lain karena memang secara aturan rumus perhitungan luas segitiga dan lingkaran adalah berbeda. 22 | 23 | Alasan kenapa ada deklarasi method `calculate_area()` di parent class adalah agar sub class `Triange` dan `Circle` memiliki method `calculate_area()` dengan skema seragam. 24 | 25 | Berikut adalah source code-nya: 26 | 27 | ```python 28 | class Object2D: 29 | def calculate_area(self): 30 | pass 31 | 32 | class Triangle(Object2D): 33 | def __init__(self, b, h): 34 | self.b = b 35 | self.h = h 36 | 37 | def calculate_area(self): 38 | return 1/2 * self.b * self.h 39 | 40 | class Circle(Object2D): 41 | def __init__(self, r): 42 | self.r = r 43 | 44 | def calculate_area(self): 45 | return 3.14 * self.r * self.r 46 | 47 | obj1 = Triangle(4, 10) 48 | area = obj1.calculate_area() 49 | print(f"area of {type(obj1).__name__}: {area}") 50 | # output ➜ area of Triangle: 20.0 51 | 52 | obj2 = Circle(20) 53 | area = obj2.calculate_area() 54 | print(f"area of {type(obj2).__name__}: {area}") 55 | # output ➜ area of Circle: 1256.0 56 | ``` 57 | 58 | Kode di atas berjalan normal sesuai harapan, namun memiliki kekurangan, yaitu ketika class `Object2D` diturunkan ke suatu class, bisa saja sub class tidak meng-override method `calculate_area()`. 59 | 60 | Contoh, pada kode berikut dibuat class baru bernama `Square` yang tidak meng-override method `calculate_area()`: 61 | 62 | ```python 63 | class Square(Object2D): 64 | def __init__(self, s): 65 | self.s = s 66 | 67 | obj3 = Square(6) 68 | area = obj3.calculate_area() 69 | print(f"area of {type(obj3).__name__}: {area}") 70 | # output ➜ area of Square: None 71 | ``` 72 | 73 | Output: 74 | 75 | ![Abstract method](img/abstract-method-1.png) 76 | 77 | Kode di atas ketika di-run tidak menghasilkan error, berjalan normal, hanya saja outputnya tidak sesuai harapan karena class `Square` tidak mempunyai method `calculate_area()`. Tanpa adanya method tersebut, maka pemanggilan `calculate_area()` mengarah ke method super class yang isinya mengembalikan nilai `None`. 78 | 79 | Di *real life*, ukuran source code yang kita maintain bisa saja berisi ratusan atau bahkan puluhan ribu baris dengan jumlah file sangat banyak. Di case yang seperti itu cukup susah mengecek mana class yang implementasinya sudah sesuai spesifikasi dan mana yang belum, karena saat program dijalankan tidak ada error atau warning. Untuk mengatasi masalah tersebut, solusinya adalah dengan mengimplementasikan abstract method. 80 | 81 | ## A.42.2. Praktek abstract method 82 | 83 | Di Python versi 3.4+, suatu method menjadi abstract method ketika memenuhi kriteria berikut: 84 | 85 | - Super class meng-inherit class bawaan Python bernama `ABC` milik module `abc`. 86 | - Method yang dijadikan acuan (yang nantinya wajib di-override) perlu ditambahi decorator `@abstractmethod` milik module `abc`. 87 | 88 | > ABC merupakan kependekan dari Abstract Base Class, sebuah module bawaan Python Standard Library yang berisi banyak property untuk keperluan abstraction. 89 | 90 | Sekarang, aplikasikan 2 hal di atas ke kode yang telah ditulis. Kurang lebih hasil akhirnya seperti ini. Perbedaannya ada pada deklarasi class `Object2D` dan deklarasi method `calculate_area()`. 91 | 92 | ```python 93 | 94 | from abc import ABC, abstractmethod 95 | 96 | class Object2D(ABC): 97 | @abstractmethod 98 | def calculate_area(self): 99 | pass 100 | 101 | class Triangle(Object2D): 102 | def __init__(self, b, h): 103 | self.b = b 104 | self.h = h 105 | 106 | def calculate_area(self): 107 | return 1/2 * self.b * self.h 108 | 109 | class Circle(Object2D): 110 | def __init__(self, r): 111 | self.r = r 112 | 113 | def calculate_area(self): 114 | return 3.14 * self.r * self.r 115 | 116 | class Square(Object2D): 117 | def __init__(self, s): 118 | self.s = s 119 | 120 | obj1 = Triangle(4, 10) 121 | area = obj1.calculate_area() 122 | print(f"area of {type(obj1).__name__}: {area}") 123 | 124 | obj2 = Circle(20) 125 | area = obj2.calculate_area() 126 | print(f"area of {type(obj2).__name__}: {area}") 127 | 128 | obj3 = Square(6) 129 | area = obj3.calculate_area() 130 | print(f"area of {type(obj3).__name__}: {area}") 131 | ``` 132 | 133 | Selanjutnya, coba jalankan, pasti muncul error karena class `Square` tidak berisi implementasi method `calculate_area()`. 134 | 135 | ![Abstract method](img/abstract-method-2.png) 136 | 137 | Untuk memperbaiki error, override method `calculate_area()` milik class `Square` agar sesuai spesifikasi. 138 | 139 | ```python 140 | class Square(Object2D): 141 | def __init__(self, s): 142 | self.s = s 143 | 144 | def calculate_area(self): 145 | return self.s * self.s 146 | ``` 147 | 148 | Output program setelah diperbaiki: 149 | 150 | ![Abstract method](img/abstract-method-3.png) 151 | 152 | --- 153 | 154 |
155 | 156 | ## Catatan chapter 📑 157 | 158 | ### ◉ Source code praktik 159 | 160 |
161 |     
162 |         github.com/novalagung/dasarpemrogramanpython-example/../abstract-class
163 |     
164 | 
165 | 166 | ### ◉ Chapter relevan lainnya 167 | 168 | - [OOP ➜ Class & Object](/basic/class-object) 169 | - [OOP ➜ Instance Method](/basic/instance-method) 170 | - [OOP ➜ Constructor](/basic/class-constructor) 171 | - [OOP ➜ Class Method](/basic/class-method) 172 | - [OOP ➜ Static Method](/basic/static-method) 173 | - [Function ➜ Decorator](/basic/decorator) 174 | - [OOP ➜ Class Inheritance](/basic/class-inheritance) 175 | 176 | ### ◉ Referensi 177 | 178 | - https://docs.python.org/3/library/abc.html 179 | - https://stackoverflow.com/questions/13646245/is-it-possible-to-make-abstract-classes-in-python/13646263#13646263 180 | 181 |
182 | -------------------------------------------------------------------------------- /docs/basic/enum.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 56 3 | title: A.56. Python Enumeration 4 | sidebar_label: A.56. Enumeration 5 | --- 6 | 7 | Enumeration (Enum) adalah nilai konstan, umumnya disiapkan untuk merepresentasikan sekumpulan data konstan yang konteksnya masih sama. Misalnya, **warna** yang isinya bisa merah, biru, kuning, atau warna lain. 8 | 9 | Pembuatan enum di Python sangat mudah. Caranya dengan mendeklarasikan class baru yang meng-*inherit* class `enum.Enum`, kemudian menuliskan kumpulan data sebagai class property-nya. 10 | 11 | ## A.56.1. Enum / Enumeration 12 | 13 | Di bawah ini, disiapkan sebuah enum bernama `City` dengan isi ada 4 buah pilihan kota. 14 | 15 | ```python 16 | from enum import Enum 17 | class City(Enum): 18 | MALANG = 1 19 | SURABAYA = 2 20 | YOGYAKARTA = 3 21 | JAKARTA = 4 22 | 23 | print(list(City)) 24 | # output ➜ [, , , 25 | ``` 26 | 27 | Nilai property enum bisa diisi dengan data apapun. Pada contoh di atas, nilai property enum `City` diisi dengan angka numerik. 28 | 29 | > Property enum bisa diakses dalam bentuk `list` dengan cukup membungkusnya menggunakan fungsi `list()`. 30 | 31 | Selanjutnya, buat satu variabel, isi nilainya dengan salah satu property enum (misalnya `City.YOGYAKARTA`), kemudian print. 32 | 33 | ```python 34 | city1 = City.YOGYAKARTA 35 | 36 | print(city1) 37 | # output ➜ City.YOGYAKARTA 38 | 39 | print(f"name {city1.name}") 40 | # output ➜ name YOGYAKARTA 41 | 42 | print(f"value {city1.value}") 43 | # output ➜ value 3 44 | ``` 45 | 46 | Nama enum property bisa diambil menggunakan property `name` sedangkan value-nya diambil via property `value`. 47 | 48 | ## A.56.2. Naming convention enum 49 | 50 | Sesuai penjelasan di [halaman dokumentasi Python](https://docs.python.org/3/howto/enum.html), nama class enum dianjurkan ditulis menggunakan **CamelCase**, sedangkan nama class property dituliskan **UPPERCASE**. 51 | 52 | ## A.56.3. Notasi penulisan pengaksesan enum property 53 | 54 | Dalam penggunaannya setidaknya ada 3 notasi pengaksesan enum property yang bisa digunakan. 55 | 56 | - Cara pertama menggunakan notasi `Enum.PROPERTY`. 57 | 58 | ```python 59 | city1 = City.YOGYAKARTA 60 | 61 | print(city1) 62 | # output ➜ City.YOGYAKARTA 63 | print(f"name {city1.name}") 64 | # output ➜ name YOGYAKARTA 65 | print(f"value {city1.value}") 66 | # output ➜ value 3 67 | ``` 68 | 69 | - Cara ke-2 menggunakan notasi pengaksesan dictionary dengan key berupa string. 70 | 71 | ```python 72 | city2 = City["SURABAYA"] 73 | print(city2) 74 | # output ➜ City.SURABAYA 75 | print(f"name {city2.name}") 76 | # output ➜ name SURABAYA 77 | print(f"value {city2.value}") 78 | # output ➜ value 2 79 | ``` 80 | 81 | Metode ini cukup berguna pada case ketika key enum yang perlu diambil yang sudah diketahui nilainya. 82 | 83 | - Cara ke-3 menggunakan notasi pengaksesan `Enum(value)`. 84 | 85 | ```python 86 | city3 = City(4) 87 | print(city3) 88 | # output ➜ City.JAKARTA 89 | print(f"name {city3.name}") 90 | # output ➜ name JAKARTA 91 | print(f"value {city3.value}") 92 | # output ➜ value 4 93 | ``` 94 | 95 | Metode ini pas digunakan ketika value enum sudah diketahui nilainya. 96 | 97 | ## A.56.4. Nilai property enum 98 | 99 | Property enum nilainya bisa berisi data numerik, string, atau tipe data lainnya. 100 | 101 | Di atas telah dicontohkan enum `City` yang property-nya berisi data numerik. Pada contoh ke-2 ini, enum `Color` property-nya berisi data string. 102 | 103 | ```python 104 | from enum import Enum 105 | class Color(Enum): 106 | RED = "red" 107 | BLUE = "blue" 108 | 109 | print(list(Color)) 110 | # output ➜ [, ] 111 | 112 | color1 = Color("red") 113 | color2 = Color.RED 114 | color3 = Color["BLUE"] 115 | print(color1, color2, color3) 116 | # output ➜ Color.RED Color.RED Color.BLUE 117 | ``` 118 | 119 | Selain menggunakan class `enum.Enum` saat deklarasi, bisa juga menggunakan salah satu class turunan enum lainnya, diantaranya ada: 120 | 121 | - Class `enum.Enum` ➡️ property boleh berisi data bertipe apapun 122 | - Class `enum.StrEnum` ➡️ property hanya boleh berisi tipe data string 123 | - Class `enum.IntEnum` ➡️ property hanya boleh berisi tipe data integer 124 | 125 | Cara penerapan variant enum yang telah disebut di atas adalah masih sama. Cukup ganti `Enum` dengan turunan class yang diinginkan, lalu sesuaikan tipe data nilai property di dalamnya. 126 | 127 | ### ◉ `StrEnum` 128 | 129 | Misalnya, enum `Color` kita ubah dari menggunakan `Enum` ke `StrEnum`, maka kodenya seperti ini: 130 | 131 | ```python 132 | from enum import StrEnum 133 | class Color(StrEnum): 134 | RED = "red" 135 | BLUE = "blue" 136 | 137 | print(list(Color)) 138 | # output ➜ [, ] 139 | 140 | color1 = Color("red") 141 | color2 = Color.RED 142 | color3 = Color["BLUE"] 143 | print(color1, color2, color3) 144 | # output ➜ Color.RED Color.RED Color.BLUE 145 | ``` 146 | 147 | ### ◉ `IntEnum` dan fungsi `auto()` 148 | 149 | Untuk enum dengan property bertipe numerik, bisa menggunakan fungsi `auto()` untuk generate nilai numerik unik secara otomatis. Contoh: 150 | 151 | ```python 152 | from enum import IntEnum, auto 153 | class Size(IntEnum): 154 | S = auto() 155 | M = auto() 156 | L = auto() 157 | XL = auto() 158 | 159 | print(list(Size)) 160 | # output ➜ [, , , ] 161 | 162 | size1 = Size.M 163 | size2 = Size.XL 164 | print(size1, size2) 165 | # output ➜ Size.M Size.XL 166 | ``` 167 | 168 | ## A.56.5. Pengecekan nilai enum 169 | 170 | Operator identitas `is` dan operator perbandingan `==` dan `!=` bisa digunakan untuk pengecekan nilai enum. 171 | 172 | ```python 173 | from enum import Enum 174 | class City(Enum): 175 | MALANG = 1 176 | SURABAYA = 2 177 | YOGYAKARTA = 3 178 | JAKARTA = 4 179 | 180 | def say_anything(c): 181 | if c is City.MALANG: 182 | print("Oyi sam") 183 | elif c == City.JAKARTA: 184 | print("lo gue lo gue") 185 | elif c == City.SURABAYA: 186 | print("coeg") 187 | elif c == City.YOGYAKARTA: 188 | print("monggo") 189 | 190 | city1 = City.YOGYAKARTA 191 | say_anything(city1) 192 | # output ➜ monggo 193 | ``` 194 | 195 | ## A.56.6. Perulangan enum 196 | 197 | Enum merupakan tipe yang bisa langsung digunakan pada perulangan. Contoh penggunaannya: 198 | 199 | ```python 200 | for c in City: 201 | print(c, c.name, c.value) 202 | # output ↓ 203 | # 204 | # City.MALANG MALANG 1 205 | # City.SURABAYA SURABAYA 2 206 | # City.YOGYAKARTA YOGYAKARTA 3 207 | # City.JAKARTA JAKARTA 4 208 | ``` 209 | 210 | --- 211 | 212 |
213 | 214 | ## Catatan chapter 📑 215 | 216 | ### ◉ Source code praktik 217 | 218 |
219 |     
220 |         github.com/novalagung/dasarpemrogramanpython-example/../enum
221 |     
222 | 
223 | 224 | ### ◉ Chapter relevan lainnya 225 | 226 | - [Konstanta](/basic/konstanta) 227 | 228 | ### ◉ TBA 229 | 230 | - `IntFlag` and `Flag` https://docs.python.org/3/howto/enum.html#intflag 231 | 232 | ### ◉ Referensi 233 | 234 | - https://docs.python.org/3/library/enum.html 235 | - https://docs.python.org/3/howto/enum.html 236 | 237 |
238 | -------------------------------------------------------------------------------- /docs/basic/local-global-var.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 29 3 | title: A.29. Python Variables Scope (Local vs. Global) 4 | sidebar_label: A.29. Variables Scope (Local vs. Global) 5 | --- 6 | 7 | Pada chapter ini kita akan membahas tentang variable scope, yaitu kapan suatu variabel valid dan bisa digunakan di dalam block serta beberapa fungsi yang masih relevan dengan topik variabel scope. 8 | 9 | ## A.29.1. Local vs. global variable 10 | 11 | Global variable adalah variabel yang dideklarasikan di root (tidak di dalam suatu block fungsi). Sedangkan local variable adalah yang dideklarasikan di dalam suatu block dan hanya valid di block tersebut saja. 12 | 13 | Contoh, sebuah file program Python bernama `main.py` di isi dengan kode berikut: 14 | 15 | ```python title="File main.py" 16 | name = "Cleaver Bmurglbrm" 17 | print("greetings", name) 18 | 19 | def greet(): 20 | today = "Saturday" 21 | print("happy", today, name) 22 | 23 | if name: 24 | greet() 25 | greet_message = "have a good day" 26 | print("hello", name, greet_message) 27 | 28 | # output ↓ 29 | # 30 | # greetings Cleaver Bmurglbrm 31 | # happy Saturday Cleaver Bmurglbrm 32 | # hello Cleaver Bmurglbrm have a good day 33 | ``` 34 | 35 | Variabel `name` disitu merupakan variabel global. Variabel jenis ini bisa diakses dari block manapun. Di contoh, variabel `name` diakses di dalam block fungsi `greet()` dan di block seleksi kondisi `if name:`. 36 | 37 | Berbeda dengan variabel `today` yang tempat deklarasinya ada di block fungsi `greet()`, membuatnya hanya valid untuk digunakan di block itu saja. Variabel `today` dikategorikan sebagai variabel local dengan scope adalah block fungsi `greet()`. 38 | 39 | Selain itu ada juga variabel lain bernama `greet_message` yang dideklarasikan di block seleksi kondisi `if name:`. 40 | 41 | Sekarang coba akses variabel `today` dari luar block, hasilnya pasti error. Keterangan errornya: variabel `today` tidak dikenali. 42 | 43 | ![Python variable scope local vs global](img/local-global-var-1.png) 44 | 45 | Bagaimana jika variabel `greet_message` diakses dari luar block seleksi kondisi, apakah juga error? Jawabannya, tidak! 46 | 47 | ![Python variable scope local vs global](img/local-global-var-2.png) 48 | 49 | Di editor terlihat variabel `greet_message` digaris-bawahi merah, menandakan ada error namun hanya di level linter saja. Error tersebut tidak membuat eksekusi program menjadi gagal. 50 | 51 | Sampai sini bisa ditarik kesimpulan bahwa variabel global bisa diakses dari mana saja, sedangkan variabel local bisa diakses di dalam block dimana ia dideklarasikan. Pengaksesan variabel local diluar block-nya memiliki efek samping berikut: 52 | 53 | - Jika variabel local dideklarasikan di dalam block fungsi/lambda/closure, maka pengaksesannya dari luar block menghasilkan error. 54 | - Jika variabel local dideklarasikan di block seleksi kondisi atau lainnya, maka pengaksesaannya dari luar block diperbolehkan dan tidak membuat eksekusi program menjadi error. Namun warning atau error di level linter muncul. 55 | 56 | ## A.29.2. Local dan global variable dengan nama sama 57 | 58 | Katakanlah ada variabel global dan variabel local yang namanya sama persis, di situasi seperti ini maka nilai variabel local pada block-nya adalah sesuai dengan saat deklarasinya dalam block. Di luar block, variabel tersebut nilainya kembali berisi nilai variabel global. 59 | 60 | Agar lebih jelas coba praktekan kode berikut: 61 | 62 | ```python 63 | name = "Cleaver Bmurglbrm" 64 | 65 | def greet(): 66 | name = "Keymaster Urmgrgl" 67 | print("hello", name) 68 | 69 | greet() 70 | print("greetings", name) 71 | 72 | # output ↓ 73 | # 74 | # hello Keymaster Urmgrgl 75 | # greetings Cleaver Bmurglbrm 76 | ``` 77 | 78 | Bisa dilihat dari output bahwa variabel `name` nilainya adalah `Keymaster Urmgrgl`, sesuai dengan isi variabel saat deklarasi di block fungsi `greet()`. Namun di luar block fungsi, nilainya kembali menjadi `Cleaver Bmurglbrm`. 79 | 80 | Dari sini bisa diambil kesimpulan bahwa di luar block, perubahan nilai variabel local tidak berefek ke variabel global, meskipun namanya sama persis. 81 | 82 | ## A.29.3. Keyword `global` 83 | 84 | Untuk mengubah nilai suatu variabel global dari block, maka perlu adanya penggunaan keyword `global`. Keyword ini menandai variabel dalam block bahwa reference yang digunakan adalah variabel global. Efeknya, perubahan nilai pada variabel juga berpengaruh ke variabel global. 85 | 86 | Contoh penerapan: 87 | 88 | ```python 89 | name = "Cleaver Bmurglbrm" 90 | 91 | def greet(): 92 | global name 93 | name = "Keymaster Urmgrgl" 94 | print("hello", name) 95 | 96 | greet() 97 | print("greetings", name) 98 | 99 | # output ↓ 100 | # 101 | # hello Keymaster Urmgrgl 102 | # greetings Keymaster Urmgrgl 103 | ``` 104 | 105 | Cara penggunaan keyword `global` adalah dengan cukup menuliskannya di dalam block kemudian diikuti nama variabel. Dari output terlihat bahwa di luar block fungsi `greet()` nilai variabel `name` berubah. 106 | 107 | ## A.29.4. Fungsi `globals()` 108 | 109 | Fungsi `globals()` mengembalikan informasi semua variabel global yang bisa diakses dari tempat dimana fungsi dipanggil. Nilai balik berbentuk dictionary dengan `key` adalah nama variabel dan `value` adalah nilai variabel. 110 | 111 | Contoh penerapannya bisa dilihat pada kode berikut. Ada variabel bernama `my_var` yang nilainya diakses via nilai balik pemanggilan fungsi `globals()` 112 | 113 | ```python 114 | my_var = 12 115 | 116 | def task_one(): 117 | all_global_vars = globals() 118 | print(all_global_vars['my_var']) 119 | 120 | task_one() 121 | # output ➜ 12 122 | ``` 123 | 124 | ## A.29.5. Fungsi `locals()` 125 | 126 | Fungsi `locals()` mengembalikan informasi variabel yang dideklarasikan di block dimana fungsi tersebut dipanggil dengan nilai balik berbentuk dictionary. 127 | 128 | Pada contoh berikut, variabel `my_var` dideklarasikan di luar block fungsi `task_two()`, sedangkan `another_var` didalamnya. 129 | 130 | Di dalam `task_two()`, variabel `another_var` bisa diakses via nilai balik fungsi `locals()` karena masih satu block. Tidak seperti `my_var`, pengaksesannya via nilai balik fungsi `locals()` akan menghasilkan error karena variabel tersebut tidak dikenali. 131 | 132 | ```python 133 | my_var = 12 134 | 135 | def task_two(): 136 | another_var = "Hello Python" 137 | 138 | all_locals_vars = locals() 139 | print(all_locals_vars['another_var']) 140 | 141 | try: 142 | print(all_locals_vars['my_var']) 143 | except Exception as err: 144 | print(f'error {err}') 145 | 146 | task_two() 147 | # output ↓ 148 | # 149 | # Hello Python 150 | # error 'my_var' 151 | ``` 152 | 153 | Di contoh, ditambahkan block `try except` untuk menangkap error yang muncul saat statement `all_locals_vars['my_var']` dieksekusi. 154 | 155 | --- 156 | 157 |
158 | 159 | ## Catatan chapter 📑 160 | 161 | ### ◉ Source code praktik 162 | 163 |
164 |     
165 |         github.com/novalagung/dasarpemrogramanpython-example/../local-global-var
166 |     
167 | 
168 | 169 | ### ◉ TBA 170 | 171 | - Variabel global pada module 172 | 173 | ### ◉ Referensi 174 | 175 | - https://docs.python.org/3/faq/programming.html 176 | - https://docs.python.org/3/library/functions.html#locals 177 | - https://docs.python.org/3/library/functions.html#globals 178 | 179 |
180 | -------------------------------------------------------------------------------- /docs/basic/tipe-data.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 6 3 | title: A.6. Python Tipe Data 4 | sidebar_label: A.6. Tipe Data 5 | # description: 6 | keywords: [tipe data python] 7 | faqs: 8 | - question: Tipe data di Python 9 | answer: Python mengenal cukup banyak tipe data, mulai dari yang built-in maupun custom type. Contohnya int, float, complex, str, bool, list, tuple, set, dict 10 | --- 11 | 12 | Python mengenal cukup banyak tipe data, mulai dari yang *built-in* (atau bawaan) maupun custom type. Pada chapter ini kita akan mempelajari *high-level overview* tipe-tipe tersebut. 13 | 14 | ## A.6.1. Tipe data numerik 15 | 16 | Ada setidaknya 3 tipe data numerik di Python, yaitu: 17 | 18 | | Tipe data | Keterangan | Contoh | 19 | | :-: | :- | :- | 20 | | `int` | menampung bilangan bulat atau *integer* | ` number_1 = 10000024 ` | 21 | | `float` | menampung bilangan desimal atau *floating point* | ` number_2 = 3.14 ` | 22 | | `complex` | menampung nilai berisi kombinasi bilangan real dan imajiner | ` number_3 = 120+3j ` | 23 | 24 | > Penjelasan detail mengenai string ada pada chapter [Number](/basic/number-bilangan) 25 | 26 | ## A.6.2. Tipe data string / `str` 27 | 28 | Tipe string direpresentasikan oleh `str`, pembuatannya bisa menggunakan literal string yang ditandai dengan tanda awalan dan akhiran tanda `"` atau `'`. 29 | 30 | - Menggunakan tanda petik dua (`"`) 31 | 32 | ```python 33 | # string sebaris 34 | string_1 = "hello python" 35 | 36 | # string multi-baris 37 | string_2 = """Selamat 38 | Belajar 39 | Python""" 40 | ``` 41 | 42 | - Menggunakan tanda petik satu (`'`) 43 | 44 | ```python 45 | # string sebaris 46 | string_3 = 'for the horde!' 47 | 48 | # string multi-baris 49 | string_4 = ''' 50 | Sesuk 51 | Preiiii 52 | ''' 53 | ``` 54 | 55 | Jika ada baris baru (atau *newline*) di bagian awal penulisan `'''` atau `"""` maka baris baru tersebut merupakan bagian dari string. Jika ingin meng-*exclude*-nya bisa menggunakan `"""\` atau `'''\`. Contoh: 56 | 57 | ```python 58 | string_5 = '''\ 59 | Sesuk 60 | Preiiii 61 | ''' 62 | ``` 63 | 64 | > Penjelasan detail mengenai string ada pada chapter [String](/basic/string) 65 | 66 | ## A.6.3. Tipe data `bool` 67 | 68 | Literal untuk tipe data boolean di Python adalah `True` untuk nilai benar, dan `False` untuk nilai salah. 69 | 70 | ```python 71 | bool_1 = True 72 | bool_2 = False 73 | ``` 74 | 75 | ## A.6.4. Tipe data `None` 76 | 77 | Tipe data `None` merepresentasikan nilai kosong (seperti nilai `null` atau `nil` di bahasa lain). Pengecekan nilai kosong digunakan 78 | 79 | ```python 80 | data = "hello" 81 | print(data) 82 | # output ➜ hello 83 | 84 | data = None 85 | print(data) 86 | # output ➜ data 87 | 88 | data = "python" 89 | print(data) 90 | # output ➜ python 91 | ``` 92 | 93 | > Penjelasan lebih detail mengenai `None` ada pada chapter [None](/basic/none) 94 | 95 | ## A.6.5. Tipe data list 96 | 97 | List adalah tipe data di Python untuk menampung nilai kolektif yang disimpan secara urut, dengan isi bisa berupa banyak varian tipe data (tidak harus sejenis). Cara penerapan list adalah dengan menuliskan nilai kolektif dengan pembatas `,` dan diapit tanda `[` dan `]`. 98 | 99 | ```python 100 | # list with int as element's data type 101 | list_1 = [2, 4, 8, 16] 102 | 103 | # list with str as element's data type 104 | list_2 = ["grayson", "jason", "tim", "damian"] 105 | 106 | # list with various data type in the element 107 | list_3 = [24, False, "Hello Python"] 108 | ``` 109 | 110 | Pengaksesan element list menggunakan notasi `list[index_number]`. Contoh: 111 | 112 | ```python 113 | list_1 = [2, 4, 8, 16] 114 | print(list_1[2]) 115 | # output ➜ 8 116 | ``` 117 | 118 | > Penjelasan detail mengenai list ada pada chapter [List](/basic/list) 119 | 120 | ## A.6.6. Tipe data tuple 121 | 122 | Tuple adalah tipe data kolektif yang mirip dengan list, dengan pembeda adalah: 123 | 124 | - Nilai pada data list adalah bisa diubah (*mutable*), sedangkan nilai data `tuple` tidak bisa diubah (*immutable*). 125 | - List menggunakan tanda `[` dan `]` untuk penulisan literal, sedangkan pada tuple yang digunakan adalah tanda `(` dan `)`. 126 | 127 | ```python 128 | # tuple with int as element's data type 129 | tuple_1 = (2, 3, 4) 130 | 131 | # tuple with str as element's data type 132 | tuple_2 = ("numenor", "valinor") 133 | 134 | # tuple with various data type in the element 135 | tuple_3 = (24, False, "Hello Python") 136 | ``` 137 | 138 | Pengaksesan element tuple menggunakan notasi `tuple[index_number]`. Contoh: 139 | 140 | ```python 141 | tuple_1 = (2, 3, 4) 142 | print(tuple_1[2]) 143 | # output ➜ 4 144 | ``` 145 | 146 | > Penjelasan detail mengenai tuple ada pada chapter [Tuple](/basic/tuple) 147 | 148 | ## A.6.7. Tipe data dictionary 149 | 150 | Tipe data `dict` atau dictionary berguna untuk menyimpan data kolektif terstruktur berbentuk *key value*. Contoh penerapan: 151 | 152 | ```python 153 | profile_1 = { 154 | "name": "Noval", 155 | "is_male": False, 156 | "age": 16, 157 | "hobbies": ["gaming", "learning"] 158 | } 159 | ``` 160 | 161 | Pengaksesan property dictionary menggunakan notasi `dict[property_name]`. Contoh: 162 | 163 | ```python 164 | print("name: %s" % (profile_1["name"])) 165 | # output ➜ name: Noval 166 | 167 | print("hobbies: %s" % (profile_1["hobbies"])) 168 | # output ➜ name: ["gaming", "learning"] 169 | ``` 170 | 171 | Penulisan data dictionary diperbolehkan secara horizontal, contohnya seperti berikut: 172 | 173 | ```python 174 | profile_1 = { "name": "Noval", "hobbies": ["gaming", "learning"] } 175 | ``` 176 | 177 | > Penjelasan detail mengenai dictionary ada pada chapter [Dictionary](/basic/dictionary) 178 | 179 | ## A.6.8. Tipe data set 180 | 181 | Tipe data set adalah cara lain untuk menyimpan data kolektif. Tipe data ini memiliki beberapa kelemahan: 182 | 183 | - Tidak bisa menyimpan informasi urutan data 184 | - Elemen data yang sudah dideklarasikan tidak bisa diubah nilainya (tapi bisa dihapus) 185 | - Tidak bisa diakses menggunakan index (tetapi bisa menggunakan perulangan) 186 | 187 | Contoh penerapan set: 188 | 189 | ```python 190 | set_1 = {"pineapple", "spaghetti"} 191 | print(set_1) 192 | # output ➜ {"pineapple", "spaghetti"} 193 | ``` 194 | 195 | > Penjelasan detail mengenai set ada pada chapter [Set](/basic/set) 196 | 197 | ## A.6.9. Tipe data lainnya 198 | 199 | Selain tipe-tipe di atas ada juga beberapa tipe data lainnya, seperti frozenset, bytes, memoryview, range; yang kesemuanya akan dibahas satu per satu di chapter terpisah. 200 | 201 | > - Penjelasan detail mengenai frozenset ada pada chapter [Set ➜ frozenset](/basic/set#a157-frozenset) 202 | > - Penjelasan detail mengenai range ada pada chapter [Perulangan ➜ for & range](/basic/for-range#a92-penerapan-fungsi-range) 203 | 204 | --- 205 | 206 |
207 | 208 | ## Catatan chapter 📑 209 | 210 | ### ◉ Source code praktik 211 | 212 |
213 |     
214 |         github.com/novalagung/dasarpemrogramanpython-example/../tipe-data
215 |     
216 | 
217 | 218 | ### ◉ Chapter relevan lainnya 219 | 220 | - [String](/basic/string) 221 | - [List](/basic/list) 222 | - [Tuple](/basic/tuple) 223 | - [Set](/basic/set) 224 | - [Dictionary](/basic/dictionary) 225 | 226 | ### ◉ Referensi 227 | 228 | - https://docs.python.org/3/tutorial/introduction.html 229 | - https://docs.python.org/3/library/stdtypes.html#typesseq 230 | 231 |
232 | -------------------------------------------------------------------------------- /docs/basic/slice.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 20 3 | title: A.20. Python Slice (Data Sequence Slicing) 4 | sidebar_label: A.20. Slice 5 | --- 6 | 7 | Pada chapter ini kita akan belajar tentang penerapan teknik slice pada data sequence. 8 | 9 | ## A.20.1. Pengenalan slice 10 | 11 | Teknik slice atau slicing digunakan untuk mengakses sekumpulan element/item dari data sequence sesuai dengan index yang diinginkan. Data sequence sendiri adalah klasifikasi tipe data yang berisi kumpulan data terurut atau sekuensial. Yang termasuk dalam tipe data sequence adalah [list](/basic/list), [range](/basic/for-range#a92-penerapan-fungsi-range), [tuple](/basic/tuple), dan [string](/basic/string). 12 | 13 | Operasi slice mengembalikan data bertipe sama seperti data aslinya, sedangkan isi sesuai dengan index yang ditentukan. 14 | 15 | Salah satu penerapan slice adalah dengan memanfaatkan notasi `data[start:end]` atau `data[start:end:step]`. 16 | 17 | - `start` adalah index awal slicing. Misalkan index `start` adalah `2` maka slicing dimulai dari element index ke-2. 18 | - `end` adalah index akhir slicing. Misalkan index `end` adalah `5` maka slicing berakhir **sebelum** element index ke-5 (yang berarti element ke-4). 19 | - `step` by default nilainya `1`, kegunaannya untuk menentukan apakah element yang dikembalikan adalah setiap `step` index. 20 | 21 | Lanjut praktek. Pada contoh berikut disiapkan variabel `data_str` berisi string `hello world` yang kemudian akan di-slice datanya. 22 | 23 | ```python 24 | data_str = "hello world" 25 | print(data_str) 26 | # output ➜ hello world 27 | ``` 28 | 29 | Variabel `data_str` visualisasinya dalam bentuk *sequence* kurang lebih seperti ini. Lebar element data adalah `11` dengan index awal `0` dan index akhir `10`. 30 | 31 | ![Slicing python](img/slice-1.png) 32 | 33 | Ok, sekarang kita coba slice `data_str`: 34 | 35 | - Slicing element index ke-0 hingga ke-2, maka notasinya adalah `data_str[0:3]`. Perlu diketahui bahwa `end` diisi dengan nilai `index-1`, jadi jika ingin mengambil element hingga index ke-2 maka nilai `end` adalah `3`. 36 | 37 | ```python 38 | data_str = "hello world" 39 | 40 | slice1 = data_str[0:3] 41 | print(slice1) 42 | # output ➜ hel 43 | ``` 44 | 45 | ![Slicing python](img/slice-2.png) 46 | 47 | - Slicing element index ke-2 hingga ke-7, maka notasinya adalah `data_str[2:8]`. 48 | 49 | ```python 50 | slice2 = data_str[2:8] 51 | print(slice2) 52 | # output ➜ llo wo 53 | ``` 54 | 55 | ![Slicing python](img/slice-3.png) 56 | 57 | - Slicing element hingga index ke-4, maka notasinya adalah `data_str[:5]`. Nilai `start` jika tidak diisi maka default-nya adalah `0`. Notasi tersebut adalah ekuivalen dengan `data_str[0:5]`. 58 | 59 | ```python 60 | slice3 = data_str[:5] 61 | print(slice3) 62 | # output ➜ hello 63 | ``` 64 | 65 | ![Slicing python](img/slice-4.png) 66 | 67 | - Slicing element dimulai index ke-4, maka notasinya adalah `data_str[4:]`. Nilai `end` jika tidak diisi maka default-nya adalah nilai jumlah element data (ekuivalen dengan notasi `data_str[4:len(data_str)]`). 68 | 69 | ```python 70 | slice4 = data_str[4:] 71 | print(slice4) 72 | # output ➜ o world 73 | ``` 74 | 75 | ![Slicing python](img/slice-5.png) 76 | 77 | - Slicing element dimulai index ke-3 hingga ke-6 dengan element yang dikembalikan adalah setiap 1 element, maka notasinya adalah `data_str[3:7:1]`. 78 | 79 | ```python 80 | slice5 = data_str[3:7:1] 81 | print(slice5) 82 | # output ➜ lo w 83 | ``` 84 | 85 | ![Slicing python](img/slice-6.png) 86 | 87 | - Slicing element dimulai index ke-2 hingga ke-8 dengan ketentuan element yang dikembalikan adalah setiap 2 element, notasinya: `data_str[2:9:2]`. 88 | 89 | ```python 90 | slice6 = data_str[2:9:2] 91 | print(slice6) 92 | # output ➜ lowr 93 | ``` 94 | 95 | ![Slicing python](img/slice-7.png) 96 | 97 | - Slicing seluruh element bisa dilakukan dengan notasi `data_str[:]`. Notasi tersebut adalah ekuivalen dengan `data_str[0:len(data_str)]`. 98 | 99 | ```python 100 | slice7 = data_str[:] 101 | print(slice7) 102 | # output ➜ hello world 103 | ``` 104 | 105 | ![Slicing python](img/slice-1.png) 106 | 107 | - Slicing seluruh element dengan ketentuan element yang dikembalikan adalah setiap 2 element, ditulis dengan notasi `data_str[::2]`. Notasi tersebut adalah ekuivalen dengan `data_str[0:len(data_str):2]`. 108 | 109 | ```python 110 | slice8 = data_str[::2] 111 | print(slice8) 112 | # output ➜ hlowrd 113 | ``` 114 | 115 | ![Slicing python](img/slice-8.png) 116 | 117 | ### ◉ Tentang slicing seluruh element 118 | 119 | Slicing seluruh element bisa dilakukan dengan notasi `data[0:len(data)]` atau `data[0:len(data):1]`. Sebagai contoh, 3 statement printing tuple berikut memunculkan output yang sama meskipun data tuple yang ditampilkan adalah dari variabel yang berbeda. 120 | 121 | ```python 122 | data_tuple = (1, 3, 5, 7, 9, 11, 13, 14) 123 | print(data_tuple) 124 | # output ➜ (1, 3, 5, 7, 9, 11, 13, 14) 125 | 126 | tuple1 = data_tuple[0:len(data_tuple)] 127 | print(tuple1) 128 | # output ➜ (1, 3, 5, 7, 9, 11, 13, 14) 129 | 130 | tuple2 = data_tuple[0:len(data_tuple):1] 131 | print(tuple2) 132 | # output ➜ (1, 3, 5, 7, 9, 11, 13, 14) 133 | ``` 134 | 135 | Ok, lalu kenapa harus menggunakan teknik ini? padahal operasi assignment data tuple ke variabel baru jauh lebih mudah, misalnya: 136 | 137 | ```python 138 | tuple3 = data_tuple 139 | print(tuple3) 140 | # output ➜ (1, 3, 5, 7, 9, 11, 13, 14) 141 | ``` 142 | 143 | Statement assignment `tuple3` di atas isinya adalah sama dengan data hasil operasi slicing `tuple1` dan `tuple2`, namun *reference*-nya adalah berbeda. 144 | 145 | > Pembahasan detail mengenai *reference* ada di chapter [Object ID & Reference](/basic/object-id-reference) 146 | 147 | ## A.20.2. Fungsi `slice()` 148 | 149 | Notasi penulisan slice bisa disimpan pada suatu variabel dengan memanfaatkan fungsi `slice()`. Nilai `start`, `end`, dan `step` dijadikan argument pemanggilan fungsi tersebut dengan notasi `slice(start, end)` atau `slice(start, end, step)`. 150 | 151 | Pada contoh berikut, perhatikan bagaimana perbedaan slicing pada `list1`, `list2`, dan `list3`: 152 | 153 | ```python 154 | data_list = [2, 4, 6, 7, 9, 11, 13] 155 | print(data_list) 156 | # output ➜ [2, 4, 6, 7, 9, 11, 13] 157 | 158 | list1 = data_list[2:6:1] 159 | print(list1) 160 | # output ➜ [6, 7, 9, 11] 161 | 162 | list2 = data_list[slice(2, 6, 1)] 163 | print(list2) 164 | # output ➜ [6, 7, 9, 11] 165 | 166 | sl = slice(2, 6) 167 | list3 = data_list[sl] 168 | print(list3) 169 | # output ➜ [6, 7, 9, 11] 170 | ``` 171 | 172 | --- 173 | 174 |
175 | 176 | ## Catatan chapter 📑 177 | 178 | ### ◉ Source code praktik 179 | 180 |
181 |     
182 |         github.com/novalagung/dasarpemrogramanpython-example/../slice
183 |     
184 | 
185 | 186 | ### ◉ Chapter relevan lainnya 187 | 188 | - [List](/basic/list) 189 | - [Tuple](/basic/tuple) 190 | - [String](/basic/string) 191 | - [Object ID & Reference](/basic/object-id-reference) 192 | 193 | ### ◉ TBA 194 | 195 | - Negative index slicing 196 | 197 | ### ◉ Referensi 198 | 199 | - https://docs.python.org/3/library/stdtypes.html#sequence-types-list-tuple-range 200 | - https://python-reference.readthedocs.io/en/latest/docs/functions/slice.html 201 | - https://stackoverflow.com/questions/509211/how-slicing-in-python-works 202 | 203 |
204 | -------------------------------------------------------------------------------- /docs/basic/iterable-iterator.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 58 3 | title: A.58. Python Iterable & Iterator 4 | sidebar_label: A.58. Iterable & Iterator 5 | --- 6 | 7 | Pada chapter ini kita akan belajar tentang konsep sekaligus penerapan iterable dan iterator di Python. 8 | 9 | ## A.58.1. Apa itu iterable? 10 | 11 | **Iteration** atau iterasi adalah proses pengaksesan item-item suatu data kolektif sesuai urutannya satu-per-satu (menggunakan metode perulangan). Penerapan keyword `for in` pada data string, list, atau data kolektif lainnya adalah contoh dari iterasi. 12 | 13 | ```python 14 | condition = "weteng luwe" 15 | for c in condition: 16 | print(c) 17 | 18 | numbers = [10, 12, 32, 44] 19 | for n in numbers: 20 | print(n) 21 | ``` 22 | 23 | Di atas, variabel `condition` di-iterasi menggunakan keyword `for in`, variabel `c` disetiap perulangan terisi dengan huruf string satu-per-satu, bergantian, mulai huruf pertama hingga terakhir. 24 | 25 | Begitu juga dengan variabel `numbers`, nilai numerik dalam list di-iterasi dengan setiap nilai ditampung variabel `n` untuk kemudian di-print. 26 | 27 | **Iterable** adalah object yang bisa di-iterasi, contohnya seperti tuple, list, string, dan tipe data kolektif lainnya. Sederhananya, setiap object yang bisa digunakan pada keyword `for in` adalah pasti iterable. 28 | 29 | ## A.58.2. Apa itu iterator? 30 | 31 | Iterator berbeda dibanding iterable. Iterator adalah object iterable yang bisa mengingat *state* perulangannya. Jadi object tersebut tau informasi seperti perulangan sedang berada di indeks ke berapa, elemen berikutnya apa, dan info mengenai kapan perulangan berhenti. 32 | 33 | Object iterable bisa dikonversi menjadi iterator, caranya dengan membungkusnya menggunakan fungsi `iter()`. Contoh: 34 | 35 | ```python 36 | condition = "weteng luwe" 37 | for c in iter(condition): 38 | print(c) 39 | 40 | numbers = [10, 12, 32, 44] 41 | for n in iter(numbers): 42 | print(n) 43 | ``` 44 | 45 | Ok, lalu apa benefitnya? apa bedanya dengan iterable biasa? Jika mengacu ke contoh di atas, tidak akan terlihat perbedaannya dimana, karena object iterable dan iterator keduanya pasti bisa digunakan pada perulangan menggunakan keyword `for in`. 46 | 47 | Agar lebih jelas, kita berkenalan dulu dengan fungsi baru bernama `next()`. Fungsi ini berguna untuk mengembalikan data iterasi berikutnya. Contoh penerapannya silakan lihat kode berikut ini: 48 | 49 | ```python 50 | numbers = [10, 12, 32, 44] 51 | numbers_iter = iter(numbers) 52 | 53 | n = next(numbers_iter) 54 | print(n) # output ➜ 10 55 | 56 | n = next(numbers_iter) 57 | print(n) # output ➜ 12 58 | 59 | n = next(numbers_iter) 60 | print(n) # output ➜ 32 61 | 62 | n = next(numbers_iter) 63 | print(n) # output ➜ 44 64 | ``` 65 | 66 | Data list `numbers` dikonversi ke bentuk iterator menggunakan fungsi `iter()`, kemudian digunakan sebagai argument pemanggilan fungsi `next()` 4 kali, hasilnya: 67 | 68 | - Pemanggilan ke-1 mengembalikan item index ke-0, yaitu angka `10` 69 | - Pemanggilan ke-2 mengembalikan item index ke-1, yaitu angka `12` 70 | - Pemanggilan ke-3 mengembalikan item index ke-2, yaitu angka `32` 71 | - Pemanggilan ke-4 mengembalikan item index ke-3, yaitu angka `44` 72 | 73 | Dari sini terlihat bahwa object iterator benar-benar mengingat informasi state-nya. Setelah pemanggilan fungsi `next()` pertama, object `numbers_iter` tau bahwa item indeks ke-1 sudah diakses, dan pengaksesan berikutnya adalah indeks ke-2, dan seterusnya. 74 | 75 | > Penggunaan fungsi `next()` terhadap object iterator yang sudah terakses semua itemnya menghasilkan error. Manfaatkan keyword `try except` jika diperlukan. 76 | 77 | ## A.58.3. Custom iterator 78 | 79 | Selain menggunakan fungsi `iter()` pembuatan iterator juga bisa dilakukan via custom class. Caranya dengan mendesain custom class agar memiliki 2 hal berikut: 80 | 81 | 1. Custom class harus *inherit* class `Iterator` milik module `collections.abc`. 82 | 2. Di dalam class harus ada fungsi `__next__(self)` yang otomatis dipanggil setiap kali object digunakan pada fungsi `next()`. 83 | 84 | Pada contoh berikut, disiapkan class bernama `LoopReverse` dengan tugas adalah menghasilkan object iterator yang mengembalikan item data kolektif berurutan dari belakang (terbalik). 85 | 86 | ```python 87 | from collections.abc import Iterator 88 | 89 | class LoopReverse(Iterator): 90 | 91 | def __init__(self, data): 92 | self.data = data 93 | self.i = 0 94 | 95 | def __next__(self): 96 | if (self.i+1) > len(self.data): 97 | raise StopIteration 98 | else: 99 | r = self.data[len(self.data)-self.i-1] 100 | self.i = self.i + 1 101 | return r 102 | 103 | numbers = [23, 2, 1, 54] 104 | for n in LoopReverse(numbers): 105 | print(n) 106 | 107 | # output ↓ 108 | # 109 | # 54 110 | # 1 111 | # 2 112 | # 23 113 | ``` 114 | 115 | Penjelasan: 116 | - Sewaktu class dinisialisasi, instance attribute `i` disiapkan dengan nilai `0` dan attribute `data` berisi data yang disisipkan via argument (pada konteks ini yang dimaksud adalah data `[23, 2, 1, 54]`). 117 | - Di setiap perulangan, fungsi `__next__(self)` dipanggil, ketika nilai `i` masih di bawah jumlah item `data`, maka item nomor `i` dari belakang dikembalikan. Selebihnya, exception `StopIteration` di-raise untuk menandai bahwa iterasi sudah dihentikan. 118 | 119 | Coba test juga pengaksesan item iterator via fungsi `next()`. Contoh: 120 | 121 | ```python 122 | numbers = [23, 2, 1, 54] 123 | numbers_iter = LoopReverse(numbers) 124 | 125 | n = next(numbers_iter) 126 | print(n) # output ➜ 54 127 | 128 | n = next(numbers_iter) 129 | print(n) # output ➜ 1 130 | 131 | n = next(numbers_iter) 132 | print(n) # output ➜ 2 133 | 134 | n = next(numbers_iter) 135 | print(n) # output ➜ 23 136 | ``` 137 | 138 | Selain menggunakan class `Iterator` sebagai superclass, iterator custom class juga bisa dibuat dengan cukup menambahkan fungsi `__iter__(self)` yang mengembalikan data `self` tanpa perlu meng-inherit class `Iterator`. Contoh: 139 | 140 | ```python 141 | class LoopReverse: 142 | 143 | def __init__(self, data): 144 | self.data = data 145 | self.i = 0 146 | 147 | def __iter__(self): 148 | return self 149 | 150 | def __next__(self): 151 | if (self.i+1) > len(self.data): 152 | raise StopIteration 153 | else: 154 | r = self.data[len(self.data)-self.i-1] 155 | self.i = self.i + 1 156 | return r 157 | 158 | numbers = [23, 2, 1, 54] 159 | for n in LoopReverse(numbers): 160 | print(n) 161 | 162 | # output ↓ 163 | # 164 | # 54 165 | # 1 166 | # 2 167 | # 23 168 | ``` 169 | 170 | Method `__iter__(self)` harus mengembalikan object iterator yang dimana harus memiliki method `__next__(self)`. Pada contoh di atas, method `__next__(self)` kebetulan memang posisinya satu level dengan method `__iter__(self)`, oleh karena itu object `self` dijadikan nilai balik. 171 | 172 | --- 173 | 174 |
175 | 176 | ## Catatan chapter 📑 177 | 178 | ### ◉ Source code praktik 179 | 180 |
181 |     
182 |         github.com/novalagung/dasarpemrogramanpython-example/../iterable-iterator
183 |     
184 | 
185 | 186 | ### ◉ Chapter relevan lainnya 187 | 188 | - [Perulangan ➜ for & range](/basic/for-range) 189 | 190 | ### ◉ Referensi 191 | 192 | - https://docs.python.org/3/glossary.html#term-iterator 193 | - https://docs.python.org/3/library/functions.html#iter 194 | - https://docs.python.org/3/library/functions.html#next 195 | 196 |
197 | -------------------------------------------------------------------------------- /docs/basic/static-method.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 39 3 | title: A.39. Python OOP ➜ Static Method 4 | sidebar_label: A.39. OOP ➜ Static Method 5 | --- 6 | 7 | Chapter ini membahas tentang static method beserta penggunaan dan perbedaannya dibanding jenis method lainnya. 8 | 9 | ## A.39.1. Pengenalan static method 10 | 11 | Telah kita pelajari bahwa suatu fungsi agar dikenali sebagai method harus dideklarasikan di dalam block `class` dan memiliki parameter implicit `self` (untuk instance method) dan `cls` (untuk class method). 12 | 13 | Selain dua method tersebut, ada lagi jenis method lain bernama static method atau method statis, yang ciri khasnya adalah memiliki decorator `@staticmethod` dan tidak memiliki parameter *implicit* `self` maupun `cls`. 14 | 15 | Static method bisa diakses via instance object maupun via class. Contoh penerapannya bisa dilihat pada kode berikut: 16 | 17 | ```python 18 | class Person: 19 | 20 | def __init__(self, name = ""): 21 | self.name = name 22 | 23 | def info(self): 24 | print(f"{self.name}") 25 | 26 | @classmethod 27 | def create(cls, name = ""): 28 | obj = cls() 29 | obj.name = name 30 | return obj 31 | 32 | @staticmethod 33 | def say_hello(): 34 | print("hello") 35 | 36 | @staticmethod 37 | def say_something(message, name = None): 38 | if name != None: 39 | print(f"{name} said: {message}") 40 | else: 41 | print(message) 42 | 43 | p1 = Person.create("Kassandra") 44 | p1.say_hello() 45 | # output ➜ hello 46 | 47 | Person.say_hello() 48 | # output ➜ hello 49 | 50 | p2 = Person("Edward Kenway") 51 | p2.say_something("hello folks! #1") 52 | # output ➜ hello folks! #1 53 | 54 | p2.say_something("hello folks! #2", p2.name) 55 | # output ➜ Edward Kenway said: hello folks! #2 56 | 57 | Person.say_something("hello folks! #3") 58 | # output ➜ hello folks! #3 59 | ``` 60 | 61 | Pada contoh di atas, ada dua buah static method dideklarasikan: 62 | 63 | - Method `say_hello()` dideklarasikan tanpa parameter 64 | - Method `say_something()` dideklarasikan dengan 2 buah parameter 65 | 66 | Kedua method tersebut diakses untuk memunculkan 5 buah output berbeda via instance object maupun via class `Person`: 67 | 68 | - Method `say_hello()` dipanggil 2x via instance object `edward` dan via class `Person` 69 | - Method `say_something()` juga sama, diakses via instance object 2x dan diakses via class 1x 70 | 71 | ## A.39.2. Fungsi `staticmethod()` 72 | 73 | Python menyediakan fungsi bernama `staticmethod()` yang kegunaannya adalah untuk mengkonversi fungsi biasa (yang dideklarasikan di luar class) menjadi static method milik suatu class. 74 | 75 | Sebagai contoh, kode praktek yang telah ditulis kita *refator* menjadi seperti ini. Fungsi `say_hello()` dan `say_something()` dideklarasikan sebagai fungsi biasa. Kemudian dijadikan sebagai class method milik class `Person` via peneparan `staticmethod()`. 76 | 77 | ```python 78 | def say_hello(): 79 | print("hello") 80 | 81 | def say_something(message, name = None): 82 | if name != None: 83 | print(f"{name} said: {message}") 84 | else: 85 | print(message) 86 | 87 | class Person: 88 | 89 | def __init__(self, name = ""): 90 | self.name = name 91 | 92 | say_hello = staticmethod(say_hello) 93 | say_something = staticmethod(say_something) 94 | 95 | p3 = Person("Arno Victor Dorian") 96 | p3.say_hello() 97 | # output ➜ hello 98 | 99 | Person.say_hello() 100 | # output ➜ hello 101 | 102 | p4 = Person("Adéwalé") 103 | p4.say_something("hello folks! #1") 104 | # output ➜ hello folks! #1 105 | 106 | p4.say_something("hello folks! #2", p4.name) 107 | # output ➜ Adéwalé said: hello folks! #2 108 | 109 | Person.say_something("hello folks! #3") 110 | # output ➜ hello folks! #3 111 | ``` 112 | 113 | Cara penerapan fungsi `staticmethod()` adalah dengan cukup memanggilnya untuk membungkus fungsi biasa, lalu nilai baliknya ditampung sebagai attribute class. 114 | 115 | ```python 116 | class Person: 117 | 118 | def __init__(self, name = ""): 119 | self.name = name 120 | 121 | say_hello = staticmethod(say_hello) 122 | say_something = staticmethod(say_something) 123 | ``` 124 | 125 | Attribute `say_hello` dan `say_something` keduanya menjadi static method. 126 | 127 | Nama class attribute penampung pemanggilan fungsi `staticmethod()` bisa nama apapun, tidak harus sama dengan nama fungsi aslinya. Contohnya bisa dilihat pada kode berikut, fungsi `say_something()` dijadikan sebagai class method bernama `greet()` milik class `Person`. 128 | 129 | ```python 130 | def say_something(message, name = None): 131 | if name != None: 132 | print(f"{name} said: {message}") 133 | else: 134 | print(message) 135 | 136 | class Person: 137 | 138 | def __init__(self, name = ""): 139 | self.name = name 140 | 141 | greet = staticmethod(say_something) 142 | 143 | p5 = Person("Ezio Auditore da Firenze") 144 | p5.greet("hello", p5.name) 145 | # output ➜ Ezio Auditore da Firenze said: hello 146 | 147 | Person.greet("hello") 148 | # output ➜ hello 149 | 150 | say_something("nice to meet you") 151 | # output ➜ nice to meet you 152 | ``` 153 | 154 | Fungsi `say_something()` sendiri tetap bisa digunakan secara normal meskipun telah dijadikan sebagai static method milik class `Person`. 155 | 156 | ## A.39.3. Summary 157 | 158 | Perbedaan antara constructor, instance method, class method, dan static method bisa dilihat di bawah ini: 159 | 160 | ### ◉ Constructor 161 | 162 | - Fungsi dideklarasikan di dalam block `class` 163 | - Deklarasinya menggunakan nama fungsi `__init__()` 164 | - Parameter pertama harus `self`, berisi instance object 165 | - Pemanggilan constructor mengembalikan instance object 166 | - Pengaksesannya via pemanggilan nama class, contoh: `Person()` 167 | 168 | ### ◉ Instance method 169 | 170 | - Fungsi dideklarasikan di dalam block `class` 171 | - Parameter pertama harus `self`, berisi instance object 172 | - Pengaksesan instance method: 173 | - Via instance object, contoh: `p2.info()` 174 | - Via class dengan menyisipkan instance object sebagai argument pemanggilan. contoh: `Person.info(p2)` 175 | 176 | ### ◉ Class method 177 | 178 | - Fungsi dideklarasikan di dalam block `class` 179 | - Fungsi memiliki decorator `@classmethod` 180 | - Parameter pertama harus `cls`, berisi tipe data class 181 | - Pengaksesan class method: 182 | - Via class, contoh: `Person.create()` 183 | - Via instance object, contoh: `p2.create()` 184 | 185 | ### ◉ Static method 186 | 187 | - Fungsi dideklarasikan di dalam block `class` 188 | - Fungsi memiliki decorator `@staticmethod` 189 | - **Tidak** memiliki implicit parameter `self` maupun `cls` 190 | - Pengaksesan static method: 191 | - Via class, contoh: `Person.say_hello()` 192 | - Via instance object, contoh: `p1.say_hello()` 193 | 194 | --- 195 | 196 |
197 | 198 | ## Catatan chapter 📑 199 | 200 | ### ◉ Source code praktik 201 | 202 |
203 |     
204 |         github.com/novalagung/dasarpemrogramanpython-example/../static-method
205 |     
206 | 
207 | 208 | ### ◉ Chapter relevan lainnya 209 | 210 | - [OOP ➜ Class & Object](/basic/class-object) 211 | - [OOP ➜ Instance Method](/basic/instance-method) 212 | - [OOP ➜ Constructor](/basic/class-constructor) 213 | - [OOP ➜ Class Method](/basic/class-method) 214 | - [Function ➜ Decorator](/basic/decorator) 215 | - [OOP ➜ Abstract Method](/basic/abstract-method) 216 | 217 | ### ◉ Referensi 218 | 219 | - https://docs.python.org/3/tutorial/classes.html 220 | 221 |
222 | -------------------------------------------------------------------------------- /docs/basic/dataclass.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 43 3 | title: A.43. Python OOP ➜ DataClass 4 | sidebar_label: A.43. OOP ➜ DataClass 5 | --- 6 | 7 | Data class adalah class yang didesain khusus untuk tujuan penyimpanan data. 8 | 9 | Python menyediakan module bernama `dataclasses` dengan isi beberapa API untuk mempermudah pembuatan data class. Pada chapter ini kita akan mempelajarinya. 10 | 11 | ## A.43.1. Pengenalan Data Class 12 | 13 | Di bawah ini dicontohkan class bernama `Planet` disiapkan untuk pembuatan data berisi informasi planet. Class ini memiliki 3 buah instance attribute, yaitu `name`, `diameter`, dan `natural_sattelites`. Deklarasi attribute ditulis dalam fungsi `__init__()`. 14 | 15 | ```python 16 | class Planet: 17 | def __init__(self, name, diameter, natural_sattelites): 18 | self.name = name 19 | self.diameter = diameter 20 | self.natural_sattelites = natural_sattelites 21 | 22 | planets = [ 23 | Planet("Mercury", 4879, []), 24 | Planet(name="Venus", diameter=12104, natural_sattelites=[]), 25 | Planet(diameter=12742, name="Earth", natural_sattelites=["Moon"]), 26 | ] 27 | 28 | for p in planets: 29 | print(f"{p.name} | {p.diameter} km | {len(p.natural_sattelites)} moons") 30 | 31 | # output ↓ 32 | # 33 | # Mercury | 4879 km | 0 moons 34 | # Venus | 12104 km | 0 moons 35 | # Earth | 12742 km | 1 moons 36 | ``` 37 | 38 | Contoh di atas menurut penulis cukup jelas dan mudah dipahami karena jika pembaca mengikuti pembahasan secara urut, maka sudah familiar dengan class, attributes, dan object. 39 | 40 | Tidak semua class dibuat untuk keperluan operasi terhadap data, ada yang didesain sebagai utilitas, wrapper, atau lainnya. Khusus untuk class yang memang disiapkan untuk pengelolahan data, penulisannya akan lebih praktis menggunakan decorator `@dataclass` milik module `dataclasses`. 41 | 42 | Class `Planet` yang telah dibuat di atas, deklarasinya diubah menggunakan dataclass, hasilnya kurang lebih seperti ini: 43 | 44 | ```python 45 | from dataclasses import dataclass 46 | 47 | @dataclass 48 | class Planet: 49 | name: str 50 | diameter: float 51 | natural_sattelites: list[str] 52 | 53 | planets = [ 54 | Planet("Mercury", 4879, []), 55 | Planet("Venus", 12104, []), 56 | Planet("Earth", 12742, ["Moon"]), 57 | ] 58 | 59 | for p in planets: 60 | print(f"{p.name} | {p.diameter} km | {len(p.natural_sattelites)} moons") 61 | 62 | # output ↓ 63 | # 64 | # Mercury | 4879 km | 0 moons 65 | # Venus | 12104 km | 0 moons 66 | # Earth | 12742 km | 1 moons 67 | ``` 68 | 69 | Cukup tambahkan decorator `@dataclass` saat deklarasi class, lalu tulis attribute seperti penulisan class attribute, tak lupa tentukan tipe data tiap-tiap attribute. Dengan itu maka class otomatis menjadi data class, attribute-nya menjadi instance attribute dan bisa langsung diisi nilainya (via argument constructor) saat pembuatan object. 70 | 71 | - Penulisan data class 72 | 73 | ```python 74 | from dataclasses import dataclass 75 | 76 | @dataclass 77 | class Planet: 78 | name: str 79 | diameter: float 80 | natural_sattelites: list[str] 81 | ``` 82 | 83 | - Penulisan class biasa 84 | 85 | ```python 86 | class Planet: 87 | def __init__(self, name, diameter, natural_sattelites): 88 | self.name = name 89 | self.diameter = diameter 90 | self.natural_sattelites = natural_sattelites 91 | ``` 92 | 93 | ## A.43.2. Attribute mutability 94 | 95 | Selayaknya seperti class biasa, instance attribute dataclass adalah *mutable* atau bisa diubah nilainya. Contoh penerapan: 96 | 97 | ```python 98 | mars = Planet("Mars", 4, ["Phobos", "Deimos"]) 99 | mars.name = "Red Planet" 100 | mars.diameter = 6779 101 | 102 | print(f"{mars.name} | {mars.diameter} km | {len(mars.natural_sattelites)} moons") 103 | # output ➜ Red Planet | 6779 km | 2 moons 104 | ``` 105 | 106 | ## A.43.3. Instance method 107 | 108 | Data class bisa memiliki instance method dengan penulisan deklarasi sama persis seperti deklarasi method pada umumnya. Contohnya bisa dilihat di bawah ini, dimana ada data class bernama `Country` berisi 3 buah instance attribute dan satu buah instance method bernama `info()`. 109 | 110 | ```python 111 | @dataclass 112 | class Country: 113 | name: str 114 | seasons: list 115 | number_of_populations: float 116 | 117 | def info(self) -> str: 118 | return f"{self.name} | {len(self.seasons)} seasons | {self.number_of_populations} million population" 119 | 120 | countries = [ 121 | Country("Indonesia", ["Rainy", "Dry"], 275.5), 122 | Country("Palestine", ["Winter", "Summer", "Autumn", "Spring"], 5.044), 123 | Country("Mongolia", ["Winter", "Summer", "Autumn", "Spring"], 3.398), 124 | ] 125 | 126 | for c in countries: 127 | print(c.info()) 128 | 129 | # output ↓ 130 | # 131 | # Indonesia | 2 seasons | 275.5 million population 132 | # Palestine | 4 seasons | 5.044 million population 133 | # Mongolia | 4 seasons | 3.398 million population 134 | ``` 135 | 136 | ## A.43.4. Attribute default value 137 | 138 | Attribute data class bisa ditentukan nilai defaultnya menggunakan operator assignment `=` (penulisannya seperti deklarasi variabel). Dengan memberikan nilai default pada attribute, menjadikan parameter konstruktor menjadi opsional. Contoh: 139 | 140 | ```python 141 | @dataclass 142 | class Country: 143 | name = "Indonesia" 144 | seasons = ["Rainy", "Dry"] 145 | number_of_populations = 275.5 146 | 147 | def info(self) -> str: 148 | return f"{self.name} | {len(self.seasons)} seasons | {self.number_of_populations} million population" 149 | 150 | c = Country() 151 | print(c.info()) 152 | # output ➜ Indonesia | 2 seasons | 275.5 million population 153 | ``` 154 | 155 | ## A.43.5. Frozen attribute 156 | 157 | Frozen data class adalah data class yang *immutable*, artinya setelah dideklarasikan maka tidak bisa diubah nilai attribute-nya. Cara meng-enable frozen attribute adalah dengan menambahkan `frozen=True` pada decorator `@dataclass`. 158 | 159 | ```python 160 | from dataclasses import dataclass 161 | 162 | @dataclass(frozen=True) 163 | class Fruit: 164 | name: str 165 | flavor: tuple 166 | 167 | apple = Fruit("Apple", ("sweet", "tart")) 168 | apple.name = "Orange" 169 | ``` 170 | 171 | Kode di atas menghasilkan error karena semua attribute class `Fruit` immutable. 172 | 173 | ![Data class Python](img/dataclass-1.png) 174 | 175 | ## A.43.6. Inheritance 176 | 177 | Data class bisa diturunkan seperti umumnya class dengan cara penulisan masih sama. Contoh: 178 | 179 | ```python 180 | from dataclasses import dataclass 181 | 182 | @dataclass 183 | class Animal: 184 | name: str 185 | 186 | @dataclass 187 | class Bird(Animal): 188 | can_fly: bool 189 | 190 | cow = Animal(name="Cow") 191 | print(cow.name) 192 | # output ➜ Cow 193 | 194 | chicken = Bird(name="Chicken", can_fly=False) 195 | print(chicken.name, chicken.can_fly) 196 | # output ➜ Chicken False 197 | ``` 198 | 199 | --- 200 | 201 |
202 | 203 | ## Catatan chapter 📑 204 | 205 | ### ◉ Source code praktik 206 | 207 |
208 |     
209 |         github.com/novalagung/dasarpemrogramanpython-example/../dataclass
210 |     
211 | 
212 | 213 | ### ◉ Chapter relevan lainnya 214 | 215 | - [OOP ➜ Class & Object](/basic/class-object) 216 | - [OOP ➜ Instance Method](/basic/instance-method) 217 | - [OOP ➜ Constructor](/basic/class-constructor) 218 | - [OOP ➜ Instance Attribute & Class Attribute](/basic/instance-attribute-class-attribute) 219 | - [OOP ➜ Class Inheritance](/basic/class-inheritance) 220 | - [Function ➜ Decorator](/basic/decorator) 221 | 222 | ### ◉ Referensi 223 | 224 | - https://docs.python.org/3/library/dataclasses.html 225 | 226 |
227 | -------------------------------------------------------------------------------- /docs/basic/closure.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 25 3 | title: A.25. Python Closure 4 | sidebar_label: A.25. Function ➜ Closure 5 | --- 6 | 7 | Closure adalah istilah umum dalam programming untuk deklarasi fungsi yang berada di dalam fungsi (*nested function*). Pada chapter ini kita akan mempelajari cara implementasinya. 8 | 9 | ## A.25.1. Pengenalan Closure 10 | 11 | Di Python, fungsi bisa dideklarasikan di-dalam suatu fungsi. Penerapannya cukup berguna pada kasus dimana ada blok kode yang perlu di-eksekusi lebih dari satu kali tetapi eksekusinya hanya di dalam fungsi tertentu, atau eksekusinya setelah pemanggilan fungsi tertentu. 12 | 13 | Permisalan ada fungsi `inner()` yang dideklarasikan di dalam fungsi `outer()`, maka: 14 | 15 | - Fungsi `inner()` bisa diakses dari dalam fungsi `outer()` 16 | - Fungsi `inner()` juga bisa diakses dari luar fungsi `outer()` asalkan fungsi `inner()` tersebut dijadikan sebagai nilai balik fungsi `outer()` (untuk kemudian ditampung ke dalam variabel lalu dieksekusi) 17 | 18 | Program berikut berisi contoh praktis tentang fungsi `inner()` dan `outer()`. Silakan pelajari dan praktekan. 19 | 20 | ```python 21 | def outer_func(numbers = []): 22 | print(f"numbers: {numbers}") 23 | 24 | def inner_func(): 25 | print(f"max: {max(numbers)}") 26 | print(f"min: {min(numbers)}") 27 | 28 | print("call inner_func() within outer_func()") 29 | inner_func() 30 | 31 | return inner_func 32 | 33 | print("call outer_func()") 34 | f = outer_func([1, 2, 3, 4]) 35 | 36 | print("call inner_func() outside of outer_func()") 37 | f() 38 | ``` 39 | 40 | Output program: 41 | 42 | ![Python closure function](img/closure-1.png) 43 | 44 | Program di atas jika di-breakdown sesuai urutan eksekusi statement-nya kurang lebih seperti ini: 45 | 46 | - Tahap 1: eksekusi statement `print("call outer_func()")` 47 | - Tahap 2: eksekusi statement `print(f"numbers: {numbers}")` 48 | - Tahap 3: eksekusi statement `print("call inner_func() within outer_func()")` 49 | - Tahap 4: eksekusi statement `inner_func()` 50 | - Tahap 4.A. eksekusi statement `print(f"max: {max(numbers)}")` 51 | - Tahap 4.B. eksekusi statement `print(f"min: {min(numbers)}")` 52 | - Tahap 5: eksekusi statement `print("call inner_func() outside of outer_func()")` 53 | - Tahap 6: eksekusi statement `inner_func()` via `f()` dari luar fungsi `outer_func()` 54 | - Tahap 6.A. eksekusi statement `print(f"max: {max(numbers)}")` 55 | - Tahap 6.B. eksekusi statement `print(f"min: {min(numbers)}")` 56 | 57 | Jika di-*flatten* semua statement-nya maka programnya menjadi seperti ini: 58 | 59 | ```python 60 | print("call outer_func()") 61 | numbers = [1, 2, 3, 4] 62 | print(f"numbers: {numbers}") 63 | 64 | print("call inner_func() within outer_func()") 65 | print(f"max: {max(numbers)}") 66 | print(f"min: {min(numbers)}") 67 | 68 | print("call inner_func() outside of outer_func()") 69 | print(f"max: {max(numbers)}") 70 | print(f"min: {min(numbers)}") 71 | ``` 72 | 73 | ### ◉ Fungsi `min()` & `max()` 74 | 75 | Kedua fungsi ini digunakan untuk menghitung agregasi data numerik. 76 | 77 | - Fungsi `min()` untuk pencarian nilai minimum dari data list yang berisi elemen data numerik.
Contoh `min([3, 4, 1, 2, 3, 4])` menghasilkan data `1`. 78 | 79 | - Fungsi `max()` untuk pencarian nilai maksimum dari data list yang berisi elemen data numerik.
Contoh `max([3, 4, 1, 2, 3, 4])` menghasilkan data `4`. 80 | 81 | ## A.25.2. Menampung fungsi dalam variabel 82 | 83 | Pada contoh sebelumnya, fungsi `inner_func()` ditampung ke variabel bernama `f` via nilai balik pemanggilan fungsi `outer_func()`. Dari sini terlihat bahwa closure bisa disimpan ke variabel. 84 | 85 | Tidak hanya closure, fungsi biasa-pun juga bisa disimpan dalam variabel, contohnya ada pada fungsi `print_all()` berikut yang disimpan pada variabel `display` untuk kemudian di-eksekusi. 86 | 87 | ```python 88 | def print_all(message, *numbers, **others): 89 | print(f"message: {message}") 90 | print(f"numbers: {numbers}") 91 | print(f"others: {others}") 92 | 93 | display = print_all 94 | display("hello world", 1, 2, 3, 4, name="nokia 3310", discontinued=True, year_released=2000) 95 | # output ↓ 96 | # 97 | # message: hello world 98 | # numbers: (1, 2, 3, 4) 99 | # others: {'name': 'nokia 3310', 'discontinued': True, 'year_released': 2000} 100 | ``` 101 | 102 | ## A.25.3. Fungsi sebagai argument parameter 103 | 104 | Selain disimpan dalam variabel, fungsi/closure bisa juga dijadikan sebagai nilai argument suatu parameter fungsi. Metode seperti ini cukup sering digunakan terutama pada operasi data sequence atau agregasi data numerik. 105 | 106 | Contoh penerapan fungsi/closure sebagai argument pemanggilan fungsi bisa dilihat pada kode berikut ini. Silakan coba dan pelajari, penjelasannya ada dibawah kode. 107 | 108 | ```python 109 | def aggregate(message, numbers, f): 110 | res = f(numbers) 111 | print(f"{message} is {res}") 112 | 113 | def sum(numbers): 114 | total = 0 115 | for n in numbers: 116 | total += n 117 | return total 118 | 119 | def avg(numbers): 120 | total = 0 121 | for n in numbers: 122 | total += n 123 | return total / len(numbers) 124 | 125 | aggregate("total", [24, 67, 22, 98, 3, 50], sum) 126 | # output ➜ total is 264 127 | 128 | aggregate("average", [24, 67, 22, 98, 3, 50], avg) 129 | # output ➜ average is 44.0 130 | 131 | aggregate("max number", [24, 67, 22, 98, 3, 50], max) 132 | # output ➜ max number is 98 133 | 134 | aggregate("min number", [24, 67, 22, 98, 3, 50], min) 135 | # output ➜ min number is 3 136 | ``` 137 | 138 | Fungsi `aggregate()` dideklarasikan memiliki 3 buah parameter yaitu `message`, `numbers`, dan `f` dimana `f` adalah akan diisi dengan fungsi/closure. Di dalam fungsi `aggregate()`, fungsi `f` dipanggil dengan disisipkan argument yaitu `numbers` dalam pemanggilannya. 139 | 140 | Ada juga fungsi `sum()` dideklarasikan dengan tugas untuk menghitung total dari data list numerik `numbers`. Dan fungsi `avg()` untuk nilai rata-rata dari data `numbers`. 141 | 142 | Kemudian di bawahnya ada 4 buah statement pemanggilan fungsi `aggregate()`: 143 | 144 | - Pemanggilan ke-1 adalah perhitungan nilai total `numbers`. Fungsi `sum` yang telah dideklarasikan sebelumnya dijadikan sebagai argument pemanggilan fungsi `aggregate()` untuk ditampung di parameter `f`. 145 | - Pemanggilan ke-2 adalah perhitungan nilai rata-rata dimana fungsi `avg` yang telah dideklarasikan dijadikan sebagai argument pemanggilan fungsi `aggregate()`.. 146 | - Pemanggilan ke-3 adalah perhitungan nilai maksimum. Fungsi `max` yang merupakan fungsi bawaan Python digunakan sebagai argument pemanggilan fungsi `aggregate()`. 147 | - Pemanggilan ke-1 adalah perhitungan nilai minimum. Fungsi `min` yang merupakan fungsi bawaan Python digunakan sebagai argument pemanggilan fungsi `aggregate()`. 148 | 149 | Dari contoh terlihat bagaimana contoh penerapan closure sebagai nilai argument parameter fungsi. Fungsi atau closure bisa digunakan sebagai nilai argument, dengan catatan skema parameter-nya harus disesuaikan dengan kebutuhan. 150 | 151 | Di dalam fungsi `aggregate()`, closure `f` diharapkan untuk memiliki parameter yang bisa menampung data list `numbers`. Selama fungsi/closure memenuhi kriteria ini maka penggunaannya tidak menghasilkan error. 152 | 153 | --- 154 | 155 |
156 | 157 | ## Catatan chapter 📑 158 | 159 | ### ◉ Source code praktik 160 | 161 |
162 |     
163 |         github.com/novalagung/dasarpemrogramanpython-example/../args-kwargs
164 |     
165 | 
166 | 167 | ### ◉ Chapter relevan lainnya 168 | 169 | - [Function](/basic/function) 170 | - [Function ➜ Positional, Optional, Keyword Arguments](/basic/positional-optional-keyword-argument) 171 | - [Function ➜ Args & Kwargs](/basic/args-kwargs) 172 | - [Function ➜ Lambda](/basic/lambda) 173 | 174 | ### ◉ Referensi 175 | 176 | - https://docs.python.org/3/library/stdtypes.html#functions 177 | 178 |
179 | -------------------------------------------------------------------------------- /docs/basic/docstring.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 48 3 | title: A.48. Python DocString 4 | sidebar_label: A.48. DocString 5 | --- 6 | 7 | Pada chapter ini kita akan membahas tentang docstring beserta cara penerapan dan manfaatnya. 8 | 9 | ## A.48.1. Pengenalan docstring 10 | 11 | Di pembelajaran awal yaitu pada chapter [Komentar](/basic/komentar), telah disinggung bahwa salah satu cara menulis komentar adalah menggunakan karakter `"""` dengan penulisan di awal dan akhir komentar. Contoh: `""" ini komentar """`. 12 | 13 | Komentar yang ada di dalam karakter tersebut disebut docstring. DocString memiliki keistimewaan dibanding komentar biasa yang ditulis menggunakan karakter `#`. 14 | 15 | Komentar docstring otomatis menempel pada unit dimana komentar ditulis. Misalnya ditulis tepat dibawah deklarasi fungsi bernama `print_random_quote()`, maka komentarnya menembel ke fungsi tersebut. Benefitnya, informasi komentar bisa muncul setidaknya di 2 tempat: 16 | 17 | - Komentar bisa diakses menggunakan attribute `__doc__` yang menempel ke fungsi `print_random_quote()`. 18 | - Komentar dimunculkan sewaktu fungsi tersebut di-hover (dengan catatan extension Python/Pylance ter-install di editor). 19 | 20 | Perihal unit yang bisa ditempeli docstring bisa berupa fungsi, class, method, atau lainnya. 21 | 22 | ## A.48.2. Praktek penerapan docstring 23 | 24 | Mari kita praktekan agar lebih jelas. Siapkan project sederhana dengan struktur seperti ini. Isinya hanya dua file saja: 25 | 26 | - File `quote.py` berisi class `Quote` 27 | - File `main.py` berisi kode penggunaan class `Quote` 28 | 29 |
30 | 31 | ```bash title="Project structure" 32 | praktek-docstring/ 33 | │─── quote.py 34 | └─── main.py 35 | ``` 36 | 37 |
38 | 39 | Tulis kode berikut di file `quote.py`: 40 | 41 | ```python title="File quote.py" 42 | quotes = [ 43 | "never let anyone live in your head rent free", 44 | "if others can do it, then why should I?", 45 | "\n".join([ 46 | "I'm sick of following my dreams, man.", 47 | "I'm just going to ask where they're going and hook up with 'em later." 48 | ]), 49 | ] 50 | 51 | from random import randint 52 | 53 | # function `print_random_quote()`: 54 | # print one random quote, 55 | # so nothing special 56 | def print_random_quote(): 57 | 58 | i = randint(0, len(quotes)-1) 59 | print(quotes[i]) 60 | 61 | # class `Quote`: 62 | # A class Quote represent a quote. 63 | # It has the following two attributes: 64 | # - class attribute `note` 65 | # - instance method `print_quote()` 66 | class Quote: 67 | note = "A class to represent quote" 68 | 69 | # instance method `print_quote()`: 70 | # Responsible to print specific quote by index 71 | @classmethod 72 | def print_quote(cls, i): 73 | print(quotes[i]) 74 | ``` 75 | 76 | Kemudian di file `main.py`, import unit-unit dari module `quote.py` lalu gunakan. 77 | 78 | ```python title="File main.py" 79 | from quote import Quote, print_random_quote 80 | 81 | if __name__ == '__main__': 82 | print_random_quote() 83 | # output ➜ 84 | 85 | Quote.print_quote(2) 86 | # output ➜ I'm just going to ask where they're going and hook up with 'em later. 87 | ``` 88 | 89 | Sampai sini penulis rasa cukup jelas. 90 | 91 | Selanjutnya coba hover fungsi atau class yang di-import dari module `Quote.py` yang dipergunakan di `main.py`. Popup muncul tapi isinya hanya informasi deklarasi fungsi itu sendiri. Komentar yang telah ditulis tidak muncul di popup. 92 | 93 | ![Python docstring](img/docstring-1.png) 94 | 95 | Ok, sekarang kita akan modifikasi komentar pada kode yang sudah ditulis dengan mengubahnya menjadi komentar docstring. Komentar hanya dianggap docstring ketika ditulis dengan diapit karakter `"""` `"""` dan penulisannya berada tepat dibawah unit yang ingin dikomentari. 96 | 97 | ### ◉ DocString pada class dan fungsi/method 98 | 99 | Ubah isi `quote.py` menjadi seperti ini: 100 | 101 | ```python title="File quote.py" 102 | quotes = [ 103 | "never let anyone live in your head rent free", 104 | "if others can do it, then why should I?", 105 | "\n".join([ 106 | "I'm sick of following my dreams, man.", 107 | "I'm just going to ask where they're going and hook up with 'em later." 108 | ]), 109 | ] 110 | 111 | from random import randint 112 | 113 | def print_random_quote(): 114 | """ 115 | function `print_random_quote()`: 116 | print one random quote, 117 | so nothing special 118 | """ 119 | 120 | i = randint(0, len(quotes)-1) 121 | print(quotes[i]) 122 | 123 | class Quote: 124 | """ 125 | class `Quote`: 126 | A class Quote represent a quote. 127 | It has the following two attributes: 128 | - class attribute `note` 129 | - instance method `print_quote()` 130 | """ 131 | 132 | note = "A class to represent quote" 133 | 134 | @classmethod 135 | def print_quote(cls, i): 136 | """ 137 | instance method `print_quote()`: 138 | Responsible to print specific quote by index 139 | """ 140 | 141 | print(quotes[i]) 142 | ``` 143 | 144 | Sekarang coba hover lagi, lihat isi popup-nya. 145 | 146 | - Hover fungsi `print_random_quote()` 147 | 148 | ![Python docstring](img/docstring-2.png) 149 | 150 | - Hover class `Quote` 151 | 152 | ![Python docstring](img/docstring-3.png) 153 | 154 | - Hover class method `Quote.print_quote()` 155 | 156 | ![Python docstring](img/docstring-4.png) 157 | 158 | Mantab bukan? DocString ini menjadi salah satu hal yang sangat membantu dalam pengembangan. 159 | 160 | ### ◉ DocString pada attribute dan variable 161 | 162 | Untuk penerapan docstring pada attribute, caranya juga sama, yaitu dengan menuliskan komentar tepat dibawah attribute atau variabel dengan karakter `"""` `"""`. 163 | 164 | ```python title="File quote.py" 165 | # ... 166 | 167 | class Quote: 168 | """ 169 | class `Quote`: 170 | A class Quote represent a quote. 171 | It has the following two attributes: 172 | - class attribute `note` 173 | - instance method `print_quote()` 174 | """ 175 | 176 | note = "A class to represent quote" 177 | """ 178 | instance method `print_quote()`: 179 | Responsible to print specific quote by index 180 | """ 181 | 182 | @classmethod 183 | def print_quote(cls, i): 184 | """ 185 | instance method `print_quote()`: 186 | Responsible to print specific quote by index 187 | """ 188 | print(quotes[i]) 189 | ``` 190 | 191 | Coba sekarang 192 | Output ketika di-hover: 193 | 194 | ![Python docstring](img/docstring-5.png) 195 | 196 | ## A.48.3. Special name ➜ class attribute `__doc__` 197 | 198 | Informasi docstring milik fungsi, method, dan class bisa diakses secara excplit menggunakan class attribute `__doc__`. Jika mengacu ke kode yang sudah ditulis, maka pengaksesannya seperti ini: 199 | 200 | ```python 201 | from quote import Quote, print_random_quote 202 | 203 | if __name__ == '__main__': 204 | 205 | # menampilkan docstring fungsi `print_random_quote()` 206 | print(print_random_quote.__doc__) 207 | 208 | # menampilkan docstring class `Quote` 209 | print(Quote.__doc__) 210 | 211 | # menampilkan docstring class method `Quote.print_quote()` 212 | print(Quote.print_quote.__doc__) 213 | ``` 214 | 215 | Output program: 216 | 217 | ![Python docstring](img/docstring-6.png) 218 | 219 | --- 220 | 221 |
222 | 223 | ## Catatan chapter 📑 224 | 225 | ### ◉ Source code praktik 226 | 227 |
228 |     
229 |         github.com/novalagung/dasarpemrogramanpython-example/../docstring
230 |     
231 | 
232 | 233 | ### ◉ Chapter relevan lainnya 234 | 235 | - [Komentar](/basic/komentar) 236 | 237 | ### ◉ Referensi 238 | 239 | - https://peps.python.org/pep-0257/ 240 | 241 |
242 | -------------------------------------------------------------------------------- /docs/basic/duck-typing-vs-structural-typing.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 44 3 | title: A.44. Python Duck Typing vs Structural Typing 4 | sidebar_label: A.44. Duck Typing vs. Structural Typing 5 | --- 6 | 7 | Pada chapter ini kita akan belajar salah satu konsep yang ada di bahasa pemrograman dinamis, yaitu **duck typing**, beserta perbandingannya dengan **structural typing** 8 | 9 | ## A.44.1. Duck typing 10 | 11 | Istilah *duck typing* berasal dari kalimat *If it looks like a duck and quacks like a duck, it's a duck*. 12 | 13 | Duck typing adalah konsep yang menjelaskan bahwa compiler/interpreter tidak perlu tau apakah suatu fungsi itu merupakan method, lambda, atau berasal dari class tertentu, atau apapun lainnya; selama fungsi tersebut saat diakses memenuhi kriteria (nama dan skema parameter-nya sama) maka fungsi dianggap valid secara logika. 14 | 15 | Mari kita praktekan agar lebih jelas maksudnya apa. Pertama, siapkan sebuah fungsi bernama `do_the_math()`. Tugas fungsi ini sangat sederhana, yaitu menerima parameter `obj`, kemudian lewat variabel tersebut method `calculate_area()` diakses. 16 | 17 | ```python 18 | def do_the_math(obj): 19 | area = obj.calculate_area() 20 | print(f"area of {type(obj).__name__}: {area}") 21 | ``` 22 | 23 | Selanjutnya adalah bagian terpenting dari pembelajaran di chapter ini, fungsi yang sudah dibuat akan di test menggunakan beberapa skenario. 24 | 25 | ### ◉ Skenario 1: Instance method 26 | 27 | Buat class baru untuk operasi perhitungan luas segitiga. Operasi perhitungannya disiapkan di instance method bernama `calculate_area()`. Dari sini, object buatan class ini harusnya bisa dipergunakan sebagai argument fungsi `do_the_math()`. 28 | 29 | ```python 30 | class Triangle: 31 | def __init__(self, b, h): 32 | self.b = b 33 | self.h = h 34 | 35 | def calculate_area(self): 36 | return 1/2 * self.b * self.h 37 | 38 | obj1 = Triangle(4, 10) 39 | do_the_math(obj1) 40 | # output ➜ area of Triangle: 20.0 41 | ``` 42 | 43 | Hasilnya: OK ✅ 44 | 45 | ### ◉ Skenario 2: Attribute berisi closure 46 | 47 | Berikutnya, siapkan class baru lagi dengan attribute bernama `calculate_area`, lalu isi nilai attribute tersebut dengan closure. Disini dicontohkan closure-nya adalah fungsi `number_10()` yang tugasnya mengembalikan nilai numerik `10`. 48 | 49 | ```python 50 | def number_10(): 51 | return 10 52 | 53 | class AreaOf2x10: 54 | def __init__(self) -> None: 55 | self.calculate_area = number_10 56 | 57 | obj2 = AreaOf2x10() 58 | do_the_math(obj2) 59 | # output ➜ area of AreaOf2x10: 10 60 | ``` 61 | 62 | Hasilnya: OK ✅ 63 | 64 | Fungsi `do_the_math()` berjalan sesuai harapan tanpa melihat tipe data dan struktur dari argument-nya seperti apa. Selama class memiliki property bernama `calculate_area` dan bisa diakses dalam bentuk notasi fungsi, maka bukan masalah. 65 | 66 | ### ◉ Skenario 3: Attribute berisi lambda 67 | 68 | Pada skenario ini, sebuah class bernama `AreaOfRandomInt` dibuat disertai dengan attribute bernama `calculate_area` yang berisi operasi perkalian angka random yang ditulis dalam syntax lambda. 69 | 70 | ```python 71 | import random 72 | 73 | class AreaOfRandomInt: 74 | def __init__(self) -> None: 75 | self.calculate_area = lambda : random.randint(0, 10) * 2 76 | 77 | obj3 = AreaOfRandomInt() 78 | do_the_math(obj3) 79 | # output ➜ 16 80 | ``` 81 | 82 | Hasilnya: OK ✅ 83 | 84 | ### ◉ Skenario 4: Class method 85 | 86 | Bisa dibilang skenario ini yang paling unik. Buat sebuah class baru berisi class method `calculate_area()`. Lalu jadikan class tersebut sebagai argument pemanggilan fungsi `do_the_math()`. Jadi disini kita tidak menggunakan instance object sama sekali. 87 | 88 | ```python 89 | class NotReallyA2dObject: 90 | @classmethod 91 | def calculate_area(cls): 92 | return "where is the number?" 93 | 94 | do_the_math(NotReallyA2dObject) 95 | # output ➜ where is the number? 96 | ``` 97 | 98 | Hasilnya: OK ✅ 99 | 100 | Fungsi `do_the_math()` tetap bisa menjalankan tugasnya dengan baik, bahkan untuk argument yang bukan instance object sekalipun. Selama argument memiliki fungsi `calculate_area()` maka semuanya aman terkendali. 101 | 102 | ## A.44.2. Structural typing 103 | 104 | Structural typing bisa diibaratkan sebagai duck typing tapi versi yang lebih ketat. Structural typing mengharuskan suatu fungsi atau method untuk memilki spesifikasi yang sama persis sesuai yang dideklarasikan. Misalnya ada suatu object berisi method dengan hanya nama fungsi dan skema parameternya saja yang sama dibanding yang dibutuhkan, maka itu tidak cukup dan error pasti muncul. 105 | 106 | Cara penerapan structural typing adalah dengan menentukan tipe data parameter secara *explicit*. Mari coba praktekan via kode berikut agar lebih jelas. 107 | 108 | Pertama, siapkan sebuah class bernama `Object2D` yang memiliki abstract method `calculate_area()`. Lalu buat juga fungsi `do_the_math()` tapi kali ini argument nya bertipe data `Object2D`. 109 | 110 | ```python 111 | from abc import ABC, abstractmethod 112 | 113 | class Object2D(ABC): 114 | @abstractmethod 115 | def calculate_area(self): 116 | pass 117 | 118 | def do_the_math(obj: Object2D): 119 | area = obj.calculate_area() 120 | print(f"area of {type(obj).__name__}: {area}") 121 | ``` 122 | 123 | Dari sini terlihat bahwa untuk bisa menggunakan fungsi `do_the_math()` data argument harus bertipe `Object2D` atau class turunannya. Inilah bagaimana structural typing diaplikasikan di Python. 124 | 125 | Selanjutnya, buat class implementasinya, tak lupa panggil fungsi `do_the_math()`, dan isi argument-nya menggunakan instance object. Jalankan program, hasilnya tidak akan error, karena saat pemanggilan fungsi `do_the_math()` argument yang disisipkan tipe datanya sesuai spesifikasi, yaitu bertipe `Object2D` atau class turunannya. 126 | 127 | ```python 128 | class Triangle(Object2D): 129 | def __init__(self, b, h): 130 | self.b = b 131 | self.h = h 132 | 133 | def calculate_area(self): 134 | return 1/2 * self.b * self.h 135 | 136 | class Circle(Object2D): 137 | def __init__(self, r): 138 | self.r = r 139 | 140 | def calculate_area(self): 141 | return 3.14 * self.r * self.r 142 | 143 | class Square(Object2D): 144 | def __init__(self, s): 145 | self.s = s 146 | 147 | def calculate_area(self): 148 | return self.s * self.s 149 | 150 | do_the_math(Triangle(4, 10)) 151 | # output ➜ area of Triangle: 20.0 152 | 153 | do_the_math(Circle(20)) 154 | # output ➜ area of Circle: 1256.0 155 | 156 | do_the_math(Square(6)) 157 | # output ➜ area of Square: 36 158 | ``` 159 | 160 | Selanjutnya, coba test fungsi `do_the_math()` menggunakan argument berisi data yang bukan bertipe `Object2D` dan juga bukan turunannya. 161 | 162 | ```python 163 | class NotReallyA2dObject: 164 | @classmethod 165 | def calculate_area(cls): 166 | return "where is the number?" 167 | 168 | do_the_math(NotReallyA2dObject) 169 | ``` 170 | 171 | Silakan cek di editor masing-masing, pada statement `do_the_math()` terlihat ada warning. 172 | 173 | ![Duck typing vs structural typing](img/duck-typing-vs-structural-typing-1.png) 174 | 175 | > Python merupakan bahasa pemrograman dinamis yang dukungan terhadap structural typing tidak terlalu bagus. Keterangan tidak valid pada gambar di atas hanyalah warning, tidak benar-benar error. Kode program sendiri tetap bisa dijalankan. 176 | 177 | --- 178 | 179 |
180 | 181 | ## Catatan chapter 📑 182 | 183 | ### ◉ Source code praktik 184 | 185 |
186 |     
187 |         github.com/novalagung/dasarpemrogramanpython-example/../duck-typing-vs-structural-typing
188 |     
189 | 
190 | 191 | ### ◉ Chapter relevan lainnya 192 | 193 | - [Tipe Data](/basic/tipe-data) 194 | - [OOP ➜ Abstract Method](/basic/abstract-method) 195 | 196 | ### ◉ Referensi 197 | 198 | - https://stackoverflow.com/questions/4205130/what-is-duck-typing 199 | - https://docs.python.org/3/glossary.html#term-duck-typing 200 | 201 |
202 | --------------------------------------------------------------------------------