From 2f33bb373efac67fcc6d6fa4c7ed8e97bd0fe9aa Mon Sep 17 00:00:00 2001 From: feilong Date: Fri, 24 Dec 2021 22:46:14 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E8=AE=A2=E5=88=B0=E7=AC=AC5=E7=AB=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../class.md" | 4 + .../function.md" | 5 +- .../install.md" | 1 + .../run.md" | 2 + .../ide.md" | 1 + .../style.md" | 2 +- .../step.md" | 1 - .../3.\345\207\275\346\225\260/call.md" | 2 +- .../3.\345\207\275\346\225\260/fact1.md" | 2 +- .../3.\345\207\275\346\225\260/fact2.md" | 1 + .../3.\345\207\275\346\225\260/fibonacci1.md" | 1 + .../3.\345\207\275\346\225\260/fibonacci2.md" | 4 +- .../helloworld2.md" | 1 + .../4.\347\261\273/hash_key_value_set.md" | 3 +- .../hash_key_value_set_by_compose.md" | 1 + .../4.\347\261\273/key_value_set.md" | 3 +- .../calc.md" | 1 + .../if-else.md" | 1 + .../none.md" | 3 +- .../7.\345\276\252\347\216\257/for.md" | 1 + .../7.\345\276\252\347\216\257/while.md" | 1 + .../dict.md" | 1 + .../list.md" | 1 + .../builtin_class.md" | 1 + .../dict.md" | 1 + .../iter.md" | 1 + .../list01.md" | 1 + .../list02.md" | 1 + .../encode.md" | 1 + .../triple01.md" | 1 + .../triple02.md" | 1 + .../3.\346\226\255\350\250\200/assert.md" | 4 +- .../4.with-as/enter_exit.md" | 2 +- .../4.with-as/withas.md" | 1 + .../try01.md" | 1 + .../str.md" | 1 + .../lambda.md" | 1 + .../file_piece_sha256.md" | 1 + .../std02.md" | 1 + .../option_parser.json" | 20 +- .../option_parser.md" | 212 ++++++++++++++++ .../sys_argv.json" | 25 +- .../sys_argv.md" | 174 +++++++++++++ .../date.json" | 18 +- .../date.md" | 70 +++++ .../for_each_month.json" | 20 +- .../for_each_month.md" | 86 +++++++ .../time_span.json" | 17 +- .../time_span.md" | 90 +++++++ .../copy.json" | 17 +- .../copy.md" | 131 ++++++++++ .../count_file.json" | 24 +- .../count_file.md" | 160 ++++++++++++ .../dir.json" | 14 +- .../dir.md" | 57 +++++ .../list_file_in_dir.json" | 14 +- .../list_file_in_dir.md" | 72 ++++++ .../walk_dir.json" | 18 +- .../walk_dir.md" | 87 +++++++ .../zip_with_progress.json" | 23 +- .../zip_with_progress.md" | 138 ++++++++++ .../error_code.json" | 17 +- .../error_code.md" | 74 ++++++ .../mysql_connection.json" | 17 +- .../mysql_connection.md" | 166 ++++++++++++ .../mysql_connector.json" | 17 +- .../mysql_connector.md" | 197 ++++++++++++++ .../mysql_install.json" | 20 +- .../mysql_install.md" | 134 ++++++++++ .../mysql_kv.json" | 17 +- .../mysql_kv.md" | 240 ++++++++++++++++++ .../redis_connector.json" | 17 +- .../redis_connector.md" | 163 ++++++++++++ .../redis_install.json" | 16 +- .../redis_install.md" | 82 ++++++ .../redis_kv.json" | 20 +- .../redis_kv.md" | 174 +++++++++++++ .../sqlite_connection.json" | 20 +- .../sqlite_connection.md" | 174 +++++++++++++ .../sqlite_connector.json" | 20 +- .../sqlite_connector.md" | 131 ++++++++++ .../sqlite_kv.json" | 21 +- .../sqlite_kv.md" | 210 +++++++++++++++ .../os_info.json" | 17 +- .../os_info.md" | 224 ++++++++++++++++ .../platform_info.json" | 21 +- .../platform_info.md" | 152 +++++++++++ .../package.json" | 30 +-- .../package.md" | 213 ++++++++++++++++ .../tcp.json" | 32 +-- .../tcp.md" | 192 ++++++++++++++ .../send_mail.json" | 23 +- .../send_mail.md" | 115 +++++++++ main.py | 8 +- 94 files changed, 4077 insertions(+), 447 deletions(-) create mode 100644 "data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/1.\350\247\243\346\236\220\345\221\275\344\273\244\350\241\214\345\217\202\346\225\260/option_parser.md" create mode 100644 "data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/1.\350\247\243\346\236\220\345\221\275\344\273\244\350\241\214\345\217\202\346\225\260/sys_argv.md" create mode 100644 "data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/2.\346\227\266\351\227\264\346\227\245\346\234\237\345\244\204\347\220\206/date.md" create mode 100644 "data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/2.\346\227\266\351\227\264\346\227\245\346\234\237\345\244\204\347\220\206/for_each_month.md" create mode 100644 "data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/2.\346\227\266\351\227\264\346\227\245\346\234\237\345\244\204\347\220\206/time_span.md" create mode 100644 "data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/copy.md" create mode 100644 "data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/count_file.md" create mode 100644 "data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/dir.md" create mode 100644 "data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/list_file_in_dir.md" create mode 100644 "data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/walk_dir.md" create mode 100644 "data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/zip_with_progress.md" create mode 100644 "data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/error_code.md" create mode 100644 "data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/mysql_connection.md" create mode 100644 "data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/mysql_connector.md" create mode 100644 "data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/mysql_install.md" create mode 100644 "data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/mysql_kv.md" create mode 100644 "data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/redis_connector.md" create mode 100644 "data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/redis_install.md" create mode 100644 "data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/redis_kv.md" create mode 100644 "data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/sqlite_connection.md" create mode 100644 "data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/sqlite_connector.md" create mode 100644 "data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/sqlite_kv.md" create mode 100644 "data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/5.\346\223\215\344\275\234\347\263\273\347\273\237\345\222\214\347\216\257\345\242\203/os_info.md" create mode 100644 "data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/5.\346\223\215\344\275\234\347\263\273\347\273\237\345\222\214\347\216\257\345\242\203/platform_info.md" create mode 100644 "data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/6.\346\272\220\347\240\201\346\211\223\345\214\205/package.md" create mode 100644 "data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/7.\347\275\221\347\273\234\347\274\226\347\250\213/tcp.md" create mode 100644 "data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/8.\345\217\221\351\200\201\351\202\256\344\273\266/send_mail.md" diff --git "a/data/1.python\345\210\235\351\230\266/1.\351\242\204\345\244\207\347\237\245\350\257\206/2.\347\250\213\345\272\217\350\256\276\350\256\241\346\200\235\346\203\263/class.md" "b/data/1.python\345\210\235\351\230\266/1.\351\242\204\345\244\207\347\237\245\350\257\206/2.\347\250\213\345\272\217\350\256\276\350\256\241\346\200\235\346\203\263/class.md" index e17d452..1dc1dbc 100644 --- "a/data/1.python\345\210\235\351\230\266/1.\351\242\204\345\244\207\347\237\245\350\257\206/2.\347\250\213\345\272\217\350\256\276\350\256\241\346\200\235\346\203\263/class.md" +++ "b/data/1.python\345\210\235\351\230\266/1.\351\242\204\345\244\207\347\237\245\350\257\206/2.\347\250\213\345\272\217\350\256\276\350\256\241\346\200\235\346\203\263/class.md" @@ -19,6 +19,7 @@ Python 是一门多范式编程语言,其中包括面向对象编程。 首先,我们用 `Python 类(class)` 定义一个密码城邦人物类型: ```python +# -*- coding: UTF-8 -*- class CryptographyPeople: def __init__(self, name_cn, name_en, role, desc): self.name_cn = name_cn @@ -30,6 +31,7 @@ class CryptographyPeople: 其次,我们添加一个简易的密码城邦人物解析器,它的作用是将类似`'马提尔达(Matilda)是一位商人(merchant),用于电子商务。',`这样的`人物剧本`解析成`CryptographyPeople`,创建一个密码城邦人物: ```python +# -*- coding: UTF-8 -*- class SimpleCryptographyPeopleParser: def __init__(self, text) -> None: self.text = text @@ -95,6 +97,7 @@ class SimpleCryptographyPeopleParser: 最后,我们希望创建一个密码城邦,它包含 `add` 和 `introduce` 两个方法: ```python +# -*- coding: UTF-8 -*- class CryptographyCity: def __init__(self): self.peoples = [] @@ -110,6 +113,7 @@ class CryptographyCity: 最终,我们可以构建起密码城邦,并让市民们全部自报家门: ```python +# -*- coding: UTF-8 -*- if __name__ == '__main__': crypto_roles = ... diff --git "a/data/1.python\345\210\235\351\230\266/1.\351\242\204\345\244\207\347\237\245\350\257\206/2.\347\250\213\345\272\217\350\256\276\350\256\241\346\200\235\346\203\263/function.md" "b/data/1.python\345\210\235\351\230\266/1.\351\242\204\345\244\207\347\237\245\350\257\206/2.\347\250\213\345\272\217\350\256\276\350\256\241\346\200\235\346\203\263/function.md" index d99d2db..6ae5423 100644 --- "a/data/1.python\345\210\235\351\230\266/1.\351\242\204\345\244\207\347\237\245\350\257\206/2.\347\250\213\345\272\217\350\256\276\350\256\241\346\200\235\346\203\263/function.md" +++ "b/data/1.python\345\210\235\351\230\266/1.\351\242\204\345\244\207\347\237\245\350\257\206/2.\347\250\213\345\272\217\350\256\276\350\256\241\346\200\235\346\203\263/function.md" @@ -3,6 +3,7 @@ 每个编程语言都有其内在的编程范式,体现着编程语言设计者的哲学。编程语言发展史上有许多杰出的人物。下面是一些例子: ```python +# -*- coding: UTF-8 -*- programmers = [ "约翰·巴科斯(JohnWarnerBackus), 创建了Fortran语言", "阿兰·库珀(Alan Cooper), 开发了Visual Basic语言", @@ -16,7 +17,8 @@ programmers = [ 为了进一步对上述文本数据解析,获得如下格式的结构化信息: -```json +```python +# -*- coding: UTF-8 -*- [ {"name_cn": "约翰·巴科斯", "name_en": "JohnWarnerBackus", "achievement": "创建了Fortran语言"}, {"name_cn": "阿兰·库珀", "name_en": "Alan Cooper", "achievement": "开发了Visual Basic语言"}, @@ -33,6 +35,7 @@ programmers = [ 完整的代码模版如下: ```python +# -*- coding: UTF-8 -*- def parse_parts(creator): index = creator.find(',') name, achievement = creator[0:index], creator[index+1:] diff --git "a/data/1.python\345\210\235\351\230\266/1.\351\242\204\345\244\207\347\237\245\350\257\206/3.\345\256\211\350\243\205Python/install.md" "b/data/1.python\345\210\235\351\230\266/1.\351\242\204\345\244\207\347\237\245\350\257\206/3.\345\256\211\350\243\205Python/install.md" index ab0737c..719efc0 100644 --- "a/data/1.python\345\210\235\351\230\266/1.\351\242\204\345\244\207\347\237\245\350\257\206/3.\345\256\211\350\243\205Python/install.md" +++ "b/data/1.python\345\210\235\351\230\266/1.\351\242\204\345\244\207\347\237\245\350\257\206/3.\345\256\211\350\243\205Python/install.md" @@ -31,6 +31,7 @@ install = { * 按`q`退出查询 ```python +# -*- coding: UTF-8 -*- if __name__ == '__main__': install = { "Windows": "请下载 Windows 安装包安装:https://www.python.org/downloads/windows/", diff --git "a/data/1.python\345\210\235\351\230\266/1.\351\242\204\345\244\207\347\237\245\350\257\206/4.\350\277\220\350\241\214\346\226\271\345\274\217/run.md" "b/data/1.python\345\210\235\351\230\266/1.\351\242\204\345\244\207\347\237\245\350\257\206/4.\350\277\220\350\241\214\346\226\271\345\274\217/run.md" index 6cac971..89515fc 100644 --- "a/data/1.python\345\210\235\351\230\266/1.\351\242\204\345\244\207\347\237\245\350\257\206/4.\350\277\220\350\241\214\346\226\271\345\274\217/run.md" +++ "b/data/1.python\345\210\235\351\230\266/1.\351\242\204\345\244\207\347\237\245\350\257\206/4.\350\277\220\350\241\214\346\226\271\345\274\217/run.md" @@ -31,6 +31,7 @@ shells = [ 通过shell,我们可以让操作系统执行Python程序。而Python是解释型语言,源代码不是直接翻译成机器语言,而是先翻译成中间代码,再由解释器对中间代码进行解释运行。有两种执行Python程序的方式,下面的`Python 字典`包含了这两种方式的信息: ```python +# -*- coding: UTF-8 -*- run = { "repl": { "title": "交互式编程( Interactive )", @@ -71,6 +72,7 @@ run = { 基本代码框架如下: ```python +# -*- coding: UTF-8 -*- if __name__ == '__main__': run = { "i": { diff --git "a/data/1.python\345\210\235\351\230\266/1.\351\242\204\345\244\207\347\237\245\350\257\206/5.\345\270\270\347\224\250\345\274\200\345\217\221\345\267\245\345\205\267/ide.md" "b/data/1.python\345\210\235\351\230\266/1.\351\242\204\345\244\207\347\237\245\350\257\206/5.\345\270\270\347\224\250\345\274\200\345\217\221\345\267\245\345\205\267/ide.md" index e1adcd0..1bd947d 100644 --- "a/data/1.python\345\210\235\351\230\266/1.\351\242\204\345\244\207\347\237\245\350\257\206/5.\345\270\270\347\224\250\345\274\200\345\217\221\345\267\245\345\205\267/ide.md" +++ "b/data/1.python\345\210\235\351\230\266/1.\351\242\204\345\244\207\347\237\245\350\257\206/5.\345\270\270\347\224\250\345\274\200\345\217\221\345\267\245\345\205\267/ide.md" @@ -66,6 +66,7 @@ py_ide_infos = [ 基本的程序框架如下: ```python +# -*- coding: UTF-8 -*- def parse_ide_trend(top_ide_trend): top_ides = [] top_ide_lines = top_ide_trend.split('\n')[1:] diff --git "a/data/1.python\345\210\235\351\230\266/1.\351\242\204\345\244\207\347\237\245\350\257\206/6.\347\274\226\347\240\201\350\247\204\350\214\203/style.md" "b/data/1.python\345\210\235\351\230\266/1.\351\242\204\345\244\207\347\237\245\350\257\206/6.\347\274\226\347\240\201\350\247\204\350\214\203/style.md" index 92dceed..8f93f40 100644 --- "a/data/1.python\345\210\235\351\230\266/1.\351\242\204\345\244\207\347\237\245\350\257\206/6.\347\274\226\347\240\201\350\247\204\350\214\203/style.md" +++ "b/data/1.python\345\210\235\351\230\266/1.\351\242\204\345\244\207\347\237\245\350\257\206/6.\347\274\226\347\240\201\350\247\204\350\214\203/style.md" @@ -47,7 +47,7 @@ python_style_guides = ''' 基本代码框架如下: ```python - +# -*- coding: UTF-8 -*- def top_words(splits, text, top_n=5): i = 0 word_dict = {} diff --git "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/1.\347\274\251\350\277\233\350\247\204\345\210\231/step.md" "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/1.\347\274\251\350\277\233\350\247\204\345\210\231/step.md" index 65b34bf..99bb23f 100644 --- "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/1.\347\274\251\350\277\233\350\247\204\345\210\231/step.md" +++ "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/1.\347\274\251\350\277\233\350\247\204\345\210\231/step.md" @@ -32,7 +32,6 @@ if i<10 { } ``` - 而 Python 程序则是用缩进来表示块作用域的开始和结束: ```python diff --git "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/3.\345\207\275\346\225\260/call.md" "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/3.\345\207\275\346\225\260/call.md" index ac919ef..e72fb03 100644 --- "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/3.\345\207\275\346\225\260/call.md" +++ "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/3.\345\207\275\346\225\260/call.md" @@ -3,6 +3,7 @@ 使用函数设计一组 “容器API”:init/set/get/exist,用例如下: ```python +# -*- coding: UTF-8 -*- def init(): # TODO(You): 实现初始化 @@ -15,7 +16,6 @@ def get(dict, key): def exist(dict, key): # TODO(You): 实现判断接口 - if __name__ == '__main__': dict = init() for i in range(10): diff --git "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/3.\345\207\275\346\225\260/fact1.md" "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/3.\345\207\275\346\225\260/fact1.md" index d4946d1..232a970 100644 --- "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/3.\345\207\275\346\225\260/fact1.md" +++ "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/3.\345\207\275\346\225\260/fact1.md" @@ -5,12 +5,12 @@ 不使用函数递归,实现一个阶乘计算函数(n<=170): ```python +# -*- coding: UTF-8 -*- def fact(n): r = 1 # TODO(You): 请在此编写代码 return r - if __name__ == '__main__': print(fact(10)) ``` diff --git "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/3.\345\207\275\346\225\260/fact2.md" "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/3.\345\207\275\346\225\260/fact2.md" index c57357d..143a3ea 100644 --- "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/3.\345\207\275\346\225\260/fact2.md" +++ "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/3.\345\207\275\346\225\260/fact2.md" @@ -3,6 +3,7 @@ 使用函数递归的方式可以方便的写出阶乘计算。 ```python +# -*- coding: UTF-8 -*- # TODO(You): 请实现递归计算阶乘 diff --git "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/3.\345\207\275\346\225\260/fibonacci1.md" "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/3.\345\207\275\346\225\260/fibonacci1.md" index f849e20..ee7e530 100644 --- "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/3.\345\207\275\346\225\260/fibonacci1.md" +++ "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/3.\345\207\275\346\225\260/fibonacci1.md" @@ -3,6 +3,7 @@ 数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子引入了数列0、1、1、2、3、5、8、13、21、34...,称为斐波那契数列(Fibonacci sequence),又称“黄金分割数列”或者“兔子数列”。使用函数递归或非递归的方式都可以方便地计算斐波那契函数:F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2) ```python +# -*- coding: UTF-8 -*- # TODO(You): 请实现递归计算斐波那契函数 diff --git "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/3.\345\207\275\346\225\260/fibonacci2.md" "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/3.\345\207\275\346\225\260/fibonacci2.md" index c0fc924..492bcfc 100644 --- "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/3.\345\207\275\346\225\260/fibonacci2.md" +++ "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/3.\345\207\275\346\225\260/fibonacci2.md" @@ -3,15 +3,13 @@ 斐波那契的递归实现版本里面有很多冗余计算,可以通过增加缓存来优化。 ```python +# -*- coding: UTF-8 -*- def fibonacci_inner(n, cache): if n == 1 or n == 2: return 1 - r = 0 - # TODO(You): 实现缓存 - def fibonacci(n): return fibonacci_inner(n, {}) diff --git "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/3.\345\207\275\346\225\260/helloworld2.md" "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/3.\345\207\275\346\225\260/helloworld2.md" index 63de81b..f7c9020 100644 --- "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/3.\345\207\275\346\225\260/helloworld2.md" +++ "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/3.\345\207\275\346\225\260/helloworld2.md" @@ -3,6 +3,7 @@ 函数是代码复用的最简单形式。在第一章里我们已经多次不经介绍地使用了函数来组织代码。现在可以系统认识下函数的参数。 ```python +# -*- coding: UTF-8 -*- def dump(index, default=0, *args, **kw): print('打印函数参数') print('---') diff --git "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/4.\347\261\273/hash_key_value_set.md" "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/4.\347\261\273/hash_key_value_set.md" index 534ef8f..473815f 100644 --- "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/4.\347\261\273/hash_key_value_set.md" +++ "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/4.\347\261\273/hash_key_value_set.md" @@ -5,9 +5,9 @@ 基本代码框架如下 ```python +# -*- coding: UTF-8 -*- from key_value_set import KeyValueSet - class HashKeyValueSet(KeyValueSet): def __init__(self) -> None: super().__init__() @@ -33,6 +33,7 @@ class HashKeyValueSet(KeyValueSet): 用例如下: ```python +# -*- coding: UTF-8 -*- if __name__ == '__main__': hashset = HashKeyValueSet() diff --git "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/4.\347\261\273/hash_key_value_set_by_compose.md" "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/4.\347\261\273/hash_key_value_set_by_compose.md" index 0985d68..823b924 100644 --- "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/4.\347\261\273/hash_key_value_set_by_compose.md" +++ "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/4.\347\261\273/hash_key_value_set_by_compose.md" @@ -5,6 +5,7 @@ 相比于本节第2题,下面代码使用组合的方式复合`KeyValueSet`的功能,从而实现`HashKeyValueSet`。 ```python +# -*- coding: UTF-8 -*- from key_value_set import KeyValueSet class HashKeyValueSet: diff --git "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/4.\347\261\273/key_value_set.md" "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/4.\347\261\273/key_value_set.md" index f56692d..669db98 100644 --- "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/4.\347\261\273/key_value_set.md" +++ "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/4.\347\261\273/key_value_set.md" @@ -3,6 +3,7 @@ 下面的类封装了一组 `set`/`get`/`keys` 接口 ```python +# -*- coding: UTF-8 -*- class KeyValueSet: def __init__(self) -> None: self.dict = {} @@ -27,6 +28,7 @@ class KeyValueSet: 我们编写一个新的class,内部通过组合`KeyValueSet`来支持上述功能,程序框架如下: ```python +# -*- coding: UTF-8 -*- class GuessSentenceGame: def __init__(self): self.kv = KeyValueSet() @@ -51,7 +53,6 @@ class GuessSentenceGame: print('哈哈,肯定猜不到得啦:{}->{},扣除2分!'.format(first_word, value)) print('游戏结束,你本次游戏得分:', self.score) - if __name__ == '__main__': sentences = [ diff --git "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/5.\351\241\272\345\272\217\350\257\255\345\217\245\347\273\223\346\236\204/calc.md" "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/5.\351\241\272\345\272\217\350\257\255\345\217\245\347\273\223\346\236\204/calc.md" index 796dc93..4215b51 100644 --- "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/5.\351\241\272\345\272\217\350\257\255\345\217\245\347\273\223\346\236\204/calc.md" +++ "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/5.\351\241\272\345\272\217\350\257\255\345\217\245\347\273\223\346\236\204/calc.md" @@ -3,6 +3,7 @@ 一行一个语句,计算长方形面积 ```python +# -*- coding: UTF-8 -*- def test(): print("* 如果想计算一个长方形的面积") print("* 那就先定义长宽,例如:x = 10, y=20") diff --git "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/6.\346\235\241\344\273\266\345\222\214\345\210\206\346\224\257/if-else.md" "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/6.\346\235\241\344\273\266\345\222\214\345\210\206\346\224\257/if-else.md" index 0b07f78..45829d5 100644 --- "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/6.\346\235\241\344\273\266\345\222\214\345\210\206\346\224\257/if-else.md" +++ "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/6.\346\235\241\344\273\266\345\222\214\345\210\206\346\224\257/if-else.md" @@ -3,6 +3,7 @@ 编写一个程序,能正确提示用户输入测试数字,判断是否是除以2等于5的数字。 ```python +# -*- coding: UTF-8 -*- def test(): test = 10 ret = input("有一个数除以2是5,请问它是什么?:") diff --git "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/6.\346\235\241\344\273\266\345\222\214\345\210\206\346\224\257/none.md" "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/6.\346\235\241\344\273\266\345\222\214\345\210\206\346\224\257/none.md" index e01fd39..5b24ec4 100644 --- "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/6.\346\235\241\344\273\266\345\222\214\345\210\206\346\224\257/none.md" +++ "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/6.\346\235\241\344\273\266\345\222\214\345\210\206\346\224\257/none.md" @@ -3,13 +3,12 @@ 存在还是不存在,提示用户输入查询关键字,判断是否在字典的key中,输出查询结果。 ```python +# -*- coding: UTF-8 -*- def is_existed(): database = { "monkey": "猴王说,我写的程序在五指山上的服务器上运行5000年了!" } - key = input('请输入你要查询的关键字:') - print("* 猴王数据库正在努力检索中...") # TODO(You): 请在此实现正确的查询判断 diff --git "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/7.\345\276\252\347\216\257/for.md" "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/7.\345\276\252\347\216\257/for.md" index 71ba143..406904e 100644 --- "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/7.\345\276\252\347\216\257/for.md" +++ "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/7.\345\276\252\347\216\257/for.md" @@ -3,6 +3,7 @@ 使用 for 遍历打印列表信息 ```python +# -*- coding: UTF-8 -*- if __name__ == '__main__': list = [ { diff --git "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/7.\345\276\252\347\216\257/while.md" "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/7.\345\276\252\347\216\257/while.md" index 78c5b56..eb116e0 100644 --- "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/7.\345\276\252\347\216\257/while.md" +++ "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/7.\345\276\252\347\216\257/while.md" @@ -3,6 +3,7 @@ 使用 while 遍历,打印列表信息 ```python +# -*- coding: UTF-8 -*- if __name__ == '__main__': list = [ { diff --git "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/8.\346\225\260\346\215\256\347\261\273\345\236\213/dict.md" "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/8.\346\225\260\346\215\256\347\261\273\345\236\213/dict.md" index c7f66ee..cdcc2e6 100644 --- "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/8.\346\225\260\346\215\256\347\261\273\345\236\213/dict.md" +++ "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/8.\346\225\260\346\215\256\347\261\273\345\236\213/dict.md" @@ -3,6 +3,7 @@ 字典的基本使用,插入key-value,并打印结果 ```python +# -*- coding: UTF-8 -*- if __name__ == '__main__': map = {} map['name'] = "monkey" diff --git "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/8.\346\225\260\346\215\256\347\261\273\345\236\213/list.md" "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/8.\346\225\260\346\215\256\347\261\273\345\236\213/list.md" index a13acd3..6e95461 100644 --- "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/8.\346\225\260\346\215\256\347\261\273\345\236\213/list.md" +++ "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/8.\346\225\260\346\215\256\347\261\273\345\236\213/list.md" @@ -3,6 +3,7 @@ 列表的基本使用,使用append/pop,打印结果 ```python +# -*- coding: UTF-8 -*- if __name__ == '__main__': array = [] array.append(10) diff --git "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/9.\345\206\205\347\275\256\347\261\273/builtin_class.md" "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/9.\345\206\205\347\275\256\347\261\273/builtin_class.md" index 77e4b49..42ea321 100644 --- "a/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/9.\345\206\205\347\275\256\347\261\273/builtin_class.md" +++ "b/data/1.python\345\210\235\351\230\266/2.\345\237\272\347\241\200\350\257\255\346\263\225/9.\345\206\205\347\275\256\347\261\273/builtin_class.md" @@ -3,6 +3,7 @@ 内置类的使用,列表元素去重+过滤小于3的元素 ```python +# -*- coding: UTF-8 -*- def remove_duplicates(items): # TODO(You): 实现去重 diff --git "a/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/1.\345\210\227\350\241\250\346\216\250\345\257\274\345\274\217/dict.md" "b/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/1.\345\210\227\350\241\250\346\216\250\345\257\274\345\274\217/dict.md" index 7203d0c..918380f 100644 --- "a/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/1.\345\210\227\350\241\250\346\216\250\345\257\274\345\274\217/dict.md" +++ "b/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/1.\345\210\227\350\241\250\346\216\250\345\257\274\345\274\217/dict.md" @@ -3,6 +3,7 @@ Python 独步天下的推导式表达式,使用字典推导式过滤,打印非windows系统的 Python 安装介绍 ```python +# -*- coding: UTF-8 -*- if __name__ == '__main__': install = { "w": { diff --git "a/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/1.\345\210\227\350\241\250\346\216\250\345\257\274\345\274\217/iter.md" "b/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/1.\345\210\227\350\241\250\346\216\250\345\257\274\345\274\217/iter.md" index 9d33c9f..730833e 100644 --- "a/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/1.\345\210\227\350\241\250\346\216\250\345\257\274\345\274\217/iter.md" +++ "b/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/1.\345\210\227\350\241\250\346\216\250\345\257\274\345\274\217/iter.md" @@ -3,6 +3,7 @@ Python 独步天下的推导式表达式,使用元表推导式过滤长度小于等于4的书籍 ```python +# -*- coding: UTF-8 -*- def test(): books = ('程序员修炼之道', '构建之法', '代码大全', 'TCP/IP协议详解') diff --git "a/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/1.\345\210\227\350\241\250\346\216\250\345\257\274\345\274\217/list01.md" "b/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/1.\345\210\227\350\241\250\346\216\250\345\257\274\345\274\217/list01.md" index c0b075a..107df86 100644 --- "a/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/1.\345\210\227\350\241\250\346\216\250\345\257\274\345\274\217/list01.md" +++ "b/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/1.\345\210\227\350\241\250\346\216\250\345\257\274\345\274\217/list01.md" @@ -3,6 +3,7 @@ Python 独步天下的推导式表达式,使用列表推导式过滤出偶数列表 ```python +# -*- coding: UTF-8 -*- if __name__ == '__main__': list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] diff --git "a/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/1.\345\210\227\350\241\250\346\216\250\345\257\274\345\274\217/list02.md" "b/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/1.\345\210\227\350\241\250\346\216\250\345\257\274\345\274\217/list02.md" index 7bd53d8..9e4a13d 100644 --- "a/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/1.\345\210\227\350\241\250\346\216\250\345\257\274\345\274\217/list02.md" +++ "b/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/1.\345\210\227\350\241\250\346\216\250\345\257\274\345\274\217/list02.md" @@ -3,6 +3,7 @@ Python 独步天下的推导式表达式,使用列表推导式过滤不热的天气 ```python +# -*- coding: UTF-8 -*- if __name__ == '__main__': obj_list = [ {"key": "day1", "value": "大雨哗啦啦啦啦下", 'tags': ["不热"]}, diff --git "a/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/10.\345\255\227\347\254\246\347\274\226\347\240\201\344\270\216\350\247\243\347\240\201/encode.md" "b/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/10.\345\255\227\347\254\246\347\274\226\347\240\201\344\270\216\350\247\243\347\240\201/encode.md" index aa4dbe8..77ca330 100644 --- "a/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/10.\345\255\227\347\254\246\347\274\226\347\240\201\344\270\216\350\247\243\347\240\201/encode.md" +++ "b/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/10.\345\255\227\347\254\246\347\274\226\347\240\201\344\270\216\350\247\243\347\240\201/encode.md" @@ -3,6 +3,7 @@ 二进制只是二进制,取决于怎么编码和解码,unicode 转 utf8 ```python +# -*- coding: UTF-8 -*- if __name__ == '__main__': unicode_str = u'二进制只是二进制,取决于怎么编码和解码' print(unicode_str) diff --git "a/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/2.\344\270\211\345\205\203\350\241\250\350\276\276\345\274\217/triple01.md" "b/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/2.\344\270\211\345\205\203\350\241\250\350\276\276\345\274\217/triple01.md" index e1a7977..090d754 100644 --- "a/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/2.\344\270\211\345\205\203\350\241\250\350\276\276\345\274\217/triple01.md" +++ "b/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/2.\344\270\211\345\205\203\350\241\250\350\276\276\345\274\217/triple01.md" @@ -3,6 +3,7 @@ Python 没有问号表达式了!使用三元组表达式统计偶数个数 ```python +# -*- coding: UTF-8 -*- if __name__ == '__main__': pi = [3, 14, 15, 9, 26, 5, 35, 8, 97, 932] even_count = 0 diff --git "a/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/2.\344\270\211\345\205\203\350\241\250\350\276\276\345\274\217/triple02.md" "b/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/2.\344\270\211\345\205\203\350\241\250\350\276\276\345\274\217/triple02.md" index 2b6b672..f9d683e 100644 --- "a/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/2.\344\270\211\345\205\203\350\241\250\350\276\276\345\274\217/triple02.md" +++ "b/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/2.\344\270\211\345\205\203\350\241\250\350\276\276\345\274\217/triple02.md" @@ -3,6 +3,7 @@ 使用嵌套的三元组表达式统计数字频率,如果是2的倍数加1,如果是4的倍数加2,否则加0 ```python +# -*- coding: UTF-8 -*- if __name__ == '__main__': pi = [3, 14, 15, 9, 26, 5, 35, 8, 97, 932] even_count = 0 diff --git "a/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/3.\346\226\255\350\250\200/assert.md" "b/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/3.\346\226\255\350\250\200/assert.md" index 441e543..cb344b3 100644 --- "a/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/3.\346\226\255\350\250\200/assert.md" +++ "b/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/3.\346\226\255\350\250\200/assert.md" @@ -3,6 +3,7 @@ 所谓断言,就是证明,使用 assert 对输入函数输入参数和函数返回结果分别做前校验和后校验 ```python +# -*- coding: UTF-8 -*- def check_param(key_value_map, key): '''参数校验,断言就是对输入参数的一个证明,这些参数必须符合这些要求 key_value_map: 非空字典 @@ -10,17 +11,14 @@ def check_param(key_value_map, key): ''' # TODO(You): 请在此实现校验代码 - def get(key_value_map, key): check_param(key_value_map, key) return key_value_map.get(key) - def set(key_value_map, key, value): check_param(key_value_map, key) key_value_map[key] = value - if __name__ == '__main__': key_value_map = {} set(key_value_map, "test", {}) diff --git "a/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/4.with-as/enter_exit.md" "b/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/4.with-as/enter_exit.md" index fcdc278..bfaba53 100644 --- "a/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/4.with-as/enter_exit.md" +++ "b/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/4.with-as/enter_exit.md" @@ -3,6 +3,7 @@ 实现一个范围耗时统计类。 实现了 `__enter__` 和 `__exit__` 成员的类,可以通过 with as 语法使用,程序进入和离开范围的时候会自动调用 `__enter__` 和 `__exit__` 方法。 ```python +# -*- coding: UTF-8 -*- import time class TimeSpan: @@ -21,7 +22,6 @@ if __name__ == '__main__': ```python import time - class TimeSpan: def __init__(self) -> None: self.start = None diff --git "a/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/4.with-as/withas.md" "b/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/4.with-as/withas.md" index 386a09b..c91c7ff 100644 --- "a/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/4.with-as/withas.md" +++ "b/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/4.with-as/withas.md" @@ -3,6 +3,7 @@ JSON文件读写 ```python +# -*- coding: UTF-8 -*- import json def load_json(file): diff --git "a/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/5.\345\274\202\345\270\270\346\215\225\350\216\267\351\242\204\345\244\204\347\220\206/try01.md" "b/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/5.\345\274\202\345\270\270\346\215\225\350\216\267\351\242\204\345\244\204\347\220\206/try01.md" index 69b0e4e..51ebc9d 100644 --- "a/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/5.\345\274\202\345\270\270\346\215\225\350\216\267\351\242\204\345\244\204\347\220\206/try01.md" +++ "b/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/5.\345\274\202\345\270\270\346\215\225\350\216\267\351\242\204\345\244\204\347\220\206/try01.md" @@ -3,6 +3,7 @@ 'a.json'文件不存在,下面代码会有异常,请编写异常控制代码,控制异常的最小范围,出现异常正常打印日志和堆栈 ```python +# -*- coding: UTF-8 -*- import json import traceback import logging diff --git "a/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/6.\345\255\227\347\254\246\344\270\262\346\226\271\346\263\225/str.md" "b/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/6.\345\255\227\347\254\246\344\270\262\346\226\271\346\263\225/str.md" index 058622b..6afd914 100644 --- "a/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/6.\345\255\227\347\254\246\344\270\262\346\226\271\346\263\225/str.md" +++ "b/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/6.\345\255\227\347\254\246\344\270\262\346\226\271\346\263\225/str.md" @@ -3,6 +3,7 @@ Python 的字符串处理, 一个朴实无华的四则运算计算器,批量计算小学生四则运算表达式 ```python +# -*- coding: UTF-8 -*- import re def naive_calc(code): diff --git "a/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/7.lambda\345\207\275\346\225\260/lambda.md" "b/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/7.lambda\345\207\275\346\225\260/lambda.md" index 25f4cb0..dda2132 100644 --- "a/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/7.lambda\345\207\275\346\225\260/lambda.md" +++ "b/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/7.lambda\345\207\275\346\225\260/lambda.md" @@ -3,6 +3,7 @@ Python 高阶函数编程,使用 lambda 表达式获取key,将list转成dict ```python +# -*- coding: UTF-8 -*- def list_to_dict(list, key_func): d = {} for item in list: diff --git "a/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/8.\346\226\207\344\273\266/file_piece_sha256.md" "b/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/8.\346\226\207\344\273\266/file_piece_sha256.md" index 3ee3afe..ccd37e6 100644 --- "a/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/8.\346\226\207\344\273\266/file_piece_sha256.md" +++ "b/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/8.\346\226\207\344\273\266/file_piece_sha256.md" @@ -3,6 +3,7 @@ 一种基于 sha256 的文件分片 hash 计算方式 ```python +# -*- coding: UTF-8 -*- import hashlib def file_piece_sha256(in_file_path, piece_size): diff --git "a/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/9.\345\270\270\347\224\250\346\240\207\345\207\206\345\272\223/std02.md" "b/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/9.\345\270\270\347\224\250\346\240\207\345\207\206\345\272\223/std02.md" index 7393345..15c3c82 100644 --- "a/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/9.\345\270\270\347\224\250\346\240\207\345\207\206\345\272\223/std02.md" +++ "b/data/1.python\345\210\235\351\230\266/3.\350\277\233\351\230\266\350\257\255\346\263\225/9.\345\270\270\347\224\250\346\240\207\345\207\206\345\272\223/std02.md" @@ -3,6 +3,7 @@ json 序列化和反序列化 ```python +# -*- coding: UTF-8 -*- import json if __name__ == '__main__': # TODO(You): 请在此实现json序列化和反序列化代码 diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/1.\350\247\243\346\236\220\345\221\275\344\273\244\350\241\214\345\217\202\346\225\260/option_parser.json" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/1.\350\247\243\346\236\220\345\221\275\344\273\244\350\241\214\345\217\202\346\225\260/option_parser.json" index 357d34d..07a58b9 100644 --- "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/1.\350\247\243\346\236\220\345\221\275\344\273\244\350\241\214\345\217\202\346\225\260/option_parser.json" +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/1.\350\247\243\346\236\220\345\221\275\344\273\244\350\241\214\345\217\202\346\225\260/option_parser.json" @@ -1,20 +1,8 @@ { - "multiline": [ - { - "dest=\"host\"": "dest=\"h\"" - }, - { - "dest=\"port\"": "dest=\"p\"" - }, - { - "action=\"store_true\"": "action=\"store_false\"" - }, - { - "\"-s\", \"--server\"": "\"-s\"" - } - ], - "source": "option_parser.py", + "source": "option_parser.md", "depends": [], "exercise_id": 184, - "type": "code_options" + "type": "code_options", + "author": "huanhuilong", + "notebook_enable": true } \ No newline at end of file diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/1.\350\247\243\346\236\220\345\221\275\344\273\244\350\241\214\345\217\202\346\225\260/option_parser.md" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/1.\350\247\243\346\236\220\345\221\275\344\273\244\350\241\214\345\217\202\346\225\260/option_parser.md" new file mode 100644 index 0000000..6a7509a --- /dev/null +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/1.\350\247\243\346\236\220\345\221\275\344\273\244\350\241\214\345\217\202\346\225\260/option_parser.md" @@ -0,0 +1,212 @@ +# Python 命令行解析 + +使用 optparse 库配置指定命令行选项,并解析命令行 +1. 选项 '-s' 和选项 '--server' 等价 +2. 选项 '--host' 设置默认为 0.0.0.0 +3. 选项 '--port' 设置默认为 80 +4. 选项 '--ssl' 如果指定,则 option.ssl=True + +```python +# -*- coding: UTF-8 -*- +from ast import parse +from optparse import OptionParser + +if __name__ == "__main__": + parser = OptionParser() + + # TODO(You): 请在此添加上述要求的4个命令行参数选项配置 + + (options, args) = parser.parse_args() + print(f"server={options.server}") + print(f"host={options.host}") + print(f"port={options.port}") + print(f"ssl={options.ssl}") +``` + +请选出下列能**正确**实现这一功能的选项。 + +## template + +```python +from ast import parse +from optparse import OptionParser + +if __name__ == "__main__": + parser = OptionParser() + + parser.add_option( + "-s", "--server", + dest="server", + help="server", + metavar="SERVER" + ) + + parser.add_option( + "-h", "--host", + dest="host", + help="host", + default='0.0.0.0', + metavar="HOST" + ) + + parser.add_option( + '-p', "--port", + dest="port", + help="port", + default='80', + metavar="PORT" + ) + + parser.add_option( + "--ssl", + dest="ssl", + help="ssl", + action="store_true", + metavar="SSL" + ) + (options, args) = parser.parse_args() + print(f"server={options.server}") + print(f"host={options.host}") + print(f"port={options.port}") + print(f"ssl={options.ssl}") +``` + +## 答案 + +```python +parser.add_option( + "-s", "--server", + dest="server", + help="server", + metavar="SERVER" +) + +parser.add_option( + "-h", "--host", + dest="host", + help="host", + default='0.0.0.0', + metavar="HOST" +) + +parser.add_option( + '-p', "--port", + dest="port", + help="port", + default='80', + metavar="PORT" +) + +parser.add_option( + "--ssl", + dest="ssl", + help="ssl", + action="store_true", + metavar="SSL" +) +``` + +## 选项 + +### A + +```python +parser.add_option( + "-s", "--server", + dest="server", + help="server", + metavar="SERVER" +) + +parser.add_option( + "-h", "--host", + dest="host", + help="host", + metavar="HOST" +) + +parser.add_option( + '-p', "--port", + dest="port", + help="port", + default='80', + metavar="PORT" +) + +parser.add_option( + "--ssl", + dest="ssl", + help="ssl", + action="store_true", + metavar="SSL" +) +``` + +### B + +```python +parser.add_option( + "--server", + dest="server", + help="server", + metavar="SERVER" +) + +parser.add_option( + "-h", "--host", + dest="host", + help="host", + default='0.0.0.0', + metavar="HOST" +) + +parser.add_option( + '-p', "--port", + dest="port", + help="port", + default='80', + metavar="PORT" +) + +parser.add_option( + "--ssl", + dest="ssl", + help="ssl", + action="store_true", + metavar="SSL" +) +``` + +### C + +```python +parser.add_option( + "-s", "--server", + dest="server", + help="server", + metavar="SERVER" +) + +parser.add_option( + "-h", "--host", + dest="host", + help="host", + default='0.0.0.0', + metavar="HOST" +) + +parser.add_option( + '-p', "--port", + dest="port", + help="port", + default='80', + metavar="PORT" +) + +parser.add_option( + "--ssl", + dest="ssl", + help="ssl", + metavar="SSL" +) +``` diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/1.\350\247\243\346\236\220\345\221\275\344\273\244\350\241\214\345\217\202\346\225\260/sys_argv.json" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/1.\350\247\243\346\236\220\345\221\275\344\273\244\350\241\214\345\217\202\346\225\260/sys_argv.json" index 9846d06..6e7ede7 100644 --- "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/1.\350\247\243\346\236\220\345\221\275\344\273\244\350\241\214\345\217\202\346\225\260/sys_argv.json" +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/1.\350\247\243\346\236\220\345\221\275\344\273\244\350\241\214\345\217\202\346\225\260/sys_argv.json" @@ -1,25 +1,8 @@ { - "multiline": [ - { - "i = i + 1": "" - }, - { - "if i+1 < count:": "", - " next_token = sys.argv[i+1]": "next_token = sys.argv[i+1]", - " i = i + 1": "i = i + 1" - }, - { - "if token[1] != '-':": "if token[1] == '-':" - }, - { - "return token[1:]": "return token" - }, - { - "return token[2:]": "return token[1:]" - } - ], - "source": "sys_argv.py", + "source": "sys_argv.md", "depends": [], "exercise_id": 183, - "type": "code_options" + "type": "code_options", + "author": "huanhuilong", + "notebook_enable": true } \ No newline at end of file diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/1.\350\247\243\346\236\220\345\221\275\344\273\244\350\241\214\345\217\202\346\225\260/sys_argv.md" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/1.\350\247\243\346\236\220\345\221\275\344\273\244\350\241\214\345\217\202\346\225\260/sys_argv.md" new file mode 100644 index 0000000..1892639 --- /dev/null +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/1.\350\247\243\346\236\220\345\221\275\344\273\244\350\241\214\345\217\202\346\225\260/sys_argv.md" @@ -0,0 +1,174 @@ +# Python 命令行解析 + +手工编写 Python 命令行解析,支持 '-x' 或者 '--x' 类型选项处理,如果没有指定值则设置为True + +```python +# -*- coding: UTF-8 -*- +import sys + +def error(info): + print(info) + sys.exit(0) + +def parse_option(token): + if len(token) == 0 or len(token) == 1 or token[0] != '-': + error("格式错误,选项长度至少大于2并且第一个字符必须是 '-'") + + if token[1] != '-': + return token[1:] + + if len(token) == 2 or token[2] == '-': + error("格式错误,不支持空选项 '--' 或则三横杆选项 '---x' ") + + return token[2:] + +def parse_value(token): + if token is None: + return True + + if len(token) == 0: + return True + + if token[0] == '-': + error('格式错误') + else: + return token + +if __name__ == '__main__': + count = len(sys.argv) + options = {} + + # TODO(You): 请在此使用 parse_option 和 parse_value 解析命令行 + + for option in options: + value = options[option] + print("{}={}".format(option, value)) +``` + +请选出下列能**正确**实现这一功能的选项。 + +## template + +```python + +import sys + +def error(info): + print(info) + sys.exit(0) + +def parse_option(token): + if len(token) == 0 or len(token) == 1 or token[0] != '-': + error("格式错误,选项长度至少大于2并且第一个字符必须是 '-'") + + if token[1] != '-': + return token[1:] + + if len(token) == 2 or token[2] == '-': + error("格式错误,不支持空选项 '--' 或则三横杆选项 '---x' ") + + return token[2:] + + +def parse_value(token): + if token is None: + return True + + if len(token) == 0: + return True + + if token[0] == '-': + error('格式错误') + else: + return token + + +if __name__ == '__main__': + count = len(sys.argv) + options = {} + i = 1 + while i < count: + token = sys.argv[i] + next_token = None + if i+1 < count: + next_token = sys.argv[i+1] + i = i + 1 + option = parse_option(token) + value = parse_value(next_token) + options[option] = value + i += 1 + for option in options: + value = options[option] + print("{}={}".format(option, value)) +``` + +## 答案 + +```python +i = 1 +while i < count: + token = sys.argv[i] + next_token = None + if i+1 < count: + next_token = sys.argv[i+1] + i = i + 1 + + option = parse_option(token) + value = parse_value(next_token) + + options[option] = value + i += 1 +``` + +## 选项 + +### A + +```python +i = 1 +while i < count: + token = sys.argv[i] + next_token = None + if i+1 < count: + next_token = sys.argv[i+1] + + option = parse_option(token) + value = parse_value(next_token) + + options[option] = value + i += 1 +``` + +### B + +```python +i = 1 +while i < count: + token = sys.argv[i] + next_token = None + if i+1 < count: + next_token = sys.argv[i+1] + i = i + 1 + + option = parse_option(token) + value = parse_value(next_token) + + options[option] = value +``` + +### C + +```python +i = 1 +while i < count: + token = sys.argv[i] + next_token = None + if i+1 < count: + next_token = sys.argv[i+1] + + option = parse_value(token) + value = parse_option(next_token) + + options[option] = value + i += 1 +``` diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/2.\346\227\266\351\227\264\346\227\245\346\234\237\345\244\204\347\220\206/date.json" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/2.\346\227\266\351\227\264\346\227\245\346\234\237\345\244\204\347\220\206/date.json" index 64dd9dd..2d794af 100644 --- "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/2.\346\227\266\351\227\264\346\227\245\346\234\237\345\244\204\347\220\206/date.json" +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/2.\346\227\266\351\227\264\346\227\245\346\234\237\345\244\204\347\220\206/date.json" @@ -1,18 +1,8 @@ { - "multiline": [ - { - "datetime.now()": "date.now()" - }, - { - "timedelta(days=-1)": "timedelta(days=1)", - "timedelta(days=1)": "timedelta(days=-1)" - }, - { - "strftime": "format" - } - ], - "source": "date.py", + "source": "date.md", "depends": [], "exercise_id": 6, - "type": "code_options" + "type": "code_options", + "author": "huanhuilong", + "notebook_enable": true } \ No newline at end of file diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/2.\346\227\266\351\227\264\346\227\245\346\234\237\345\244\204\347\220\206/date.md" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/2.\346\227\266\351\227\264\346\227\245\346\234\237\345\244\204\347\220\206/date.md" new file mode 100644 index 0000000..9ef14fd --- /dev/null +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/2.\346\227\266\351\227\264\346\227\245\346\234\237\345\244\204\347\220\206/date.md" @@ -0,0 +1,70 @@ +# Python 时间日期 + +常用日期时间处理 + +```python +# -*- coding: UTF-8 -*- +from datetime import datetime, timedelta + +if __name__ == '__main__': + today = datetime.now() + print(today) + print(today.strftime("%d/%m/%y")) + print(today.strftime("%A %d %B %Y")) + + # TODO(You): 请在此计算昨天和明天日期 + + print(yesterday) + print(nextday) +``` + +请选出下列实现,**不正确** 的选项。 + +## template + +```python +from datetime import datetime, timedelta + + +if __name__ == '__main__': + today = datetime.now() + print(today) + print(today.strftime("%d/%m/%y")) + print(today.strftime("%A %d %B %Y")) + + yesterday = today + timedelta(days=-1) + nextday = today + timedelta(days=1) + + print(yesterday) + print(nextday) +``` + +## 答案 + +```python +yesterday = today + timedelta(weeks=0,days=1) +nextday = today + timedelta(weeks=0,days=-1) +``` + +## 选项 + +### A + +```python +yesterday = today + timedelta(days=-1) +nextday = today + timedelta(days=1) +``` + +### B + +```python +yesterday = today + timedelta(weeks=0,days=-1) +nextday = today + timedelta(weeks=0,days=1) +``` + +### C + +```python +yesterday = today - timedelta(days=1) +nextday = today - timedelta(days=-1) +``` diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/2.\346\227\266\351\227\264\346\227\245\346\234\237\345\244\204\347\220\206/for_each_month.json" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/2.\346\227\266\351\227\264\346\227\245\346\234\237\345\244\204\347\220\206/for_each_month.json" index 91efe83..ea05fd3 100644 --- "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/2.\346\227\266\351\227\264\346\227\245\346\234\237\345\244\204\347\220\206/for_each_month.json" +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/2.\346\227\266\351\227\264\346\227\245\346\234\237\345\244\204\347\220\206/for_each_month.json" @@ -1,20 +1,8 @@ { - "one_line": { - "start < finish": [ - "start > finish" - ], - "d.month)[1]": [ - "d.month)[0]" - ], - "d+timedelta": [ - "d-timedelta" - ], - "timedelta(calendar.monthrange(d.year, d.month)[1])": [ - "timedelta(31)" - ] - }, - "source": "for_each_month.py", + "source": "for_each_month.md", "depends": [], "exercise_id": 5, - "type": "code_options" + "type": "code_options", + "author": "huanhuilong", + "notebook_enable": true } \ No newline at end of file diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/2.\346\227\266\351\227\264\346\227\245\346\234\237\345\244\204\347\220\206/for_each_month.md" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/2.\346\227\266\351\227\264\346\227\245\346\234\237\345\244\204\347\220\206/for_each_month.md" new file mode 100644 index 0000000..7578acd --- /dev/null +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/2.\346\227\266\351\227\264\346\227\245\346\234\237\345\244\204\347\220\206/for_each_month.md" @@ -0,0 +1,86 @@ +# Python 时间加法 + +从2008年1月开始到本月,遍历每一个月份的1号,并打印信息 + +```python +# -*- coding: UTF-8 -*- +from datetime import date, timedelta +from calendar import monthrange + +def next_month(d): + # TODO(You): 请在此实现计算下一个月的代码 + return value + +def for_each_month(start, finish, action): + while start < finish: + action(start) + start = next_month(start) + +if __name__ == '__main__': + for_each_month( + date(2008, 1, 1), + date.today(), + lambda d: print(d) + ) +``` + +请选出以下实现 **错误** 的代码。 + +## template + +```python +from datetime import date, timedelta +import calendar + +def next_month(d): + return d+timedelta(calendar.monthrange(d.year, d.month)[1]) + +def for_each_month(start, finish, action): + while start < finish: + action(start) + start = next_month(start) + + +def test(): + for_each_month( + date(2008, 1, 1), + date.today(), + lambda d: print(d) + ) + +if __name__ == '__main__': + test() +``` + +## 答案 + +```python +offset = monthrange(d.year, d.month) +days_in_month, first_weeky_day = offset +value = d+timedelta(days_in_month) +``` + +## 选项 + +### A + +```python +offset = monthrange(d.year, d.month) +first_weeky_day, days_in_month = offset +value = d+timedelta(days_in_month) +``` + +### B + +```python +days_in_month = monthrange(d.year, d.month)[1] +value = d+timedelta(days_in_month) +``` + +### C + +```python +offset = monthrange(d.year, d.month) +days_in_month = offset[1] +value = d+timedelta(days_in_month) +``` diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/2.\346\227\266\351\227\264\346\227\245\346\234\237\345\244\204\347\220\206/time_span.json" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/2.\346\227\266\351\227\264\346\227\245\346\234\237\345\244\204\347\220\206/time_span.json" index 442137f..6b9e44b 100644 --- "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/2.\346\227\266\351\227\264\346\227\245\346\234\237\345\244\204\347\220\206/time_span.json" +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/2.\346\227\266\351\227\264\346\227\245\346\234\237\345\244\204\347\220\206/time_span.json" @@ -1,17 +1,8 @@ { - "multiline": [ - { - "time.time() * 1000": "time.time()" - }, - { - "毫秒": "微秒" - }, - { - "round(time.time() * 1000)": "time.time() * 1000" - } - ], - "source": "time_span.py", + "source": "time_span.md", "depends": [], "exercise_id": 4, - "type": "code_options" + "type": "code_options", + "author": "huanhuilong", + "notebook_enable": true } \ No newline at end of file diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/2.\346\227\266\351\227\264\346\227\245\346\234\237\345\244\204\347\220\206/time_span.md" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/2.\346\227\266\351\227\264\346\227\245\346\234\237\345\244\204\347\220\206/time_span.md" new file mode 100644 index 0000000..1f18057 --- /dev/null +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/2.\346\227\266\351\227\264\346\227\245\346\234\237\345\244\204\347\220\206/time_span.md" @@ -0,0 +1,90 @@ +# Python 计时器 + +便利的 Python 计时器,统计从 0 遍历到 100000 消耗的时间,精确到毫秒 + +```python +# -*- coding: UTF-8 -*- +from datetime import datetime +from time import time, mktime + +class TimeSpan: + def __init__(self) -> None: + self.start = round(time() * 1000) + + def elapse_mill_secs(self): + # TODO(You): 请在此计算从开始到现在的耗时,精确到毫秒 + + def elapse_secs(self): + return (self.elapse_mill_secs())/1000 + +if __name__ == '__main__': + s = TimeSpan() + + for i in range(0, 100000): + pass + print('耗时: {} 毫秒'.format(s.elapse_mill_secs())) + print('耗时: {} 秒'.format(s.elapse_secs())) +``` + +以下实现,**错误** 的是?。 + +## template + +```python +import time + +class TimeSpan: + def __init__(self) -> None: + self.start = round(time.time() * 1000) + + def elapse_mill_secs(self): + end = round(time.time() * 1000) + return end-self.start + + def elapse_secs(self): + end = round(time.time() * 1000) + return (end-self.start)/1000 + + +if __name__ == '__main__': + s = TimeSpan() + + for i in range(0, 100000): + pass + print('耗时: {} 毫秒'.format(s.elapse_mill_secs())) + print('耗时: {} 秒'.format(s.elapse_secs())) +``` + +## 答案 + +```python +def elapse_mill_secs(self): + end = round(time(datetime.now())*1000) + return end-self.start +``` + +## 选项 + +### A + +```python +def elapse_mill_secs(self): + end = round(time() * 1000) + return end-self.start +``` + +### B + +```python +def elapse_mill_secs(self): + end = round(mktime(datetime.now().timetuple())*1000) + return end-self.start +``` + +### C + +```python +def elapse_mill_secs(self): + end = round(datetime.now().timestamp() * 1000) + return end-self.start +``` diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/copy.json" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/copy.json" index f12962c..cf5a15e 100644 --- "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/copy.json" +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/copy.json" @@ -1,17 +1,8 @@ { - "one_line": { - "\"copy.py\", \"/tmp/copy.py\"": [ - "\"/tmp/copy.py\", \"copy.py\"" - ], - "\"copy.py\", \"/tmp/copy2.py\"": [ - "\"/tmp/copy2.py\", \"copy.py\"" - ], - "dirs_exist_ok=True": [ - "dirs_exist_ok=False" - ] - }, - "source": "copy.py", + "source": "copy.md", "depends": [], "exercise_id": 18, - "type": "code_options" + "type": "code_options", + "author": "huanhuilong", + "notebook_enable": true } \ No newline at end of file diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/copy.md" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/copy.md" new file mode 100644 index 0000000..39ea137 --- /dev/null +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/copy.md" @@ -0,0 +1,131 @@ +# Python 文件夹拷贝 + +实现文件夹拷贝,要求如下: + +1. 使用 shutil 拷贝 "copy.py" 文件到 "/tmp/copy.py" +2. 拷贝 "copy.py" 文件到 "/tmp/copy2.py", 保留元数据 +3. 递归拷贝目录 "./" 到 "/tmp/file_test/",如果已存在就覆盖 + +```python +# -*- coding: UTF-8 -*- +import shutil + +def test(): + # TODO(You): 请在此实现代码 + +if __name__ == '__main__': + test() +``` + +请选出下列能**正确**实现这一功能的选项。 + +## template + +```python +import shutil + + +def test(): + # 拷贝文件 + shutil.copy("copy.py", "/tmp/copy.py") + + # 拷贝文件,保持元数据 + shutil.copy2("copy.py", "/tmp/copy2.py") + + # 递归拷贝目录 + shutil.copytree("./", "/tmp/file_test/", dirs_exist_ok=True) + +if __name__ == '__main__': + test() +``` + +## 答案 + +```python +# 拷贝文件 +shutil.copy( + "copy.py", + "/tmp/copy.py" +) + +# 拷贝文件,保持元数据 +shutil.copy2( + "copy.py", + "/tmp/copy2.py" +) + +# 递归拷贝目录 +shutil.copytree( + "./", + "/tmp/file_test/", + dirs_exist_ok=True +) +``` + +## 选项 + +### A + +```python +# 拷贝文件 +shutil.copy( + "/tmp/copy.py", + "copy.py" +) + +# 拷贝文件,保持元数据 +shutil.copy2( + "/tmp/copy2.py", + "copy.py" +) + +# 递归拷贝目录 +shutil.copytree( + "/tmp/file_test/", + "./", + dirs_exist_ok=True +) +``` + +### B + +```python +shutil.copy( + "copy.py", + "/tmp/copy.py" +) + +# 拷贝文件,保持元数据 +shutil.copy( + "copy.py", + "/tmp/copy2.py" +) + +# 递归拷贝目录 +shutil.copytree( + "./", + "/tmp/file_test/", + dirs_exist_ok=True +) +``` + +### C + +```python +shutil.copy( + "copy.py", + "/tmp/copy.py" +) + +# 拷贝文件,保持元数据 +shutil.copy2( + "copy.py", + "/tmp/copy2.py" +) + +# 递归拷贝目录 +shutil.copytree( + "./", + "/tmp/file_test/" +) +``` diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/count_file.json" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/count_file.json" index 09bf268..20a1d45 100644 --- "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/count_file.json" +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/count_file.json" @@ -1,24 +1,8 @@ { - "multiline": [ - { - "blank = False": "" - }, - { - "i += 1": "" - }, - { - "while i < line_len": "while i <= line_len" - }, - { - "if blank:": "", - " line_token_count += 1": "line_token_count += 1" - }, - { - "break": "continue" - } - ], - "source": "count_file.py", + "source": "count_file.md", "depends": [], "exercise_id": 19, - "type": "code_options" + "type": "code_options", + "author": "huanhuilong", + "notebook_enable": true } \ No newline at end of file diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/count_file.md" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/count_file.md" new file mode 100644 index 0000000..46f6ce2 --- /dev/null +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/count_file.md" @@ -0,0 +1,160 @@ +# Python 文件统计 + +统计文件中行数,非空行数,以及空格间隔的token数 + +```python +# -*- coding: UTF-8 -*- +import json + +def count_file(file): + line_count = 0 + non_empty_line_count = 0 + token_count = 0 + + with open(file, 'r') as f: + while True: + # 读取每行 + line = f.readline() + if not line: + break + + line_count += 1 + line_len = len(line) + line_token_count = 0 + + # TODO(You): 请在此实现统计单行token数 + + token_count += line_token_count + if line_token_count > 0: + non_empty_line_count += 1 + + return { + 'file': file, + 'line_count': line_count, + 'line_token_count': token_count, + 'non_empty_line_count': non_empty_line_count + } + +if __name__ == '__main__': + ret = count_file('count_file.py') + print('行数:', ret['line_count']) + print('非空行:', ret['non_empty_line_count']) + print('非空词数:', ret['line_token_count']) + with open('/tmp/count.json', 'w') as f: + f.write(json.dumps(ret, indent=2, ensure_ascii=False)) +``` + +请选出下列能**正确**实现这一功能的选项。 + +## template + +```python +import json + + +def count_file(file): + line_count = 0 + non_empty_line_count = 0 + token_count = 0 + + with open(file, 'r') as f: + while True: + line = f.readline() + if not line: + break + line_count += 1 + + line_len = len(line) + i = 0 + blank = True + line_token_count = 0 + while i < line_len: + char = line[i] + if char in [' ', '\t', '\b']: + blank = True + else: + if blank: + line_token_count += 1 + blank = False + i += 1 + + token_count += line_token_count + if line_token_count > 0: + non_empty_line_count += 1 + + return { + 'file': file, + 'line_count': line_count, + 'line_token_count': token_count, + 'non_empty_line_count': non_empty_line_count + } + + +if __name__ == '__main__': + ret = count_file('count_file.py') + print('行数:', ret['line_count']) + print('非空行:', ret['non_empty_line_count']) + print('非空词数:', ret['line_token_count']) + with open('/tmp/count.json', 'w') as f: + f.write(json.dumps(ret, indent=2, ensure_ascii=False)) +``` + +## 答案 + +```python +blank = False +for char in line: + if char in [' ', '\t', '\b']: + blank = True + else: + if blank: + line_token_count += 1 + blank = False +``` + +## 选项 + +### A + +```python +blank = True +i = 0 +while i < line_len: + char = line[i] + if char in [' ', '\t', '\b']: + blank = True + else: + if blank: + line_token_count += 1 + blank = False + i += 1 +``` + +### B + +```python +blank = True +i = 0 +while i < line_len: + char = line[i] + if char in [' ', '\t', '\b', '\n']: + if not blank: + line_token_count += 1 + blank = True + else: + blank = False + i += 1 +``` + +### C + +```python +blank = True +for char in line: + if char in [' ', '\t', '\b', '\n']: + if not blank: + line_token_count += 1 + blank = True + else: + blank = False +``` diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/dir.json" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/dir.json" index 33274a8..8c44fb8 100644 --- "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/dir.json" +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/dir.json" @@ -1,14 +1,8 @@ { - "one_line": { - "makedirs": [ - "mkdir" - ], - "exist_ok=True": [ - "exist_ok=False" - ] - }, - "source": "dir.py", + "source": "dir.md", "depends": [], "exercise_id": 16, - "type": "code_options" + "type": "code_options", + "author": "huanhuilong", + "notebook_enable": true } \ No newline at end of file diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/dir.md" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/dir.md" new file mode 100644 index 0000000..458c24e --- /dev/null +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/dir.md" @@ -0,0 +1,57 @@ +# Python 创建文件夹 + +使用 os 递归创建文件夹,已存在就覆盖 + +```python +# -*- coding: UTF-8 -*- +import os +if __name__ == '__main__': + # TODO(You): 请在此实现代码 +``` + +请选出下列能**正确**实现这一功能的选项。 + +## template + +```python +import os +if __name__ == '__main__': + os.makedirs("/tmp/test/test/test/", exist_ok=True) +``` + +## 答案 + +```python +os.makedirs( + "/tmp/test/test/test/", + exist_ok=True +) +``` + +## 选项 + +### A + +```python +os.makedirs( + "/tmp/test/test/test/" +) +``` + +### B + +```python +os.makedir( + "/tmp/test/test/test/", + exist_ok=True +) +``` + +### C + +```python +os.makedirs( + "/tmp/test/test/test/", + True +) +``` diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/list_file_in_dir.json" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/list_file_in_dir.json" index 8c251ee..6d85edd 100644 --- "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/list_file_in_dir.json" +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/list_file_in_dir.json" @@ -1,14 +1,8 @@ { - "one_line": { - "ordered_list_dir('./')": [ - "os.listdir('./')" - ], - "entries.sort()": [ - "" - ] - }, - "source": "list_file_in_dir.py", + "source": "list_file_in_dir.md", "depends": [], "exercise_id": 17, - "type": "code_options" + "type": "code_options", + "author": "huanhuilong", + "notebook_enable": true } \ No newline at end of file diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/list_file_in_dir.md" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/list_file_in_dir.md" new file mode 100644 index 0000000..ea49568 --- /dev/null +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/list_file_in_dir.md" @@ -0,0 +1,72 @@ +# Python 文件遍历(1) + +稳定排序地遍历一个文件下的文件 + +```python +# -*- coding: UTF-8 -*- +import os + +def ordered_list_dir(dir): + # TODO(You): 请在此实现代码 + return entries + +if __name__ == '__main__': + entries = ordered_list_dir('./') + for entry in entries: + print(entry) +``` + +请选出下列能**正确**实现这一功能的选项。 + +## template + +```python +import os + + +def ordered_list_dir(dir): + entries = os.listdir(dir) + entries.sort() + return entries + +if __name__ == '__main__': + entries = ordered_list_dir('./') + for entry in entries: + print(entry) +``` + +## 答案 + +```python +def ordered_list_dir(dir): + entries = os.listdir(dir) + entries.sort() + return entries +``` + +## 选项 + +### A + +```python +def ordered_list_dir(dir): + entries = os.listdir(dir) + return entries +``` + +### B + +```python +def ordered_list_dir(dir): + entries = os.listdir(dir) + return entries.sort() +``` + +### C + +```python +def ordered_list_dir(dir): + entries = os.path.listdir(dir) + entries.sort() + return entries +``` diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/walk_dir.json" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/walk_dir.json" index 2131e65..fff9809 100644 --- "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/walk_dir.json" +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/walk_dir.json" @@ -1,18 +1,8 @@ { - "multiline": [ - { - "file_paths.append(file_path)": "", - "file_path = os.path.join(root, file_name)": "file_paths.append(file_path)" - }, - { - "files": "directories" - }, - { - "os.walk(abs_dir_name)": "os.walk(dir_name)" - } - ], - "source": "walk_dir.py", + "source": "walk_dir.md", "depends": [], "exercise_id": 21, - "type": "code_options" + "type": "code_options", + "author": "huanhuilong", + "notebook_enable": true } \ No newline at end of file diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/walk_dir.md" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/walk_dir.md" new file mode 100644 index 0000000..8cd21ff --- /dev/null +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/walk_dir.md" @@ -0,0 +1,87 @@ +# Python 文件遍历(2) + +遍历一个文件夹下的所有子文件夹,并返回所有'config.json'文件的绝对路径列表 + +```python +# -*- coding: UTF-8 -*- +import os + +def retrieve_file_paths(dir_name): + file_paths = [] + abs_dir_name = os.path.abspath(dir_name) + + # TODO(You): 请在此实现遍历代码 + + return file_paths + +if __name__ == '__main__': + file_paths = retrieve_file_paths('./') + print(file_paths) +``` + +以下实现,**错误**的代码是? + +## template + +```python +import os + + +def retrieve_file_paths(dir_name): + file_paths = [] + abs_dir_name = os.path.abspath(dir_name) + for root, directories, files in os.walk(abs_dir_name): + for file_name in files: + file_path = os.path.join(root, file_name) + file_paths.append(file_path) + return file_paths + +if __name__ == '__main__': + file_paths = retrieve_file_paths('./') + print(file_paths) +``` + +## 答案 + +```python +for base, dirs, files in os.walk(abs_dir_name): + for dir in dirs: + cfg_file = os.path.join(base, dir, 'config.json') + if os.path.exists(cfg_file): + file_paths.append(cfg_file) +``` + +## 选项 + +### A + +```python +for base, dirs, files in os.walk(abs_dir_name): + for file_name in files: + if file_name == 'config.json': + file_path = os.path.join(base, file_name) + file_paths.append(file_path) +``` + +### B + +```python +cfg_file = os.path.join(abs_dir_name, 'config.json') +if os.path.exists(cfg_file): + file_paths.append(cfg_file) + +for base, dirs, files in os.walk(abs_dir_name): + for dir in dirs: + cfg_file = os.path.join(base, dir, 'config.json') + if os.path.exists(cfg_file): + file_paths.append(cfg_file) +``` + +### C + +```python +for base, dirs, files in os.walk(abs_dir_name): + cfg_file = os.path.join(base, 'config.json') + if os.path.exists(cfg_file): + file_paths.append(cfg_file) +``` diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/zip_with_progress.json" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/zip_with_progress.json" index 7d45c84..f6a5e5b 100644 --- "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/zip_with_progress.json" +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/zip_with_progress.json" @@ -1,23 +1,8 @@ { - "one_line": { - "nonlocal bar, total_files": [ - "bar, total_files" - ], - "if bar is not None": [ - "if bar is None" - ], - "if bar is None": [ - "if bar is not None" - ], - "'zip'": [ - "'tar'" - ], - "logger=logger": [ - "logger=progress" - ] - }, - "source": "zip_with_progress.py", + "source": "zip_with_progress.md", "depends": [], "exercise_id": 20, - "type": "code_options" + "type": "code_options", + "author": "huanhuilong", + "notebook_enable": true } \ No newline at end of file diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/zip_with_progress.md" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/zip_with_progress.md" new file mode 100644 index 0000000..3526507 --- /dev/null +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/3.\346\225\260\346\215\256\346\226\207\344\273\266\350\257\273\345\206\231/zip_with_progress.md" @@ -0,0 +1,138 @@ +# Python 文件夹压缩 + +使用 shutil 对文件夹进行zip压缩,压缩过程显示进度条 + +```python +# -*- coding: UTF-8 -*- +import os +import shutil +import logging +from progress.bar import IncrementalBar +logger = logging.getLogger(__name__) + +def count_files_in_dir(dir): + totalFiles = 0 + for base, dirs, files in os.walk(dir): + totalFiles += len(files) + return totalFiles + +def zip_with_progress(dir_path, zip_file): + bar = None + total_files = count_files_in_dir(dir_path) + + def progress(*args, **kwargs): + # TODO(You): 进度条显示 + + # 调用shutil.make_archive时,临时替换其 logger 参数,用来显示进度条 + old_info = logger.info + logger.info = lambda *args, **kwargs: progress(*args, **kwargs) + shutil.make_archive(dir_path, 'zip', dir_path, logger=logger) + logger.info = old_info + + if bar is not None: + bar.finish() + +if __name__ == '__main__': + zip_with_progress('./', '/tmp/test_file_zip.zip') + print() +``` + +请选出下列能**正确**实现这一功能的选项。 + +## template + +```python +import os +import shutil +import logging +from progress.bar import IncrementalBar +logger = logging.getLogger(__name__) + + +def count_files_in_dir(dir): + totalFiles = 0 + for base, dirs, files in os.walk(dir): + totalFiles += len(files) + return totalFiles + + +def zip_with_progress(dir_path, zip_file): + bar = None + total_files = count_files_in_dir(dir_path) + + def progress(*args, **kwargs): + if not args[0].startswith('adding'): + return + + nonlocal bar, total_files + if bar is None: + print('@开始压缩:{}'.format(zip_file)) + bar = IncrementalBar('正在压缩:', max=total_files) + bar.next(1) + + old_info = logger.info + logger.info = lambda *args, **kwargs: progress(*args, **kwargs) + + shutil.make_archive(dir_path, 'zip', dir_path, logger=logger) + logger.info = old_info + + if bar is not None: + bar.finish() + +if __name__ == '__main__': + zip_with_progress('./', '/tmp/test_file_zip.zip') + print() +``` + +## 答案 + +```python +def progress(*args, **kwargs): + if not args[0].startswith('adding'): + return + + nonlocal bar, total_files + if bar is None: + print('@开始压缩:{}'.format(zip_file)) + bar = IncrementalBar('正在压缩:', max=total_files) + bar.next(1) +``` + +## 选项 + +### A + +```python +def progress(*args, **kwargs): + if not args[0].startswith('adding'): + return + + if bar is None: + print('@开始压缩:{}'.format(zip_file)) + bar = IncrementalBar('正在压缩:', max=total_files) + bar.next(1) +``` + +### B + +```python +def progress(*args, **kwargs): + nonlocal bar, total_files + if bar is None: + print('@开始压缩:{}'.format(zip_file)) + bar = IncrementalBar('正在压缩:', max=total_files) + bar.next(1) +``` + +### C + +```python +def progress(*args, **kwargs): + if not args[0].startswith('adding'): + return + + nonlocal bar, total_files + print('@开始压缩:{}'.format(zip_file)) + bar = IncrementalBar('正在压缩:', max=total_files) + bar.next(1) +``` diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/error_code.json" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/error_code.json" index dfe0693..44e242d 100644 --- "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/error_code.json" +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/error_code.json" @@ -1,17 +1,8 @@ { - "one_line": { - "ErrorCode.internal_ret_2_http(error_code)": [ - "str(error_code)" - ], - "ErrorCode(Enum)": [ - "ErrorCode(object)" - ], - "ret['err'].name.lower()": [ - "ret['err'].name" - ] - }, - "source": "error_code.py", + "source": "error_code.md", "depends": [], "exercise_id": 159, - "type": "code_options" + "type": "code_options", + "author": "huanhuilong", + "notebook_enable": true } \ No newline at end of file diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/error_code.md" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/error_code.md" new file mode 100644 index 0000000..d8e3a85 --- /dev/null +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/error_code.md" @@ -0,0 +1,74 @@ +# 错误码处理 + +编写一个错误码枚举,实现一个 "错误码转换成字符串" 的静态方法: internal_ret_2_http + +```python +# -*- coding: UTF-8 -*- +from enum import Enum + +class ErrorCode(Enum): + SUCCESS = 0 + FAILED = 1 + NOT_FOUND = 2 + ALREADY_EXIST = 3 + INVALID_PARAMETERS = 4 + + @staticmethod + def internal_ret_2_http(ret): + # TODO(You): 请在此实现代码 + +if __name__ == '__main__': + ret = {'err': ErrorCode.NOT_FOUND} + ErrorCode.internal_ret_2_http(ret) + assert ret['err'] == 'not_found' +``` + +请选出下列能**正确**实现这一功能的选项。 + +## template + +```python +from enum import Enum + +class ErrorCode(Enum): + SUCCESS = 0 + FAILED = 1 + NOT_FOUND = 2 + ALREADY_EXIST = 3 + INVALID_PARAMETERS = 4 + + @staticmethod + def internal_ret_2_http(ret): + ret['err'] = ret['err'].name.lower() + +if __name__ == '__main__': + ret = {'err': ErrorCode.NOT_FOUND} + ErrorCode.internal_ret_2_http(ret) + assert ret['err'] == 'not_found' +``` + +## 答案 + +```python +ret['err'] = ret['err'].name.lower() +``` + +## 选项 + +### A + +```python +ret['err'] = ret['err'].name +``` + +### B + +```python +ret['err'] = str(ret['err']).lower() +``` + +### C + +```python +ret['err'] = str(ret['err']) +``` diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/mysql_connection.json" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/mysql_connection.json" index 5c364b1..0f28932 100644 --- "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/mysql_connection.json" +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/mysql_connection.json" @@ -1,20 +1,11 @@ { - "one_line": { - "cursor.fetchall()": [ - "cursor.fetchone()" - ], - "self.conn.commit()": [ - "self.conn.rollback()" - ], - "self.conn.rollback()": [ - "self.conn.commit()" - ] - }, - "source": "mysql_connection.py", + "source": "mysql_connection.md", "depends": [ "error_code.py", "mysql_connector.py" ], "exercise_id": 160, - "type": "code_options" + "type": "code_options", + "author": "huanhuilong", + "notebook_enable": true } \ No newline at end of file diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/mysql_connection.md" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/mysql_connection.md" new file mode 100644 index 0000000..5628022 --- /dev/null +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/mysql_connection.md" @@ -0,0 +1,166 @@ +# Python MySQL Connection + +封装一个 MySQL 连接类,继承自 MySQLConnector,请先完成【Python MySQL Connector】 + +```python +# -*- coding: UTF-8 -*- +import logging +from error_code import ErrorCode +from mysql.connector import Error +from mysql_connector import MySQLConnector +logger = logging.Logger(__name__) +mysql_connection_pool = None + +class MySQLConnection(MySQLConnector): + def __init__(self, host, port, user, password, database) -> None: + super().__init__(host, port, user, password, database) + + def execute(self, sql, args): + # TODO(You): 请在此实现代码 + +if __name__ == '__main__': + kv = MySQLConnection( + "127.0.0.1", 3306, + "root", "WNpx8c\zr!fF", + "test" + ) + + ret = kv.open() + assert ret['err'] == ErrorCode.SUCCESS + + ret = kv.execute("select * from test") + assert ret['err'] == ErrorCode.SUCCESS + ret = kv.close() + assert ret['err'] == ErrorCode.SUCCESS +``` + +请选出下列能**正确**实现 execute 方法的选项。 + +## template + +```python +import logging +from error_code import ErrorCode +from mysql.connector import Error +from mysql_connector import MySQLConnector +logger = logging.Logger(__name__) +mysql_connection_pool = None + + +class MySQLConnection(MySQLConnector): + def __init__(self, host, port, user, password, database) -> None: + super().__init__(host, port, user, password, database) + + def execute(self, sql, args): + cursor = self.conn.cursor() + try: + cursor.execute(sql, args) + results = cursor.fetchall() or [] + self.conn.commit() + return {'err': ErrorCode.SUCCESS, 'results': list(map(lambda t: t[0], results))} + except Error as e: + self.conn.rollback() + logger.error('execute mysql query exception:', str(e)) + return {'err': ErrorCode.DB_QUERY_EXCEPT} + finally: + cursor.close() + + +if __name__ == '__main__': + kv = MySQLConnection( + "127.0.0.1", 3306, + "root", "WNpx8c\zr!fF", + "test" + ) + + ret = kv.open() + assert ret['err'] == ErrorCode.SUCCESS + + ret = kv.execute("select * from test") + assert ret['err'] == ErrorCode.SUCCESS + ret = kv.close() + assert ret['err'] == ErrorCode.SUCCESS +``` + +## 答案 + +```python +class MySQLConnection(MySQLConnector): + ... + def execute(self, sql, args): + cursor = self.conn.cursor() + try: + cursor.execute(sql, args) + results = cursor.fetchall() or [] + self.conn.commit() + return { + 'err': ErrorCode.SUCCESS, + 'results': list(map(lambda t: t[0], results)) + } + except Error as e: + self.conn.rollback() + logger.error('execute mysql query exception:', str(e)) + return {'err': ErrorCode.DB_QUERY_EXCEPT} + finally: + cursor.close() +``` + +## 选项 + +### A + +```python +class MySQLConnection(MySQLConnector): + ... + def execute(self, sql, args): + cursor = self.conn.cursor() + try: + cursor.execute(sql, args) + results = cursor.fetchall() + self.conn.commit() + return { + 'err': ErrorCode.SUCCESS, + 'results': list(map(lambda t: t[0], results)) + } + except Error as e: + self.conn.rollback() + logger.error('execute mysql query exception:', str(e)) + return {'err': ErrorCode.DB_QUERY_EXCEPT} + finally: + cursor.close() +``` + +### B + +```python +class MySQLConnection(MySQLConnector): + ... + def execute(self, sql, args): + cursor = self.conn.cursor() + cursor.execute(sql, args) + results = cursor.fetchall() or [] + self.conn.commit() + return { + 'err': ErrorCode.SUCCESS, + 'results': list(map(lambda t: t[0], results)) + } +``` + +### C + +```python +class MySQLConnection(MySQLConnector): + ... + def execute(self, sql, args): + cursor = self.conn.cursor() + try: + cursor.execute(sql, args) + results = cursor.fetchall() or [] + return { + 'err': ErrorCode.SUCCESS, + 'results': list(map(lambda t: t[0], results)) + } + except Error as e: + logger.error('execute mysql query exception:', str(e)) + return {'err': ErrorCode.DB_QUERY_EXCEPT} +``` diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/mysql_connector.json" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/mysql_connector.json" index 0daae20..04885ed 100644 --- "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/mysql_connector.json" +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/mysql_connector.json" @@ -1,19 +1,10 @@ { - "one_line": { - "global mysql_connection_pool": [ - "mysql_connection_pool" - ], - "self.conn.is_connected()": [ - "not self.conn.is_connected()" - ], - "get_connection": [ - "create_connection" - ] - }, - "source": "mysql_connector.py", + "source": "mysql_connector.md", "depends": [ "error_code.py" ], "exercise_id": 155, - "type": "code_options" + "type": "code_options", + "author": "huanhuilong", + "notebook_enable": true } \ No newline at end of file diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/mysql_connector.md" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/mysql_connector.md" new file mode 100644 index 0000000..120f355 --- /dev/null +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/mysql_connector.md" @@ -0,0 +1,197 @@ +# Python MySQL Connector + +封装一个 MySQL 的连接器,支持 open/close + +```python +# -*- coding: UTF-8 -*- +import logging +from error_code import ErrorCode +from mysql.connector import pooling +from mysql.connector import Error +logger = logging.Logger(__name__) +mysql_connection_pool = None + +class MySQLConnector(): + def __init__(self, host, port, user, password, database) -> None: + global mysql_connection_pool + if mysql_connection_pool is None: + mysql_connection_pool = pooling.MySQLConnectionPool( + pool_name="some_pool_name", + pool_size=10, + pool_reset_session=True, + host=host, + port=port, + database=database, + user=user, + password=password + ) + + self.conn = None + + def open(self): + # TODO(You): 请在此实现代码 + + def close(self): + if self.conn is not None: + if self.conn.is_connected(): + self.conn.close() + self.conn = None + return {'err': ErrorCode.SUCCESS} + +if __name__ == '__main__': + kv = MySQLConnector( + "127.0.0.1", 3306, + "root", "WNpx8c\zr!fF", + "test" + ) + + ret = kv.open() + if ret['err'] == ErrorCode.SUCCESS: + print("数据库打开成功") + kv.close() +``` + +请选出下列对 open 实现**正确**的是? + +## template + +```python +import logging +from error_code import ErrorCode +from mysql.connector import pooling +from mysql.connector import Error +logger = logging.Logger(__name__) +mysql_connection_pool = None + +class MySQLConnector(): + def __init__(self, host, port, user, password, database) -> None: + global mysql_connection_pool + if mysql_connection_pool is None: + mysql_connection_pool = pooling.MySQLConnectionPool( + pool_name="some_pool_name", + pool_size=10, + pool_reset_session=True, + host=host, + port=port, + database=database, + user=user, + password=password + ) + + self.conn = None + + def open(self): + try: + self.conn = mysql_connection_pool.get_connection() + if self.conn.is_connected(): + db_Info = self.conn.get_server_info() + print("db info: ", db_Info) + return {"err": ErrorCode.SUCCESS} + else: + self.conn = None + logger.error('open mysql connection failed, can not connect:') + return {"err": ErrorCode.DB_OPEN_FAILED} + except Error as e: + logger.error('open mysql connection exception:', str(e)) + self.close() + return {"err": ErrorCode.DB_OPEN_FAILED} + + def close(self): + if self.conn is not None: + if self.conn.is_connected(): + self.conn.close() + self.conn = None + return {'err': ErrorCode.SUCCESS} + + +if __name__ == '__main__': + kv = MySQLConnector( + "127.0.0.1", 3306, + "root", "WNpx8c\zr!fF", + "test" + ) + + ret = kv.open() + if ret['err'] == ErrorCode.SUCCESS: + print("数据库打开成功") + kv.close() +``` + +## 答案 + +```python +class MySQLConnector(): + ... + def open(self): + try: + self.conn = mysql_connection_pool.get_connection() + if self.conn.is_connected(): + db_Info = self.conn.get_server_info() + print("db info: ", db_Info) + return {"err": ErrorCode.SUCCESS} + else: + self.conn = None + logger.error('open mysql connection failed, can not connect:') + return {"err": ErrorCode.DB_OPEN_FAILED} + except Error as e: + logger.error('open mysql connection exception:', str(e)) + self.close() + return {"err": ErrorCode.DB_OPEN_FAILED} +``` + +## 选项 + +### A + +```python +class MySQLConnector(): + ... + def open(self): + self.conn = mysql_connection_pool.get_connection() + if self.conn.is_connected(): + db_Info = self.conn.get_server_info() + print("db info: ", db_Info) + return {"err": ErrorCode.SUCCESS} + else: + self.conn = None + logger.error('open mysql connection failed, can not connect:') + return {"err": ErrorCode.DB_OPEN_FAILED} +``` + +### B + +```python +class MySQLConnector(): + ... + def open(self): + try: + self.conn = mysql_connection_pool.get_connection() + db_Info = self.conn.get_server_info() + print("db info: ", db_Info) + return {"err": ErrorCode.SUCCESS} + except Error as e: + logger.error('open mysql connection exception:', str(e)) + self.close() + return {"err": ErrorCode.DB_OPEN_FAILED} +``` + +### C + +```python +class MySQLConnector(): + ... + def open(self): + try: + self.conn = mysql_connection_pool.get_connection() + if self.conn.is_connected(): + db_Info = self.conn.get_server_info() + print("db info: ", db_Info) + return {"err": ErrorCode.SUCCESS} + else: + self.conn = None + logger.error('open mysql connection failed, can not connect:') + return {"err": ErrorCode.DB_OPEN_FAILED} + except Error as e: + logger.error('open mysql connection exception:', str(e)) + return {"err": ErrorCode.DB_OPEN_FAILED} +``` diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/mysql_install.json" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/mysql_install.json" index 0b17c17..31aca6a 100644 --- "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/mysql_install.json" +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/mysql_install.json" @@ -1,22 +1,10 @@ { - "one_line": { - "-P 3306": [ - "-p 3306" - ], - "-p": [ - "-p 123456" - ], - "_key varchar(32)": [ - "key varchar(32)" - ], - "pip install": [ - "python install" - ] - }, - "source": "mysql_install.py", + "source": "mysql_install.md", "depends": [ "error_code.py" ], "exercise_id": 158, - "type": "code_options" + "type": "code_options", + "author": "huanhuilong", + "notebook_enable": true } \ No newline at end of file diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/mysql_install.md" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/mysql_install.md" new file mode 100644 index 0000000..5183087 --- /dev/null +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/mysql_install.md" @@ -0,0 +1,134 @@ +# Python MySQL 安装说明 + +本机测试需要先安装 mysql,假设密码是123456,请勿在命令行下直接输入密码。下面的代码输出的信息有: + +1. 安装 MySQL +2. 启动 MySQL +3. 登录数据库 +4. 创建一个 test 数据库,创建一个 key_value 表,包含 key 和 value 两个字段。 + +```python +# -*- coding: UTF-8 -*- +def dump_depends(depends): + print() + print("# 依赖配置") + for i in range(0, len(depends)): + print("{}. {}".format(i, depends[i])) + + +if __name__ == '__main__': + + # TODO(You): 请编写 db 和 login_commands 两个变量 + db = ... + login_commands = ... + + dump_depends([ + '安装 MySQL : https://dev.mysql.com/downloads/installer/' + '启动 MySQL 本地服务: 每个平台不同', + f'登录数据库:{login_commands}', + f'请创建初始化数据库:\n{db}', + 'Python 库安装: pip install mysql-connector-python', + ]) +``` + +以下对 db 和 login_commands 变量赋值**正确**的是? + +## template + +```python + +def dump_depends(depends): + print() + print("# 依赖配置") + for i in range(0, len(depends)): + print("{}. {}".format(i, depends[i])) + + +if __name__ == '__main__': + + db = ''' + create database test; + use test; + create table if not exists key_value ( + _key varchar(32) not NULL, + value text not NULL, + PRIMARY KEY (`_key`) + )ENGINE=InnoDB DEFAULT CHARSET=utf8; + ''' + + login_commands = 'mysql -h 127.0.0.1 -P 3306 -u root -p' + + dump_depends([ + '安装 MySQL : https://dev.mysql.com/downloads/installer/' + '启动 MySQL 本地服务: 每个平台不同', + f'登录数据库:{login_commands}', + f'请创建初始化数据库:\n{db}', + 'Python 库安装: pip install mysql-connector-python', + ]) +``` + +## 答案 + +```python +db = ''' +create database test; +use test; +create table if not exists key_value ( + _key varchar(32) not NULL, + value text not NULL, + PRIMARY KEY (`_key`) +)ENGINE=InnoDB DEFAULT CHARSET=utf8; +''' + +login_commands = 'mysql -h 127.0.0.1 -P 3306 -u root -p' +``` + +## 选项 + +### A + +```python +db = ''' +create database test; +use test; +create table if not exists key_value ( + key varchar(32) not NULL, + value text not NULL, + PRIMARY KEY (`key`) +)ENGINE=InnoDB DEFAULT CHARSET=utf8; +''' + +login_commands = 'mysql -h 127.0.0.1 -P 3306 -u root -p' +``` + +### B + +```python +db = ''' +create database test; +use test; +create table if not exists key_value ( + _key varchar(32) not NULL, + value text not NULL, + PRIMARY KEY (`_key`) +)ENGINE=InnoDB DEFAULT CHARSET=utf8; +''' + +login_commands = 'mysql -h 127.0.0.1 -p 3306 -u root' +``` + +### C + +```python +db = ''' +create database test; +use test; +create table if not exists key_value ( + key varchar(32) not NULL, + value text not NULL, + PRIMARY KEY (`key`) +)ENGINE=InnoDB DEFAULT CHARSET=utf8; +''' + +login_commands = 'mysql -h 127.0.0.1 -P 3306 -u root -p123456' +``` diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/mysql_kv.json" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/mysql_kv.json" index 904275b..6591cc1 100644 --- "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/mysql_kv.json" +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/mysql_kv.json" @@ -1,21 +1,12 @@ { - "one_line": { - "self.execute(sql, (key,))": [ - "self.execute(sql, (key))" - ], - "if len(results) == 0": [ - "if len(results) != 0" - ], - "json.loads(results[0])": [ - "results[0]" - ] - }, - "source": "mysql_kv.py", + "source": "mysql_kv.md", "depends": [ "error_code.py", "mysql_connector.py", "mysql_connection.py" ], "exercise_id": 24, - "type": "code_options" + "type": "code_options", + "author": "huanhuilong", + "notebook_enable": true } \ No newline at end of file diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/mysql_kv.md" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/mysql_kv.md" new file mode 100644 index 0000000..a9b5460 --- /dev/null +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/mysql_kv.md" @@ -0,0 +1,240 @@ +# Python MySQL 读写 + +使用 MySQL 实现一个 key-value(string:json) 读写库,请先完成【Python MySQL 安装说明】、【Python MySQL Connector】和【Python MySQL Connection】 + +```python +# -*- coding: UTF-8 -*- +import logging +import json +from error_code import ErrorCode +from mysql_connection import MySQLConnection +logger = logging.Logger(__name__) +mysql_connection_pool = None + +class MySQLKeyValueStore(MySQLConnection): + def __init__(self, host, port, user, password, database) -> None: + super().__init__(host, port, user, password, database) + + def set(self, key, value): + if self.conn is None: + return {'err': ErrorCode.DB_OPEN_FAILED} + + try: + value = json.dumps(value) + sql = 'insert into key_value set _key=%s, value=%s on duplicate key update value=%s' + args = (key, value, value) + return self.execute(sql, args) + except Exception as e: + logger.error(f'set key:{key} exception:{str(e)}') + return {"err": ErrorCode.DB_QUERY_EXCEPT} + + def get(self, key): + # TODO(You): 请实现 get 方法 + + +if __name__ == '__main__': + kv = MySQLKeyValueStore( + "127.0.0.1", 3306, + "root", "WNpx8c\zr!fF", + "test" + ) + + ret = kv.open() + assert ret['err'] == ErrorCode.SUCCESS + + ret = kv.set('test', {"number": 0}) + assert ret['err'] == ErrorCode.SUCCESS + + ret = kv.get('test') + print(ret) + assert ret['err'] == ErrorCode.SUCCESS + assert ret['value']['number'] == 0 + ret = kv.close() + assert ret['err'] == ErrorCode.SUCCESS +``` + +请选出下列能**正确**实现这一功能的选项。 + +## template + +```python +import logging +import json +from error_code import ErrorCode +from mysql_connection import MySQLConnection +logger = logging.Logger(__name__) +mysql_connection_pool = None + + +class MySQLKeyValueStore(MySQLConnection): + def __init__(self, host, port, user, password, database) -> None: + super().__init__(host, port, user, password, database) + + def set(self, key, value): + if self.conn is None: + return {'err': ErrorCode.DB_OPEN_FAILED} + + try: + value = json.dumps(value) + sql = 'insert into key_value set _key=%s, value=%s on duplicate key update value=%s' + args = (key, value, value) + return self.execute(sql, args) + except Exception as e: + logger.error(f'set key:{key} exception:{str(e)}') + return {"err": ErrorCode.DB_QUERY_EXCEPT} + + def get(self, key): + if self.conn is None: + return {'err': ErrorCode.DB_NOT_OPEN} + + try: + sql = 'select value from key_value where _key=%s' + ret = self.execute(sql, (key,)) + if ret['err'] != ErrorCode.SUCCESS: + return ret + results = ret['results'] + if len(results) == 0: + logger.warning(f'get key:{key}, empty.') + return {"err": ErrorCode.NOT_FOUND} + else: + return {"err": ErrorCode.SUCCESS, "key": key, "value": json.loads(results[0])} + except Exception as e: + logger.error(f'get key:{key} exception:{str(e)}') + return {"err": ErrorCode.DB_QUERY_EXCEPT} + + +if __name__ == '__main__': + kv = MySQLKeyValueStore( + "127.0.0.1", 3306, + "root", "WNpx8c\zr!fF", + "test" + ) + + ret = kv.open() + assert ret['err'] == ErrorCode.SUCCESS + + ret = kv.set('test', {"number": 0}) + assert ret['err'] == ErrorCode.SUCCESS + + ret = kv.get('test') + print(ret) + assert ret['err'] == ErrorCode.SUCCESS + assert ret['value']['number'] == 0 + ret = kv.close() + assert ret['err'] == ErrorCode.SUCCESS +``` + +## 答案 + +```python +class MySQLKeyValueStore(MySQLConnection): + ... + def get(self, key): + if self.conn is None: + return {'err': ErrorCode.DB_NOT_OPEN} + + try: + sql = 'select value from key_value where _key=%s' + ret = self.execute(sql, (key,)) + if ret['err'] != ErrorCode.SUCCESS: + return ret + results = ret['results'] + if len(results) == 0: + logger.warning(f'get key:{key}, empty.') + return {"err": ErrorCode.NOT_FOUND} + else: + return {"err": ErrorCode.SUCCESS, "key": key, "value": json.loads(results[0])} + except Exception as e: + logger.error(f'get key:{key} exception:{str(e)}') + return {"err": ErrorCode.DB_QUERY_EXCEPT} +``` + +## 选项 + +### A + +```python +class MySQLKeyValueStore(MySQLConnection): + ... + def get(self, key): + if self.conn is None: + return {'err': ErrorCode.DB_NOT_OPEN} + + try: + sql = 'select value from key_value where _key=%s' + ret = self.execute(sql, (key,)) + + results = ret['results'] + if len(results) == 0: + logger.warning(f'get key:{key}, empty.') + return {"err": ErrorCode.NOT_FOUND} + else: + return {"err": ErrorCode.SUCCESS, "key": key, "value": json.loads(results[0])} + except Exception as e: + logger.error(f'get key:{key} exception:{str(e)}') + return {"err": ErrorCode.DB_QUERY_EXCEPT} +``` + +### B + +```python +class MySQLKeyValueStore(MySQLConnection): + ... + def get(self, key): + if self.conn is None: + return {'err': ErrorCode.DB_NOT_OPEN} + + try: + sql = 'select value from key_value where _key=%s' + ret = self.execute(sql, (key,)) + if ret['err'] != ErrorCode.SUCCESS: + return ret + results = ret['results'] + return {"err": ErrorCode.SUCCESS, "key": key, "value": json.loads(results[0])} + except Exception as e: + logger.error(f'get key:{key} exception:{str(e)}') + return {"err": ErrorCode.DB_QUERY_EXCEPT} +``` + +### C + +```python +class MySQLKeyValueStore(MySQLConnection): + ... + def get(self, key): + if self.conn is None: + return {'err': ErrorCode.DB_NOT_OPEN} + + sql = 'select value from key_value where _key=%s' + ret = self.execute(sql, (key,)) + if ret['err'] != ErrorCode.SUCCESS: + return ret + results = ret['results'] + if len(results) == 0: + logger.warning(f'get key:{key}, empty.') + return {"err": ErrorCode.NOT_FOUND} + else: + return {"err": ErrorCode.SUCCESS, "key": key, "value": json.loads(results[0])} +``` + +### D + +```python +class MySQLKeyValueStore(MySQLConnection): + ... + def get(self, key): + try: + sql = 'select value from key_value where _key=%s' + ret = self.execute(sql, (key,)) + if ret['err'] != ErrorCode.SUCCESS: + return ret + results = ret['results'] + if len(results) == 0: + logger.warning(f'get key:{key}, empty.') + return {"err": ErrorCode.NOT_FOUND} + else: + return {"err": ErrorCode.SUCCESS, "key": key, "value": json.loads(results[0])} + except Exception as e: + logger.error(f'get key:{key} exception:{str(e)}') + return {"err": ErrorCode.DB_QUERY_EXCEPT} +``` diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/redis_connector.json" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/redis_connector.json" index 9076bc2..cb8c95f 100644 --- "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/redis_connector.json" +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/redis_connector.json" @@ -1,19 +1,10 @@ { - "one_line": { - "global redis_connection_pool": [ - "redis_connection_pool" - ], - "if self.conn is not None": [ - "if self.conn is None" - ], - "self.conn.close()": [ - "" - ] - }, - "source": "redis_connector.py", + "source": "redis_connector.md", "depends": [ "error_code.py" ], "exercise_id": 162, - "type": "code_options" + "type": "code_options", + "author": "huanhuilong", + "notebook_enable": true } \ No newline at end of file diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/redis_connector.md" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/redis_connector.md" new file mode 100644 index 0000000..304a318 --- /dev/null +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/redis_connector.md" @@ -0,0 +1,163 @@ +# Python Redis 连接器 + +实现一个 redis 连接器,能打开/关闭 redis 连结,使用连接池 + +```python +# -*- coding: UTF-8 -*- +import logging +import json +from error_code import ErrorCode +import redis +logger = logging.Logger(__name__) + +redis_connection_pool = None + +class RedisConnector(): + def __init__(self, host, port, password) -> None: + global redis_connection_pool + if redis_connection_pool is None: + redis_connection_pool = redis.ConnectionPool( + host=host, + port=port, + password=password + ) + self.conn = None + + def open(self): + # TODO(You): 请在此实现打开 redis 代码 + + def close(self): + if self.conn is not None: + self.conn.close() + self.conn = None + return {'err': ErrorCode.SUCCESS} + +if __name__ == '__main__': + redis_connector = RedisConnector("127.0.0.1", 6379, None) + + ret = redis_connector.open() + assert ret['err'] == ErrorCode.SUCCESS + ret = redis_connector.close() + assert ret['err'] == ErrorCode.SUCCESS +``` + +请选出下列能**正确**实现这一功能的选项。 + +## template + +```python +import logging +import json +from error_code import ErrorCode +import redis +logger = logging.Logger(__name__) + +redis_connection_pool = None + +class RedisConnector(): + def __init__(self, host, port, password) -> None: + global redis_connection_pool + if redis_connection_pool is None: + redis_connection_pool = redis.ConnectionPool( + host=host, + port=port, + password=password + ) + self.conn = None + + def open(self): + if self.conn is not None: + return {"err": ErrorCode.SUCCESS} + + try: + self.conn = redis.StrictRedis( + connection_pool=redis_connection_pool) + return {"err": ErrorCode.SUCCESS} + except Exception as e: + logger.error('open redis exception:', str(e)) + self.conn = None + return {"err": ErrorCode.DB_OPEN_FAILED} + + def close(self): + if self.conn is not None: + self.conn.close() + self.conn = None + return {'err': ErrorCode.SUCCESS} + +if __name__ == '__main__': + redis_connector = RedisConnector("127.0.0.1", 6379, None) + + ret = redis_connector.open() + assert ret['err'] == ErrorCode.SUCCESS + ret = redis_connector.close() + assert ret['err'] == ErrorCode.SUCCESS +``` + +## 答案 + +```python +class RedisConnector(): + ... + def open(self): + if self.conn is not None: + return {"err": ErrorCode.SUCCESS} + + try: + self.conn = redis.StrictRedis( + connection_pool=redis_connection_pool) + return {"err": ErrorCode.SUCCESS} + except Exception as e: + logger.error('open redis exception:', str(e)) + self.conn = None + return {"err": ErrorCode.DB_OPEN_FAILED} +``` + +## 选项 + +### A + +```python +class RedisConnector(): + ... + def open(self): + try: + self.conn = redis.StrictRedis( + connection_pool=redis_connection_pool) + return {"err": ErrorCode.SUCCESS} + except Exception as e: + logger.error('open redis exception:', str(e)) + self.conn = None + return {"err": ErrorCode.DB_OPEN_FAILED} +``` + +### B + +```python +class RedisConnector(): + ... + def open(self): + if self.conn is not None: + return {"err": ErrorCode.SUCCESS} + + self.conn = redis.StrictRedis( + connection_pool=redis_connection_pool) + return {"err": ErrorCode.SUCCESS} +``` + +### C + +```python +class RedisConnector(): + ... + def open(self): + if self.conn is not None: + return {"err": ErrorCode.SUCCESS} + + try: + self.conn = redis.StrictRedis(redis_connection_pool) + return {"err": ErrorCode.SUCCESS} + except Exception as e: + logger.error('open redis exception:', str(e)) + self.conn = None + return {"err": ErrorCode.DB_OPEN_FAILED} +``` diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/redis_install.json" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/redis_install.json" index 961f97d..211590b 100644 --- "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/redis_install.json" +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/redis_install.json" @@ -1,18 +1,10 @@ { - "one_line": { - "redis-server": [ - "redis", - "redis_server" - ], - "redis-cli": [ - "redis", - "redis_cli" - ] - }, - "source": "redis_install.py", + "source": "redis_install.md", "depends": [ "error_code.py" ], "exercise_id": 156, - "type": "code_options" + "type": "code_options", + "author": "huanhuilong", + "notebook_enable": true } \ No newline at end of file diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/redis_install.md" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/redis_install.md" new file mode 100644 index 0000000..a2a2d58 --- /dev/null +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/redis_install.md" @@ -0,0 +1,82 @@ +# Python Redis 安装说明 + +熟悉 Redis 的基本操作,下面的代码会打印: + +1. 安装 redis +2. 启动 redis 服务的命令 +3. 登录进入 redis 客户端 +4. 安装 redis 的 Python 库 + +```python +# -*- coding: UTF-8 -*- +def dump_depends(depends): + print() + print("# 依赖配置") + for i in range(0, len(depends)): + print("{}. {}".format(i, depends[i])) + +if __name__ == '__main__': + start_server = #TODO(You): 请编写启动 redis 服务命令 + login_redis = #TODO(You): 请编写登录到 redis 的命令 + + dump_depends([ + '安装 redis :https://redis.io/download', + f'启动 redis 服务: {start_server}', + f'进入 redis 命令行客户端: {login_redis}', + '库安装: pip install redis', + ]) +``` + +以下 `start_server` 和 `login_redis` 命令字符串正确的是? + +## template + +```python + +def dump_depends(depends): + print() + print("# 依赖配置") + for i in range(0, len(depends)): + print("{}. {}".format(i, depends[i])) + +if __name__ == '__main__': + start_server = 'redis-server' + login_redis = 'redis-cli -h 127.0.0.1 -p 6379' + + dump_depends([ + '安装 redis :https://redis.io/download', + f'启动 redis 服务: {start_server}', + f'进入 redis 命令行客户端: {login_redis}', + '库安装: pip install redis', + ]) +``` + +## 答案 + +```python +start_server = 'redis-server' +login_redis = 'redis-cli -h 127.0.0.1 -p 6379' +``` + +## 选项 + +### A + +```python +start_server = 'redis' +login_redis = 'redis-cli -h 127.0.0.1 -p 6379' +``` + +### B + +```python +start_server = 'redis-server' +login_redis = 'redis -h 127.0.0.1 -p 6379' +``` + +### C + +```python +start_server = 'redis' +login_redis = 'redis-cli -h 127.0.0.1 -P 6379' +``` diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/redis_kv.json" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/redis_kv.json" index 4378419..eda9c50 100644 --- "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/redis_kv.json" +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/redis_kv.json" @@ -1,22 +1,10 @@ { - "one_line": { - "assert type(value) == type({})": [ - "assert type(value) == type([])" - ], - "self.conn.set(key, json.dumps(value))": [ - "self.conn.set(key, value)" - ], - "if self.conn is None": [ - "if self.conn is not None" - ], - "{\"err\": ErrorCode.NOT_FOUND}": [ - "{\"err\": ErrorCode.SUCCESS}" - ] - }, - "source": "redis_kv.py", + "source": "redis_kv.md", "depends": [ "error_code.py" ], "exercise_id": 22, - "type": "code_options" + "type": "code_options", + "author": "huanhuilong", + "notebook_enable": true } \ No newline at end of file diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/redis_kv.md" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/redis_kv.md" new file mode 100644 index 0000000..f99af77 --- /dev/null +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/redis_kv.md" @@ -0,0 +1,174 @@ +# Python Redis 读写 + +使用 Redis 实现一个 key-value(string:json) 读写库。请先完成【Python Redis 安装说明】和【Python Redis 连接器】 + +```python +# -*- coding: UTF-8 -*- +import logging +import json +from error_code import ErrorCode +from redis_connector import RedisConnector +logger = logging.Logger(__name__) +redis_connection = None + +class RedisKeyValueStore(RedisConnector): + def __init__(self, host, port, password) -> None: + super().__init__(host, port, password) + + def set(self, key, value): + # TODO(You): 请在此实现Redis写入代码 + + def get(self, key): + if self.conn is None: + return {'err': ErrorCode.DB_NOT_OPEN} + + try: + results = self.conn.get(key) + if results is None: + return {"err": ErrorCode.NOT_FOUND} + return {"err": ErrorCode.SUCCESS, "key": key, "value": json.loads(results)} + except Exception as e: + logger.error(f'get key:{key} exception:{str(e)}') + return {"err": ErrorCode.DB_QUERY_EXCEPT} + + +if __name__ == '__main__': + kv = RedisKeyValueStore("127.0.0.1", 6379, None) + ret = kv.open() + assert ret['err'] == ErrorCode.SUCCESS + + ret = kv.set("test", {"number": 0}) + assert ret['err'] == ErrorCode.SUCCESS + + ret = kv.get("test") + assert ret['err'] == ErrorCode.SUCCESS + assert ret['value']['number'] == 0 + + ret = kv.close() + assert ret['err'] == ErrorCode.SUCCESS +``` + +请选出下列能**正确**实现这一功能的选项。 + +## template + +```python +import logging +import json +from error_code import ErrorCode +from redis_connector import RedisConnector +logger = logging.Logger(__name__) +redis_connection = None + + +class RedisKeyValueStore(RedisConnector): + def __init__(self, host, port, password) -> None: + super().__init__(host, port, password) + + def set(self, key, value): + if self.conn is None: + return {'err': ErrorCode.DB_OPEN_FAILED} + + assert type(key) == type('') + assert type(value) == type({}) + + try: + self.conn.set(key, json.dumps(value)) + return {'err': ErrorCode.SUCCESS} + except Exception as e: + logger.error(f'set key:{key} exception:{str(e)}') + return {"err": ErrorCode.DB_QUERY_EXCEPT} + + def get(self, key): + if self.conn is None: + return {'err': ErrorCode.DB_NOT_OPEN} + + try: + results = self.conn.get(key) + if results is None: + return {"err": ErrorCode.NOT_FOUND} + return {"err": ErrorCode.SUCCESS, "key": key, "value": json.loads(results)} + except Exception as e: + logger.error(f'get key:{key} exception:{str(e)}') + return {"err": ErrorCode.DB_QUERY_EXCEPT} + + +if __name__ == '__main__': + kv = RedisKeyValueStore("127.0.0.1", 6379, None) + ret = kv.open() + assert ret['err'] == ErrorCode.SUCCESS + + ret = kv.set("test", {"number": 0}) + assert ret['err'] == ErrorCode.SUCCESS + + ret = kv.get("test") + print(ret) + assert ret['err'] == ErrorCode.SUCCESS + assert ret['value']['number'] == 0 + ret = kv.close() + assert ret['err'] == ErrorCode.SUCCESS +``` + +## 答案 + +```python +class RedisKeyValueStore(RedisConnector): + ... + def set(self, key, value): + if self.conn is None: + return {'err': ErrorCode.DB_OPEN_FAILED} + + try: + self.conn.set(key, json.dumps(value)) + return {'err': ErrorCode.SUCCESS} + except Exception as e: + logger.error(f'set key:{key} exception:{str(e)}') + return {"err": ErrorCode.DB_QUERY_EXCEPT} +``` + +## 选项 + +### A + +```python +class RedisKeyValueStore(RedisConnector): + ... + def set(self, key, value): + try: + self.conn.set(key, json.dumps(value)) + return {'err': ErrorCode.SUCCESS} + except Exception as e: + logger.error(f'set key:{key} exception:{str(e)}') + return {"err": ErrorCode.DB_QUERY_EXCEPT} +``` + +### B + +```python +class RedisKeyValueStore(RedisConnector): + ... + def set(self, key, value): + if self.conn is None: + return {'err': ErrorCode.DB_OPEN_FAILED} + + self.conn.set(key, json.dumps(value)) + return {'err': ErrorCode.SUCCESS} + +``` + +### C + +```python +class RedisKeyValueStore(RedisConnector): + ... + def set(self, key, value): + if self.conn is None: + return {'err': ErrorCode.DB_OPEN_FAILED} + + try: + self.conn.set(key, value) + return {'err': ErrorCode.SUCCESS} + except Exception as e: + logger.error(f'set key:{key} exception:{str(e)}') + return {"err": ErrorCode.DB_QUERY_EXCEPT} +``` diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/sqlite_connection.json" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/sqlite_connection.json" index 35543b2..9f6926f 100644 --- "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/sqlite_connection.json" +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/sqlite_connection.json" @@ -1,23 +1,11 @@ { - "one_line": { - "self.conn.rollback()": [ - "" - ], - "self.conn.commit()": [ - "" - ], - "cursor.fetchall()": [ - "cursor.fetchone()" - ], - "_key varchar(32)": [ - "key varchar(32)" - ] - }, - "source": "sqlite_connection.py", + "source": "sqlite_connection.md", "depends": [ "error_code.py", "sqlite_connector.py" ], "exercise_id": 157, - "type": "code_options" + "type": "code_options", + "author": "huanhuilong", + "notebook_enable": true } \ No newline at end of file diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/sqlite_connection.md" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/sqlite_connection.md" new file mode 100644 index 0000000..162cf1c --- /dev/null +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/sqlite_connection.md" @@ -0,0 +1,174 @@ +# Python SQLITE Connection + +继承自前一节的 SqliteConnector,增加执行sql接口,请先完成【Python SQLITE Connector】 + +```python +# -*- coding: UTF-8 -*- +import logging +from error_code import ErrorCode +from sqlite_connector import SqliteConnector +logger = logging.Logger(__name__) + +class SqliteConnection(SqliteConnector): + def __init__(self, db_file) -> None: + super().__init__(db_file) + + def execute(self, sql, arg=None): + # TODO(You): 请在此实现查询代码 + + +if __name__ == '__main__': + kv = SqliteConnection("/tmp/test.db") + + ret = kv.open() + assert ret['err'] == ErrorCode.SUCCESS + + sql = '''create table if not exists key_value ( + _key varchar(32) primary key not null, + value text not null + );''' + ret = kv.execute(sql) + assert ret['err'] == ErrorCode.SUCCESS + ret = kv.close() + assert ret['err'] == ErrorCode.SUCCESS +``` + +请选出下列能**正确**实现这一功能的选项。 + +## template + +```python +import logging +from error_code import ErrorCode +from sqlite_connector import SqliteConnector +logger = logging.Logger(__name__) + + +class SqliteConnection(SqliteConnector): + def __init__(self, db_file) -> None: + super().__init__(db_file) + + def execute(self, sql, arg=None): + results = [] + try: + cursor = self.conn.execute(sql, arg or tuple()) + if cursor is not None: + results = cursor.fetchall() + self.conn.commit() + return {'err': ErrorCode.SUCCESS, 'results': results} + except Exception as e: + logger.error( + f'execute sql exception, sql:{sql}, arg:{arg}, exception:{str(e)}') + self.conn.rollback() + return {'err': ErrorCode.DB_QUERY_EXCEPT, 'results': results} + + +if __name__ == '__main__': + kv = SqliteConnection("/tmp/test.db") + + ret = kv.open() + assert ret['err'] == ErrorCode.SUCCESS + + sql = '''create table if not exists key_value ( + _key varchar(32) primary key not null, + value text not null + );''' + ret = kv.execute(sql) + assert ret['err'] == ErrorCode.SUCCESS + ret = kv.close() + assert ret['err'] == ErrorCode.SUCCESS +``` + +## 答案 + +```python +class SqliteConnection(SqliteConnector): + ... + def execute(self, sql, arg=None): + results = [] + try: + cursor = self.conn.execute(sql, arg or tuple()) + if cursor is not None: + results = cursor.fetchall() + self.conn.commit() + return {'err': ErrorCode.SUCCESS, 'results': results} + except Exception as e: + logger.error( + f'execute sql exception, sql:{sql}, arg:{arg}, exception:{str(e)}') + self.conn.rollback() + return {'err': ErrorCode.DB_QUERY_EXCEPT, 'results': results} +``` + +## 选项 + +### A + +```python +class SqliteConnection(SqliteConnector): + ... + def execute(self, sql, arg=None): + results = [] + cursor = self.conn.execute(sql, arg or tuple()) + if cursor is not None: + results = cursor.fetchall() + self.conn.commit() + return {'err': ErrorCode.SUCCESS, 'results': results} + +``` + +### B + +```python +class SqliteConnection(SqliteConnector): + ... + def execute(self, sql, arg=None): + results = [] + try: + cursor = self.conn.execute(sql, arg or tuple()) + results = cursor.fetchall() + self.conn.commit() + return {'err': ErrorCode.SUCCESS, 'results': results} + except Exception as e: + logger.error( + f'execute sql exception, sql:{sql}, arg:{arg}, exception:{str(e)}') + self.conn.rollback() + return {'err': ErrorCode.DB_QUERY_EXCEPT, 'results': results} +``` + +### C + +```python +class SqliteConnection(SqliteConnector): + ... + def execute(self, sql, arg=None): + results = [] + try: + cursor = self.conn.execute(sql, arg or tuple()) + if cursor is not None: + results = cursor.fetchall() + self.conn.commit() + return {'err': ErrorCode.SUCCESS, 'results': results} + except Exception as e: + logger.error( + f'execute sql exception, sql:{sql}, arg:{arg}, exception:{str(e)}') + return {'err': ErrorCode.DB_QUERY_EXCEPT, 'results': results} +``` + +### D + +```python +class SqliteConnection(SqliteConnector): + ... + def execute(self, sql, arg=None): + results = [] + try: + cursor = self.conn.execute(sql, arg or tuple()) + if cursor is not None: + results = cursor.fetchall() + return {'err': ErrorCode.SUCCESS, 'results': results} + except Exception as e: + logger.error( + f'execute sql exception, sql:{sql}, arg:{arg}, exception:{str(e)}') + self.conn.rollback() + return {'err': ErrorCode.DB_QUERY_EXCEPT, 'results': results} +``` diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/sqlite_connector.json" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/sqlite_connector.json" index df64564..2656247 100644 --- "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/sqlite_connector.json" +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/sqlite_connector.json" @@ -1,22 +1,10 @@ { - "one_line": { - "self.conn.close()": [ - "" - ], - "self.close()": [ - "" - ], - "if self.conn is not None": [ - "if self.conn is None" - ], - "sqlite3.connect": [ - "sqlite3.open" - ] - }, - "source": "sqlite_connector.py", + "source": "sqlite_connector.md", "depends": [ "error_code.py" ], "exercise_id": 161, - "type": "code_options" + "type": "code_options", + "author": "huanhuilong", + "notebook_enable": true } \ No newline at end of file diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/sqlite_connector.md" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/sqlite_connector.md" new file mode 100644 index 0000000..854f3d7 --- /dev/null +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/sqlite_connector.md" @@ -0,0 +1,131 @@ +# Python SQLITE Connector + +对 sqlite3 做一个基本的封装,支持 open/close,打开的时候配置检查后续操作在同一个线程 + +```python +# -*- coding: UTF-8 -*- +import logging +import sqlite3 +from error_code import ErrorCode +logger = logging.Logger(__name__) + +class SqliteConnector(): + def __init__(self, db_file) -> None: + self.db_file = db_file + self.conn = None + + def open(self): + # TODO(You): 请实现打开Sqlite代码 + + def close(self): + if self.conn is not None: + self.conn.close() + self.conn = None + return {'err': ErrorCode.SUCCESS} + + +if __name__ == '__main__': + kv = SqliteConnector("/tmp/test.db") + + ret = kv.open() + assert ret['err'] == ErrorCode.SUCCESS + ret = kv.close() + assert ret['err'] == ErrorCode.SUCCESS +``` + +请选出下列能**正确**实现这一功能的选项。 + +## template + +```python +import logging +import sqlite3 +from error_code import ErrorCode +logger = logging.Logger(__name__) + + +class SqliteConnector(): + def __init__(self, db_file) -> None: + self.db_file = db_file + self.conn = None + + def open(self): + try: + self.conn = sqlite3.connect(self.db_file, check_same_thread=True) + return {"err": ErrorCode.SUCCESS} + except Exception as e: + logger.error('open sqlite exception:', str(e)) + self.close() + return {"err": ErrorCode.DB_OPEN_FAILED} + + def close(self): + if self.conn is not None: + self.conn.close() + self.conn = None + return {'err': ErrorCode.SUCCESS} + + +if __name__ == '__main__': + kv = SqliteConnector("/tmp/test.db") + + ret = kv.open() + assert ret['err'] == ErrorCode.SUCCESS + ret = kv.close() + assert ret['err'] == ErrorCode.SUCCESS +``` + +## 答案 + +```python +class SqliteConnector(): + ... + def open(self): + try: + self.conn = sqlite3.connect(self.db_file, check_same_thread=True) + return {"err": ErrorCode.SUCCESS} + except Exception as e: + logger.error('open sqlite exception:', str(e)) + self.close() + return {"err": ErrorCode.DB_OPEN_FAILED} +``` + +## 选项 + +### A + +```python +class SqliteConnector(): + ... + def open(self): + self.conn = sqlite3.connect(self.db_file, check_same_thread=True) + return {"err": ErrorCode.SUCCESS} +``` + +### B + +```python +class SqliteConnector(): + ... + def open(self): + try: + self.conn = sqlite3.connect(self.db_file, check_same_thread=True) + return {"err": ErrorCode.SUCCESS} + except Exception as e: + logger.error('open sqlite exception:', str(e)) + return {"err": ErrorCode.DB_OPEN_FAILED} +``` + +### C + +```python +class SqliteConnector(): + ... + def open(self): + try: + self.conn = sqlite3.connect(self.db_file) + return {"err": ErrorCode.SUCCESS} + except Exception as e: + logger.error('open sqlite exception:', str(e)) + self.close() + return {"err": ErrorCode.DB_OPEN_FAILED} +``` diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/sqlite_kv.json" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/sqlite_kv.json" index 7752683..e0dc1c2 100644 --- "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/sqlite_kv.json" +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/sqlite_kv.json" @@ -1,25 +1,12 @@ { - "one_line": { - "len(results) == 0": [ - "len(results) >= 0", - "len(results) != 0" - ], - "_key varchar(32)": [ - "key varchar(32)" - ], - "value = json.loads(results[0][0])": [ - "" - ], - "if self.conn is None": [ - "if self.conn is not None" - ] - }, - "source": "sqlite_kv.py", + "source": "sqlite_kv.md", "depends": [ "error_code.py", "sqlite_connector.py", "sqlite_connection.py" ], "exercise_id": 23, - "type": "code_options" + "type": "code_options", + "author": "huanhuilong", + "notebook_enable": true } \ No newline at end of file diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/sqlite_kv.md" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/sqlite_kv.md" new file mode 100644 index 0000000..8c3c8c8 --- /dev/null +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/4.\346\225\260\346\215\256\345\272\223\346\223\215\344\275\234/sqlite_kv.md" @@ -0,0 +1,210 @@ +# Python SQLITE 读写 + +使用 SQLITE 实现一个 key-value(string:json) 读写库,请先完成【Python SQLITE Connector】和【Python SQLITE Connection】 + +```python +# -*- coding: UTF-8 -*- +import logging +import json +from error_code import ErrorCode +from sqlite_connection import SqliteConnection +logger = logging.Logger(__name__) + +class SqliteKeyValueStore(SqliteConnection): + def __init__(self, db_file) -> None: + super().__init__(db_file) + + def open(self): + ret = super().open() + if ret['err'] != ErrorCode.SUCCESS: + return ret + + sql = '''create table if not exists key_value ( + _key varchar(32) primary key not null, + value text not null + );''' + return self.execute(sql) + + def set(self, key, value): + # TODO(You): 请在此实现Sqlite写入key-value代码,其中value是json + + def get(self, key): + if self.conn is None: + return {'err': ErrorCode.SQLITE_NOT_OPEN} + + try: + sql = 'select value from key_value where _key=?' + ret = self.execute(sql, [key]) + if ret['err'] != ErrorCode.SUCCESS: + return ret + + results = ret['results'] + if len(results) == 0: + return {"err": ErrorCode.NOT_FOUND} + else: + value = json.loads(results[0][0]) + return {"err": ErrorCode.SUCCESS, "key": key, "value": value} + except Exception as e: + logger.error(f'get key:{key} exception:{str(e)}') + return {"err": ErrorCode.DB_QUERY_EXCEPT} + + +if __name__ == '__main__': + kv = SqliteKeyValueStore("/tmp/test.db") + + ret = kv.open() + assert ret['err'] == ErrorCode.SUCCESS + + ret = kv.set('test', {"number": 0}) + assert ret['err'] == ErrorCode.SUCCESS + + ret = kv.get('test') + print(ret) + assert ret['err'] == ErrorCode.SUCCESS + assert ret['value']['number'] == 0 + ret = kv.close() + assert ret['err'] == ErrorCode.SUCCESS +``` + +请选出下列能**正确**实现这一功能的选项。 + +## template + +```python +import logging +import json +from error_code import ErrorCode +from sqlite_connection import SqliteConnection +logger = logging.Logger(__name__) + + +class SqliteKeyValueStore(SqliteConnection): + def __init__(self, db_file) -> None: + super().__init__(db_file) + + def open(self): + ret = super().open() + if ret['err'] != ErrorCode.SUCCESS: + return ret + + sql = '''create table if not exists key_value ( + _key varchar(32) primary key not null, + value text not null + );''' + return self.execute(sql) + + def set(self, key, value): + if self.conn is None: + return {'err': ErrorCode.DB_OPEN_FAILED} + + try: + value = json.dumps(value) + sql = 'insert or replace into key_value values(?, ?)' + return self.execute(sql, [key, value]) + except Exception as e: + logger.error(f'set key:{key} exception:{str(e)}') + return {"err": ErrorCode.DB_QUERY_EXCEPT} + + def get(self, key): + if self.conn is None: + return {'err': ErrorCode.SQLITE_NOT_OPEN} + + try: + sql = 'select value from key_value where _key=?' + ret = self.execute(sql, [key]) + if ret['err'] != ErrorCode.SUCCESS: + return ret + + results = ret['results'] + if len(results) == 0: + return {"err": ErrorCode.NOT_FOUND} + else: + value = json.loads(results[0][0]) + return {"err": ErrorCode.SUCCESS, "key": key, "value": value} + except Exception as e: + logger.error(f'get key:{key} exception:{str(e)}') + return {"err": ErrorCode.DB_QUERY_EXCEPT} + + +if __name__ == '__main__': + kv = SqliteKeyValueStore("/tmp/test.db") + + ret = kv.open() + assert ret['err'] == ErrorCode.SUCCESS + + ret = kv.set('test', {"number": 0}) + assert ret['err'] == ErrorCode.SUCCESS + + ret = kv.get('test') + print(ret) + assert ret['err'] == ErrorCode.SUCCESS + assert ret['value']['number'] == 0 + ret = kv.close() + assert ret['err'] == ErrorCode.SUCCESS +``` + +## 答案 + +```python +class SqliteKeyValueStore(SqliteConnection): + ... + def set(self, key, value): + if self.conn is None: + return {'err': ErrorCode.DB_OPEN_FAILED} + + try: + value = json.dumps(value) + sql = 'insert or replace into key_value values(?, ?)' + return self.execute(sql, [key, value]) + except Exception as e: + logger.error(f'set key:{key} exception:{str(e)}') + return {"err": ErrorCode.DB_QUERY_EXCEPT} +``` + +## 选项 + +### A + +```python +class SqliteKeyValueStore(SqliteConnection): + ... + def set(self, key, value): + try: + value = json.dumps(value) + sql = 'insert or replace into key_value values(?, ?)' + return self.execute(sql, [key, value]) + except Exception as e: + logger.error(f'set key:{key} exception:{str(e)}') + return {"err": ErrorCode.DB_QUERY_EXCEPT} +``` + +### B + +```python +class SqliteKeyValueStore(SqliteConnection): + ... + def set(self, key, value): + if self.conn is None: + return {'err': ErrorCode.DB_OPEN_FAILED} + + value = json.dumps(value) + sql = 'insert or replace into key_value values(?, ?)' + return self.execute(sql, [key, value]) +``` + +### C + +```python +class SqliteKeyValueStore(SqliteConnection): + ... + def set(self, key, value): + if self.conn is None: + return {'err': ErrorCode.DB_OPEN_FAILED} + + try: + sql = 'insert or replace into key_value values(?, ?)' + return self.execute(sql, [key, value]) + except Exception as e: + logger.error(f'set key:{key} exception:{str(e)}') + return {"err": ErrorCode.DB_QUERY_EXCEPT} +``` diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/5.\346\223\215\344\275\234\347\263\273\347\273\237\345\222\214\347\216\257\345\242\203/os_info.json" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/5.\346\223\215\344\275\234\347\263\273\347\273\237\345\222\214\347\216\257\345\242\203/os_info.json" index b6a7edd..18f69fb 100644 --- "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/5.\346\223\215\344\275\234\347\263\273\347\273\237\345\222\214\347\216\257\345\242\203/os_info.json" +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/5.\346\223\215\344\275\234\347\263\273\347\273\237\345\222\214\347\216\257\345\242\203/os_info.json" @@ -1,17 +1,8 @@ { - "one_line": { - "break": [ - "continue" - ], - "options.get(key)": [ - "options[key]" - ], - "option['action']()": [ - "option['action']" - ] - }, - "source": "os_info.py", + "source": "os_info.md", "depends": [], "exercise_id": 14, - "type": "code_options" + "type": "code_options", + "author": "huanhuilong", + "notebook_enable": true } \ No newline at end of file diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/5.\346\223\215\344\275\234\347\263\273\347\273\237\345\222\214\347\216\257\345\242\203/os_info.md" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/5.\346\223\215\344\275\234\347\263\273\347\273\237\345\222\214\347\216\257\345\242\203/os_info.md" new file mode 100644 index 0000000..33c4a2f --- /dev/null +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/5.\346\223\215\344\275\234\347\263\273\347\273\237\345\222\214\347\216\257\345\242\203/os_info.md" @@ -0,0 +1,224 @@ +# Python 操作系统信息 + +提示用户输入查看信息选项,输出对应操作系统信息,使用配置驱动的程序模式 + +```python +# -*- coding: UTF-8 -*- +import os + +def select(config): + # 交互式选择程序,请理解这部分逻辑 + print(config['options_tip']) + options = config['options'] + + selects = [] + for key in options: + desc = options[key]["desc"] + selects.append(key) + print(f"* {key}: {desc}") + print() + + input_tip = config['input_tip'] + select_tip = '/'.join(selects) + tip = f'{input_tip}[{select_tip}, 按q退出]:' + + while True: + key = input(tip) + if key == 'q': + break + + option = options.get(key) + if option: + desc = option['desc'] + print(f"@{desc}:") + option['action']() + else: + print("[错误] 不支持的选项") + +def dump(tip, value): + # 打印提示 + print(tip+':') + print(value) + print() + +def dump_basic_info(): + # 打印基础信息 + dump('os.name', os.name) + +def dump_path_info(): + # 打印路径信息 + dump('os.getcwd()', os.getcwd()) + dump('os.get_exec_path()', os.get_exec_path()) + +def dump_env_info(): + # 打印环境信息 + dump('os.environ', os.environ) + +if __name__ == '__main__': + select( + # TODO(You): 请正确配置 select 的参数 + ) +``` + +请选出下列能**正确**实现这一功能的选项。 + +## template + +```python +import os + + +def select(config): + print(config['options_tip']) + options = config['options'] + + selects = [] + for key in options: + desc = options[key]["desc"] + selects.append(key) + print(f"* {key}: {desc}") + print() + + input_tip = config['input_tip'] + select_tip = '/'.join(selects) + tip = f'{input_tip}[{select_tip}, 按q退出]:' + + while True: + key = input(tip) + if key == 'q': + break + + option = options.get(key) + if option: + desc = option['desc'] + print(f"@{desc}:") + option['action']() + else: + print("[错误] 不支持的选项") + + +def dump(tip, value): + print(tip+':') + print(value) + print() + +def dump_basic_info(): + dump('os.name', os.name) + +def dump_path_info(): + dump('os.getcwd()', os.getcwd()) + dump('os.get_exec_path()', os.get_exec_path()) + +def dump_env_info(): + dump('os.environ', os.environ) + +if __name__ == '__main__': + select({ + 'options_tip': '通过 platform 可以查询一些有意思的信息', + 'input_tip': '请输入你感兴趣的信息', + 'options': { + 'b': { + "desc": "b is basic, 系统基本信息", + "action": dump_basic_info + }, + 'p': { + "desc": "p is path, 路径信息", + "action": dump_path_info + }, + 'e': { + "desc": "e is env, 环境信息", + "action": dump_env_info + } + }, + }) +``` + +## 答案 + +```python +select({ + 'options_tip': '通过 platform 可以查询一些有意思的信息', + 'input_tip': '请输入你感兴趣的信息', + 'options': { + 'b': { + "desc": "b is basic, 系统基本信息", + "action": dump_basic_info + }, + 'p': { + "desc": "p is path, 路径信息", + "action": dump_path_info + }, + 'e': { + "desc": "e is env, 环境信息", + "action": dump_env_info + } + }, +}) +``` + +## 选项 + +### A + +```python +select({ + 'options_tip': '通过 platform 可以查询一些有意思的信息', + 'input_tip': '请输入你感兴趣的信息', + 'b': { + "desc": "b is basic, 系统基本信息", + "action": dump_basic_info + }, + 'p': { + "desc": "p is path, 路径信息", + "action": dump_path_info + }, + 'e': { + "desc": "e is env, 环境信息", + "action": dump_env_info + } +}) +``` + +### B + +```python +select( options = { + 'options_tip': '通过 platform 可以查询一些有意思的信息', + 'input_tip': '请输入你感兴趣的信息', + 'b': { + "desc": "b is basic, 系统基本信息", + "action": dump_basic_info + }, + 'p': { + "desc": "p is path, 路径信息", + "action": dump_path_info + }, + 'e': { + "desc": "e is env, 环境信息", + "action": dump_env_info + } +}) +``` + +### C + +```python +select( + options_tip = '通过 platform 可以查询一些有意思的信息', + input_tip = '请输入你感兴趣的信息', + options = { + 'b': { + "desc": "b is basic, 系统基本信息", + "action": dump_basic_info + }, + 'p': { + "desc": "p is path, 路径信息", + "action": dump_path_info + }, + 'e': { + "desc": "e is env, 环境信息", + "action": dump_env_info + } + } +) +``` diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/5.\346\223\215\344\275\234\347\263\273\347\273\237\345\222\214\347\216\257\345\242\203/platform_info.json" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/5.\346\223\215\344\275\234\347\263\273\347\273\237\345\222\214\347\216\257\345\242\203/platform_info.json" index 84ffd64..7702a51 100644 --- "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/5.\346\223\215\344\275\234\347\263\273\347\273\237\345\222\214\347\216\257\345\242\203/platform_info.json" +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/5.\346\223\215\344\275\234\347\263\273\347\273\237\345\222\214\347\216\257\345\242\203/platform_info.json" @@ -1,21 +1,8 @@ { - "multiline": [ - { - "for key in config['options']:": "for key, option in config['options']:", - "option = config['options'][key]": "" - }, - { - "action(key)": "action()" - }, - { - "break": "continue" - }, - { - "if key == 'q'": "if key != 'q'" - } - ], - "source": "platform_info.py", + "source": "platform_info.md", "depends": [], "exercise_id": 15, - "type": "code_options" + "type": "code_options", + "author": "huanhuilong", + "notebook_enable": true } \ No newline at end of file diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/5.\346\223\215\344\275\234\347\263\273\347\273\237\345\222\214\347\216\257\345\242\203/platform_info.md" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/5.\346\223\215\344\275\234\347\263\273\347\273\237\345\222\214\347\216\257\345\242\203/platform_info.md" new file mode 100644 index 0000000..2ff5e37 --- /dev/null +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/5.\346\223\215\344\275\234\347\263\273\347\273\237\345\222\214\347\216\257\345\242\203/platform_info.md" @@ -0,0 +1,152 @@ +# Python 操作系统信息 + +提示用户输入选项,输出对应选项类型的平台信息 + +```python +# -*- coding: UTF-8 -*- +import platform + +def select(config, show_info): + print(config['options_tip']) + + selects = [] + for key in config['options']: + option = config['options'][key] + selects.append(key) + print(f"* {key}: {option}") + + tip = f"{config['input_tip']}[{'/'.join(selects)}, 按q退出]:" + while True: + key = input(tip) + if key == 'q': + break + else: + show_info(key) + print() + +def test(): + def show_info(key): + if key == 'p': + # TODO(You): 打印平台信息 + elif key == 'py': + # TODO(You): 打印Python信息 + + select({ + 'options_tip': '通过 platform 可以查询一些有意思的信息', + 'input_tip': '请输入你感兴趣的信息', + 'options': { + 'p': "p is platform, 平台信息", + 'py': "py is python, Python 信息", + }, + }, show_info) + +if __name__ == '__main__': + test() +``` + +以下对函数 show_info 实现 **符合语义** 的是? + +## template + +```python +import platform + + +def select(config, show_info): + print(config['options_tip']) + + selects = [] + for key in config['options']: + option = config['options'][key] + selects.append(key) + print(f"* {key}: {option}") + + tip = f"{config['input_tip']}[{'/'.join(selects)}, 按q退出]:" + while True: + key = input(tip) + if key == 'q': + break + else: + show_info(key) + print() + + +def test(): + def show_info(key): + if key == 'p': + print(platform.architecture()) + print(platform.platform()) + print(platform.processor()) + print(platform.machine()) + elif key == 'py': + print(platform.python_build()) + print(platform.python_implementation()) + print(platform.python_compiler()) + print(platform.python_version()) + + select({ + 'options_tip': '通过 platform 可以查询一些有意思的信息', + 'input_tip': '请输入你感兴趣的信息', + 'options': { + 'p': "p is platform, 平台信息", + 'py': "py is python, Python 信息", + }, + }, show_info) + +if __name__ == '__main__': + test() +``` + +## 答案 + +```python +def show_info(key): + if key == 'p': + print(platform.architecture()) + print(platform.platform()) + print(platform.processor()) + print(platform.machine()) + elif key == 'py': + print(platform.python_build()) + print(platform.python_implementation()) + print(platform.python_compiler()) + print(platform.python_version()) +``` + +## 选项 + +### A + +```python +def show_info(key): + print(platform.python_build()) + print(platform.python_implementation()) + print(platform.python_compiler()) + print(platform.python_version()) +``` + +### B + +```python +def show_info(key): + if key == 'p': + print(platform.python_build()) + print(platform.python_implementation()) + print(platform.python_compiler()) + print(platform.python_version()) + elif key == 'py': + print(platform.architecture()) + print(platform.platform()) + print(platform.processor()) + print(platform.machine()) +``` + +### C + +```python +def show_info(key): + print(platform.architecture()) + print(platform.platform()) + print(platform.processor()) + print(platform.machine()) +``` diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/6.\346\272\220\347\240\201\346\211\223\345\214\205/package.json" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/6.\346\272\220\347\240\201\346\211\223\345\214\205/package.json" index 724e687..7981e61 100644 --- "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/6.\346\272\220\347\240\201\346\211\223\345\214\205/package.json" +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/6.\346\272\220\347\240\201\346\211\223\345\214\205/package.json" @@ -1,30 +1,8 @@ { - "one_line": { - "if sub_dir is not None:": [ - "if sub_dir is None:" - ], - "depth+1": [ - "depth" - ], - "depth == 0": [ - "depth == 1" - ], - "next_space = [*space]": [ - "next_space = [space]", - "next_space = [**space]" - ], - "type(node[i+1]) == type([])": [ - "type(node[i+1]) != type([])" - ], - "while i < count": [ - "while i <= count" - ], - "last = i == len(node) - 1": [ - "last = i == len(node)" - ] - }, - "source": "package.py", + "source": "package.md", "depends": [], "exercise_id": 13, - "type": "code_options" + "type": "code_options", + "author": "huanhuilong", + "notebook_enable": true } \ No newline at end of file diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/6.\346\272\220\347\240\201\346\211\223\345\214\205/package.md" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/6.\346\272\220\347\240\201\346\211\223\345\214\205/package.md" new file mode 100644 index 0000000..975aa31 --- /dev/null +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/6.\346\272\220\347\240\201\346\211\223\345\214\205/package.md" @@ -0,0 +1,213 @@ +# Python 打包 + +打印出 Python 打包目录层次结构,类似命令行 tree 的效果,本题难度微提,请仔细阅读下面的注释,思考后做题。 + +```python +# -*- coding: UTF-8 -*- +def dump_node(node, space, last): + space = ''.join(space) + if last: + print(f"{space}└── {node}") + else: + print(f"{space}├── {node}") + +def tree_project(node, depth, space): + + count = len(node) + i = 0 + + # 遍历一层下的节点 + while i < count: + sub_node = node[i] + + # 获取子目录数据 + sub_dir = None + if i+1 < len(node): + if type(node[i+1]) == type([]): + sub_dir = node[i+1] + i += 1 + + # 判断是否是本级别最后一个节点 + last = i == len(node) - 1 + + # 打印当前节点 + dump_node(sub_node, space, last) + + # 如果含有子目录,则递归打印子目录结构 + if sub_dir is not None: + # TODO(You): 请在此实现计算当前层缩进空格的代码 + + tree_project(sub_dir, depth+1, next_space) + + i += 1 + + +def test(): + project_files = [ + "packaging_tutorial", + [ + "LICENSE", + "pyproject.toml", + "README.md", + "setup.cfg", + "src", + [ + "example_package_1", + [ + "__init__.py", + "example_1.py" + ], + "example_package_2", + [ + "__init__.py", + "example_2.py" + ], + ], + "tests/" + ] + ] + + print() + print("# 介绍一下 Python 打包") + print("* Python 打包教程:https://packaging.python.org/tutorials/packaging-projects/") + print("* 一个典型 Python 包的目录结构如下:") + print() + tree_project(project_files, 0, ['']) + print() + +if __name__ == '__main__': + test() +``` + +请选出下列能**正确**实现`计算当前层缩进空格数`的代码是。 + +## template + +```python + +def dump_node(node, space, last): + space = ''.join(space) + if last: + print(f"{space}└── {node}") + else: + print(f"{space}├── {node}") + + +def tree_project(node, depth, space): + + count = len(node) + i = 0 + while i < count: + sub_node = node[i] + + sub_dir = None + if i+1 < len(node): + if type(node[i+1]) == type([]): + sub_dir = node[i+1] + i += 1 + + last = i == len(node) - 1 + dump_node(sub_node, space, last) + + if sub_dir is not None: + next_space = None + if depth == 0: + next_space = [''] + else: + next_space = [*space] + if not last: + next_space.append('| ') + else: + next_space.append(' ') + tree_project(sub_dir, depth+1, next_space) + + i += 1 + + +def test(): + project_files = [ + "packaging_tutorial", + [ + "LICENSE", + "pyproject.toml", + "README.md", + "setup.cfg", + "src", + [ + "example_package_1", + [ + "__init__.py", + "example_1.py" + ], + "example_package_2", + [ + "__init__.py", + "example_2.py" + ], + ], + "tests/" + ] + ] + + print() + print("# 介绍一下 Python 打包") + print("* Python 打包教程:https://packaging.python.org/tutorials/packaging-projects/") + print("* 一个典型 Python 包的目录结构如下:") + print() + tree_project(project_files, 0, ['']) + print() + +if __name__ == '__main__': + test() +``` + +## 答案 + +```python +if depth == 0: + next_space = [''] +else: + next_space = [*space] + if not last: + next_space.append('| ') + else: + next_space.append(' ') +``` + +## 选项 + +### A + +```python +next_space = [*space] +if not last: + next_space.append('| ') +else: + next_space.append(' ') +``` + +### B + +```python +if depth == 0: + next_space = [' '] +else: + next_space = [*space] + if not last: + next_space.append('| ') + else: + next_space.append(' ') +``` + +### C + +```python +if depth == 0: + next_space = [''] +else: + next_space = [*space] + if last: + next_space.append(' ') + else: + next_space.append('| ') +``` diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/7.\347\275\221\347\273\234\347\274\226\347\250\213/tcp.json" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/7.\347\275\221\347\273\234\347\274\226\347\250\213/tcp.json" index 6fed014..5323a03 100644 --- "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/7.\347\275\221\347\273\234\347\274\226\347\250\213/tcp.json" +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/7.\347\275\221\347\273\234\347\274\226\347\250\213/tcp.json" @@ -1,32 +1,8 @@ { - "multiline": [ - { - "socket.SOCK_STREAM": "socket.SOCK_DGRAM" - }, - { - "s.bind((host, port))": "" - }, - { - "s.listen()": "" - }, - { - "s.connect((host, port))": "s.connect(host, port)" - }, - { - "s.bind((host, port))": "s.bind(host, port)" - }, - { - "continue": "break" - }, - { - "bytes(msg, 'utf-8')": "msg" - }, - { - "str(data, 'utf8')": "data" - } - ], - "source": "tcp.py", + "source": "tcp.md", "depends": [], "exercise_id": 7, - "type": "code_options" + "type": "code_options", + "author": "huanhuilong", + "notebook_enable": true } \ No newline at end of file diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/7.\347\275\221\347\273\234\347\274\226\347\250\213/tcp.md" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/7.\347\275\221\347\273\234\347\274\226\347\250\213/tcp.md" new file mode 100644 index 0000000..39ef4c1 --- /dev/null +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/7.\347\275\221\347\273\234\347\274\226\347\250\213/tcp.md" @@ -0,0 +1,192 @@ +# Python 网络编程 + +编写一个简易的 ECHO 服务机器人。满足: + +1. 客户端发送文本,服务端回复同样的文本,两边都打印各自收到的文本。 +2. 客户端支持用户输入'q' 退出。 +3. 客户端支持每次不大于 140 的文本输入,如果超出则提示重新输入。 +4. 客户端必须正确打印字符串。 + +```python +# -*- coding: UTF-8 -*- +import socket +import sys + +def echo_server(host, port): + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + s.bind((host, port)) + s.listen() + conn, addr = s.accept() + with conn: + print('收到客户端请求:', addr) + while True: + data = conn.recv(1024) + print('收到客户端数据:', str(data, 'utf8')) + if not data: + break + conn.sendall(data) + +def echo_client(host, port, input_message): + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + s.connect((host, port)) + + # TODO(You): 请正确实现发送处理逻辑 + while True: + msg = input_message("请输入信息[按q退出]:") + data = ... + print('收到服务端回包:', str(data, 'utf8')) + +if __name__ == '__main__': + host = '127.0.0.1' + port = 9999 + + # 如果命令行指定了 'server' 参数,就启动服务端程序 + # 否则,启动客户端程序 + if len(sys.argv) > 1 and sys.argv[1] == 'server': + echo_server(host, port) + else: + echo_client(host, port, lambda tip: input(tip)) +``` + +请选出下列能**正确**实现客户端处理用户输入,发送消息的代码。 + +## template + +```python +import socket +import sys + + +def echo_server(host, port): + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + s.bind((host, port)) + s.listen() + conn, addr = s.accept() + with conn: + print('收到客户端请求:', addr) + while True: + data = conn.recv(1024) + print('收到客户端数据:', str(data, 'utf8')) + if not data: + break + conn.sendall(data) + + +def echo_client(host, port, input_message): + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: + s.connect((host, port)) + while True: + msg = input_message("请输入信息[按q退出]:") + if len(msg) > 140: + print("您的输入太长了~~,请重新输入!") + continue + + if msg == 'q': + break + + msg_buffer = bytes(msg, 'utf-8') + s.sendall(msg_buffer) + + data = s.recv(1024) + print('收到服务端回包:', str(data, 'utf8')) + +if __name__ == '__main__': + host = '127.0.0.1' + port = 9999 + if len(sys.argv) > 1 and sys.argv[1] == 'server': + echo_server(host, port) + else: + echo_client(host, port, lambda tip: input(tip)) +``` + +## 答案 + +```python +while True: + msg = input_message("请输入信息[按q退出]:") + if msg == 'q': + break + + if len(msg) > 140: + print("您的输入太长了~~,请重新输入!") + continue + + msg_buffer = bytes(msg, 'utf-8') + s.sendall(msg_buffer) + + data = s.recv(1024) + print('收到服务端回包:', str(data, 'utf8')) +``` + +## 选项 + +### A + +```python +while True: + msg = input_message("请输入信息[按q退出]:") + if msg == 'q': + break + + msg_buffer = bytes(msg, 'utf-8') + s.sendall(msg_buffer) + + data = s.recv(1024) + print('收到服务端回包:', str(data, 'utf8')) +``` + +### B + +```python +while True: + msg = input_message("请输入信息[按q退出]:") + if msg == 'q': + break + + if len(msg) > 140: + print("您的输入太长了~~,请重新输入!") + continue + + s.sendall(msg) + data = s.recv(1024) + + print('收到服务端回包:', str(data, 'utf8')) +``` + +### C + +```python +while True: + msg = input_message("请输入信息[按q退出]:") + if msg == 'q': + break + + if len(msg) > 140: + print("您的输入太长了~~,请重新输入!") + continue + + msg_buffer = bytes(msg, 'utf-8') + s.sendall(msg_buffer) + data = s.recv() + + print('收到服务端回包:', str(data, 'utf8')) +``` + +### D + +```python +while True: + msg = input_message("请输入信息[按q退出]:") + if msg == 'q': + break + + if len(msg) > 140: + print("您的输入太长了~~,请重新输入!") + continue + + msg_buffer = bytes(msg, 'utf-8') + s.sendall(msg_buffer) + + data = s.recv(1024) + print('收到服务端回包:', data) +``` diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/8.\345\217\221\351\200\201\351\202\256\344\273\266/send_mail.json" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/8.\345\217\221\351\200\201\351\202\256\344\273\266/send_mail.json" index ba9e3aa..37e4318 100644 --- "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/8.\345\217\221\351\200\201\351\202\256\344\273\266/send_mail.json" +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/8.\345\217\221\351\200\201\351\202\256\344\273\266/send_mail.json" @@ -1,23 +1,8 @@ { - "one_line": { - "msg['From'] = sender": [ - "msg['From'] = receiver" - ], - "msg['To'] = receiver": [ - "msg['To'] = sender" - ], - "port = 465": [ - "port = 466" - ], - "smtp.qq.com": [ - "ftp.qq.com" - ], - "SMTP_SSL": [ - "SMTP" - ] - }, - "source": "send_mail.py", + "source": "send_mail.md", "depends": [], "exercise_id": 25, - "type": "code_options" + "type": "code_options", + "author": "huanhuilong", + "notebook_enable": true } \ No newline at end of file diff --git "a/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/8.\345\217\221\351\200\201\351\202\256\344\273\266/send_mail.md" "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/8.\345\217\221\351\200\201\351\202\256\344\273\266/send_mail.md" new file mode 100644 index 0000000..ac841a2 --- /dev/null +++ "b/data/2.python\344\270\255\351\230\266/1.\345\237\272\346\234\254\346\212\200\350\203\275/8.\345\217\221\351\200\201\351\202\256\344\273\266/send_mail.md" @@ -0,0 +1,115 @@ +# Python mail + +发送QQ邮件 + +```python +# -*- coding: UTF-8 -*- +import smtplib +import ssl +from email.mime.text import MIMEText + +def test(): + sender = input("请输入你的QQ邮箱:") + password = input("请输入你的QQ邮箱密码: ") + receiver = input("请输入目标QQ邮箱:") + content = input("请输入发送消息:") + + smtp_server = "smtp.qq.com" + port = 465 + + subject = "我在学习Python发送QQ邮件" + msg = MIMEText(content) + msg['Subject'] = subject + msg['From'] = sender + msg['To'] = receiver + + try: + # TODO(You): 请在此实现发送邮件代码 + except Exception as e: + print("发送失败了") + print(e) + return {'err': 1} + + return {'err': 0} + +if __name__ == '__main__': + test() +``` + +请选出下列能**正确**实现这一功能的选项。 + +## template + +```python +import smtplib +import ssl +from email.mime.text import MIMEText + + +def test(): + sender = input("请输入你的QQ邮箱:") + password = input("请输入你的QQ邮箱密码: ") + receiver = input("请输入目标QQ邮箱:") + content = input("请输入发送消息:") + + smtp_server = "smtp.qq.com" + port = 465 + + subject = "我在学习Python发送QQ邮件" + msg = MIMEText(content) + msg['Subject'] = subject + msg['From'] = sender + msg['To'] = receiver + + try: + server = smtplib.SMTP_SSL(smtp_server, port) + server.login(sender, password) + server.sendmail(sender, receiver, msg.as_string()) + server.quit() + except Exception as e: + print("发送失败了") + print(e) + return {'err': 1} + + return {'err': 0} + +if __name__ == '__main__': + test() +``` + +## 答案 + +```python +server = smtplib.SMTP_SSL(smtp_server, port) +server.login(sender, password) +server.sendmail(sender, receiver, msg.as_string()) +server.quit() +``` + +## 选项 + +### A + +```python +server = smtplib.SMTP_SSL(smtp_server, port) +server.sendmail(sender, receiver, msg.as_string()) +server.quit() +``` + +### B + +```python +server = smtplib.SMTP_SSL(smtp_server, port) +server.login(sender, password) +server.sendmail(receiver, sender, msg) +server.quit() +``` + +### C + +```python +server = smtplib.SMTP_SSL(smtp_server, port) +server.login(sender, password) +server.sendmail(receiver, sender, msg.as_string()) +server.quit() +``` diff --git a/main.py b/main.py index 9a8ebee..3242314 100644 --- a/main.py +++ b/main.py @@ -6,8 +6,8 @@ import os import re if __name__ == '__main__': - walker = TreeWalker("data", "python", "python") - walker.walk() + # walker = TreeWalker("data", "python", "python") + # walker.walk() - # md = MDWalker('data/1.python初阶/4.面向对象编程') - # md.walk() + md = MDWalker('data/2.python中阶/1.基本技能') + md.walk() -- GitLab