Pelican is a static site generator that requires no database or server-side logic.
- Installation
- Create a project
- Create an article
- Generate your site
- Preview your site
- Themes
Pelican is a static site generator that requires no database or server-side logic.
echo คำว่า test1 test2 ลงไปที่ไฟล์ /tmp/out.txt
%python import subprocess e = 'echo "test1 test2" > /tmp/out.txt' subprocess.call(e, shell=True)
ตั้งชื่อไฟล์ของ log เป็นวันเวลาปัจจุบัน ไว้ใต้ /tmp แล้วใส่ข้อความ Hello World! ลงไป ด้วยการ echo
%python import datetime import subprocess run_time = datetime.datetime.now() + datetime.timedelta(hours=7) tmp_file = '/tmp/' + run_time.strftime("%Y-%m-%dT%H:%M:%S") + '.log' print(tmp_file) # /tmp/2023-02-21T13:23:52.log e = f'echo "Hello World!" >> {tmp_file}' subprocess.call(e, shell=True)
ตรวจสอบว่าได้สร้างไฟล์ขึ้นมามั๊ย
%sh ls -l '/tmp/'
ดูเนื้อหาในไฟล์
%sh cat '/tmp/2023-02-21T13:23:52.log'
ใช้ Pandas อ่าน Text file
%python import pandas as pd # read text file df = pd.read_fwf('/tmp/2023-02-21T14:55:00.log') print(type(df)) print(df) print(df.count())
สร้างดาต้าเบส หรือเปิดดาต้าเบส
import sqlite3 con = sqlite3.connect("tutorial.db")
เตรียม cursor
cur = con.cursor()
สร้างตาราง
cur.execute("CREATE TABLE movie(title, year, score)")
ตรวจสอบตารางที่มีจาก sqlite_master
res = cur.execute("SELECT name FROM sqlite_master") print(res.fetchone()) # ('movie',)
insert ข้อมูล
cur.execute(""" INSERT INTO movie VALUES ('Monty Python and the Holy Grail', 1975, 8.2), ('And Now for Something Completely Different', 1971, 7.5) """) con.commit()
select ข้อมูล
res = cur.execute("SELECT score FROM movie") print(res.fetchall())
insert ข้อมูลด้วย executemany()
data = [ ("Monty Python Live at the Hollywood Bowl", 1982, 7.9), ("Monty Python's The Meaning of Life", 1983, 7.5), ("Monty Python's Life of Brian", 1979, 8.0), ] cur.executemany("INSERT INTO movie VALUES(?, ?, ?)", data) con.commit() # Remember to commit the transaction after executing INSERT.
for row in cur.execute("SELECT year, title FROM movie ORDER BY year"): print(row)
Verify that the database has been written to disk by calling con.close()
to close the existing connection
con.close()
Tool
read file
with open(ipfile, 'r', encoding='utf-8') as f: lines = f.readlines() print(f'{ipfile} = {len(lines)} line(s)')
write file
with open(opfile, 'w', encoding='utf-8') as f: f.write('readme\n')
ทดสอบบน Ubuntu 20.04.5 LTS ใน WSL 2
ติดตั้ง gnupg
(น่าจะติดตั้งอยู่แล้ว)
sudo apt-get install gnupg
$ gpg --version gpg (GnuPG) 2.2.19 libgcrypt 1.8.5 Copyright (C) 2019 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Home: /home/jack/.gnupg Supported algorithms: Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH, CAMELLIA128, CAMELLIA192, CAMELLIA256 Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224 Compression: Uncompressed, ZIP, ZLIB, BZIP2
ติดตั้ง python-gnupg
pip install python-gnupg
import os import gnupg os.system('rm -rf /home/jack/gpghome') os.system('mkdir /home/jack/gpghome') gpg = gnupg.GPG(gnupghome='/home/jack/gpghome') input_data = gpg.gen_key_input( key_length=4096, name_email='mr.phaisarn@gmail.com', passphrase='my passphrase') key = gpg.gen_key(input_data) print(key)
84511C0301E2D51E59D79C91B5432E86F4B8925A
export ค่า public key และ private key ไว้ในไฟล์ mykeyfile.asc
import gnupg key='84511C0301E2D51E59D79C91B5432E86F4B8925A' gpg = gnupg.GPG(gnupghome='/home/jack/gpghome') ascii_armored_public_keys = gpg.export_keys(key,passphrase='my passphrase') ascii_armored_private_keys = gpg.export_keys(key, True, passphrase='my passphrase') with open('mykeyfile.asc', 'w') as f: f.write(ascii_armored_public_keys) f.write(ascii_armored_private_keys)
-----BEGIN PGP PUBLIC KEY BLOCK----- mQINBGNqDu4BEADY6n5U0Fs4YBhAejiPZu5hI5i3oYbscK5xQSSXvgkUwoQkmHKQ JVv+Chq4+jCguBSlmVXXMNnk45F7OhjuxpfrXDSxQPivwchXTh0117UEtTi5jE2s eZTP5fMSdHomdD4NgU9PfSUiSPNH/PGnSQ8AFstFdFff846ry+dPu3XJdbkkVtEP Cbv6idGCa2u/ZMukj2o2ZbvOXNVj1M5RFOpqJ6m52UQXA1W8S/Qr3g7gJ41jTWE3 oOP1oSfw5IbuO6yTrhOjwELTM2BexXwUAEtW59A8e+1JVh1xtbiTRxmnC+WHZ1T1 RQ9a7rFbFyqmboZ5RE8wUX7SsklzPyXtZhCnsFfBt3OVJNyD5hPoZ4qq7ihGeIIa OD2g2VDu+uHeJg4Vqd8YcafFruLs0WR0BAdliYHClhhGSTQ2mFK7jQDfAVZYuFhZ kKqd7WV7++e/oyLViWxDvhBN1XQ7Wbw5o1hkgeH6cyFg9nX/psVecXCriOJJUyVh AKeFypLgfUiXkNoNuiWIcyJer55wIzjV0oTcLmHLtedh4Bh0+qvI+EI2UnKW2Ih0 Xas9jE3nx97T5365MD7hDjjm7sqmbg3xbih2VXUC+WjPuaisqbGgM/3vO06VA2A4 jg3j1SUm0N4IN8LSFzmAtvoSc5kvHDzTgySCYwlC3YowjKPciMu24jfjXwARAQAB tClBdXRvZ2VuZXJhdGVkIEtleSA8bXIucGhhaXNhcm5AZ21haWwuY29tPokCTgQT AQoAOBYhBIRRHAMB4tUeWdeckbVDLob0uJJaBQJjag7uAhsvBQsJCAcCBhUKCQgL AgQWAgMBAh4BAheAAAoJELVDLob0uJJaL1AP+QEa1Uc1etOnSlz8V6IV5vcpPn0i 6T1cAAb0yfHELKScL4zC6oPq2AyWTTJUT9T/qiHtWi38bM90fkNfefpMdMHeh0TQ GsTBeAO5YdF+I5GERib2m1vKJjaPVOQWaW0GhGo9fhI8TBdK0b4138JvHpdVsqub /KbsoRXriXQxrYEy7bnl7Rsr2rYmRlFN5MGkxbVjmHYg1FJle6e6kCRD3sNs2juD a1HDqYk6/MF6D5LlQ/o7tI53zeRrSAoOvY+yEnmp9a6Pb2X8vw3IGEzP12uad84X sD2BhXLntie47svDqSbzOdPD0ON/W6M5DuCtWM9qwMrYHI8QyZqLG2sY7Mmz/2kQ 9R9+nU2O5I5sYWpkcW4olMEpe7jaiUNlq8tErIoOxDonc9tUrumoHOQvuxVodnSr f1zJ5ypbE+v2Cz8MHw5hoBwQWokxZ8qrTo1zP3XvDe9tM5LykFOo8O1RJ1YmCJ58 qaHpC5jIZ/b+2/YKClG3XUxqFVBHLl5YvdfEXnJzOqRHLmakd7HyOgUbMBV0FtYf E+ipdjfRPXsLh5cbF+HoVkScrcY+qmTSdN1m4c1ffLO419SAvhKgdC51VAd8UdoQ ZYjx3vD06ghHO8sNyvuUL9z0XmuJykNxC1eVVnxgV8gf16OVymwMxcu5RPMIDtGS 0H7kHgfl3AmPCLrW =m6l6 -----END PGP PUBLIC KEY BLOCK----- -----BEGIN PGP PRIVATE KEY BLOCK----- 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 CY8IutY= =6b0l -----END PGP PRIVATE KEY BLOCK-----
import gnupg from pprint import pprint gpg = gnupg.GPG(gnupghome='/home/jack/gpghome') key_data = open('mykeyfile.asc').read() import_result = gpg.import_keys(key_data) pprint(import_result.results)
[{'fingerprint': '84511C0301E2D51E59D79C91B5432E86F4B8925A', 'ok': '0', 'text': 'Not actually changed\n'}, {'fingerprint': '84511C0301E2D51E59D79C91B5432E86F4B8925A', 'ok': '0', 'text': 'Not actually changed\n'}, {'fingerprint': '84511C0301E2D51E59D79C91B5432E86F4B8925A', 'ok': '16', 'text': 'Not actually changed\nContains private key\n'}]
import gnupg from pprint import pprint gpg = gnupg.GPG(gnupghome='/home/jack/gpghome') public_keys = gpg.list_keys() private_keys = gpg.list_keys(True) print('public keys:') pprint(public_keys) print('private keys:') pprint(private_keys)
public keys: [{'algo': '1', 'cap': 'escaESCA', 'compliance': '23', 'curve': '', 'date': '1667895022', 'dummy': '', 'expires': '', 'fingerprint': '84511C0301E2D51E59D79C91B5432E86F4B8925A', 'flag': '', 'hash': '', 'issuer': '', 'keygrip': 'AADC0ABF3CA1285034094D0381E0142B513D5514', 'keyid': 'B5432E86F4B8925A', 'length': '4096', 'origin': '0', 'ownertrust': 'u', 'sig': '', 'sigs': [], 'subkeys': [], 'token': '', 'trust': 'u', 'type': 'pub', 'uids': ['Autogenerated Key <mr.phaisarn@gmail.com>'], 'updated': ''}] private keys: [{'algo': '1', 'cap': 'escaESCA', 'compliance': '23', 'curve': '', 'date': '1667895022', 'dummy': '', 'expires': '', 'fingerprint': '84511C0301E2D51E59D79C91B5432E86F4B8925A', 'flag': '', 'hash': '', 'issuer': '', 'keygrip': 'AADC0ABF3CA1285034094D0381E0142B513D5514', 'keyid': 'B5432E86F4B8925A', 'length': '4096', 'origin': '0', 'ownertrust': 'u', 'sig': '', 'sigs': [], 'subkeys': [], 'token': '+', 'trust': 'u', 'type': 'sec', 'uids': ['Autogenerated Key <mr.phaisarn@gmail.com>'], 'updated': ''}]
import gnupg gpg = gnupg.GPG(gnupghome='/home/jack/gpghome') unencrypted_string = 'Who are you? How did you get in my house?' encrypted_data = gpg.encrypt(unencrypted_string, 'mr.phaisarn@gmail.com') encrypted_string = str(encrypted_data) print('ok: ', encrypted_data.ok) print('status: ', encrypted_data.status) print('stderr: ', encrypted_data.stderr) print('unencrypted_string: ', unencrypted_string) print('encrypted_string: ', encrypted_string)
ok: True status: encryption ok stderr: gpg: WARNING: unsafe permissions on homedir '/home/jack/gpghome' [GNUPG:] KEY_CONSIDERED 84511C0301E2D51E59D79C91B5432E86F4B8925A 0 [GNUPG:] KEY_CONSIDERED 84511C0301E2D51E59D79C91B5432E86F4B8925A 2 [GNUPG:] ENCRYPTION_COMPLIANCE_MODE 23 [GNUPG:] BEGIN_ENCRYPTION 2 9 [GNUPG:] END_ENCRYPTION unencrypted_string: Who are you? How did you get in my house? encrypted_string: -----BEGIN PGP MESSAGE----- hQIMA7VDLob0uJJaAQ//czHG42eeN1rtFTo6qdvoHSa/B3uJNeFSobUi4gUCxceh yVbZ0La8pnLMy2JmA2agYaOvC6OhAXfNOhPXV5jinMTvwGB+dKC1qaAYXMknQjyF 5whvmQeBbuQX8AoKxs7hAYmlQO8mrHDBoP2xSdY/AgLeqdlnbZNcDR+NIpoPJS8a zr+KHYAhEyZT0Bm6FAw7DvhriB4nJRLeMLoIQKIJTN3ZeEdlcZAt5xYL24dZfz8/ 4Qpn++ItqsCQfXJ1leJIIE/oB4E83/J4FZuS1xh7n9OomBT2fRG8hmGlSzFYepX/ jDzjApmA/R4HGd6BuJZdNy6SV2DERs2NlTRko98IDFdCIg2Jp7jsSGSZowsKD7z5 rIU110iwR6hRropsuX18jlRk6QM1Um+dSGbHXTUk1OzUDE5uC3hBZsB0s9M2q5DS HN+EbyatT9hB9X5Obf7w9Vj+Jta9q5voL/riZ2d+GFr8oR0d594An7Dup12zBff/ kdV7DgibAqorCD1MvVePOpvYw2NdhukRluOsVtXySkcAGy8VssBLoW3kqilOvrhq pCJUG157TnhKnYW0l4BJ7KVoNFwBGsJKzS0Drh5Iq6LmiqHsKv7neK9LkApDeehD EhdNoGN79fPvEYmync2bbGbVq6F7czHADwVKqNv0aDxaCrFHASsSXkGNbqMQ+tnS YgFfzEOmYoDR7UjEog/OrBJAnPSgDcwn3I0xuU3RtDaEvlHCt6aX+NHEyIUvsIe+ Don8uUXi4VkjO2uoCOyNgwndoigDuouh8NDv5DIWcKt+KMGPkgKEmfbOxJNA0Rl5 TK5E =Jyon -----END PGP MESSAGE-----
import gnupg gpg = gnupg.GPG(gnupghome='/home/jack/gpghome') unencrypted_string = 'Who are you? How did you get in my house?' encrypted_data = gpg.encrypt(unencrypted_string, 'mr.phaisarn@gmail.com') encrypted_string = str(encrypted_data) decrypted_data = gpg.decrypt(encrypted_string, passphrase='my passphrase') print('ok: ', decrypted_data.ok) print('status: ', decrypted_data.status) print('stderr: ', decrypted_data.stderr) print('decrypted string: ', decrypted_data.data)
ok: True status: decryption ok stderr: gpg: WARNING: unsafe permissions on homedir '/home/jack/gpghome' [GNUPG:] ENC_TO B5432E86F4B8925A 1 0 [GNUPG:] KEY_CONSIDERED 84511C0301E2D51E59D79C91B5432E86F4B8925A 0 [GNUPG:] KEY_CONSIDERED 84511C0301E2D51E59D79C91B5432E86F4B8925A 0 [GNUPG:] DECRYPTION_KEY 84511C0301E2D51E59D79C91B5432E86F4B8925A 84511C0301E2D51E59D79C91B5432E86F4B8925A u [GNUPG:] KEY_CONSIDERED 84511C0301E2D51E59D79C91B5432E86F4B8925A 0 gpg: encrypted with 4096-bit RSA key, ID B5432E86F4B8925A, created 2022-11-08 "Autogenerated Key <mr.phaisarn@gmail.com>" [GNUPG:] BEGIN_DECRYPTION [GNUPG:] DECRYPTION_COMPLIANCE_MODE 23 [GNUPG:] DECRYPTION_INFO 2 9 [GNUPG:] PLAINTEXT 62 1667895570 [GNUPG:] PLAINTEXT_LENGTH 41 [GNUPG:] DECRYPTION_OKAY [GNUPG:] GOODMDC [GNUPG:] END_DECRYPTION decrypted string: b'Who are you? How did you get in my house?'
import gnupg gpg = gnupg.GPG(gnupghome='/home/jack/gpghome') open('my-unencrypted.txt', 'w').write('You need to Google Venn diagram.') with open('my-unencrypted.txt', 'rb') as f: status = gpg.encrypt_file( f, recipients=['mr.phaisarn@gmail.com'], output='my-encrypted.txt.gpg') print('ok: ', status.ok) print('status: ', status.status) print('stderr: ', status.stderr)
ok: True status: encryption ok stderr: gpg: WARNING: unsafe permissions on homedir '/home/jack/gpghome' [GNUPG:] KEY_CONSIDERED 84511C0301E2D51E59D79C91B5432E86F4B8925A 0 [GNUPG:] KEY_CONSIDERED 84511C0301E2D51E59D79C91B5432E86F4B8925A 2 [GNUPG:] ENCRYPTION_COMPLIANCE_MODE 23 [GNUPG:] BEGIN_ENCRYPTION 2 9 [GNUPG:] END_ENCRYPTION
-----BEGIN PGP MESSAGE----- hQIMA7VDLob0uJJaARAAhwNuaLm5/eSCV81Uw+H2E536AzzXm/yPxM0CIjLjYxnE +GwgvBxJsYtuuwCElUfYkIKYNzAWOGGRje961Be3+g5kjFfphvl4I1Xzwb5RKdWa i9raKNQ1/PLQ6Hr8Fc3yh08QcgLkihyRgVKZ3suTX+KRzWd3/SS8rjS27nigQk8C IoIuwJIsBYpB8xbBDM+Sfo2XJm938Z7n9ZfdDiuO0hEWBo5qF85Vh0jY91BVyPqD yGYcsivK/OqRG/VrPTrp01+2+jBn5HPZoPCnjEZdyJ3p+k/bnvAymKpKmPfEHrt3 4FwJ0EIfFROx6u2xBWhoRAhl5vLjIgRqccwEHD9+HrT3aFyeQhOKcQoV0TXy5Y0w rYLRBny2oolCGW1NqZi43pjamQXXVpJLDjOsn8pzhdbFiSxUrFZj2WXET7ItQaVd fQQnPxpOpj7LOOncLdZ0qfGMYjNNXGoKlaPfdtJy1yQlz8mUUdZZAjAdCpKpnfca YxuFmzMy2gGBKsYYrLB2FH6HasRbjb5uQ1qO72vybuPWCBNkX5jgWHGLddNagxR7 9EwMnvu958Oy3TiFfrr7YKWPIOQXaLx8WsgXCCl2rFJKG4Hy81ZM5k7DDQzzQFGd w+a5FWo/cthXm6qx2LSE2ByFyAerqwe/T/wkAYmrQLIJdxZIWxp5xsuPBS6W6oLS WwEiSHXqJPjqKHKnZwS0W9kWq/68voNf03QlEkN0+Hm3PRmEFIJnpw19BtfQEoY3 Rv/XCQXE2G6NVMajvFj72fvFzTUUyVRa8m//nu2wg9vG5JMjJbThA8L8+5E= =WZm8 -----END PGP MESSAGE-----
ถ้า import public key แล้วนำมาใช้ encrypt จะได้ error invalid recipient
ok: False status: invalid recipient stderr: gpg: WARNING: unsafe permissions on homedir `/home/jack/gpghome' gpg: EAECD251: There is no assurance this key belongs to the named user [GNUPG:] INV_RECP 10 84511C0301E2D51E59D79C91B5432E86F4B8925A gpg: [stdin]: encryption failed: Unusable public key
ให้เพิ่ม gpg.trust_keys()
import gnupg gpg = gnupg.GPG(gnupghome='/home/jack/gpghome') gpg.trust_keys('84511C0301E2D51E59D79C91B5432E86F4B8925A', 'TRUST_ULTIMATE') open('my-unencrypted.txt', 'w').write('You need to Google Venn diagram.') with open('my-unencrypted.txt', 'rb') as f: status = gpg.encrypt_file( f, recipients='84511C0301E2D51E59D79C91B5432E86F4B8925A', output='encrypted.txt.gpg') print('ok: ', status.ok) print('status: ', status.status) print('stderr: ', status.stderr)
import gnupg gpg = gnupg.GPG(gnupghome='/home/jack/gpghome') with open('my-encrypted.txt.gpg', 'rb') as f: status = gpg.decrypt_file(f, passphrase='my passphrase', output='my-decrypted.txt') print('ok: ', status.ok) print('status: ', status.status) print('stderr: ', status.stderr)
ok: True status: decryption ok stderr: gpg: WARNING: unsafe permissions on homedir '/home/jack/gpghome' [GNUPG:] ENC_TO B5432E86F4B8925A 1 0 [GNUPG:] KEY_CONSIDERED 84511C0301E2D51E59D79C91B5432E86F4B8925A 0 [GNUPG:] KEY_CONSIDERED 84511C0301E2D51E59D79C91B5432E86F4B8925A 0 [GNUPG:] DECRYPTION_KEY 84511C0301E2D51E59D79C91B5432E86F4B8925A 84511C0301E2D51E59D79C91B5432E86F4B8925A u [GNUPG:] KEY_CONSIDERED 84511C0301E2D51E59D79C91B5432E86F4B8925A 0 gpg: encrypted with 4096-bit RSA key, ID B5432E86F4B8925A, created 2022-11-08 "Autogenerated Key <mr.phaisarn@gmail.com>" [GNUPG:] BEGIN_DECRYPTION [GNUPG:] DECRYPTION_COMPLIANCE_MODE 23 [GNUPG:] DECRYPTION_INFO 2 9 [GNUPG:] PLAINTEXT 62 1667895671 [GNUPG:] PLAINTEXT_LENGTH 32 [GNUPG:] DECRYPTION_OKAY [GNUPG:] GOODMDC [GNUPG:] END_DECRYPTION
Install
pip install joblib
การหา square root ด้วย Python
from math import sqrt li = [sqrt(i ** 2) for i in range(10)] print(li) # [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]
ใช้ joblib
from math import sqrt from joblib import Parallel, delayed li = Parallel(n_jobs=2)(delayed(sqrt)(i**2) for i in range(10)) print(li) # [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]
verbose: int, optional
The verbosity level: if non zero, progress messages are printed. Above 50, the output is sent to stdout. The frequency of the messages increases with the verbosity level. If it more than 10, all iterations are reported.
%python from math import sqrt from joblib import Parallel, delayed li = Parallel(n_jobs=2, verbose=100)(delayed(sqrt)(i**2) for i in range(10)) print(li) # [Parallel(n_jobs=2)]: Using backend LokyBackend with 2 concurrent workers. # [Parallel(n_jobs=2)]: Done 1 tasks | elapsed: 0.5s # [Parallel(n_jobs=2)]: Done 2 tasks | elapsed: 0.5s # [Parallel(n_jobs=2)]: Done 3 tasks | elapsed: 0.5s # [Parallel(n_jobs=2)]: Done 4 tasks | elapsed: 0.5s # [Parallel(n_jobs=2)]: Done 5 tasks | elapsed: 0.5s # [Parallel(n_jobs=2)]: Done 6 tasks | elapsed: 0.5s # [Parallel(n_jobs=2)]: Done 7 tasks | elapsed: 0.5s # [Parallel(n_jobs=2)]: Done 8 out of 10 | elapsed: 0.5s remaining: 0.1s # [Parallel(n_jobs=2)]: Done 10 out of 10 | elapsed: 0.5s remaining: 0.0s # [Parallel(n_jobs=2)]: Done 10 out of 10 | elapsed: 0.5s finished # [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0]
default backend
เป็น loky
เราสามารถเปลี่ยนเป็น threading
, multiprocessing
ได้
from math import sqrt from joblib import Parallel, delayed li = Parallel(n_jobs=2, verbose=100, backend='threading')(delayed(sqrt)(i**2) for i in range(10)) print(li)
MkDocs is a fast, simple and downright gorgeous static site generator that’s geared towards building project documentation. Documentation source files are written in Markdown, and configured with a single YAML
To install MkDocs, run the following command from the command line:
pip install mkdocs
> mkdocs -h Usage: mkdocs [OPTIONS] COMMAND [ARGS]... MkDocs - Project documentation with Markdown. Options: -V, --version Show the version and exit. -q, --quiet Silence warnings -v, --verbose Enable verbose output -h, --help Show this message and exit. Commands: build Build the MkDocs documentation gh-deploy Deploy your documentation to GitHub Pages new Create a new MkDocs project serve Run the builtin development server
> mkdocs --version mkdocs, version 1.5.1 from C:\Project\tmp\mkdocs1\.venv\lib\site-packages\mkdocs (Python 3.10)
For more details, see the Installation Guide.
Getting started is super easy. To create a new project, run the following command from the command line:
mkdocs new my-project cd my-project
$ tree . ├── docs │ └── index.md └── mkdocs.yml
There’s a single configuration file named mkdocs.yml
, and a folder named docs
that will contain your documentation source files (docs
is the default value for the docs_dir configuration setting). Right now the docs
folder just contains a single documentation page, named index.md
.
ไฟล์ mkdocs.yml
site_name: My Docs
ไฟล์ docs/index.md
# Welcome to MkDocs For full documentation visit [mkdocs.org](https://www.mkdocs.org). ## Commands * `mkdocs new [dir-name]` - Create a new project. * `mkdocs serve` - Start the live-reloading docs server. * `mkdocs build` - Build the documentation site. * `mkdocs -h` - Print help message and exit. ## Project layout mkdocs.yml # The configuration file. docs/ index.md # The documentation homepage. ... # Other markdown pages, images and other files.
MkDocs comes with a built-in dev-server that lets you preview your documentation as you work on it. Make sure you’re in the same directory as the mkdocs.yml
configuration file, and then start the server by running the mkdocs serve
command:
> mkdocs serve INFO - Building documentation... INFO - Cleaning site directory INFO - Documentation built in 0.24 seconds INFO - [21:14:45] Watching paths for changes: 'docs', 'mkdocs.yml' INFO - [21:14:45] Serving on http://127.0.0.1:8000/
Open up http://127.0.0.1:8000/ in your browser, and you’ll see the default home page being displayed:
The fenced code blocks extension adds an alternate method of defining code blocks without indentation.
The first line should contain 3 or more backtick (`
) characters, and the last line should contain the same number of backtick characters (`
):
``` Fenced code blocks are like Standard Markdown’s regular code blocks, except that they’re not indented and instead rely on start and end fence lines to delimit the code block. ```
With this approach, the language can optionally be specified on the first line after the backticks which informs any syntax highlighters of the language used:
```python def fn(): pass ``` ```sql SELECT * FROM FOO ``` ```c main() { print('Hello'); } ```
Note that fenced code blocks can not be indented. Therefore, they cannot be nested inside list items, blockquotes, etc.
That’s looking good. You’re ready to deploy the first pass of your MkLorum
documentation. First build the documentation:
mkdocs build
This will create a new directory, named site
. Take a look inside the directory:
$ ls site about fonts index.html license search.html css img js mkdocs sitemap.xml
Notice that your source documentation has been output as two HTML files named index.html
and about/index.html
. You also have various other media that’s been copied into the site
directory as part of the documentation theme. You even have a sitemap.xml
file and mkdocs/search_index.json
.
If you’re using source code control such as git
you probably don’t want to check your documentation builds into the repository. Add a line containing site/
to your .gitignore
file.
echo "site/" >> .gitignore
If you’re using another source code control tool you’ll want to check its documentation on how to ignore specific directories.
A string giving the absolute path of the executable binary for the Python interpreter, on systems where this makes sense. If Python is unable to retrieve the real path to its executable, sys.executable
will be an empty string or None
.
>>> import sys >>> sys.executable 'C:\\Python310\\python.exe'
Return the directory name of pathname path. This is the first element of the pair returned by passing path to the function split()
.
>>> import os >>> import sys >>> os.path.dirname(sys.executable) 'C:\\Python310'
>>> import os >>> import sys >>> os.path.dirname(sys.executable) 'C:\\Users\\<username>\\AppData\\Local\\Programs\\Python\\Python38\\python.exe'
Go to This PC → Right-click → Click on Properties → Advanced System Settings.
You will see the System Properties. From here navigate to the Advanced Tab -> Click on Environment Variables.
You will see a top half for the user variables and the bottom half for System variables.
Check the System Variables and double-click on the Path (to edit the Path).
Check for the path of Python(which you wish to run i.e. Python 2.x or 3.x) and move it to the top of the Path list.
Restart the Command Prompt, and now when you check the version of Python, it should correctly display the required version.
List all files and directories in a directory
from os import listdir my_path = '/home/jack' files_list = listdir(my_path) print(files_list)
List all files in a directory
from os import listdir from os.path import isfile, join my_path = '/home/jack' files_list = [f for f in listdir(my_path) if isfile(join(my_path, f))] print(files_list)
List all directories in a directory
from genericpath import isdir from os import listdir from os.path import isfile, join my_path = '/home/jack' files_list = [f for f in listdir(my_path) if isdir(join(my_path, f))] print(files_list)
from datetime import date today = date.today() print(type(today)) # <class 'datetime.date'> print(today) # 2022-08-19
เวลาปัจจุบันของ server
from datetime import datetime now = datetime.now() # current date and time print(type(now)) # <class 'datetime.datetime'> print(now) # 2022-08-19 07:51:55.893002
นำเวลาปัจจุบันของ server มาบวก 7 ชั่วโมง
import datetime now = datetime.datetime.now() print(now) # 2022-08-19 08:32:36.803853 now = now + datetime.timedelta(hours=7) print(now) # 2022-08-19 15:32:36.803853
from datetime import datetime now = datetime.now() # current date and time year = now.strftime("%Y") print("year:", year) # year: 2022 month = now.strftime("%m") print("month:", month) # month: 08 day = now.strftime("%d") print("day:", day) # day: 19 time = now.strftime("%H:%M:%S") print("time:", time) # time: 08:12:42 date_time = now.strftime("%m/%d/%Y, %H:%M:%S") print("date and time:",date_time) # date and time: 08/19/2022, 08:12:42
from datetime import datetime now = datetime.now() # current date and time time_tuple = now.timetuple() print(type(time_tuple)) # <class 'time.struct_time'> print(now) # 2022-08-19 07:55:03.144893 print(time_tuple) # time.struct_time(tm_year=2022, tm_mon=8, tm_mday=19, tm_hour=7, tm_min=55, tm_sec=3, tm_wday=4, tm_yday=231, tm_isdst=-1)
หาค่า timestamp จาก current date และ time
import time from datetime import datetime now = datetime.now() # current date and time time_tuple = now.timetuple() timestamp = int(time.mktime(time_tuple)) print(now) # 2022-08-19 07:59:21.232243 print(timestamp) # 1660895961
เปลี่ยน type ของข้อมูล (float
, int
, str
, bytes
)
import time from datetime import datetime now = datetime.now() # current date and time time_tuple = now.timetuple() timestamp = time.mktime(time_tuple) print(type(timestamp)) print(timestamp) # <class 'float'> # 1660898887.0 timestamp = int(timestamp) print(type(timestamp)) print(timestamp) # <class 'int'> # 1660898887 timestamp = str(timestamp) print(type(timestamp)) print(timestamp) # <class 'str'> # 1660898887 timestamp = str.encode(timestamp) print(type(timestamp)) print(timestamp) # <class 'bytes'> # b'1660898887' timestamp = timestamp.decode() print(type(timestamp)) print(timestamp) # <class 'str'> # 1660898887
หาค่า timestamp จากวันที่ ที่กำหนด
import time from datetime import datetime # date in string format dt="19/08/2022" time_tuple = datetime.strptime(dt, "%d/%m/%Y").timetuple() print(time_tuple) # time.struct_time(tm_year=2022, tm_mon=8, tm_mday=19, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=4, tm_yday=231, tm_isdst=-1) timestamp = time.mktime(time_tuple) print(timestamp) # 1660867200.0
The weekday()
method we used above returns the day of the week as an integer, where Monday is 0 and Sunday is 6.
from datetime import datetime # get current datetime dt = datetime.now() print('Datetime is:', dt) # get day of week as an integer x = dt.weekday() print('Day of a week is:', x) # output # Datetime is: 2023-03-20 15:50:11.044832 # Day of a week is: 0
from datetime import datetime, timedelta dt = datetime.now() - timedelta(days=1) print('Datetime is:', dt) x = dt.weekday() print('Day of a week is:', x) # Datetime is: 2023-03-19 15:52:50.568494 # Day of a week is: 6
The isoweekday() method to get the day of the week as an integer, where Monday is 1 and Sunday is 7. i.e., To start from the weekday number from 1, we can use isoweekday()
in place of weekday()
.
from datetime import datetime # get current datetime dt = datetime.now() print('Datetime is:', dt) print('Weekday is:', dt.isoweekday())