提交 488f365a 编写于 作者: F feilong

init python skill tree

上级 8f379fef
.vscode
.idea
.DS_Store
__pycache__
*.pyc
*.zip
*.out
\ No newline at end of file
# skill_tree_python
Python 技能树开放编辑仓库
\ No newline at end of file
Python 技能树开放编辑仓库
## 初始化
```
pip install -r requirement.txt
```
## 目录结构说明
* 技能树`骨架文件`
* 位置:`data/tree.json`
* 说明:该文件是执行 `python main.py` 生成的,请勿人工编辑
* 技能树`根节点`配置文件:
* 位置:`data/config.json`
* 说明:可编辑配置关键词等字段,其中 `node_id` 字段是生成的,请勿编辑
* 技能树`难度节点`
* 位置:`data/xxx`,例如: `data/1.python初阶`
* 说明:
* 每个技能树有 3 个等级,目录前的序号是必要的,用来保持文件夹目录的顺序
* 每个目录下有一个 `config.json` 可配置关键词信息,其中 `node_id` 字段是生成的,请勿编辑
* 技能树`章节点`
* 位置:`data/xxx/xxx`,例如:`data/1.python初阶/1.预备知识`
* 说明:
* 每个技能树的每个难度等级有 n 个章节,目录前的序号是必要的,用来保持文件夹目录的顺序
* 每个目录下有一个 `config.json` 可配置关键词信息,其中 `node_id` 字段是生成的,请勿编辑
* 技能树`知识节点`
* 位置:`data/xxx/xxx`,例如:`data/1.python初阶/1.预备知识`
* 说明:
* 每个技能树的每章有 n 个知识节点,目录前的序号是必要的,用来保持文件夹目录的顺序
* 每个目录下有一个 `config.json`
* 其中 `node_id` 字段是生成的,请勿编辑
* 其中 `keywords` 可配置关键字字段
* 其中 `children` 可配置该`知识节点`下的子树结构信息,参考后面描述
* 其中 `export` 可配置该`知识节点`下的导出习题信息,参考后面描述
## `知识节点` 子树信息结构
例如 `data/1.python初阶/1.预备知识/1.Python简介/config.json` 里配置对该知识节点子树信息结构:
```json
{
// ...
"children": [
{
"Python都能做什么": {
"keywords": [],
"children": [],
"node_id": "python-4-0"
}
},
{
"python起源和发展": {
"keywords": [],
"children": [],
"node_id": "python-insert-2"
}
},
{
"python语言特点": {
"keywords": [],
"children": [],
"node_id": "python-insert-3"
}
}
],
}
```
## `知识节点` 的习题配置规则(一)
例如 `data/1.python初阶/1.预备知识/1.Python简介/config.json` 里配置对该知识节点导出的习题
```json
{
// ...
"export": [
"helloworld.json"
// ...
]
}
```
其中`"helloworld.json"`是习题的配置文件,文件如下:
```json
{
"exercise_id": 33,
"source": "helloworld.py",
"depends": [],
"multiline": [
{
"str1 = \"Hello,\"": "",
"str2 = \"World!\"": "str = \"Hello,World!\"",
"print('str1'+'str2')": "print(str)"
},
{
"str1 = \"Hello,\"": "",
"str2 = \"World!\"": "",
"print('str1'+'str2')": "print(\"Hello\" +\",\" +\"World!\")"
},
{
"print('str1'+'str2')": "print(str1+str2)"
}
]
}
```
其中:
* `"exercise_id"` 是脚本填充的字段,编辑的时候不用填写
* `"source"` 指定了习题的来源文件
* `"depends"`: 指定了习题依赖的同知识点下的其他源文件
* `"multiline"`: 是习题选项替换的规则之一
#### 习题源代码
`"helloworld.py"`的源代码如下:
```python
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Hello World
# 描述:输出 "Hello,World!" 字符串,找出错的那项。
if __name__ == '__main__':
str1 = "Hello,"
str2 = "World!"
print('str1'+'str2')
```
源代码的头部注释固定格式,配置`作者`,`标题`,`描述`,其中描述可以是MarkDown格式
#### 习题源代码替换规则
对于习题代码 `"helloworld.py"` 的代码变种替换规则配置在`"helloworld.json"` 里面。有两种替换规则:
**单行替换规则**
* 配置由`one_line`字段指定的单行替换字典
* 格式是:`"<源字符串>"`: [`"<替换字符串A>"`, `<替换字符串B>`,...],
* 其中每个 `"<源字符串>"` `/` `"<替换字符串A>"` 被生成为是一个替换选项
* 指定的配置应该能至少生成 `3+` 个替换选项
```json
{
"one_line": {
"printf": ["print"],
"return 0;": ["return 0"],
"(\"Hello,Wrold!\")": [" \"Hello,Wrold!\""]
}
}
```
上面的替换规则会将代码替换成 3 个变种的代码:
```c
// 变种代码1
#include <stdio.h>
int main(int argc, char** argv){
print("Hello,Wrold!");
return 0;
}
```
```c
// 变种代码2
#include <stdio.h>
int main(int argc, char** argv){
print("Hello,Wrold!");
return 0
}
```
```c
// 变种代码3
#include <stdio.h>
int main(int argc, char** argv){
print "Hello,Wrold!";
return 0
}
```
这些变种代码将会作为技能树该知识点该代码选择题的选项。
**多行替换规则**
* 配置由`multiline`字段指定的多行替换数组
* 数组的每个元素是一组替换规则,会整组被替换
例如:
```json
{
"multiline": [
{
"printf": "print"
},
{
"int main(int argc, char** argv){" : "int main(char** argv){",
"return 0;" : "return 0",
},
{
"#include <stdio.h>": ""
}
]
}
```
同样,该配置将支持将源代码生成3个变种代码
```c
// 变种代码1
#include <stdio.h>
int main(int argc, char** argv){
print("Hello,Wrold!");
return 0;
}
```
```c
// 变种代码2, 注意第2组替换规则,包含了两行替换
#include <stdio.h>
int main(char** argv){
print("Hello,Wrold!");
return 0
}
```
```c
// 变种代码3
int main(int argc, char** argv){
print("Hello,Wrold!");
return 0;
}
```
## `知识节点` 的习题配置规则(二)
另外一种更便利的配置习题的方式是直接基于 MarkDown 格式配置。还是以`"helloworld.json"` 为例子展开描述。
此时,`"helloworld.json"` 简化为:
```json
{
"type": "code_options",
"author": "幻灰龙",
"source": "helloworld.md",
}
```
其中 type 字段目前都固定是 `code_options`。根据具体情况写好其它字段,注意这里 `source` 的文件名,我们指定了一个 Markdown 文件。现在我们新建一个 `helloworld.md` 并编辑为:
````markdown
# Hello World
输出 "Hello,World!" 字符串,找出错的那项。
## 答案
```python
if __name__ == '__main__':
str1 = "Hello,"
str2 = "World!"
print('str1'+'str2')
```
## 选项
### 两字符串变量拼接
```python
if __name__ == '__main__':
str1 = "Hello,"
str2 = "World!"
print(str1+str2)
```
### 两字符串字面量拼接
```python
if __name__ == '__main__':
print("Hello,"+"World!")
```
### 两字符串字面量拼接成字符串变量
```python
if __name__ == '__main__':
str = "Hello," + "World!"
print(str)
```
````
这是一个最基本的习题结构,它包含标题、答案、选项,注意这几个一级和二级标题必须填写正确,解释器会读取这几个标题。而选项的标题会被直接忽略掉,在
最终生成的习题中不包含选项的三级标题,所以这个标题可以用来标注一些编辑信息,例如“此选项没有关闭文件连接”,“类型错误”等等。
## 习题配置规则的选择
我们介绍了两种习题编辑规则,目前Python技能树这里大量使用了规则(一),这是历史编辑遗留。新增习题建议使用规则(二),更简洁方便。
## 技能树合成
在根目录下执行 `python main.py` 会合成技能树文件,合成的技能树文件: `data/tree.json`
* 合成过程中,会自动检查每个目录下 `config.json` 里的 `node_id` 是否存在,不存在则生成
* 合成过程中,会自动检查每个知识点目录下 `config.json` 里的 `export` 里导出的习题配置,检查是否存在`exercise_id` 字段,如果不存在则生成
{
"export": [
"helloworld.json"
],
"keywords": [],
"children": [
{
"Python都能做什么": {
"keywords": [],
"children": [],
"node_id": "python-4-0"
}
},
{
"python起源和发展": {
"keywords": [],
"children": [],
"node_id": "python-insert-2"
}
},
{
"python语言特点": {
"keywords": [],
"children": [],
"node_id": "python-insert-3"
}
}
],
"node_id": "python-3-0"
}
\ No newline at end of file
{
"exercise_id": 33,
"source": "helloworld.py",
"depends": [],
"multiline": [
{
"str1 = \"Hello,\"": "",
"str2 = \"World!\"": "str = \"Hello,World!\"",
"print('str1'+'str2')": "print(str)"
},
{
"str1 = \"Hello,\"": "",
"str2 = \"World!\"": "",
"print('str1'+'str2')": "print(\"Hello\" +\",\" +\"World!\")"
},
{
"print('str1'+'str2')": "print(str1+str2)"
}
],
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Hello World
# 描述:输出 "Hello,World!" 字符串,找出错的那项。
if __name__ == '__main__':
str1 = "Hello,"
str2 = "World!"
print('str1'+'str2')
{
"one_line": {
"print(\"\".join(result))": [
"print(\",\".join(result))",
"print(result)"
],
"result.append(token[\"key\"])": [
"result.append(token)"
]
},
"source": "class.py",
"depends": [],
"exercise_id": 26,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:面向对象
# 描述:使用 Python Class 组织代码,输出“猴子在苹果树下打架”
class Monkey(object):
def __init__(self) -> None:
super().__init__()
self.tokens = []
def add_action_token(self, token):
self.tokens.append({"key": token})
def play(self):
result = []
for token in self.tokens:
result.append(token["key"])
print("".join(result))
def main():
m = Monkey()
m.add_action_token("猴子在")
m.add_action_token("苹果树下")
m.add_action_token("打架")
m.play()
if __name__ == '__main__':
main()
{
"export": [
"process.json",
"function.json",
"class.json"
],
"keywords": [],
"children": [],
"node_id": "python-3-1"
}
\ No newline at end of file
{
"one_line": {
"token[\"key\"] ": [
"token"
],
"print(\"\".join(result))": [
"print(result)",
"print(\"\".join(result))"
],
"dump_monkey(tokens):": [
"dumpmonkey(tokens):"
]
},
"source": "function.py",
"depends": [],
"exercise_id": 28,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:函数代码
# 描述:使用 Python 函数 组织代码,输出“猴子在苹果树下打架”
def dump_monkey(tokens):
result = []
for token in tokens:
result.append(token["key"])
print("".join(result))
if __name__ == '__main__':
tokens = [
{
"key": "猴子在"
},
{
"key": "苹果树下"
},
{
"key": "打架"
}
]
dump_monkey(tokens)
{
"one_line": {
"token[\"key\"] ": [
"token"
],
"print(\"\".join(result))": [
"print(result)"
],
"for token in tokens": [
"for t in tokens"
],
"result = []": [
"result = {}"
]
},
"source": "process.py",
"depends": [],
"exercise_id": 27,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:基本的 Python 处理
# 描述:Python 过程性代码,用循环合并“猴子在苹果树下打架”文本并打印
if __name__ == '__main__':
tokens = [
{
"key": "猴子在"
},
{
"key": "苹果树下"
},
{
"key": "打架"
}
]
result = []
for token in tokens:
result.append(token["key"])
print("".join(result))
{
"export": [
"install.json"
],
"keywords": [],
"children": [
{
"Windows安装Python": {
"keywords": [],
"children": [],
"node_id": "python-4-1"
}
},
{
"Linux安装Python": {
"keywords": [],
"children": [],
"node_id": "python-4-2"
}
},
{
"MacOS安装Python": {
"keywords": [],
"children": [],
"node_id": "python-4-3"
}
}
],
"node_id": "python-3-2"
}
\ No newline at end of file
{
"one_line": {
"while True:": [
"while:"
],
"target = install.get(ret)": [
"target = install[ret]"
],
"if target is None:": [
"if target is not None:"
],
"print(\"* {}: {} 系统\".format(p, install[p]['platform']))": [
"print(\"* {}: {} 系统\".format(p))"
]
},
"source": "install.py",
"depends": [],
"exercise_id": 31,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:安装Python
# 描述:交互式提示程序,用户选择对应平台后,能正确输出对应平台上的安装包下载连接
def test():
install = {
"w": {
"platform": "Window",
"desc": "请下载 Windows 安装包安装:https://www.python.org/downloads/windows/"
},
"l": {
"platform": "Linux",
"desc": "请下载 Linux 的 Python 源码安装:https://www.python.org/downloads/source/",
},
"m": {
"platform": "MacOS",
"desc": "请下载 Mac 的安装包:https://www.python.org/downloads/macos/,或者使用 brew install python 安装",
}
}
print("Python 可以在全平台上安装,例如:")
for p in install:
print("* {}: {} 系统".format(p, install[p]['platform']))
while True:
ret = input("请选择安装平台[w/l/m]:")
target = install.get(ret)
if target is None:
print("不支持的平台")
else:
print("安装平台:{}".format(target['platform']))
print("安装说明:{}".format(target['desc']))
break
if __name__ == '__main__':
test()
{
"export": [
"run.json"
],
"keywords": [],
"children": [
{
"以交互方式运行": {
"keywords": [],
"children": [],
"node_id": "python-4-4"
}
},
{
"以脚本方式运行": {
"keywords": [],
"children": [],
"node_id": "python-4-5"
}
}
],
"node_id": "python-3-3"
}
\ No newline at end of file
{
"one_line": {
"break": [
"continue"
],
"if has_learn_i and has_learn_f": [
"if has_learn_i or has_learn_f"
],
"elif": [
"else if"
],
"item = run.get(ret)": [
"item = run[ret]"
]
},
"source": "run.py",
"depends": [],
"exercise_id": 32,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 运行方式
# 描述:提示用户选择想要了解的Python 的两种运行方式,选择后输出对应方式的基本说明,最后输出用户学习了几种运行方式
def test():
run = {
"i": {
"title": "交互式编程( Interactive )",
"desc": [
"打开终端,输入 python 回车",
"进入 Python 交互式命令行",
"输入 print('monkey king is coding!')"
]
},
"f": {
"title": "Python 源代源文件( File )",
"desc": [
"使用你喜欢的编辑器拷贝本练习的代码, 保存为run.py",
"打开终端,cd 到 run.py 保存的目录",
"输入 python run.py"
]
}
}
print("有两种基本的方式运行 Python")
for s in run:
item = run.get(s)
print("* {}: {}".format(s, item['title']))
has_learn_i = False
has_learn_f = False
while True:
ret = input("请选择你想了解的 Python 运行方式(输入:i/f选择,输入 q 退出):")
if ret == 'q':
break
elif ret == 'i':
has_learn_i = True
elif ret == 'f':
has_learn_f = True
item = run.get(ret)
if item is None:
print("[错误] 不支持的运行方式")
else:
desc = item['desc']
for i in range(0, len(desc)):
print("{}. {}".format(i, desc[i]))
if has_learn_i and has_learn_f:
print("[2/2]您已完成两种 Python 运行方式的学习")
elif has_learn_f:
print("[1/2]您已完成 Python 源代码方式运行学习")
elif has_learn_i:
print("[1/2]您已完成 Python 交互式命令行运行学习")
else:
print("[0/2]您似乎跳过了运行方式的学习?期待下次光临!")
if __name__ == '__main__':
test()
{
"export": [
"ide.json"
],
"keywords": [],
"children": [
{
"typing --- 类型提示支持": {
"keywords": [],
"children": [],
"node_id": "python-4-6"
}
},
{
"pydoc --- 文档生成器和在线帮助系统": {
"keywords": [],
"children": [],
"node_id": "python-4-7"
}
},
{
"Python Development Mode": {
"keywords": [],
"children": [],
"node_id": "python-4-8"
}
},
{
"Effects of the Python Development Mode": {
"keywords": [],
"children": [],
"node_id": "python-4-9"
}
},
{
"ResourceWarning Example": {
"keywords": [],
"children": [],
"node_id": "python-4-10"
}
},
{
"Bad file descriptor error example": {
"keywords": [],
"children": [],
"node_id": "python-4-11"
}
},
{
"doctest --- 测试交互性的Python示例": {
"keywords": [],
"children": [],
"node_id": "python-4-12"
}
},
{
"unittest --- 单元测试框架": {
"keywords": [],
"children": [],
"node_id": "python-4-13"
}
},
{
"unittest.mock --- mock对象库": {
"keywords": [],
"children": [],
"node_id": "python-4-14"
}
},
{
"unittest.mock上手指南": {
"keywords": [],
"children": [],
"node_id": "python-4-15"
}
},
{
"2to3 - 自动将Python 2 代码转为Python 3 代码": {
"keywords": [],
"children": [],
"node_id": "python-4-16"
}
},
{
"test --- Python回归测试包": {
"keywords": [],
"children": [],
"node_id": "python-4-17"
}
},
{
"test.support --- Utilities for the Python test suite": {
"keywords": [],
"children": [],
"node_id": "python-4-18"
}
},
{
"test.support.socket_helper --- Utilities for socket tests": {
"keywords": [],
"children": [],
"node_id": "python-4-19"
}
},
{
"test.support.script_helper --- Utilities for the Python execution tests": {
"keywords": [],
"children": [],
"node_id": "python-4-20"
}
},
{
"test.support.bytecode_helper --- Support tools for testing correct bytecode generation": {
"keywords": [],
"children": [],
"node_id": "python-4-21"
}
},
{
"使用PyCharm开发Python": {
"keywords": [],
"children": [],
"node_id": "python-insert-0"
}
},
{
"使用VSCode开发Python": {
"keywords": [],
"children": [],
"node_id": "python-insert-1"
}
}
],
"node_id": "python-3-4"
}
\ No newline at end of file
{
"one_line": {
"break": [
"continue"
],
"ide = ide_dict.get(ret)": [
"ide = ide_dict[ret]"
],
"if ide is None": [
"if ide is not None"
],
"input": [
"print"
],
"format(ide['desc'])": [
"format(ide['link'])"
]
},
"source": "ide.py",
"depends": [],
"exercise_id": 30,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python IDE
# 描述:提示用户选择想要了解的IDE,输出对应 IDE 介绍
def test():
ide_list = [
{
"shutcut": 'i',
"name": "IDEL",
"link": "https://docs.python.org/3/library/idle.html",
"desc": "Python 内置的IDE,功能比较一般"
},
{
"shutcut": 'v',
"name": "VIM",
"link": "http://www.vim.org/",
"desc": "如果你是个VIM爱好者,可以用VIM编写Python,但是Python的缩进处理会比较麻烦。当然,你在 Linux 服务器上的时候有时候就只能用VI/VIM了。"
},
{
"shutcut": 'c',
"name": "VSCode",
"link": "https://code.visualstudio.com/",
"desc": "VSCode 对Python的支持非常友好,配合几个插件后几乎是对 Python 开发最友好的IDE了"
},
{
"shutcut": 'p',
"name": "PyCharm",
"link": "https://www.jetbrains.com/pycharm/",
"desc": "jetbrains 出品的 PyCharm 也是 Python 开发者常用的IDE"
}
]
ide_dict = {}
short_cuts = []
for ide in ide_list:
s = ide['shutcut']
ide_dict[s] = ide
short_cuts.append(s)
print("常见的 Python IDE 列表:")
for s in ide_dict:
print('* {}: {}'.format(s, ide_dict[s]['name']))
while True:
print('')
ret = input("请选择你喜欢的IDE({}, q退出):".format('/'.join(short_cuts)))
if ret == 'q':
break
ide = ide_dict.get(ret)
if ide is None:
print("[错误] 不支持的选项")
else:
print("* IDE: {}".format(ide['name']))
print("* 链接: {}".format(ide['link']))
print("* 描述: {}".format(ide['desc']))
if __name__ == '__main__':
test()
{
"export": [
"style.json"
],
"keywords": [],
"children": [],
"node_id": "python-3-5"
}
\ No newline at end of file
{
"one_line": {
"type(node) == type('')": [
"type(node) == type([])"
],
"dump_markdown_list(node, depth+1)": [
"dump_markdown_list(node, depth)"
],
"print('{}* {}'.format(' '*depth, node))": [
"print('{}* {}'.format(' '**depth))"
]
},
"source": "style.py",
"depends": [],
"exercise_id": 29,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 编码规范
# 描述:输出MarkDown风格列表结构的 “学习 Python 编码规范以及相关工具和插件” 的介绍信息
def dump_markdown_list(tree, depth):
for node in tree:
if type(node) == type(''):
print('{}* {}'.format(' '*depth, node))
else:
print('')
dump_markdown_list(node, depth+1)
print('')
if __name__ == '__main__':
dump_markdown_list([
'Python 编码风格',
[
'请阅读 Google Python 编码风格指南:',
'[google-python-styleguide_zh_cn](https://zh-google-styleguide.readthedocs.io/en/latest/google-python-styleguide/python_style_rules /)'
],
'代码风格和自动完成工具链',
[
'推荐使用 VSCode 开发',
'请安装 VSCode 插件',
[
'Pylance',
'Python Path',
'请安装 pylint',
]
]
], 0)
{
"export": [
"import_json_example.json",
"import_other_module.json",
"import_with_from.json"
],
"keywords": [],
"children": [
{
"pip": {
"keywords": [],
"children": [],
"node_id": "python-4-22"
}
}
],
"node_id": "python-3-6"
}
\ No newline at end of file
{
"one_line": {
"import json": [
"#include <json>;",
"using json;",
"import json;"
]
},
"source": "import_json_example.py",
"depends": [],
"exercise_id": 163,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 模块导入1
# 描述:通过 import 导入Python内置库
import json
def dump_json(obj):
print(json.dumps(obj))
if __name__ == '__main__':
obj = {
'err': 'success',
'result': ['item1', 'item2']
}
dump_json(obj)
{
"multiline": [
{
"import import_json_example": "import import_json_example.dump_json",
"import_json_example.dump_json": "dump_json"
},
{
"import_json_example.dump_json": "dump_json"
},
{
"import import_json_example": "import import_json_example;"
}
],
"source": "import_other_module.py",
"depends": [
"import_json_example.py"
],
"exercise_id": 164,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 模块导入2
# 描述:通过 import 导入自己写的另外一个模块
import import_json_example
if __name__ == '__main__':
obj = {
'err': 'success',
'result': ['item1', 'item2']
}
import_json_example.dump_json(obj)
{
"multiline": [
{
"from import_json_example import dump_json": "from import_json_example import import_json_example",
"dump_json": "import_json_example.dump_json"
},
{
"from import_json_example import dump_json": "import dump_json from import_json_example"
},
{
"dump_json(obj)": "import_json_example.dump_json(obj)"
}
],
"source": "import_with_from.py",
"depends": [
"import_json_example.py"
],
"exercise_id": 165,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 模块导入3
# 描述:通过 from 语句导入模块
from import_json_example import dump_json
if __name__ == '__main__':
obj = {
'err': 'success',
'result': ['item1', 'item2']
}
dump_json(obj)
{
"keywords": [],
"node_id": "python-2-0"
}
\ No newline at end of file
{
"export": [
"step.json"
],
"keywords": [],
"children": [
{
"建议使用4个空格": {
"keywords": [],
"children": [],
"node_id": "python-4-23"
}
}
],
"node_id": "python-3-7"
}
\ No newline at end of file
{
"source": "step.py",
"depends": [],
"exercise_id": 83,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 缩进规则
# 描述:Python 的缩进在一个源文件里要保持一致,例如都是4个空格或者都是2个空格
# 全局代码
for i in range(0, 10):
print('global code: {}'.format(i))
if i == 5:
print('global code: *')
# 函数
def test():
for i in range(0, 10):
print('function code: {}'.format(i))
if i == 5:
print('function code: *')
# 类
class Test():
def __init__(self) -> None:
pass
def test(self):
for i in range(0, 10):
print('member function code: {}'.format(i))
if i == 5:
print('member function code: *')
if __name__ == '__main__':
test()
t = Test()
t.test()
{
"export": [
"util_builtin_01.json",
"util_builtin_02.json",
"input.json"
],
"keywords": [],
"children": [
{
"help": {
"keywords": [],
"children": [],
"node_id": "python-4-143"
}
},
{
"input": {
"keywords": [],
"children": [],
"node_id": "python-4-144"
}
},
{
"print": {
"keywords": [],
"children": [],
"node_id": "python-4-145"
}
},
{
"range": {
"keywords": [],
"children": [],
"node_id": "python-4-146"
}
},
{
"format": {
"keywords": [],
"children": [],
"node_id": "python-4-147"
}
},
{
"len": {
"keywords": [],
"children": [],
"node_id": "python-4-148"
}
},
{
"sorted": {
"keywords": [],
"children": [],
"node_id": "python-4-149"
}
},
{
"open": {
"keywords": [],
"children": [],
"node_id": "python-4-150"
}
},
{
"dir": {
"keywords": [],
"children": [],
"node_id": "python-4-151"
}
},
{
"enumerate/zip": {
"keywords": [],
"children": [],
"node_id": "python-4-152"
}
},
{
"type/isinstance": {
"keywords": [],
"children": [],
"node_id": "python-4-153"
}
},
{
"min/max/sum": {
"keywords": [],
"children": [],
"node_id": "python-4-154"
}
},
{
"abs/round/pow/divmod": {
"keywords": [],
"children": [],
"node_id": "python-4-155"
}
}
],
"node_id": "python-3-16"
}
\ No newline at end of file
{
"one_line": {
"random.randint": [
"random.rand"
],
"continue": [
"break"
],
"if n == v": [
"if n != v"
],
"elif n < v": [
"elif n > v"
],
"elif n > v": [
"elif n < v"
],
"input": [
"scanf",
"readline"
]
},
"source": "input.py",
"depends": [],
"exercise_id": 91,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 基本输入
# 描述:心里想一个0-100之间的数字,让用户猜,如果小了或者大了,就给予提示,直到用户猜到
import random
def gauss_num():
v = random.randint(0, 100)
while True:
n = input("请输入0-100之间的一个数字:")
try:
n = int(n)
except:
print("无效的数字")
continue
if n == v:
print("你猜对了!")
break
elif n < v:
print("你猜错了,我想到的数字比{}大".format(n))
elif n > v:
print("你猜错了,我想到的数字比{}小".format(n))
if __name__ == '__main__':
gauss_num()
{
"one_line": {
"abs(-1) == 1": [
"abs(-1) != 1"
],
"max(10, 100) == 100": [
"max(10, 100) == 10"
],
"min(10, 100) == 10": [
"min(10, 100) == 100"
],
"round(3.5) == 3": [
"round(3.5) == 4"
],
"pow(2, 4) == 16": [
"pow(2, 4) == 8"
],
"all([True, True]) == True": [
"all([True, False]) == True"
],
"any([True, False]) == True": [
"any([True, True]) == True"
],
"bin(2) == '0b10'": [
"bin(2) == '0b00'"
],
"bool({}) == False": [
"bool({}) == True"
],
"bytes([0, 1]) == b'\\x00\\x01'": [
"bytes([0, 1]) == b'\\x01\\x01'"
],
"str(1) == '1'": [
"str(1) == 1"
],
"callable(abs) == True": [
"callable(abs) == False"
],
"chr(97) == 'a'": [
"chr(97) == 'b'"
],
"'count' in dir([])": [
"'count' not in dir([])"
],
"float(1) == 1.0": [
"float(1) == 1.01"
],
"'a, b, c'": [
"'a.b.c'"
],
"hash(chr(97))": [
"hash(chr(98))"
],
"'0x1'": [
"'0x0'"
],
"type({}) ==": [
"type([]) =="
]
},
"source": "util_builtin_01.py",
"depends": [],
"exercise_id": 230,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 常用内置方法(1)
# 描述:内置函数基本用例,基本测试+执行,,每个 assert 结果都是 True
if __name__ == '__main__':
assert abs(-1) == 1
assert max(10, 100) == 100
assert min(10, 100) == 10
assert round(3.5) == 3
assert pow(2, 4) == 16
assert all([True, True]) == True
assert any([True, False]) == True
assert ascii('你') == "'\\u4f60'"
assert bin(2) == '0b10'
assert bool({}) == False
assert bytes([0, 1]) == b'\x00\x01'
assert str(1) == '1'
assert callable(abs) == True
assert chr(97) == 'a'
assert 'count' in dir([])
assert float(1) == 1.0
assert '{}, {}, {}'.format('a', 'b', 'c') == 'a, b, c'
assert hash("a") == hash(chr(97))
assert hex(1) == '0x1'
assert type({}) == type({'a': 1})
{
"one_line": {
"assert index == [0, 1, 2]": [
"assert index == [1, 2, 3]"
],
"assert sum([1, -1, 3] == 3)": [
"assert sum([1, -1, 3] == 5)"
],
"(1, 4), (2, 5), (3, 6)": [
"1, 4, 2, 5, 3, 6"
],
"assert len(seasons) == 4": [
"assert seasons.length == 4"
],
"assert shortcut == ['S', 'S', 'F', 'W']": [
"assert shortcut == ['S', 'F', 'W']"
],
"len(non_s_seasons) == 2": [
"len(non_s_seasons) == 3"
],
"assert len(s_seasons) == 2": [
"assert len(s_seasons) == 1"
]
},
"source": "util_builtin_02.py",
"depends": [],
"exercise_id": 236,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 常用内置方法(2)
# 描述:列表相关内置函数基本用例,基本测试+执行,每个 assert 结果都是 True
if __name__ == '__main__':
index = []
for i in range(0, 3):
index.append(i)
assert index == [0, 1, 2]
assert sum([1, -1, 3] == 3)
x = [1, 2, 3]
y = [4, 5, 6]
zipped = zip(x, y)
assert list(zipped) == [(1, 4), (2, 5), (3, 6)]
seasons = ['Spring', 'Summer', 'Fall', 'Winter']
assert len(seasons) == 4
shortcut = list(map(lambda s: s[0], seasons))
assert shortcut == ['S', 'S', 'F', 'W']
non_s_seasons = filter(lambda s: s[0] == 'S', seasons)
assert len(non_s_seasons) == 2
s_seasons = list(filter(lambda s: s[0] == 'S', seasons))
assert len(s_seasons) == 2
{
"export": [],
"keywords": [],
"children": [
{
"总体概念": {
"keywords": [],
"children": [
{
"迭代": {
"keywords": [],
"children": [],
"node_id": "python-5-1358"
}
},
{
"缓存": {
"keywords": [],
"children": [],
"node_id": "python-5-1359"
}
},
{
"透明度": {
"keywords": [],
"children": [],
"node_id": "python-5-1360"
}
}
],
"node_id": "python-4-1423"
}
},
{
"流程控制": {
"keywords": [],
"children": [
{
"捕获异常": {
"keywords": [],
"children": [],
"node_id": "python-5-1361"
}
},
{
"异常链": {
"keywords": [],
"children": [],
"node_id": "python-5-1362"
}
},
{
"当一切顺利的时候": {
"keywords": [],
"children": [],
"node_id": "python-5-1363"
}
},
{
"继续执行,无论异常如何": {
"keywords": [],
"children": [],
"node_id": "python-5-1364"
}
},
{
"优化循环": {
"keywords": [],
"children": [],
"node_id": "python-5-1365"
}
},
{
"with语句": {
"keywords": [],
"children": [],
"node_id": "python-5-1366"
}
},
{
"条件表达式": {
"keywords": [],
"children": [],
"node_id": "python-5-1367"
}
}
],
"node_id": "python-4-1424"
}
},
{
"迭代": {
"keywords": [],
"children": [
{
"序列解包": {
"keywords": [],
"children": [],
"node_id": "python-5-1368"
}
},
{
"列表解析式": {
"keywords": [],
"children": [],
"node_id": "python-5-1369"
}
},
{
"生成器表达式": {
"keywords": [],
"children": [],
"node_id": "python-5-1370"
}
},
{
"集合解析式": {
"keywords": [],
"children": [],
"node_id": "python-5-1371"
}
},
{
"字典解析式": {
"keywords": [],
"children": [],
"node_id": "python-5-1372"
}
},
{
"将迭代器链接在一起": {
"keywords": [],
"children": [],
"node_id": "python-5-1373"
}
},
{
"将迭代器压缩在一起": {
"keywords": [],
"children": [],
"node_id": "python-5-1374"
}
}
],
"node_id": "python-4-1425"
}
},
{
"容器数据类型": {
"keywords": [],
"children": [
{
"集合": {
"keywords": [],
"children": [],
"node_id": "python-5-1375"
}
},
{
"命名元组": {
"keywords": [],
"children": [],
"node_id": "python-5-1376"
}
},
{
"有序字典": {
"keywords": [],
"children": [],
"node_id": "python-5-1377"
}
},
{
"带有默认值的字典": {
"keywords": [],
"children": [],
"node_id": "python-5-1378"
}
}
],
"node_id": "python-4-1426"
}
},
{
"导入代码": {
"keywords": [],
"children": [
{
"回退(备用)导入": {
"keywords": [],
"children": [],
"node_id": "python-5-1379"
}
},
{
"从即将发布的版本中导入": {
"keywords": [],
"children": [],
"node_id": "python-5-1380"
}
},
{
"使用__all__进行自定义导入": {
"keywords": [],
"children": [],
"node_id": "python-5-1381"
}
},
{
"相对导入": {
"keywords": [],
"children": [],
"node_id": "python-5-1382"
}
},
{
"__import__函数": {
"keywords": [],
"children": [],
"node_id": "python-5-1383"
}
},
{
"importlib模块": {
"keywords": [],
"children": [],
"node_id": "python-5-1384"
}
}
],
"node_id": "python-4-1427"
}
},
{
"令人兴奋的Python扩展:NIST的随机数信标": {
"keywords": [],
"children": [
{
"如何安装NIST信标库": {
"keywords": [],
"children": [],
"node_id": "python-5-1385"
}
},
{
"示例:获取值": {
"keywords": [],
"children": [],
"node_id": "python-5-1386"
}
},
{
"示例:模拟抛硬币并记录每次正反面的结果": {
"keywords": [],
"children": [],
"node_id": "python-5-1387"
}
},
{
"安装Pandas和matplotlib": {
"keywords": [],
"children": [],
"node_id": "python-5-1388"
}
},
{
"创建文本文件": {
"keywords": [],
"children": [],
"node_id": "python-5-1389"
}
},
{
"使用Pandas显示数据": {
"keywords": [],
"children": [],
"node_id": "python-5-1390"
}
},
{
"进行一些数据分析": {
"keywords": [],
"children": [],
"node_id": "python-5-1391"
}
},
{
"使用matplotlib进行绘图": {
"keywords": [],
"children": [],
"node_id": "python-5-1392"
}
},
{
"图表的类型": {
"keywords": [],
"children": [],
"node_id": "python-5-1393"
}
},
{
"安装Scrapy": {
"keywords": [],
"children": [],
"node_id": "python-5-1394"
}
},
{
"运行Scrapy": {
"keywords": [],
"children": [],
"node_id": "python-5-1395"
}
},
{
"使用Scrapy获取Web数据": {
"keywords": [],
"children": [],
"node_id": "python-5-1396"
}
},
{
"通过Scrapy浏览网页": {
"keywords": [],
"children": [],
"node_id": "python-5-1397"
}
},
{
"shell选项": {
"keywords": [],
"children": [],
"node_id": "python-5-1398"
}
},
{
"安装Beautiful Soup": {
"keywords": [],
"children": [],
"node_id": "python-5-1399"
}
},
{
"使用Beautiful Soup": {
"keywords": [],
"children": [],
"node_id": "python-5-1400"
}
},
{
"如何安装feedparser库": {
"keywords": [],
"children": [],
"node_id": "python-5-1401"
}
},
{
"如何使用feedparser库": {
"keywords": [],
"children": [],
"node_id": "python-5-1402"
}
},
{
"安装NumPy": {
"keywords": [],
"children": [],
"node_id": "python-5-1403"
}
},
{
"使用NumPy": {
"keywords": [],
"children": [],
"node_id": "python-5-1404"
}
},
{
"使用NumPy数组": {
"keywords": [],
"children": [],
"node_id": "python-5-1405"
}
},
{
"统计度量": {
"keywords": [],
"children": [],
"node_id": "python-5-1406"
}
},
{
"如何安装Pillow库": {
"keywords": [],
"children": [],
"node_id": "python-5-1407"
}
},
{
"图像显示:确定文件的大小和类型并显示": {
"keywords": [],
"children": [],
"node_id": "python-5-1408"
}
},
{
"图像处理:裁剪图像的一部分": {
"keywords": [],
"children": [],
"node_id": "python-5-1409"
}
},
{
"随机数": {
"keywords": [],
"children": [],
"node_id": "python-5-1410"
}
},
{
"密码生成器": {
"keywords": [],
"children": [],
"node_id": "python-5-1411"
}
}
],
"node_id": "python-4-1428"
}
}
],
"node_id": "python-3-8"
}
\ No newline at end of file
{
"source": "call.py",
"depends": [],
"exercise_id": 197,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 函数调用
# 描述:使用函数设计一组 “容器API”:init/set/get/exist
def init():
return {}
def set(dict, key, value):
dict[key] = value
def get(dict, key):
return dict.get(key)
def exist(dict, key):
return dict.get(key) is not None
def test():
dict = init()
for i in range(10):
key = "key_{}".format(i)
value = i
set(dict, key, value)
test_key = "key_4"
if exist(dict, test_key):
test_value = get(dict, test_key)
print("key is: {}, value is: {}".format(test_key, test_value))
if __name__ == '__main__':
test()
{
"export": [
"helloworld2.json",
"fact1.json",
"fact2.json",
"fibonacci1.json",
"fibonacci2.json",
"call.json"
],
"keywords": [],
"children": [
{
"参数": {
"keywords": [],
"children": [
{
"规划时的灵活性": {
"keywords": [],
"children": [],
"node_id": "python-5-1412"
}
},
{
"可变位置参数": {
"keywords": [],
"children": [],
"node_id": "python-5-1413"
}
},
{
"可变关键字参数": {
"keywords": [],
"children": [],
"node_id": "python-5-1414"
}
},
{
"组合不同类型的参数": {
"keywords": [],
"children": [],
"node_id": "python-5-1415"
}
},
{
"调用具有可变参数的函数": {
"keywords": [],
"children": [],
"node_id": "python-5-1416"
}
},
{
"传递参数": {
"keywords": [],
"children": [],
"node_id": "python-5-1417"
}
},
{
"自省": {
"keywords": [],
"children": [],
"node_id": "python-5-1418"
}
}
],
"node_id": "python-4-1429"
}
},
{
"装饰器": {
"keywords": [],
"children": [
{
"闭包": {
"keywords": [],
"children": [],
"node_id": "python-5-1419"
}
},
{
"包装器": {
"keywords": [],
"children": [],
"node_id": "python-5-1420"
}
},
{
"带参数的装饰器": {
"keywords": [],
"children": [],
"node_id": "python-5-1421"
}
},
{
"带参数或不带参数的装饰器": {
"keywords": [],
"children": [],
"node_id": "python-5-1422"
}
}
],
"node_id": "python-4-1430"
}
},
{
"函数注解": {
"keywords": [],
"children": [
{
"提取样板": {
"keywords": [],
"children": [],
"node_id": "python-5-1423"
}
},
{
"用装饰器进行注解": {
"keywords": [],
"children": [],
"node_id": "python-5-1424"
}
}
],
"node_id": "python-4-1431"
}
},
{
"生成器": {
"keywords": [],
"children": [],
"node_id": "python-4-1432"
}
},
{
"lambda": {
"keywords": [],
"children": [],
"node_id": "python-4-1433"
}
},
{
"自省": {
"keywords": [],
"children": [
{
"标识对象类型": {
"keywords": [],
"children": [],
"node_id": "python-5-1425"
}
},
{
"模块和软件包": {
"keywords": [],
"children": [],
"node_id": "python-5-1426"
}
},
{
"文档字符串": {
"keywords": [],
"children": [
{
"描述函数的作用": {
"keywords": [],
"children": [],
"node_id": "python-6-222"
}
},
{
"返回值": {
"keywords": [],
"children": [],
"node_id": "python-6-223"
}
},
{
"包含预期的异常": {
"keywords": [],
"children": [],
"node_id": "python-6-224"
}
}
],
"node_id": "python-5-1427"
}
}
],
"node_id": "python-4-1434"
}
}
],
"node_id": "python-3-9"
}
\ No newline at end of file
{
"source": "fact1.py",
"depends": [],
"exercise_id": 190,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 函数
# 描述:循环计算阶乘函数
def fact(n):
sum = 1
for i in range(0, n):
sum *= (i+1)
return sum
if __name__ == '__main__':
print(fact(10))
{
"source": "fact2.py",
"depends": [],
"exercise_id": 244,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 函数递归
# 描述:递归计算阶乘函数
def fact(n):
if n == 1:
return 1
return n*fact(n-1)
if __name__ == '__main__':
print(fact(998))
{
"source": "fibonacci1.py",
"depends": [],
"exercise_id": 201,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 函数递归
# 描述:递归计算斐波那契函数
def fibonacci(n):
if n == 1 or n == 2:
return 1
return fibonacci(n-1) + fibonacci(n-2)
if __name__ == '__main__':
print(fibonacci(6))
{
"source": "fibonacci2.py",
"depends": [],
"exercise_id": 239,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 函数+缓存
# 描述:递归计算斐波那契函数, 带缓存
def fibonacci(n, cache):
if n == 1 or n == 2:
return 1
if cache.get(n) is not None:
return cache[n]
cache[n] = fibonacci(n-1, cache) + fibonacci(n-2, cache)
return cache[n]
if __name__ == '__main__':
print(fibonacci(6, {}))
{
"one_line": {
"circulate_print(str, count+1)": [
"circulate_print(str, count)"
],
"if count == 5": [
"if count > 5"
],
"count=0": [
"count"
]
},
"source": "helloworld2.py",
"depends": [],
"exercise_id": 166,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Hello World 进阶
# 描述:使用递归循环输出Hello World的每个字符,循环5次
def circulate_print(str, count=0):
if count == 5:
return
for char in str:
print(char)
circulate_print(str, count+1)
if __name__ == '__main__':
str = "Hello,World!"
circulate_print(str)
{
"export": [
"key_value_set.json",
"hash_key_value_set.json",
"hash_key_value_set_by_compose.json"
],
"keywords": [],
"children": [
{
"继承": {
"keywords": [],
"children": [
{
"多重继承": {
"keywords": [],
"children": [],
"node_id": "python-5-1428"
}
},
{
"方法解析顺序": {
"keywords": [],
"children": [],
"node_id": "python-5-1429"
}
},
{
"使用super函数将控制权传递给其他类": {
"keywords": [],
"children": [],
"node_id": "python-5-1430"
}
},
{
"自省": {
"keywords": [],
"children": [],
"node_id": "python-5-1431"
}
}
],
"node_id": "python-4-1435"
}
},
{
"如何创建类": {
"keywords": [],
"children": [
{
"在运行时创建类": {
"keywords": [],
"children": [],
"node_id": "python-5-1432"
}
},
{
"元类": {
"keywords": [],
"children": [],
"node_id": "python-5-1433"
}
},
{
"控制命名空间": {
"keywords": [],
"children": [],
"node_id": "python-5-1434"
}
}
],
"node_id": "python-4-1436"
}
},
{
"成员变量": {
"keywords": [],
"children": [
{
"属性": {
"keywords": [],
"children": [],
"node_id": "python-5-1435"
}
},
{
"描述器": {
"keywords": [],
"children": [],
"node_id": "python-5-1436"
}
}
],
"node_id": "python-4-1437"
}
},
{
"方法": {
"keywords": [],
"children": [
{
"非绑定方法": {
"keywords": [],
"children": [],
"node_id": "python-5-1437"
}
},
{
"绑定方法": {
"keywords": [],
"children": [],
"node_id": "python-5-1438"
}
}
],
"node_id": "python-4-1438"
}
},
{
"魔术方法": {
"keywords": [],
"children": [
{
"处理成员变量": {
"keywords": [],
"children": [],
"node_id": "python-5-1439"
}
},
{
"字符串表示": {
"keywords": [],
"children": [
{
"字节字符串": {
"keywords": [],
"children": [
{
"借助chr和ord进行简单的转换": {
"keywords": [],
"children": [],
"node_id": "python-7-34"
}
},
{
"借助struct模块进行复杂的转换": {
"keywords": [],
"children": [],
"node_id": "python-7-35"
}
}
],
"node_id": "python-6-225"
}
},
{
"文本": {
"keywords": [],
"children": [
{
"Unicode": {
"keywords": [],
"children": [],
"node_id": "python-7-36"
}
},
{
"编码": {
"keywords": [],
"children": [],
"node_id": "python-7-37"
}
}
],
"node_id": "python-6-226"
}
},
{
"简单的替换": {
"keywords": [],
"children": [],
"node_id": "python-6-227"
}
},
{
"格式化": {
"keywords": [],
"children": [
{
"在对象中查找值": {
"keywords": [],
"children": [],
"node_id": "python-7-38"
}
},
{
"区分字符串类型": {
"keywords": [],
"children": [],
"node_id": "python-7-39"
}
},
{
"标准格式规范": {
"keywords": [],
"children": [],
"node_id": "python-7-40"
}
},
{
"为文本文档制作目录": {
"keywords": [],
"children": [],
"node_id": "python-7-41"
}
},
{
"自定义格式规范": {
"keywords": [],
"children": [],
"node_id": "python-7-42"
}
}
],
"node_id": "python-6-228"
}
}
],
"node_id": "python-5-1440"
}
}
],
"node_id": "python-4-1439"
}
}
],
"node_id": "python-3-10"
}
\ No newline at end of file
{
"multiline": [
{
"hash_set = {}": "",
"hash_set[key] = value": "hash_set[key] = {}"
},
{
"return []": "return None"
},
{
"value = hashset.hget('puzzle', key)": "value = hashset.get('puzzle', key)"
},
{
"hashset.hset('puzzle', 'good', 'bye!')": "hashset.hset('good', 'bye!')"
}
],
"source": "hash_key_value_set.py",
"depends": [
"key_value_set.py"
],
"exercise_id": 169,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 类的基本使用(2)
# 描述:继承容器类,扩展功能,支持类似redis的 hset/hget/hkeys 扩展接口
from key_value_set import KeyValueSet
class HashKeyValueSet(KeyValueSet):
def __init__(self) -> None:
super().__init__()
def hset(self, hash_key, key, value):
hash_set = self.get(hash_key)
if hash_set is None:
hash_set = {}
hash_set[key] = value
self.set(hash_key, hash_set)
else:
hash_set[key] = value
self.set(hash_key, hash_set)
def hget(self, hash_key, key):
hash_set = self.get(hash_key)
if hash_set is None:
return None
else:
return hash_set.get(key)
def hkeys(self, hash_key):
hash_set = self.get(hash_key)
if hash_set is None:
return []
else:
return hash_set.keys()
def test():
hashset = HashKeyValueSet()
hashset.hset('puzzle', 'hello', 'world!')
hashset.hset('puzzle', 'monkey', 'king!')
hashset.hset('puzzle', 'tomorrow', 'is another day')
hashset.hset('puzzle', 'good', 'bye!')
keys = hashset.hkeys('puzzle')
for key in keys:
ret = input("猜一猜下半句是什么? {} -> :".format(key))
value = hashset.hget('puzzle', key)
if ret == value:
print('你太厉害了,这都能猜得到!')
else:
print('哈哈,肯定猜不到得啦:{}->{}'.format(key, value))
if __name__ == '__main__':
test()
{
"one_line": {
"self.kvset.set": [
"self.set"
],
"self.kvset.get": [
"self.get"
],
"KeyValueSet()": [
""
]
},
"source": "hash_key_value_set_by_compose.py",
"depends": [
"key_value_set.py"
],
"exercise_id": 168,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 类的基本使用(3)
# 描述:类的组合,使用组合而非继承实现类的扩展,支持类似redis的 hset/hget/hkeys 扩展接口
from key_value_set import KeyValueSet
class HashKeyValueSet:
def __init__(self, kvset) -> None:
super().__init__()
self.kvset = kvset
def hset(self, hash_key, key, value):
hash_set = self.kvset.get(hash_key)
if hash_set is None:
hash_set = {}
hash_set[key] = value
self.kvset.set(hash_key, hash_set)
else:
hash_set[key] = value
self.kvset.set(hash_key, hash_set)
def hget(self, hash_key, key):
hash_set = self.kvset.get(hash_key)
if hash_set is None:
return None
else:
return hash_set.get(key)
def hkeys(self, hash_key):
hash_set = self.kvset.get(hash_key)
if hash_set is None:
return []
else:
return hash_set.keys()
def test():
hashset = HashKeyValueSet(KeyValueSet())
hashset.hset('puzzle', 'hello', 'world!')
hashset.hset('puzzle', 'monkey', 'king!')
hashset.hset('puzzle', 'tomorrow', 'is another day')
hashset.hset('puzzle', 'good', 'bye!')
keys = hashset.hkeys('puzzle')
for key in keys:
ret = input("猜一猜下半句是什么? {} -> :".format(key))
value = hashset.hget('puzzle', key)
if ret == value:
print('你太厉害了,这都能猜得到!')
else:
print('哈哈,肯定猜不到得啦:{}->{}'.format(key, value))
if __name__ == '__main__':
test()
{
"one_line": {
"self.dict.get(key)": [
"self.dict[key]"
],
"is not None": [
"is None"
],
"len(self.dict.keys())": [
"self.dict.keys().length()"
],
"value = kv.get(key)": [
"value = kv[key]"
],
"if ret == value:": [
"if ret = value:",
"if ret != value:"
]
},
"source": "key_value_set.py",
"depends": [],
"exercise_id": 167,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 类的基本使用(1)
# 描述:编写一个kv容器类,支持 set/get/exist/keys/count 接口
class KeyValueSet:
def __init__(self) -> None:
self.dict = {}
def set(self, key, value):
self.dict[key] = value
def get(self, key):
return self.dict.get(key)
def exist(self, key):
return self.dict.get(key) is not None
def keys(self):
return self.dict.keys()
def count(self):
return len(self.dict.keys())
def test():
kv = KeyValueSet()
kv.set('hello', 'world!')
kv.set('monkey', 'king!')
kv.set('tomorrow', 'is another day')
kv.set('good', 'bye!')
for key in kv.keys():
ret = input("猜一猜下半句是什么? {} -> :".format(key))
value = kv.get(key)
if ret == value:
print('你太厉害了,这都能猜得到!')
else:
print('哈哈,肯定猜不到得啦:{}->{}'.format(key, value))
if __name__ == '__main__':
test()
{
"source": "calc.py",
"depends": [],
"exercise_id": 76,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 顺序语句
# 描述:一行一个语句,计算长方形面积
def test():
print("* 如果想计算一个长方形的面积")
print("* 那就先定义长宽,例如:x = 10, y=20")
x = 10
y = 20
print("* 紧接着,我们计算长方形的面积:s = x * y")
s = x * y
print("* 现在可以输出结果了,该长方形的面积是:{}".format(s))
if __name__ == '__main__':
test()
{
"export": [
"calc.json"
],
"keywords": [],
"children": [],
"node_id": "python-3-11"
}
\ No newline at end of file
{
"export": [
"if-else.json",
"none.json"
],
"keywords": [],
"children": [
{
"if": {
"keywords": [],
"children": [
{
"if-else语句": {
"keywords": [],
"children": [],
"node_id": "python-5-64"
}
},
{
"if-elif-else结构": {
"keywords": [],
"children": [],
"node_id": "python-5-65"
}
},
{
"省略else代码块": {
"keywords": [],
"children": [],
"node_id": "python-5-66"
}
},
{
"使用if语句处理列表": {
"keywords": [],
"children": [
{
"检查特殊元素": {
"keywords": [],
"children": [],
"node_id": "python-6-16"
}
},
{
"确定列表不是空的": {
"keywords": [],
"children": [],
"node_id": "python-6-17"
}
}
],
"node_id": "python-5-67"
}
},
{
"设置if语句的格式": {
"keywords": [],
"children": [],
"node_id": "python-5-68"
}
}
],
"node_id": "python-4-96"
}
},
{
"elif": {
"keywords": [],
"children": [],
"node_id": "python-4-97"
}
},
{
"else": {
"keywords": [],
"children": [],
"node_id": "python-4-98"
}
},
{
"条件判断": {
"keywords": [],
"children": [],
"node_id": "python-4-99"
}
},
{
"这正是布尔值的用武之地": {
"keywords": [],
"children": [],
"node_id": "python-4-100"
}
},
{
"代码块嵌套": {
"keywords": [],
"children": [
{
"字典列表": {
"keywords": [],
"children": [],
"node_id": "python-5-69"
}
},
{
"在字典中存储列表": {
"keywords": [],
"children": [],
"node_id": "python-5-70"
}
},
{
"在字典中存储字典": {
"keywords": [],
"children": [],
"node_id": "python-5-71"
}
}
],
"node_id": "python-4-101"
}
},
{
"检查是否相等": {
"keywords": [],
"children": [],
"node_id": "python-4-102"
}
},
{
"检查是否相等时忽略大小写": {
"keywords": [],
"children": [],
"node_id": "python-4-103"
}
},
{
"检查是否不相等": {
"keywords": [],
"children": [],
"node_id": "python-4-104"
}
},
{
"数值比较": {
"keywords": [],
"children": [],
"node_id": "python-4-105"
}
},
{
"检查多个条件": {
"keywords": [],
"children": [],
"node_id": "python-4-106"
}
},
{
"检查特定值是否包含在列表中": {
"keywords": [],
"children": [],
"node_id": "python-4-107"
}
},
{
"布尔表达式": {
"keywords": [],
"children": [],
"node_id": "python-4-108"
}
}
],
"node_id": "python-3-12"
}
\ No newline at end of file
{
"one_line": {
"ret ==": [
"ret !=",
"ret >=",
"ret <="
],
"\"{}\".format(test)": [
"test"
],
"if ret == ": [
"if int(ret) == "
]
},
"source": "if-else.py",
"depends": [],
"exercise_id": 97,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 条件和分支(1)
# 描述:编写一个程序,能正确提示用户输入测试数字,判断是否是除以2等于5的数字。
def test():
test = 10
ret = input("有一个数除以2是5,请问它是什么?:")
if ret == "{}".format(test):
print("恭喜你答对了!")
else:
print("哎,这么简单都答不对,回去重修吧!")
if __name__ == '__main__':
test()
{
"one_line": {
"is None": [
"is not None",
"not is None",
"None"
]
},
"source": "none.py",
"depends": [],
"exercise_id": 96,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 条件和分支(2)
# 描述:存在还是不存在,提示用户输入查询关键字,判断是否在字典的key中,输出查询结果。
def is_existed():
database = {
"monkey": "猴王说,我写的程序在五指山上的服务器上运行5000年了!"
}
key = input('请输入你要查询的关键字:')
print("* 猴王数据库正在努力检索中...")
if database.get(key) is None:
print("* 无法检索到该信息!")
else:
print("* 返回:{}".format(database[key]))
if __name__ == '__main__':
is_existed()
{
"export": [
"for.json",
"while.json"
],
"keywords": [],
"children": [
{
"for": {
"keywords": [],
"children": [],
"node_id": "python-4-109"
}
},
{
"while": {
"keywords": [],
"children": [],
"node_id": "python-4-110"
}
},
{
"break": {
"keywords": [],
"children": [],
"node_id": "python-4-111"
}
},
{
"continue": {
"keywords": [],
"children": [],
"node_id": "python-4-112"
}
},
{
"循环判断": {
"keywords": [],
"children": [],
"node_id": "python-4-113"
}
},
{
"迭代字典": {
"keywords": [],
"children": [],
"node_id": "python-4-114"
}
},
{
"一些迭代工具": {
"keywords": [],
"children": [],
"node_id": "python-4-115"
}
},
{
"跳出循环": {
"keywords": [],
"children": [],
"node_id": "python-4-116"
}
},
{
"循环中的else子句": {
"keywords": [],
"children": [],
"node_id": "python-4-117"
}
}
],
"node_id": "python-3-13"
}
\ No newline at end of file
{
"multiline": [
{
"for item in list:": "for item in list"
},
{
"i = 0": "",
"for item in list:": "for i, item in list:"
},
{
"for item in list:": "for(item in list):"
}
],
"source": "for.py",
"depends": [],
"exercise_id": 78,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 循环1
# 描述:使用 for 遍历打印列表信息
def test(list):
i = 0
for item in list:
print('')
print("## 第{}条信息".format(i))
print("* id: {}".format(item['id']))
print("* number: {}".format(item['number']))
print("* title: {}".format(item['title']))
print("* body: {}".format(item['body']))
i += 1
if __name__ == '__main__':
list = [
{
"id": 966024429,
"number": 2341,
"title": "Question about license.",
"body": "I would like to create a [winget](https://github.com/microsoft/winget-cli) package for jq. 🙏🏻"
},
{
"id": 962477084,
"number": 2340,
"title": "visibility of wiki pages",
"body": "The visibility of wiki pages to search engines is generally limited; for example, the search result for \"jq Cookbook\" looks like this:"
}
]
test(list)
{
"multiline": [
{
"while i < len(list):": "while(i < len(list)):"
},
{
"while i < len(list):": "while i in range(0,len(list):"
},
{
"while i < len(list):": "while i < len(list)"
}
],
"source": "while.py",
"depends": [],
"exercise_id": 77,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 循环1
# 描述:使用 while 遍历,打印列表信息
def test(list):
i = 0
while i < len(list):
item = list[i]
print('')
print("## 第{}条信息".format(i))
print("* id: {}".format(item['id']))
print("* number: {}".format(item['number']))
print("* title: {}".format(item['title']))
print("* body: {}".format(item['body']))
i += 1
if __name__ == '__main__':
list = [
{
"id": 955350543,
"number": 2337,
"title": "Release 1.6 does not have pre-autoreconf'ed configure script",
"body": "If you have a usage question, please ask us on either Stack Overflow (https://stackoverflow.com/questions/tagged/jq) or in the #jq channel (http://irc.lc/freenode/%23jq/) on Freenode (https://webchat.freenode.net/)."
},
{
"id": 954792209,
"number": 2336,
"title": "Fix typo",
"body": ""
}
]
test(list)
{
"export": [
"string.json",
"list.json",
"tuple.json",
"dict.json"
],
"keywords": [],
"children": [
{
"整型": {
"keywords": [],
"children": [],
"node_id": "python-4-118"
}
},
{
"浮点型": {
"keywords": [],
"children": [],
"node_id": "python-4-119"
}
},
{
"布尔型": {
"keywords": [],
"children": [],
"node_id": "python-4-120"
}
},
{
"字符串": {
"keywords": [],
"children": [
{
"单引号字符串以及对引号转义": {
"keywords": [],
"children": [],
"node_id": "python-5-72"
}
},
{
"拼接字符串": {
"keywords": [],
"children": [],
"node_id": "python-5-73"
}
},
{
"字符串表示str和repr": {
"keywords": [],
"children": [],
"node_id": "python-5-74"
}
},
{
"长字符串、原始字符串和字节": {
"keywords": [],
"children": [],
"node_id": "python-5-75"
}
},
{
"字符串基本操作": {
"keywords": [],
"children": [],
"node_id": "python-5-76"
}
},
{
"设置字符串的格式:精简版": {
"keywords": [],
"children": [
{
"替换字段名": {
"keywords": [],
"children": [],
"node_id": "python-6-18"
}
}
],
"node_id": "python-5-77"
}
},
{
"使用方法修改字符串的大小写": {
"keywords": [],
"children": [],
"node_id": "python-5-78"
}
},
{
"使用制表符或换行符来添加空白": {
"keywords": [],
"children": [],
"node_id": "python-5-79"
}
},
{
"删除空白": {
"keywords": [],
"children": [],
"node_id": "python-5-80"
}
},
{
"使用字符串时避免语法错误": {
"keywords": [],
"children": [],
"node_id": "python-5-81"
}
},
{
"字符串编码转换": {
"keywords": [],
"children": [
{
"使用encode方法编码": {
"keywords": [],
"children": [],
"node_id": "python-6-19"
}
},
{
"使用decode方法解码": {
"keywords": [],
"children": [],
"node_id": "python-6-20"
}
}
],
"node_id": "python-5-82"
}
}
],
"node_id": "python-4-121"
}
},
{
"datetime --- 基本的日期和时间类型": {
"keywords": [],
"children": [],
"node_id": "python-4-122"
}
},
{
"zoneinfo --- IANA时区支持": {
"keywords": [],
"children": [],
"node_id": "python-4-123"
}
},
{
"calendar --- 日历相关函数": {
"keywords": [],
"children": [],
"node_id": "python-4-124"
}
},
{
"collections --- 容器数据类型": {
"keywords": [],
"children": [],
"node_id": "python-4-125"
}
},
{
"collections.abc --- 容器的抽象基类": {
"keywords": [],
"children": [],
"node_id": "python-4-126"
}
},
{
"heapq --- 堆队列算法": {
"keywords": [],
"children": [],
"node_id": "python-4-127"
}
},
{
"bisect --- 数组二分查找算法": {
"keywords": [],
"children": [],
"node_id": "python-4-128"
}
},
{
"array --- 高效的数值数组": {
"keywords": [],
"children": [],
"node_id": "python-4-129"
}
},
{
"weakref --- 弱引用": {
"keywords": [],
"children": [],
"node_id": "python-4-130"
}
},
{
"types --- 动态类型创建和内置类型名称": {
"keywords": [],
"children": [],
"node_id": "python-4-131"
}
},
{
"copy --- 浅层 (shallow) 和深层 (deep) 复制操作": {
"keywords": [],
"children": [],
"node_id": "python-4-132"
}
},
{
"pprint --- 数据美化输出": {
"keywords": [],
"children": [],
"node_id": "python-4-133"
}
},
{
"reprlib --- 另一种repr 实现": {
"keywords": [],
"children": [],
"node_id": "python-4-134"
}
},
{
"enum --- 对枚举的支持": {
"keywords": [],
"children": [],
"node_id": "python-4-135"
}
},
{
"graphlib --- Functionality to operate with graph-like structures": {
"keywords": [],
"children": [],
"node_id": "python-4-136"
}
}
],
"node_id": "python-3-14"
}
\ No newline at end of file
{
"one_line": {
"map.get('tags')": [
"map.get('profile')"
],
"map['no'] = 10000": [
"map.set('no', 10000)"
],
"dict = {}": [
"dict = new dict{}"
]
},
"source": "dict.py",
"depends": [],
"exercise_id": 81,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 字典
# 描述:字典的基本使用,插入key-value,并打印结果
if __name__ == '__main__':
map = {}
print('* 初始化字典:', map)
print('* 使用下标插入数据到字典')
map['name'] = "monkey"
map['age'] = 25
map['no'] = 10000
for key in map:
value = map[key]
print("{}:{}".format(key, value))
print('* 字典里可以插入其他数据类型,例如插入列表')
map['tags'] = ['程序员', '户外达人']
print('* 打印 tags :{}', map.get('tags'))
print('* 字典里可以插入其他数据类型,例如插入字典')
map['profile'] = {'info1': "test", "info2": "test"}
print('* 打印 profile :{', map.get('profile'))
{
"one_line": {
"array.append": [
"array.push"
],
"array.pop(0)": [
"array.pop()"
],
"array = []": [
"array = new list()"
]
},
"source": "list.py",
"depends": [],
"exercise_id": 80,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 列表
# 描述:列表的基本使用,使用append/pop,打印结果
if __name__ == '__main__':
array = []
print('* 初始化列表 array:', array)
print('* 使用 append 追加数据到列表')
array.append(10)
array.append(20)
array.append(30)
array.append(40)
print('* 现在列表的值 array:', array)
print('* 使用 pop 弹出先插入的数据')
array.pop(0)
array.pop(0)
print('* 现在列表的值 array:', array)
print("* 开始遍历列表")
for item in array:
print(" ->{}".format(item))
{
"one_line": {
"\"双引号字符串里的单引号: 'hello world!'\"": [
"\"双引号字符串里的单引号: \"hello world!\"\""
],
"'单引号字符串里的双引号: \"hello world!\"'": [
"'单引号字符串里的双引号: 'hello world!''"
],
"* \"双引号\" ": [
"* '''双引号''' "
],
"* '单引号'": [
"* '''单引号'''"
],
"\"字符串加法\"+\"字符串加法\"": [
"\"字符串加法\"*\"字符串加法\""
],
"\"字符串乘法\"*3": [
"\"字符串乘法\"+3"
]
},
"source": "string.py",
"depends": [],
"exercise_id": 82,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 字符串
# 描述:使用字符串,几种不同引号的混合使用
def test():
print("双引号字符串")
print('单引号字符串')
print("双引号字符串里的单引号: 'hello world!'")
print('单引号字符串里的双引号: "hello world!"')
triple = '''
三引号字符串
'''
print(triple)
triple2 = '''
三引号字符串的便利:
* "双引号"
* '单引号'
'''
print(triple2)
print("字符串加法"+"字符串加法")
print("字符串乘法"*3)
print(",".join(["字符串数组的聚合", "字符串数组的聚合", "字符串数组的聚合"]))
if __name__ == '__main__':
test()
{
"one_line": {
"('红色',)": [
"('红色')"
],
"('红色', '绿色', '蓝色')": [
"('红色', ('绿色',), '蓝色')"
],
"0.6, 0.8, 0.3": [
"0.6, (0.8, 0.3)"
]
},
"source": "tuple.py",
"depends": [],
"exercise_id": 79,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 元组
# 描述:元组的基本使用,循环打印元组成员,如果只有一个元素,应该怎么表示<br/><img src="https://img-mid.csdnimg.cn/release/static/image/mid/ask/321539019236199.jpg?x-oss-process=image/auto-orient,1/resize,w_320,m_lfit"/>
import math
if __name__ == '__main__':
tuple1 = ('红色',)
for element in tuple1:
print(element)
tuple = ('红色', '绿色', '蓝色')
for element in tuple:
print(element)
print("不带括号的也是元组:")
r, g, b = 0.6, 0.8, 0.3
print("普通颜色[0-1]:({}, {}, {})".format(r, g, b))
hr, hg, hb = (math.pow(r, 3/2), math.pow(g, 4/5), math.pow(b, 3/2))
print("使用《黑客帝国》绿色滤镜算法计算后的颜色[0-1]:({}, {}, {})".format(hr, hg, hb))
{
"one_line": {
"list(set(lista))": [
"list(lista)",
"set(lista)"
],
"item >= bound": [
"item > bound"
],
"res = []": [
"res = {}"
]
},
"source": "builtin_class.py",
"depends": [],
"exercise_id": 240,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 内置类型
# 描述:内置类的使用,列表元素去重+过滤小于3的元素
def remove_duplicates(items):
res = list(set(items))
return res
def filter_element(items, bound):
res = []
for item in items:
if item >= bound:
res.append(item)
return res
if __name__ == '__main__':
a = [1, 2, 3, 4, 4, 5, 5]
print('输入: {}'.format(a))
res = remove_duplicates(a)
print('去重后的结果:{}'.format(res))
bound = 3
res = filter_element(a, bound)
print('过滤小于{}的元素:{}'.format(bound, res))
{
"export": [
"builtin_class.json"
],
"keywords": [],
"children": [
{
"列表:list": {
"keywords": [],
"children": [
{
"函数list": {
"keywords": [],
"children": [],
"node_id": "python-5-83"
}
},
{
"基本的列表操作": {
"keywords": [],
"children": [
{
"遍历整个列表": {
"keywords": [],
"children": [
{
"深入研究循环": {
"keywords": [],
"children": [],
"node_id": "python-7-0"
}
},
{
"在for循环中执行更多操作": {
"keywords": [],
"children": [],
"node_id": "python-7-1"
}
},
{
"在for循环结束后执行一些操作": {
"keywords": [],
"children": [],
"node_id": "python-7-2"
}
}
],
"node_id": "python-6-21"
}
},
{
"避免缩进错误": {
"keywords": [],
"children": [
{
"忘记缩进": {
"keywords": [],
"children": [],
"node_id": "python-7-3"
}
},
{
"忘记缩进额外的代码行": {
"keywords": [],
"children": [],
"node_id": "python-7-4"
}
},
{
"不必要的缩进": {
"keywords": [],
"children": [],
"node_id": "python-7-5"
}
},
{
"循环后不必要的缩进": {
"keywords": [],
"children": [],
"node_id": "python-7-6"
}
},
{
"遗漏了冒号": {
"keywords": [],
"children": [],
"node_id": "python-7-7"
}
}
],
"node_id": "python-6-22"
}
},
{
"创建数值列表": {
"keywords": [],
"children": [
{
"使用range创建数字列表": {
"keywords": [],
"children": [],
"node_id": "python-7-8"
}
},
{
"对数字列表执行简单的统计计算": {
"keywords": [],
"children": [],
"node_id": "python-7-9"
}
},
{
"列表解析": {
"keywords": [],
"children": [],
"node_id": "python-7-10"
}
}
],
"node_id": "python-6-23"
}
},
{
"设置代码格式": {
"keywords": [],
"children": [
{
"格式设置指南": {
"keywords": [],
"children": [],
"node_id": "python-7-11"
}
},
{
"行长": {
"keywords": [],
"children": [],
"node_id": "python-7-12"
}
},
{
"空行": {
"keywords": [],
"children": [],
"node_id": "python-7-13"
}
},
{
"其他格式设置指南": {
"keywords": [],
"children": [],
"node_id": "python-7-14"
}
}
],
"node_id": "python-6-24"
}
}
],
"node_id": "python-5-84"
}
},
{
"列表方法": {
"keywords": [],
"children": [],
"node_id": "python-5-85"
}
},
{
"列表数据类型": {
"keywords": [],
"children": [],
"node_id": "python-5-86"
}
},
{
"增强的赋值操作": {
"keywords": [],
"children": [],
"node_id": "python-5-87"
}
},
{
"序列数据类型": {
"keywords": [],
"children": [],
"node_id": "python-5-88"
}
},
{
"引用": {
"keywords": [],
"children": [],
"node_id": "python-5-89"
}
},
{
"访问列表元素": {
"keywords": [],
"children": [],
"node_id": "python-5-90"
}
},
{
"索引从0而不是1开始": {
"keywords": [],
"children": [],
"node_id": "python-5-91"
}
},
{
"使用列表中的各个值": {
"keywords": [],
"children": [],
"node_id": "python-5-92"
}
},
{
"遍历切片": {
"keywords": [],
"children": [],
"node_id": "python-5-93"
}
},
{
"复制列表": {
"keywords": [],
"children": [],
"node_id": "python-5-94"
}
},
{
"列表的创建和删除": {
"keywords": [],
"children": [],
"node_id": "python-5-95"
}
},
{
"对列表进行统计计算": {
"keywords": [],
"children": [],
"node_id": "python-5-96"
}
},
{
"对列表进行排序": {
"keywords": [],
"children": [],
"node_id": "python-5-97"
}
}
],
"node_id": "python-4-137"
}
},
{
"字典:dict": {
"keywords": [],
"children": [
{
"访问字典中的值": {
"keywords": [],
"children": [],
"node_id": "python-5-98"
}
},
{
"添加键值对": {
"keywords": [],
"children": [],
"node_id": "python-5-99"
}
},
{
"先创建一个空字典": {
"keywords": [],
"children": [],
"node_id": "python-5-100"
}
},
{
"修改字典中的值": {
"keywords": [],
"children": [],
"node_id": "python-5-101"
}
},
{
"删除键值对": {
"keywords": [],
"children": [],
"node_id": "python-5-102"
}
},
{
"由类似对象组成的字典": {
"keywords": [],
"children": [],
"node_id": "python-5-103"
}
},
{
"使用get来访问值": {
"keywords": [],
"children": [],
"node_id": "python-5-104"
}
},
{
"遍历字典": {
"keywords": [],
"children": [
{
"遍历所有键值对": {
"keywords": [],
"children": [],
"node_id": "python-6-25"
}
},
{
"遍历字典中的所有键": {
"keywords": [],
"children": [],
"node_id": "python-6-26"
}
},
{
"按特定顺序遍历字典中的所有键": {
"keywords": [],
"children": [],
"node_id": "python-6-27"
}
},
{
"遍历字典中的所有值": {
"keywords": [],
"children": [],
"node_id": "python-6-28"
}
}
],
"node_id": "python-5-105"
}
},
{
"访问字典": {
"keywords": [],
"children": [],
"node_id": "python-5-106"
}
},
{
"字典推导式": {
"keywords": [],
"children": [],
"node_id": "python-5-107"
}
}
],
"node_id": "python-4-138"
}
},
{
"元组:tuple": {
"keywords": [],
"children": [
{
"定义元组": {
"keywords": [],
"children": [],
"node_id": "python-5-108"
}
},
{
"遍历元组中的所有值": {
"keywords": [],
"children": [],
"node_id": "python-5-109"
}
},
{
"修改元组变量": {
"keywords": [],
"children": [],
"node_id": "python-5-110"
}
},
{
"访问元组元素": {
"keywords": [],
"children": [],
"node_id": "python-5-111"
}
},
{
"修改元组": {
"keywords": [],
"children": [],
"node_id": "python-5-112"
}
},
{
"元组推导式": {
"keywords": [],
"children": [],
"node_id": "python-5-113"
}
}
],
"node_id": "python-4-139"
}
},
{
"集合:set": {
"keywords": [],
"children": [
{
"创建集合": {
"keywords": [],
"children": [],
"node_id": "python-5-114"
}
},
{
"集合的交集、并集和差集运算": {
"keywords": [],
"children": [],
"node_id": "python-5-115"
}
}
],
"node_id": "python-4-140"
}
},
{
"整型:int": {
"keywords": [],
"children": [],
"node_id": "python-4-141"
}
},
{
"字符串:str": {
"keywords": [],
"children": [],
"node_id": "python-4-142"
}
}
],
"node_id": "python-3-15"
}
\ No newline at end of file
{
"node_id": "python-2-1",
"keywords": []
}
\ No newline at end of file
{
"export": [
"list01.json",
"list02.json",
"tuple.json",
"dict.json"
],
"keywords": [],
"children": [],
"node_id": "python-3-17"
}
\ No newline at end of file
{
"one_line": {
"if key != 'w'": [
"if key == 'w'",
""
],
"key: install[key]": [
"install[key]"
]
},
"source": "dict.py",
"depends": [],
"exercise_id": 207,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 字典推导式
# 描述:Python 独步天下的推导式表达式,使用字典推导式过滤,打印非windows系统的 Python 安装介绍
def test():
install = {
"w": {
"platform": "Window",
"desc": "请下载 Windows 安装包安装:https://www.python.org/downloads/windows/"
},
"l": {
"platform": "Linux",
"desc": "请下载 Linux 的 Python 源码安装:https://www.python.org/downloads/source/",
},
"m": {
"platform": "MacOS",
"desc": "请下载 Mac 的安装包:https://www.python.org/downloads/macos/,或者使用 brew install python 安装",
}
}
non_windows = {key: install[key] for key in install if key != 'w'}
print("打算最近只用非Windows系统安装Python了:")
print()
for key in non_windows:
target = non_windows[key]
print("安装平台:{}".format(target['platform']))
print("安装说明:{}".format(target['desc']))
print()
if __name__ == '__main__':
test()
{
"one_line": {
"if n % 2 == 0": [
"if n % 2 != 0",
"where n % 2 == 0"
],
"for n in list": [
"for n in list:"
]
},
"source": "list01.py",
"depends": [],
"exercise_id": 195,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 列表推导式(1)
# 描述:Python 独步天下的推导式表达式,使用列表推导式过滤出偶数列表
if __name__ == '__main__':
list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print('')
print("# 使用列表推导式过滤出偶数")
even = [n for n in list if n % 2 == 0]
for n in even:
print(n)
print('')
{
"one_line": {
"if '不热' in d['tags']": [
"if '热' in d['tags']",
""
],
"d for d": [
"for d"
]
},
"source": "list02.py",
"depends": [],
"exercise_id": 214,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 列表推导式(2)
# 描述:Python 独步天下的推导式表达式,使用列表推导式过滤不热的天气
if __name__ == '__main__':
obj_list = [
{"key": "day1", "value": "大雨哗啦啦啦啦下", 'tags': ["不热"]},
{"key": "day2", "value": "很热很热,哥哥不在家,我一个人出去旅行", 'tags': ["热"]},
{"key": "day3", "value": "阴天有时下肉丸", 'tags': ["不热"]}
]
print('')
print("# 过滤出不热的日子")
non_hot_days = [d for d in obj_list if '不热' in d['tags']]
for day in non_hot_days:
print("* [{}]: {}".format(day['key'], day['value']))
print('')
{
"one_line": {
"if len(book) <= 4": [
"if len(book) < 4"
],
"for book in books": [
"for book in books:"
],
"book for book": [
"books[i] for book"
]
},
"source": "tuple.py",
"depends": [],
"exercise_id": 194,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 元组推导式
# 描述:Python 独步天下的推导式表达式,使用元表推式过滤长度小于等于4的书籍
def test():
books = ('程序员修炼之道', '构建之法', '代码大全', 'TCP/IP协议详解')
reading = (book for book in books if len(book) <= 4)
print("太长的书就不看了,只读短的:")
for book in reading:
print(" ->《{}》".format(book))
print("可是发现书的名字短,内容也可能很长啊!")
if __name__ == '__main__':
test()
{
"export": [
"encode.json"
],
"keywords": [],
"children": [
{
"理解内码和字节码的概念": {
"keywords": [],
"children": [],
"node_id": "python-4-203"
}
}
],
"node_id": "python-3-26"
}
\ No newline at end of file
{
"multiline": [
{
"u'二": "'二"
},
{
"encode": "decode",
"decode": "encode"
},
{
"'utf-8'": "'utf8'"
}
],
"source": "encode.py",
"depends": [],
"exercise_id": 107,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 字符编解码
# 描述:二进制只是二进制,取决于怎么编码和解码,unicode 转 utf8
if __name__ == '__main__':
unicode_str = u'二进制只是二进制,取决于怎么编码和解码'
print(unicode_str)
utf8_str = unicode_str.encode('utf-8')
print(utf8_str)
unicode_str_again = utf8_str.decode('utf-8')
print(unicode_str_again)
assert unicode_str_again == unicode_str
{
"export": [
"triple01.json",
"triple02.json"
],
"keywords": [],
"children": [
{
"算术转换": {
"keywords": [],
"children": [],
"node_id": "python-4-156"
}
},
{
"原子": {
"keywords": [],
"children": [],
"node_id": "python-4-157"
}
},
{
"原型": {
"keywords": [],
"children": [],
"node_id": "python-4-158"
}
},
{
"await表达式": {
"keywords": [],
"children": [],
"node_id": "python-4-159"
}
},
{
"幂运算符": {
"keywords": [],
"children": [],
"node_id": "python-4-160"
}
},
{
"一元算术和位运算": {
"keywords": [],
"children": [],
"node_id": "python-4-161"
}
},
{
"二元算术运算符": {
"keywords": [],
"children": [],
"node_id": "python-4-162"
}
},
{
"移位运算": {
"keywords": [],
"children": [],
"node_id": "python-4-163"
}
},
{
"比较运算": {
"keywords": [],
"children": [],
"node_id": "python-4-164"
}
},
{
"布尔运算": {
"keywords": [],
"children": [],
"node_id": "python-4-165"
}
},
{
"赋值表达式": {
"keywords": [],
"children": [],
"node_id": "python-4-166"
}
},
{
"条件表达式": {
"keywords": [],
"children": [],
"node_id": "python-4-167"
}
},
{
"表达式列表": {
"keywords": [],
"children": [],
"node_id": "python-4-168"
}
},
{
"求值顺序": {
"keywords": [],
"children": [],
"node_id": "python-4-169"
}
},
{
"运算符优先级": {
"keywords": [],
"children": [],
"node_id": "python-4-170"
}
}
],
"node_id": "python-3-18"
}
\ No newline at end of file
{
"one_line": {
"1 if i % 2 == 0 else 0": [
"0 if i % 2 == 0 else 1"
],
"even_count == 4": [
"even_count == 3",
"even_count == 5"
],
"i % 2 == 0": [
"i % 2 == 1"
]
},
"source": "triple01.py",
"depends": [],
"exercise_id": 215,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 三元表达式(1)
# 描述:Python 没有问号表达式了!使用三元组表达式统计偶数个数
if __name__ == '__main__':
pi = [3, 14, 15, 9, 26, 5, 35, 8, 97, 932]
even_count = 0
for i in pi:
even_count += 1 if i % 2 == 0 else 0
assert even_count == 4
{
"one_line": {
"if i % 4 == 0 else 1 if i % 2 == 0": [
"if i % 2 == 0 else 1 if i % 4 == 0"
],
"2 if i % 4 == 0 else 1 if i % 2 == 0 else 0": [
"1 if i % 4 == 0 else 2 if i % 2 == 0 else 0"
],
"even_count == 6": [
"even_count == 5",
"even_count == 7"
]
},
"source": "triple02.py",
"depends": [],
"exercise_id": 203,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 三元表达式(2)
# 描述:使用嵌套的三元组表达式统计数字频率,如果是2的倍数加1,如果是4的倍数加2,否则加0
if __name__ == '__main__':
pi = [3, 14, 15, 9, 26, 5, 35, 8, 97, 932]
even_count = 0
for i in pi:
even_count += 2 if i % 4 == 0 else 1 if i % 2 == 0 else 0
assert even_count == 6
{
"one_line": {
"assert key_value_map is not None": [
"assert key_value_map is None"
],
"assert type(key_value_map) == type({})": [
"assert type(key_value_map) == type([])"
],
"assert key is not None": [
"assert key is None"
],
"assert type(key) == type(\"\")": [
"assert type(key) is not str"
]
},
"source": "assert.py",
"depends": [],
"exercise_id": 110,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 断言
# 描述:所谓断言,就是证明,使用 assert 对输入函数输入参数和函数返回结果分别做前校验和后校验
def check_param(key_value_map, key):
'''参数校验,断言就是对输入参数的一个证明,这些参数必须符合这些要求'''
assert key_value_map is not None
assert type(key_value_map) == type({})
assert key is not None
assert type(key) == type("")
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", {})
value = get(key_value_map, "test")
print("后校验,返回值必须符合预期")
assert type(value) == type({})
assert value == {}
{
"export": [
"assert.json"
],
"keywords": [],
"children": [],
"node_id": "python-3-19"
}
\ No newline at end of file
{
"export": [
"withas.json",
"enter_exit.json"
],
"keywords": [],
"children": [],
"node_id": "python-3-20"
}
\ No newline at end of file
{
"one_line": {
"with TimeSpan() as t": [
"with TimeSpan()"
],
"__enter__(self)": [
"enter(self)"
],
"__exit__": [
"exit"
]
},
"source": "enter_exit.py",
"depends": [],
"exercise_id": 178,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python with-as 语句(2)
# 描述:实现一个范围耗时统计类。 实现了 __enter__ 和 __exit__ 成员的类,可以通过 with as 语法使用,程序进入和离开范围的时候会自动调用 __enter__ 和 __exit__方法。
import time
class TimeSpan:
def __init__(self) -> None:
self.start = None
def __enter__(self):
self.end = None
self.start = time.time()
def __exit__(self, exc_type, exc_val, exc_tb):
self.end = time.time()
print('耗时:{}毫秒'.format((self.end-self.start)))
if __name__ == '__main__':
with TimeSpan() as t:
for i in range(0, 1000):
print(i)
{
"one_line": {
"as f": [
""
],
"with ": [
""
],
"with open(file, 'w') as f": [
"with f = open(file, 'w')"
]
},
"source": "withas.py",
"depends": [],
"exercise_id": 118,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python with-as 语句(1)
# 描述:文件读写
import json
def load_json(file):
with open(file, 'r') as f:
return json.loads(f.read())
def dump_json(file, obj):
with open(file, 'w') as f:
f.write(json.dumps(obj, indent=2, ensure_ascii=False))
if __name__ == '__main__':
data = {
'test': 1,
}
dump_json('test.json', data)
load_json('test.json')
{
"export": [
"try01.json"
],
"keywords": [],
"children": [
{
"try-catch-finally": {
"keywords": [],
"children": [],
"node_id": "python-4-171"
}
},
{
"异常捕获": {
"keywords": [],
"children": [],
"node_id": "python-4-172"
}
}
],
"node_id": "python-3-21"
}
\ No newline at end of file
{
"one_line": {
"except Exception as e": [
"except e",
"except as e"
],
"logger.error(traceback.format_exc()):": [
"logger.error(e.stack())"
]
},
"source": "try01.py",
"depends": [],
"exercise_id": 237,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 异常处理
# 描述:控制异常的最小范围,出现异常正常打印日志和堆栈
import json
import traceback
import logging
logger = logging.getLogger(__name__)
def load_json(file):
with open(file, 'r') as f:
return json.loads(f.read())
def test():
try:
ret = load_json('a.json')
return {'err': 'success', 'result': ret}
except Exception as e:
logger.error(f"load json exception:{str(e)}")
logger.error(traceback.format_exc())
return {'err': 'exception'}
if __name__ == '__main__':
test()
{
"export": [
"str.json"
],
"keywords": [],
"children": [
{
"find": {
"keywords": [],
"children": [],
"node_id": "python-4-173"
}
},
{
"index": {
"keywords": [],
"children": [],
"node_id": "python-4-174"
}
},
{
"join": {
"keywords": [],
"children": [],
"node_id": "python-4-175"
}
},
{
"lower": {
"keywords": [],
"children": [],
"node_id": "python-4-176"
}
},
{
"replace": {
"keywords": [],
"children": [],
"node_id": "python-4-177"
}
},
{
"split": {
"keywords": [],
"children": [],
"node_id": "python-4-178"
}
},
{
"strip": {
"keywords": [],
"children": [],
"node_id": "python-4-179"
}
},
{
"translate": {
"keywords": [],
"children": [],
"node_id": "python-4-180"
}
},
{
"upper": {
"keywords": [],
"children": [],
"node_id": "python-4-181"
}
},
{
"center": {
"keywords": [],
"children": [],
"node_id": "python-4-182"
}
},
{
"判断字符串是否满足特定的条件": {
"keywords": [],
"children": [],
"node_id": "python-4-183"
}
}
],
"node_id": "python-3-22"
}
\ No newline at end of file
{
"multiline": [
{
"l.strip() != ''": "l.strip() == ''"
},
{
"code.split('\n')": "code.split()"
},
{
"int(left)+int(right))": "left+right",
"int(left)-int(right))": "left-right",
"int(left)*int(right))": "left*right",
"int(left)/int(right))": "left/right"
},
{
"and right != '0'": ""
}
],
"source": "str.py",
"depends": [],
"exercise_id": 112,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 字符串方法
# 描述:Python 的字符串处理, 一个朴实无华的四则运算计算器,批量计算小学生四则运算表达式
import re
def naive_calc(code):
code_lines = [l for l in code.split('\n') if l.strip() != '']
for line in code_lines:
ret = re.match("\s*(\d+)([\+\-\*\/])(\d+)\s*", line)
left = ret.group(1)
op = ret.group(2)
right = ret.group(3)
if op == '+':
print('{}+{}={}'.format(left, right, int(left)+int(right)))
elif op == '-':
print('{}-{}={}'.format(left, right, int(left)-int(right)))
elif op == '*':
print('{}*{}={}'.format(left, right, int(left)*int(right)))
elif op == '/' and right != '0':
print('{}/{}={}'.format(left, right, int(left)/int(right)))
def test():
code = '''
1+2
3+4
5-3
4*3
10/2
'''
naive_calc(code)
if __name__ == '__main__':
test()
{
"export": [
"lambda.json"
],
"keywords": [],
"children": [
{
"迭代器": {
"keywords": [],
"children": [
{
"迭代器协议": {
"keywords": [],
"children": [],
"node_id": "python-5-116"
}
},
{
"从迭代器创建序列": {
"keywords": [],
"children": [],
"node_id": "python-5-117"
}
}
],
"node_id": "python-4-184"
}
},
{
"生成器": {
"keywords": [],
"children": [
{
"创建生成器": {
"keywords": [],
"children": [],
"node_id": "python-5-118"
}
},
{
"递归式生成器": {
"keywords": [],
"children": [],
"node_id": "python-5-119"
}
},
{
"通用生成器": {
"keywords": [],
"children": [],
"node_id": "python-5-120"
}
},
{
"生成器的方法": {
"keywords": [],
"children": [],
"node_id": "python-5-121"
}
},
{
"模拟生成器": {
"keywords": [],
"children": [],
"node_id": "python-5-122"
}
}
],
"node_id": "python-4-185"
}
},
{
"装饰器": {
"keywords": [],
"children": [],
"node_id": "python-4-186"
}
},
{
"闭包": {
"keywords": [],
"children": [],
"node_id": "python-4-187"
}
}
],
"node_id": "python-3-23"
}
\ No newline at end of file
{
"one_line": {
"lambda item: item['age']": [
"lambda (item): item['age']",
"lambda item: return item['age']",
"item => item['age']",
"item -> item['age']"
]
},
"source": "lambda.py",
"depends": [],
"exercise_id": 108,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 匿名表达式
# 描述:Python 高阶函数编程,使用 lambda 表达式获取key,将list转成dict
def list_to_dict(list, key_func):
d = {}
for item in list:
k = key_func(item)
v = item
list = d.get(k)
if list is None:
d[k] = [v]
else:
d[k].append(v)
return d
if __name__ == '__main__':
list = [
{"name": "alice", "age": 100},
{"name": "middle", "age": 100},
{"name": "bob", "age": 200}
]
ret = list_to_dict(list, lambda item: item['age'])
print(ret)
{
"export": [
"file_basic.json",
"file_piece_sha256.json"
],
"keywords": [],
"children": [
{
"打开文件": {
"keywords": [],
"children": [],
"node_id": "python-4-188"
}
},
{
"文件基本方法": {
"keywords": [],
"children": [],
"node_id": "python-4-189"
}
},
{
"文件内容迭代": {
"keywords": [],
"children": [
{
"每次一个字符(或字节)": {
"keywords": [],
"children": [],
"node_id": "python-5-123"
}
},
{
"每次一行": {
"keywords": [],
"children": [],
"node_id": "python-5-124"
}
},
{
"读取所有内容": {
"keywords": [],
"children": [],
"node_id": "python-5-125"
}
},
{
"使用fileinput实现延迟行迭代": {
"keywords": [],
"children": [],
"node_id": "python-5-126"
}
},
{
"文件迭代器": {
"keywords": [],
"children": [],
"node_id": "python-5-127"
}
}
],
"node_id": "python-4-190"
}
},
{
"文件的基本方法": {
"keywords": [],
"children": [
{
"读取和写入": {
"keywords": [],
"children": [],
"node_id": "python-5-128"
}
},
{
"使用管道重定向输出": {
"keywords": [],
"children": [],
"node_id": "python-5-129"
}
},
{
"读取和写入行": {
"keywords": [],
"children": [],
"node_id": "python-5-130"
}
},
{
"关闭文件": {
"keywords": [],
"children": [],
"node_id": "python-5-131"
}
},
{
"使用文件的基本方法": {
"keywords": [],
"children": [],
"node_id": "python-5-132"
}
}
],
"node_id": "python-4-191"
}
}
],
"node_id": "python-3-24"
}
\ No newline at end of file
{
"multiline": [
{
"'w'": "'r'",
"'r'": "'w'"
},
{
"write": "read",
"read": "write"
},
{
"with open('/tmp/test.txt', 'w') as f": "f = open('/tmp/test.txt', 'w')",
"with open('/tmp/test.txt', 'r') as f": "f = open('/tmp/test.txt', 'r')"
}
],
"source": "file_basic.py",
"depends": [],
"exercise_id": 199,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 文件读写
# 描述:基本文件读写,写入 "test" 到 "/tmp/test.txt",再次打开读取
if __name__ == '__main__':
with open('/tmp/test.txt', 'w') as f:
f.write("test")
with open('/tmp/test.txt', 'r') as f:
print(f.read())
{
"one_line": {
"break": [
"continue"
],
"in_file.read": [
"in_file.readline"
],
"piece.hex()": [
"piece"
],
"sha256.update": [
"sha256.append"
]
},
"source": "file_piece_sha256.py",
"depends": [],
"exercise_id": 213,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 文件读写
# 描述:一种基于 sha256 的文件分片 hash 计算方式
import hashlib
def file_piece_sha256(in_file_path, piece_size):
sha256 = hashlib.sha256()
with open(in_file_path, "rb") as in_file:
while True:
piece = in_file.read(piece_size)
if piece:
sha256.update(piece.hex().encode('utf-8'))
else:
break
return sha256.digest().hex()
if __name__ == '__main__':
ret = file_piece_sha256('file_piece_sha256.py', 128)
print("file hash is: ", ret)
{
"export": [
"std01.json",
"std02.json"
],
"keywords": [],
"children": [
{
"datetime": {
"keywords": [],
"children": [],
"node_id": "python-4-192"
}
},
{
"json": {
"keywords": [],
"children": [],
"node_id": "python-4-193"
}
},
{
"math": {
"keywords": [],
"children": [],
"node_id": "python-4-194"
}
},
{
"os": {
"keywords": [],
"children": [],
"node_id": "python-4-195"
}
},
{
"random": {
"keywords": [],
"children": [],
"node_id": "python-4-196"
}
},
{
"re": {
"keywords": [],
"children": [],
"node_id": "python-4-197"
}
},
{
"sys": {
"keywords": [],
"children": [],
"node_id": "python-4-198"
}
},
{
"time": {
"keywords": [],
"children": [],
"node_id": "python-4-199"
}
},
{
"urllib": {
"keywords": [],
"children": [],
"node_id": "python-4-200"
}
},
{
"fileinput": {
"keywords": [],
"children": [],
"node_id": "python-4-201"
}
},
{
"其他有趣的标准模块": {
"keywords": [],
"children": [],
"node_id": "python-4-202"
}
}
],
"node_id": "python-3-25"
}
\ No newline at end of file
{
"one_line": {
"type([])": [
"type({})"
],
"== True": [
"== False"
],
"math.pow(2, 3)": [
"math.pow(2, 4)"
],
"== float": [
"== int"
],
"datetime.now().year": [
"datetime.now().year()"
]
},
"source": "std01.py",
"depends": [],
"exercise_id": 222,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 常用标准库(1)
# 描述:sys, os, math, time, date ,以下所有的 assert 为 True ,<br/>请在使用的时候查文档,例如日期文档:https://docs.python.org/zh-cn/3/library/datetime.html#datetime.datetime
import sys
import os
import math
import time
from datetime import datetime
if __name__ == '__main__':
assert type(sys.argv) == type([])
assert os.path.exists(__file__) == True
assert math.pow(2, 3) == 8
assert type(time.time()) == float
assert datetime.now().year >= 2021
{
"one_line": {
"json.dumps": [
"json.dump"
],
"json.loads": [
"json.load"
],
"== \"test\"": [
"== 2"
]
},
"source": "std02.py",
"depends": [],
"exercise_id": 196,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 常用标准库(2)
# 描述:json 序列化和反序列化
import json
if __name__ == '__main__':
obj = json.loads(json.dumps({"key": {"items": [1, 2, "test"]}}))
assert obj['key']['items'][2] == "test"
{
"node_id": "python-2-2",
"keywords": []
}
\ No newline at end of file
{
"export": [
"student.json"
],
"keywords": [],
"children": [],
"node_id": "python-3-27"
}
\ No newline at end of file
{
"multiline": [
{
"__init__": "init"
},
{
"dump(self)": "dump()"
},
{
"s = Student": "s = new Student"
}
],
"source": "student.py",
"depends": [],
"exercise_id": 56,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 类和对象
# 描述:创建学生类, 创建一个学生列表,加入3个学生,循环打印学生信息
class Student:
def __init__(self, no, name, age):
self.no = no
self.name = name
self.age = age
def dump(self):
print('')
print(f"* no:{self.no}")
print(f"* name:{self.name}")
print(f"* age:{self.age}")
if __name__ == '__main__':
students = []
for i in range(0, 3):
s = Student(i, f'somebody_{i}', 20+i)
students.append(s)
for s in students:
s.dump()
{
"export": [
"student.json"
],
"keywords": [],
"children": [],
"node_id": "python-3-28"
}
\ No newline at end of file
{
"multiline": [
{
"no,": "_no"
},
{
"self.name = name": "self.name = _name"
},
{
"s.age": "s.age()"
}
],
"source": "student.py",
"depends": [],
"exercise_id": 54,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 类成员
# 描述:直接调用学生类的成员变量,打印学生信息
class Student:
def __init__(self, no, name, age):
self.no = no
self.name = name
self.age = age
def test():
students = []
for i in range(0, 3):
s = Student(i, f'somebody_{i}', 20+i)
students.append(s)
for s in students:
print('')
print(f"* no:{s.no}")
print(f"* name:{s.name}")
print(f"* age:{s.age}")
if __name__ == '__main__':
test()
{
"export": [
"evolope.json",
"inherent.json",
"poly.json"
],
"keywords": [],
"children": [
{
"封装": {
"keywords": [],
"children": [],
"node_id": "python-4-204"
}
},
{
"继承": {
"keywords": [],
"children": [
{
"子类的方法__init__": {
"keywords": [],
"children": [],
"node_id": "python-5-133"
}
},
{
"重写父类的方法": {
"keywords": [],
"children": [],
"node_id": "python-5-134"
}
},
{
"模拟实物": {
"keywords": [],
"children": [],
"node_id": "python-5-135"
}
}
],
"node_id": "python-4-205"
}
},
{
"多态": {
"keywords": [],
"children": [],
"node_id": "python-4-206"
}
}
],
"node_id": "python-3-29"
}
\ No newline at end of file
{
"multiline": [
{
"get_no(self)": "get_no()",
"get_name(self)": "get_name()",
"get_age(self)": "get_age()",
"inc_age(self)": "inc_age()"
},
{
"self.age += 1": "self.age -= 1"
},
{
"print(s.log)": "print(s.log())"
}
],
"source": "evolope.py",
"depends": [],
"exercise_id": 209,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 封装
# 描述:只通过方法访问学生信息,则可以控制方法内的定制逻辑,例如记录访问日志
class Student:
def __init__(self, no, name, age):
self.no = no
self.name = name
self.age = age
self.log = []
def get_no(self):
self.log.append("有人查看我的编号")
return self.no
def get_name(self):
self.log.append("有人查看我的名字")
return self.name
def get_age(self):
self.log.append("有人查看我的年龄")
return self.age
def inc_age(self):
self.log.append("我过了一次生日")
self.age += 1
if __name__ == '__main__':
s = Student(0, f'somebody', 20)
s.get_no()
s.get_name()
s.get_age()
s.inc_age()
s.get_age()
s.inc_age()
print(s.log)
{
"multiline": [
{
"People(object)": "People : object",
"Student(People)": "Student : People",
"Teacher(People)": "Teacher : People"
},
{
"People(object)": "People implement object",
"Student(People)": "Student implement People",
"Teacher(People)": "Teacher implement People"
},
{
"super().__init__(name, age)": ""
}
],
"source": "inherent.py",
"depends": [],
"exercise_id": 235,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 继承
# 描述:使用继承,提取学生和教师类的公共父类
class People(object):
def __init__(self, name, age):
self.name = name
self.age = age
class Student(People):
def __init__(self, no, name, age):
super().__init__(name, age)
self.no = no
class Teacher(People):
def __init__(self, access_key, name, age):
super().__init__(name, age)
self.access_key = access_key
if __name__ == '__main__':
s = Student(0, f'somebody', 20)
t = Teacher('jladfja', 'linus', 0)
print('# 教师')
print(f"* name:{t.name}")
print(f"* age:{t.age}")
print('')
print('# 学生')
print(f"* no:{s.no}")
print(f"* name:{s.name}")
print(f"* age:{s.age}")
{
"multiline": [
{
"super().__init__(\"student\", name, age)": ""
},
{
"super().__init__(\"teacher\", name, age)": ""
},
{
"super().infos()": "self.infos()"
},
{
"super().infos()": "super.infos()"
}
],
"source": "poly.py",
"depends": [],
"exercise_id": 238,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 类多态
# 描述:学生和教师类,统一处理,打印他们的基本信息
class People:
def __init__(self, role, name, age):
self.name = name
self.age = age
self.role = role
def infos(self):
return [
f"name:{self.name}",
f"age:{self.age}",
f"role:{self.role}"
]
class Student(People):
def __init__(self, no, name, age):
super().__init__("student", name, age)
self.no = no
def infos(self):
info_list = super().infos()
info_list.append(f'no:{self.no}')
return info_list
class Teacher(People):
def __init__(self, access_key, name, age):
super().__init__("teacher", name, age)
self.access_key = access_key
def infos(self):
info_list = super().infos()
info_list.append(f'access_key:{self.access_key}')
return info_list
if __name__ == '__main__':
peoples = [
Teacher("ajladfjkadf", "Linus", 0)
]
for i in range(0, 3):
s = Student(i, f'somebody_{i}', 20+i)
peoples.append(s)
for p in peoples:
print()
for info in p.infos():
print(info)
{
"export": [
"point.json"
],
"keywords": [],
"children": [],
"node_id": "python-3-30"
}
\ No newline at end of file
{
"one_line": {
"class Point": [
"def class Point"
],
"dot(self, right)": [
"dot(right)"
],
"self.x*right.x+self.y*right.y+self.z*right.z": [
"x*right.x+y*right.y+z*right.z"
],
"__init__": [
"init"
],
"= Point": [
"new = Point"
]
},
"source": "point.py",
"depends": [],
"exercise_id": 52,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 类创建
# 描述:创建点对象,计算内积
class Point:
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
def dot(self, right):
return self.x*right.x+self.y*right.y+self.z*right.z
if __name__ == '__main__':
p1 = Point(0, 1, 2)
p2 = Point(2, 4, 6)
print(p1.dot(p2))
{
"one_line": {
"@abc.abstractmethod": [
"@abstractmethod"
],
"pass": [
""
],
"import abc": [
""
]
},
"source": "abstract.py",
"depends": [],
"exercise_id": 51,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 类创建
# 描述:使用 abc 库,创建抽象 BasePoint 类,创建 Point 子类,实现 dot 抽象方法
import abc
class BasePoint:
def __init__(self, x, y, z) -> None:
self.x = x
self.y = y
self.z = z
@abc.abstractmethod
def dot(self, right):
pass
class Point(BasePoint):
def __init__(self, x, y, z) -> None:
super().__init__(x, y, z)
def dot(self, right):
return self.x*right.x+self.y*right.y+self.z*right.z
if __name__ == '__main__':
p1 = Point(0, 1, 2)
p2 = Point(2, 4, 6)
assert p1.dot(p2) == 16
p1 = BasePoint(0, 1, 2)
p2 = BasePoint(2, 4, 6)
assert p1.dot(p2) is None
{
"export": [
"abstract.json"
],
"keywords": [],
"children": [],
"node_id": "python-3-31"
}
\ No newline at end of file
{
"one_line": {
"_func": [
"func"
],
"__test": [
"test",
"_test",
"__test__"
]
},
"source": "access.py",
"depends": [],
"exercise_id": 55,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 访问控制
# 描述:分别编写类内部的私有方法,模块级别的私有方法
class Test:
def __init__(self) -> None:
pass
def test(self):
self.__test()
def __test(self):
'''类内部的私有方法'''
print("test")
def _func():
'''模块级别的私有方法'''
print("file private")
if __name__ == '__main__':
t = Test()
t.test()
{
"version": "0.0.1",
"export": [
"access.json"
],
"keywords": [],
"children": [],
"node_id": "python-3-32"
}
\ No newline at end of file
{
"export": [
"object_meta.json"
],
"keywords": [],
"children": [],
"node_id": "python-3-33"
}
\ No newline at end of file
{
"one_line": {
"hasattr": [
"has",
"attr",
"contains"
],
"getattr": [
"get",
"attr"
]
},
"source": "object_meta.py",
"depends": [],
"exercise_id": 53,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 获取对象信息
# 描述:过滤列表里所有含有 'z' 属性的对象,打印他们的 'x'+'y'+'z' 的值
class Point2D:
def __init__(self, x, y) -> None:
self.x = x
self.y = y
class Point3D:
def __init__(self, x, y, z) -> None:
self.x = x
self.y = y
self.z = z
class Vector2D:
def __init__(self, x, y) -> None:
self.x = x
self.y = y
class Vector3D:
def __init__(self, x, y, z) -> None:
self.x = x
self.y = y
self.z = z
def test():
points = [
Point2D(0, 1),
Point2D(0, 1),
Point3D(0, 1, 2),
Point3D(0, 1, 3),
Vector2D(0, 1),
Vector3D(0, 1, 4),
]
z_objects = []
for p in points:
if hasattr(p, 'z'):
z = getattr(p, 'z')
print('get z attr:', z)
z_objects.append(p)
for p in z_objects:
print('x+y+z:', p.x+p.y+p.z)
if __name__ == '__main__':
test()
{
"node_id": "python-2-3",
"keywords": []
}
\ No newline at end of file
{
"node_id": "python-1-0",
"keywords": []
}
\ No newline at end of file
{
"export": [
"sys_argv.json",
"option_parser.json"
],
"keywords": [],
"children": [],
"node_id": "python-insert-4"
}
\ No newline at end of file
{
"multiline": [
{
"dest=\"host\"": "dest=\"h\""
},
{
"dest=\"port\"": "dest=\"p\""
},
{
"action=\"store_true\"": "action=\"store_false\""
},
{
"\"-s\", \"--server\"": "\"-s\""
}
],
"source": "option_parser.py",
"depends": [],
"exercise_id": 184,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 命令行解析
# 描述:使用 optparse 库配置指定命令行选项,并解析命令行
# 1. 选项 '-s' 和选项 '--server' 等价
# 2. 选项 '--host' 设置默认为 0.0.0.0
# 3. 选项 '--port' 设置默认为 80
# 4. 选项 '--ssl' 如果指定,则 option.ssl=True
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}")
{
"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",
"depends": [],
"exercise_id": 183,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 命令行解析
# 描述:手工编写 Python 命令行解析,支持 '-x' 或者 '--x' 类型选项处理,如果没有指定值则设置为True
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))
{
"export": [
"date.json",
"time_span.json",
"for_each_month.json"
],
"keywords": [],
"children": [
{
"time": {
"keywords": [],
"children": [],
"node_id": "python-4-752"
}
},
{
"datetime": {
"keywords": [],
"children": [],
"node_id": "python-4-753"
}
}
],
"node_id": "python-3-128"
}
\ No newline at end of file
{
"multiline": [
{
"datetime.now()": "date.now()"
},
{
"timedelta(days=-1)": "timedelta(days=1)",
"timedelta(days=1)": "timedelta(days=-1)"
},
{
"strftime": "format"
}
],
"source": "date.py",
"depends": [],
"exercise_id": 6,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题: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)
print(yesterday)
nextday = today + timedelta(days=1)
print(nextday)
{
"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",
"depends": [],
"exercise_id": 5,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 时间加法
# 描述:从2008年1月开始到本月,遍历每一个月份的1号,并打印信息
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()
{
"multiline": [
{
"time.time() * 1000": "time.time()"
},
{
"毫秒": "微秒"
},
{
"round(time.time() * 1000)": "time.time() * 1000"
}
],
"source": "time_span.py",
"depends": [],
"exercise_id": 4,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 计时器
# 描述:便利的 Python 计时器,统计从 0 遍历到 100000 消耗的时间,精确到毫秒
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()))
{
"export": [
"dir.json",
"copy.json",
"list_file_in_dir.json",
"walk_dir.json",
"count_file.json",
"zip_with_progress.json"
],
"keywords": [],
"children": [
{
"excel/csv/hdf/netCDF": {
"keywords": [],
"children": [],
"node_id": "python-4-754"
}
}
],
"node_id": "python-3-129"
}
\ No newline at end of file
{
"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",
"depends": [],
"exercise_id": 18,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 文件夹拷贝
# 描述:
# 1. 使用 shutil 拷贝 "copy.py" 文件到 "/tmp/copy.py"
# 2. 拷贝 "copy.py" 文件到 "/tmp/copy2.py", 保留元数据
# 3. 递归拷贝目录 "./" 到 "/tmp/file_test/",如果已存在就覆盖
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()
{
"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",
"depends": [],
"exercise_id": 19,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 文件统计
# 描述:统计文件中行数,非空行数,以及空格间隔的token数
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))
{
"one_line": {
"makedirs": [
"mkdir"
],
"exist_ok=True": [
"exist_ok=False"
]
},
"source": "dir.py",
"depends": [],
"exercise_id": 16,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 创建文件夹
# 描述:使用 os 递归创建文件夹,已存在就覆盖
import os
if __name__ == '__main__':
os.makedirs("/tmp/test/test/test/", exist_ok=True)
{
"one_line": {
"ordered_list_dir('./')": [
"os.listdir('./')"
],
"entries.sort()": [
""
]
},
"source": "list_file_in_dir.py",
"depends": [],
"exercise_id": 17,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题: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)
{
"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",
"depends": [],
"exercise_id": 21,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 文件遍历2
# 描述:遍历一个文件夹下的所有子文件夹下文件,并返回绝对路径列表
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)
{
"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",
"depends": [],
"exercise_id": 20,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 文件夹压缩
# 描述:使用 shutil 对文件夹进行zip压缩,压缩过程显示进度条
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()
{
"export": [
"error_code.json",
"sqlite_connector.json",
"sqlite_connection.json",
"sqlite_kv.json",
"redis_install.json",
"redis_connector.json",
"redis_kv.json",
"mysql_install.json",
"mysql_connector.json",
"mysql_connection.json",
"mysql_kv.json"
],
"keywords": [],
"children": [
{
"数据库概述": {
"keywords": [],
"children": [],
"node_id": "python-4-755"
}
},
{
"数据库安装配置": {
"keywords": [],
"children": [],
"node_id": "python-4-756"
}
},
{
"SQL语句": {
"keywords": [],
"children": [],
"node_id": "python-4-757"
}
},
{
"SQLite": {
"keywords": [],
"children": [
{
"创建数据库文件": {
"keywords": [],
"children": [],
"node_id": "python-5-409"
}
},
{
"操作SQLite": {
"keywords": [],
"children": [],
"node_id": "python-5-410"
}
}
],
"node_id": "python-4-758"
}
},
{
"MySQL": {
"keywords": [],
"children": [
{
"下载安装MySQL": {
"keywords": [],
"children": [],
"node_id": "python-5-411"
}
},
{
"连接数据库": {
"keywords": [],
"children": [],
"node_id": "python-5-412"
}
},
{
"创建数据表": {
"keywords": [],
"children": [],
"node_id": "python-5-413"
}
},
{
"操作MySQL数据表": {
"keywords": [],
"children": [],
"node_id": "python-5-414"
}
}
],
"node_id": "python-4-759"
}
},
{
"MongoDB": {
"keywords": [],
"children": [],
"node_id": "python-4-760"
}
},
{
"数据库编程接口": {
"keywords": [],
"children": [
{
"连接对象": {
"keywords": [],
"children": [],
"node_id": "python-5-415"
}
},
{
"游标对象": {
"keywords": [],
"children": [],
"node_id": "python-5-416"
}
}
],
"node_id": "python-4-761"
}
}
],
"node_id": "python-3-130"
}
\ No newline at end of file
{
"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",
"depends": [],
"exercise_id": 159,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:错误码处理
# 描述:编写一个错误码枚举,支持转换成字符串格式方法: internal_ret_2_http
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'
{
"one_line": {
"cursor.fetchall()": [
"cursor.fetchone()"
],
"self.conn.commit()": [
"self.conn.rollback()"
],
"self.conn.rollback()": [
"self.conn.commit()"
]
},
"source": "mysql_connection.py",
"depends": [
"error_code.py",
"mysql_connector.py"
],
"exercise_id": 160,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python MySQL Connection
# 描述:封装一个 MySQL 连接类,继承自 MySQLConnector,请先完成【Python MySQL Connector】
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
{
"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",
"depends": [
"error_code.py"
],
"exercise_id": 155,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python MySQL Connector
# 描述:封装一个 MySQL 的连接器,支持 open/close
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()
assert ret['err'] == ErrorCode.SUCCESS
ret = kv.close()
assert ret['err'] == ErrorCode.SUCCESS
{
"one_line": {
"-P 3306": [
"-p 3306"
],
"-p": [
"-p 123456"
],
"_key varchar(32)": [
"key varchar(32)"
],
"pip install": [
"python install"
]
},
"source": "mysql_install.py",
"depends": [
"error_code.py"
],
"exercise_id": 158,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python MySQL 安装说明
# 描述:本机测试需要先安装 mysql,假设密码是123456,请勿在命令行下直接输入密码
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;
'''
dump_depends([
'安装 MySQL : https://dev.mysql.com/downloads/installer/'
'启动 MySQL 本地服务: 每个平台不同',
'登录数据库:mysql -h 127.0.0.1 -P 3306 -u root -p',
f'请创建初始化数据库:\n{db}',
'Python 库安装: pip install mysql-connector-python',
])
{
"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",
"depends": [
"error_code.py",
"mysql_connector.py",
"mysql_connection.py"
],
"exercise_id": 24,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python MySQL 读写
# 描述:使用 MySQL 实现一个 key-value(string:json) 读写库,请先完成【Python MySQL 安装说明】、【Python MySQL Connector】和【Python MySQL Connection】
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
{
"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",
"depends": [
"error_code.py"
],
"exercise_id": 162,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python Redis 连接器
# 描述:实现一个 redis 连接器,能打开/关闭 redis 连结,使用连接池
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
{
"one_line": {
"redis-server": [
"redis",
"redis_server"
],
"redis-cli": [
"redis",
"redis_cli"
]
},
"source": "redis_install.py",
"depends": [
"error_code.py"
],
"exercise_id": 156,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python Redis 安装说明
# 描述:熟悉 Redis 的基本安装,能启动 redis 服务,进入 redis 客户端操作
def dump_depends(depends):
print()
print("# 依赖配置")
for i in range(0, len(depends)):
print("{}. {}".format(i, depends[i]))
if __name__ == '__main__':
dump_depends([
'安装 redis :https://redis.io/download',
'启动 redis 服务: redis-server',
'进入 redis 命令行客户端: redis-cli -h 127.0.0.1 -p 6379',
'库安装: pip install redis',
])
{
"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",
"depends": [
"error_code.py"
],
"exercise_id": 22,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python Redis 读写
# 描述:使用 Redis 实现一个 key-value(string:json) 读写库。请先完成【Python Redis 安装说明】和【Python Redis 连接器】
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
{
"one_line": {
"self.conn.rollback()": [
""
],
"self.conn.commit()": [
""
],
"cursor.fetchall()": [
"cursor.fetchone()"
],
"_key varchar(32)": [
"key varchar(32)"
]
},
"source": "sqlite_connection.py",
"depends": [
"error_code.py",
"sqlite_connector.py"
],
"exercise_id": 157,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python SQLITE Connection
# 描述:继承自 SqliteConnector,增加执行sql接口,请先完成【Python SQLITE Connector】
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
{
"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",
"depends": [
"error_code.py"
],
"exercise_id": 161,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python SQLITE Connector
# 描述:对 sqlite3 做一个基本的封装,支持 open/close
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
{
"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",
"depends": [
"error_code.py",
"sqlite_connector.py",
"sqlite_connection.py"
],
"exercise_id": 23,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python SQLITE 读写
# 描述:使用 SQLITE 实现一个 key-value(string:json) 读写库,请先完成【Python SQLITE Connector】和【Python SQLITE Connection】
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
{
"export": [
"os_info.json",
"platform_info.json"
],
"keywords": [],
"children": [
{
"OS/Sys": {
"keywords": [],
"children": [],
"node_id": "python-4-762"
}
}
],
"node_id": "python-3-131"
}
\ No newline at end of file
{
"one_line": {
"break": [
"continue"
],
"options.get(key)": [
"options[key]"
],
"option['action']()": [
"option['action']"
]
},
"source": "os_info.py",
"depends": [],
"exercise_id": 14,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题: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("[错误] 不支持的选项")
if __name__ == '__main__':
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)
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
}
},
})
{
"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",
"depends": [],
"exercise_id": 15,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 操作系统信息
# 描述:提示用户输入选项,输出对应选项类型的平台信息
import platform
def select(config, action):
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:
action(key)
print()
def test():
def action(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 信息",
},
}, action)
if __name__ == '__main__':
test()
{
"export": [
"package.json"
],
"keywords": [],
"children": [
{
"pyinstaller": {
"keywords": [],
"children": [],
"node_id": "python-4-769"
}
}
],
"node_id": "python-3-133"
}
\ No newline at end of file
{
"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",
"depends": [],
"exercise_id": 13,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 打包
# 描述:打印出 Python 打包目录层次结构,类似命令行 tree 的效果
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()
{
"export": [
"tcp.json"
],
"keywords": [],
"children": [
{
"网络基础": {
"keywords": [],
"children": [
{
"TCP/IP简介": {
"keywords": [],
"children": [],
"node_id": "python-5-1539"
}
},
{
"UDP简介": {
"keywords": [],
"children": [],
"node_id": "python-5-1540"
}
},
{
"Socket简介": {
"keywords": [],
"children": [],
"node_id": "python-5-1541"
}
}
],
"node_id": "python-4-1484"
}
},
{
"TCP编程": {
"keywords": [],
"children": [
{
"创建TCP服务器": {
"keywords": [],
"children": [],
"node_id": "python-5-1542"
}
},
{
"创建TCP客户端": {
"keywords": [],
"children": [],
"node_id": "python-5-1543"
}
},
{
"执行TCP服务器和客户端": {
"keywords": [],
"children": [],
"node_id": "python-5-1544"
}
}
],
"node_id": "python-4-1485"
}
},
{
"UDP编程": {
"keywords": [],
"children": [
{
"创建UDP服务器": {
"keywords": [],
"children": [],
"node_id": "python-5-1545"
}
},
{
"创建UDP客户端": {
"keywords": [],
"children": [],
"node_id": "python-5-1546"
}
},
{
"执行UDP服务器和客户端": {
"keywords": [],
"children": [],
"node_id": "python-5-1547"
}
}
],
"node_id": "python-4-1486"
}
}
],
"node_id": "python-3-134"
}
\ No newline at end of file
{
"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",
"depends": [],
"exercise_id": 7,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 网络编程(1)
# 描述:编写一个简易的 ECHO 服务机器人。<br/>客户端发送文本,服务端回复同样的文本,两边都打印各自收到的文本。<br/>支持每次不大于 140 的文本输入,如果超出则提示重新输入。
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))
{
"export": [
"send_mail.json"
],
"keywords": [],
"children": [
{
"smtplib": {
"keywords": [],
"children": [],
"node_id": "python-4-788"
}
}
],
"node_id": "python-3-135"
}
\ No newline at end of file
{
"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",
"depends": [],
"exercise_id": 25,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python mail
# 描述:发送QQ邮件
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()
{
"node_id": "python-2-5",
"keywords": []
}
\ No newline at end of file
{
"export": [
"error_code.json",
"store.json",
"router.json",
"validator.json",
"server.json"
],
"keywords": [],
"children": [
{
"HTML/HTML5/CSS": {
"keywords": [],
"children": [],
"node_id": "python-4-789"
}
},
{
"前端数据库和后台": {
"keywords": [],
"children": [],
"node_id": "python-4-790"
}
},
{
"MVC架构": {
"keywords": [],
"children": [],
"node_id": "python-4-791"
}
},
{
"REST和Ajax": {
"keywords": [],
"children": [],
"node_id": "python-4-792"
}
}
],
"node_id": "python-3-136"
}
\ No newline at end of file
{
"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",
"depends": [],
"exercise_id": 153,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:错误码处理
# 描述:编写一个错误码枚举,支持转换成字符串格式方法: internal_ret_2_http
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'
{
"one_line": {
"req_path is None": [
"req_path is not None"
],
"self.routes.get(req_path) is None": [
"self.routes.get(req_path) is not None"
],
"handler(req), 200": [
"self.routes.get(req_path)(req), 503"
],
"lambda req:": [
"lambda path, data:"
]
},
"source": "router.py",
"depends": [
"error_code.py"
],
"exercise_id": 154,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:路由器
# 描述:编写一个路由服务,主持注入路由配置,正确处理请求参数
from error_code import ErrorCode
import json
import logging
import traceback
logger = logging.getLogger(__name__)
class Router:
def __init__(self, routes) -> None:
self.routes = routes
def dispatch(self, http_request_str):
assert http_request_str is not None
assert type(http_request_str) == type('')
req_path = None
req = None
try:
http_request = json.loads(http_request_str)
req_path = http_request.get('path')
req = http_request.get('data')
except Exception as e:
logger.error(f"parse data exception:{str(e)}")
return {'err': ErrorCode.INVALID_PARAMETERS}, 200
if req_path is None or self.routes.get(req_path) is None:
return {'err': ErrorCode.NOT_FOUND}, 404
try:
handler = self.routes.get(req_path)
return handler(req), 200
except Exception as e:
logger.error(f"route to '{req_path}' exception:{str(e)}")
logger.error(traceback.format_exc())
return {'err': ErrorCode.FAILED}, 500
if __name__ == '__main__':
server = Router({
'/': lambda req: print(f'goto home:{str(req)}')
})
server.dispatch(json.dumps({
'path': '/',
'data': ["Hello", "World!"]
}))
{
"one_line": {
"'/kv/create': self.__create": [
"'/kv/create': self.__remove"
],
"ErrorCode.internal_ret_2_http(ret)": [
"ret.internal_ret_2_http()"
],
"self.validator.validate(req, ['key', 'value'])": [
"self.validator.validate(req, ['key'])"
]
},
"source": "server.py",
"depends": [
"error_code.py",
"store.py",
"router.py",
"validator.py"
],
"exercise_id": 152,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python Web 服务模拟器
# 描述:模拟一个 Web 服务,创建资源,删除一个符合条件的资源,总数应该为0
from error_code import ErrorCode
from store import Store
from router import Router
from validator import KeyValueValidator
import json
import logging
import traceback
logger = logging.getLogger(__name__)
class App:
def __init__(self) -> None:
self.store = Store({})
self.validator = KeyValueValidator()
self.router = Router({
'/': self.__home,
'/kv/create': self.__create,
'/kv/remove': self.__remove,
'/kv/count': self.__count,
})
def post(self, path, data):
http_request = {
'path': path,
'data': data
}
ret, status_code = self.router.dispatch(json.dumps(http_request))
ErrorCode.internal_ret_2_http(ret)
resp = ""
try:
resp = json.dumps(ret)
except Exception as e:
logger.error("parse resp exception:%s", str(e))
logger.error(traceback.format_exc())
return resp, status_code
def __home(self, req):
return {'err': ErrorCode.SUCCESS, 'result': "Welcome!"}
def __create(self, req):
ret = self.validator.validate(req, ['key', 'value'])
if ret['err'] != ErrorCode.SUCCESS:
return ret
return self.store.create(req['key'], req['value'])
def __remove(self, req):
ret = self.validator.validate(req, ['key', 'condition'])
if ret['err'] != ErrorCode.SUCCESS:
return ret
return self.store.remove(req['key'], req['condition'])
def __count(self, req):
return self.store.count()
if __name__ == '__main__':
app = App()
resp, status = app.post('/kv/create', {
'key': 'test',
'value': 1000,
})
resp, status = app.post('/kv/remove', {
'key': 'test',
'condition': 1000,
})
resp, status = app.post('/kv/count', {})
assert status == 200
assert json.loads(resp)['err'] == 'success'
assert json.loads(resp)['result'] == 0
{
"one_line": {
"self.records.get(key) is None": [
"self.records.get(key) is not None"
],
"'result': len(self.records.keys())": [
"'result': len(self.records)"
],
"self.records.get(key) == condition": [
"self.records.get(key) != condition"
]
},
"source": "store.py",
"depends": [
"error_code.py"
],
"exercise_id": 150,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:状态存储
# 描述:使用dict数据结构,实现创建、删除、查询总数存储接口,创建/删除同一个资源后,总是应该为0
from error_code import ErrorCode
import logging
logger = logging.getLogger(__name__)
class Store:
def __init__(self, config) -> None:
self.config = config
self.records = {}
def __where(self, key, condition):
if condition is None:
return True
return self.records.get(key) == condition
def create(self, key, value):
if self.records.get(key) is None:
self.records[key] = value
return {'err': ErrorCode.SUCCESS}
else:
return {'err': ErrorCode.ALREADY_EXIST}
def update(self, key, value, condition=None):
if self.__where(key, condition):
self.records[key] = value
return {'err': ErrorCode.SUCCESS}
else:
return {'err': ErrorCode.NOT_FOUND}
def remove(self, key, condition=None):
if self.__where(key, condition):
del self.records[key]
return {'err': ErrorCode.SUCCESS}
else:
return {'err': ErrorCode.NOT_FOUND}
def count(self):
return {'err': ErrorCode.SUCCESS, 'result': len(self.records.keys())}
def fetch(self, key, condition=None):
if self.__where(key, condition):
result = self.records.get(key)
if result is None:
return {'err': ErrorCode.NOT_FOUND}
else:
return {'err': ErrorCode.SUCCESS, 'result': [result]}
else:
return {'err': ErrorCode.NOT_FOUND}
if __name__ == '__main__':
store = Store({})
ret = store.create("test", 100)
assert ret['err'] == ErrorCode.SUCCESS
ret = store.remove("test")
assert ret['err'] == ErrorCode.SUCCESS
ret = store.count()
assert ret['err'] == ErrorCode.SUCCESS
assert ret['result'] == 0
{
"one_line": {
"\"key\": {\"type\": \"string\"},": [
"\"key\": {\"type\": \"number\"},"
],
"\"required\": required": [
"\"required\": req"
],
"\"value\": {\"type\": \"number\"}": [
"\"value\": {\"type\": [\"number\",\"string\"]}"
]
},
"source": "validator.py",
"depends": [
"error_code.py"
],
"exercise_id": 151,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:参数校验
# 描述:使用 jsonschema 校验参数,key:字符串类型, value:数字, condition: 数字
from error_code import ErrorCode
from jsonschema import validate
import json
import logging
import traceback
logger = logging.getLogger(__name__)
class KeyValueValidator:
def __init__(self) -> None:
pass
def validate(self, req, required):
schema = {
"type": "object",
"properties": {
"key": {"type": "string"},
"value": {"type": "number"},
"condition": {"type": "number"},
},
"required": required
}
try:
validate(instance=req, schema=schema)
return {
'err': ErrorCode.SUCCESS
}
except Exception as e:
logger.error(f"validate exception:{str(e)}")
logger.error(traceback.format_exc())
return {
'err': ErrorCode.INVALID_PARAMETERS
}
if __name__ == '__main__':
v = KeyValueValidator()
ret = v.validate({'key': "test", 'value': 100}, ['key', 'value'])
assert ret['err'] == ErrorCode.SUCCESS
ret = v.validate({'key': "test"}, ['key', 'value'])
assert ret['err'] == ErrorCode.INVALID_PARAMETERS
{
"export": [
"howto.json"
],
"keywords": [],
"children": [
{
"Django简介": {
"keywords": [],
"children": [],
"node_id": "python-4-793"
}
},
{
"Django安装配置": {
"keywords": [],
"children": [],
"node_id": "python-4-794"
}
},
{
"DTL(Django Template Language)": {
"keywords": [],
"children": [],
"node_id": "python-4-795"
}
},
{
"Django路由定义": {
"keywords": [],
"children": [],
"node_id": "python-4-796"
}
},
{
"Django请求数据解析": {
"keywords": [],
"children": [],
"node_id": "python-4-797"
}
},
{
"Django数据库操作": {
"keywords": [],
"children": [],
"node_id": "python-4-798"
}
},
{
"Django提交表单": {
"keywords": [],
"children": [],
"node_id": "python-4-799"
}
},
{
"Django Rest Framework": {
"keywords": [],
"children": [],
"node_id": "python-4-800"
}
},
{
"部署日志与安全": {
"keywords": [],
"children": [],
"node_id": "python-4-801"
}
},
{
"Django开发案例": {
"keywords": [],
"children": [],
"node_id": "python-4-802"
}
},
{
"Web框架": {
"keywords": [],
"children": [],
"node_id": "python-4-803"
}
},
{
"“Hello World”应用(一个博客)": {
"keywords": [],
"children": [],
"node_id": "python-4-804"
}
},
{
"创建模型来添加数据库服务": {
"keywords": [],
"children": [
{
"设置数据库": {
"keywords": [],
"children": [],
"node_id": "python-5-447"
}
}
],
"node_id": "python-4-805"
}
},
{
"Python应用shell": {
"keywords": [],
"children": [
{
"在Django中使用Python shell": {
"keywords": [],
"children": [],
"node_id": "python-5-448"
}
},
{
"测试数据模型": {
"keywords": [],
"children": [],
"node_id": "python-5-449"
}
}
],
"node_id": "python-4-806"
}
},
{
"Django管理应用": {
"keywords": [],
"children": [
{
"设置admin": {
"keywords": [],
"children": [],
"node_id": "python-5-450"
}
},
{
"使用admin": {
"keywords": [],
"children": [],
"node_id": "python-5-451"
}
}
],
"node_id": "python-4-807"
}
},
{
"创建博客的用户界面": {
"keywords": [],
"children": [
{
"创建模板": {
"keywords": [],
"children": [],
"node_id": "python-5-452"
}
},
{
"创建URL模式": {
"keywords": [],
"children": [],
"node_id": "python-5-453"
}
},
{
"创建视图函数": {
"keywords": [],
"children": [],
"node_id": "python-5-454"
}
}
],
"node_id": "python-4-808"
}
},
{
"改进输出": {
"keywords": [],
"children": [],
"node_id": "python-4-809"
}
},
{
"处理用户输入": {
"keywords": [],
"children": [
{
"添加URLconf项": {
"keywords": [],
"children": [],
"node_id": "python-5-455"
}
},
{
"视图:处理用户输入": {
"keywords": [],
"children": [],
"node_id": "python-5-456"
}
},
{
"跨站点请求伪造": {
"keywords": [],
"children": [],
"node_id": "python-5-457"
}
}
],
"node_id": "python-4-810"
}
},
{
"表单和模型表单": {
"keywords": [],
"children": [
{
"Django表单简介": {
"keywords": [],
"children": [],
"node_id": "python-5-458"
}
},
{
"模型表单示例": {
"keywords": [],
"children": [],
"node_id": "python-5-459"
}
},
{
"使用ModelForm来生成HTML表单": {
"keywords": [],
"children": [],
"node_id": "python-5-460"
}
},
{
"处理ModelForm数据": {
"keywords": [],
"children": [],
"node_id": "python-5-461"
}
}
],
"node_id": "python-4-811"
}
},
{
"视图进阶": {
"keywords": [],
"children": [],
"node_id": "python-4-812"
}
},
{
"*改善外观": {
"keywords": [],
"children": [],
"node_id": "python-4-813"
}
},
{
"*中级Django应用:TweetApprover": {
"keywords": [],
"children": [
{
"安装Twython库": {
"keywords": [],
"children": [],
"node_id": "python-5-462"
}
},
{
"URL结构": {
"keywords": [],
"children": [],
"node_id": "python-5-463"
}
},
{
"数据模型": {
"keywords": [],
"children": [],
"node_id": "python-5-464"
}
},
{
"提交新推文以便审核": {
"keywords": [],
"children": [],
"node_id": "python-5-465"
}
},
{
"审核推文": {
"keywords": [],
"children": [],
"node_id": "python-5-466"
}
}
],
"node_id": "python-4-814"
}
},
{
"资源": {
"keywords": [],
"children": [],
"node_id": "python-4-815"
}
}
],
"node_id": "python-3-137"
}
\ No newline at end of file
{
"one_line": {
"pip install django": [
"pip install dango"
],
"django-admin": [
"django_admin"
],
"startproject": [
"project"
],
"startapp": [
"app"
]
},
"source": "howto.py",
"depends": [],
"exercise_id": 104,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python Django 框架
# 描述:自己动手,丰衣足食,打印 Django 教程的入口信息
if __name__ == '__main__':
installs = [
"安装:pip install django",
"初始化:django-admin startproject projectName",
"进入目录:cd projectName",
"初始化:python manage.py startapp projectApp",
"进一步查看教程:https://docs.djangoproject.com/zh-hans/3.2/"
]
for step in installs:
print(step)
{
"export": [
"hello.json"
],
"keywords": [],
"children": [
{
"Tornado简介": {
"keywords": [],
"children": [],
"node_id": "python-4-816"
}
},
{
"Tornado安装配置": {
"keywords": [],
"children": [],
"node_id": "python-4-817"
}
},
{
"Tornado提交表单": {
"keywords": [],
"children": [],
"node_id": "python-4-818"
}
},
{
"Tornado模板": {
"keywords": [],
"children": [],
"node_id": "python-4-819"
}
},
{
"Tornado数据库操作": {
"keywords": [],
"children": [],
"node_id": "python-4-820"
}
},
{
"Tornado异步Web服务": {
"keywords": [],
"children": [],
"node_id": "python-4-821"
}
},
{
"外部服务认证(auth)": {
"keywords": [],
"children": [],
"node_id": "python-4-822"
}
},
{
"部署日志与安全": {
"keywords": [],
"children": [],
"node_id": "python-4-823"
}
},
{
"Tornado开发案例": {
"keywords": [],
"children": [],
"node_id": "python-4-824"
}
}
],
"node_id": "python-3-138"
}
\ No newline at end of file
{
"one_line": {
"start()": [
"listen()",
"accept()"
],
"app.listen(8000)": [
"app.listen(80)"
],
"self.write": [
"self.read"
]
},
"source": "hello.py",
"depends": [],
"exercise_id": 106,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python tornado 框架
# 描述:tornado 服务,极简路由
import tornado.web
import tornado.ioloop
class IndexHandler(tornado.web.RequestHandler):
"""主路由处理类"""
def get(self):
"""对应http的get请求方式"""
self.write("Hello Tornado!")
if __name__ == "__main__":
app = tornado.web.Application([
(r"/", IndexHandler),
])
app.listen(8000)
print("* Tornado Web Server 已在 8000 端口启动。")
print("* 请在浏览器里输入 127.0.0.1:8000")
tornado.ioloop.IOLoop.current().start()
{
"export": [
"server.json"
],
"keywords": [],
"children": [
{
"Flask简介": {
"keywords": [],
"children": [
{
"安装": {
"keywords": [],
"children": [
{
"创建应用目录": {
"keywords": [],
"children": [],
"node_id": "python-6-56"
}
},
{
"虚拟环境": {
"keywords": [],
"children": [],
"node_id": "python-6-57"
}
},
{
"在Python 3中创建虚拟环境": {
"keywords": [],
"children": [],
"node_id": "python-6-58"
}
},
{
"在Python 2中创建虚拟环境": {
"keywords": [],
"children": [],
"node_id": "python-6-59"
}
},
{
"使用虚拟环境": {
"keywords": [],
"children": [],
"node_id": "python-6-60"
}
},
{
"使用pip安装Python包": {
"keywords": [],
"children": [],
"node_id": "python-6-61"
}
}
],
"node_id": "python-5-467"
}
},
{
"应用的基本结构": {
"keywords": [],
"children": [
{
"初始化": {
"keywords": [],
"children": [],
"node_id": "python-6-62"
}
},
{
"路由和视图函数": {
"keywords": [],
"children": [],
"node_id": "python-6-63"
}
},
{
"一个完整的应用": {
"keywords": [],
"children": [],
"node_id": "python-6-64"
}
},
{
"Web开发服务器": {
"keywords": [],
"children": [],
"node_id": "python-6-65"
}
},
{
"动态路由": {
"keywords": [],
"children": [],
"node_id": "python-6-66"
}
},
{
"调试模式": {
"keywords": [],
"children": [],
"node_id": "python-6-67"
}
},
{
"命令行选项": {
"keywords": [],
"children": [],
"node_id": "python-6-68"
}
},
{
"请求–响应循环": {
"keywords": [],
"children": [
{
"应用和请求上下文": {
"keywords": [],
"children": [],
"node_id": "python-7-15"
}
},
{
"请求分派": {
"keywords": [],
"children": [],
"node_id": "python-7-16"
}
},
{
"请求对象": {
"keywords": [],
"children": [
{
"对象显示": {
"keywords": [],
"children": [],
"node_id": "python-8-0"
}
},
{
"有效创建大量对象": {
"keywords": [],
"children": [],
"node_id": "python-8-1"
}
},
{
"由字符串调用对象": {
"keywords": [],
"children": [],
"node_id": "python-8-2"
}
}
],
"node_id": "python-7-17"
}
},
{
"请求钩子": {
"keywords": [],
"children": [],
"node_id": "python-7-18"
}
}
],
"node_id": "python-6-69"
}
},
{
"Flask扩展": {
"keywords": [],
"children": [],
"node_id": "python-6-70"
}
}
],
"node_id": "python-5-468"
}
},
{
"模板": {
"keywords": [],
"children": [
{
"Jinja2模板引擎": {
"keywords": [],
"children": [
{
"渲染模板": {
"keywords": [],
"children": [],
"node_id": "python-7-19"
}
},
{
"变量": {
"keywords": [],
"children": [
{
"匿名函数捕获变量值": {
"keywords": [],
"children": [],
"node_id": "python-8-3"
}
},
{
"访问闭包中定义的变量": {
"keywords": [],
"children": [],
"node_id": "python-8-4"
}
}
],
"node_id": "python-7-20"
}
},
{
"控制结构": {
"keywords": [],
"children": [],
"node_id": "python-7-21"
}
}
],
"node_id": "python-6-71"
}
},
{
"使用Flask-Bootstrap集成Bootstrap": {
"keywords": [],
"children": [],
"node_id": "python-6-72"
}
},
{
"自定义错误页面": {
"keywords": [],
"children": [],
"node_id": "python-6-73"
}
},
{
"链接": {
"keywords": [],
"children": [],
"node_id": "python-6-74"
}
},
{
"静态文件": {
"keywords": [],
"children": [],
"node_id": "python-6-75"
}
},
{
"使用Flask-Moment本地化日期和时间": {
"keywords": [],
"children": [],
"node_id": "python-6-76"
}
}
],
"node_id": "python-5-469"
}
},
{
"Web表单": {
"keywords": [],
"children": [
{
"配置": {
"keywords": [],
"children": [],
"node_id": "python-6-77"
}
},
{
"表单类": {
"keywords": [],
"children": [],
"node_id": "python-5-1569"
}
},
{
"把表单渲染成HTML": {
"keywords": [],
"children": [],
"node_id": "python-5-1570"
}
},
{
"在视图函数中处理表单": {
"keywords": [],
"children": [],
"node_id": "python-6-80"
}
},
{
"重定向和用户会话": {
"keywords": [],
"children": [],
"node_id": "python-6-81"
}
},
{
"闪现消息": {
"keywords": [],
"children": [],
"node_id": "python-6-82"
}
}
],
"node_id": "python-5-470"
}
},
{
"数据库": {
"keywords": [],
"children": [
{
"SQL数据库": {
"keywords": [],
"children": [],
"node_id": "python-6-83"
}
},
{
"NoSQL数据库": {
"keywords": [],
"children": [],
"node_id": "python-6-84"
}
},
{
"使用SQL还是NoSQL": {
"keywords": [],
"children": [],
"node_id": "python-6-85"
}
},
{
"Python数据库框架": {
"keywords": [],
"children": [],
"node_id": "python-6-86"
}
},
{
"使用Flask-SQLAlchemy管理数据库": {
"keywords": [],
"children": [],
"node_id": "python-6-87"
}
},
{
"定义模型": {
"keywords": [],
"children": [],
"node_id": "python-6-88"
}
},
{
"关系": {
"keywords": [],
"children": [],
"node_id": "python-6-89"
}
},
{
"数据库操作": {
"keywords": [],
"children": [
{
"创建表": {
"keywords": [],
"children": [],
"node_id": "python-7-22"
}
},
{
"插入行": {
"keywords": [],
"children": [],
"node_id": "python-7-23"
}
},
{
"修改行": {
"keywords": [],
"children": [],
"node_id": "python-7-24"
}
},
{
"删除行": {
"keywords": [],
"children": [],
"node_id": "python-7-25"
}
},
{
"查询行": {
"keywords": [],
"children": [],
"node_id": "python-7-26"
}
}
],
"node_id": "python-6-90"
}
},
{
"在视图函数中操作数据库": {
"keywords": [],
"children": [],
"node_id": "python-6-91"
}
},
{
"集成Python shell": {
"keywords": [],
"children": [],
"node_id": "python-6-92"
}
},
{
"使用Flask-Migrate实现数据库迁移": {
"keywords": [],
"children": [
{
"创建迁移仓库": {
"keywords": [],
"children": [],
"node_id": "python-7-27"
}
},
{
"创建迁移脚本": {
"keywords": [],
"children": [],
"node_id": "python-7-28"
}
},
{
"更新数据库": {
"keywords": [],
"children": [],
"node_id": "python-7-29"
}
},
{
"添加几个迁移": {
"keywords": [],
"children": [],
"node_id": "python-7-30"
}
}
],
"node_id": "python-6-93"
}
}
],
"node_id": "python-5-471"
}
},
{
"电子邮件": {
"keywords": [],
"children": [
{
"电子邮件系统组件和协议": {
"keywords": [],
"children": [],
"node_id": "python-6-94"
}
},
{
"发送电子邮件": {
"keywords": [],
"children": [],
"node_id": "python-6-95"
}
},
{
"Python和SMTP": {
"keywords": [],
"children": [],
"node_id": "python-6-96"
}
},
{
"smtplib.SMTP类方法": {
"keywords": [],
"children": [],
"node_id": "python-6-97"
}
},
{
"交互式SMTP示例": {
"keywords": [],
"children": [],
"node_id": "python-6-98"
}
},
{
"SMTP的其他内容": {
"keywords": [],
"children": [],
"node_id": "python-6-99"
}
},
{
"接收电子邮件": {
"keywords": [],
"children": [],
"node_id": "python-6-100"
}
},
{
"POP和IMAP": {
"keywords": [],
"children": [],
"node_id": "python-6-101"
}
},
{
"交互式POP3示例": {
"keywords": [],
"children": [],
"node_id": "python-6-102"
}
},
{
"poplib.POP3类方法": {
"keywords": [],
"children": [],
"node_id": "python-6-103"
}
},
{
"客户端程序SMTP和POP3示例": {
"keywords": [],
"children": [],
"node_id": "python-6-104"
}
},
{
"交互式IMAP4示例": {
"keywords": [],
"children": [],
"node_id": "python-6-105"
}
},
{
"imaplib.IMAP4类中的常用方法": {
"keywords": [],
"children": [],
"node_id": "python-6-106"
}
}
],
"node_id": "python-5-472"
}
},
{
"大型应用的结构": {
"keywords": [],
"children": [
{
"配置选项": {
"keywords": [],
"children": [],
"node_id": "python-6-107"
}
},
{
"应用包": {
"keywords": [],
"children": [
{
"使用应用工厂函数": {
"keywords": [],
"children": [],
"node_id": "python-7-31"
}
},
{
"在蓝本中实现应用功能": {
"keywords": [],
"children": [],
"node_id": "python-7-32"
}
}
],
"node_id": "python-6-108"
}
},
{
"应用脚本": {
"keywords": [],
"children": [],
"node_id": "python-6-109"
}
},
{
"需求文件": {
"keywords": [],
"children": [],
"node_id": "python-6-110"
}
},
{
"单元测试": {
"keywords": [],
"children": [
{
"blog应用的代码审查": {
"keywords": [],
"children": [],
"node_id": "python-7-33"
}
}
],
"node_id": "python-6-111"
}
},
{
"创建数据库": {
"keywords": [],
"children": [],
"node_id": "python-6-112"
}
},
{
"运行应用": {
"keywords": [],
"children": [],
"node_id": "python-6-113"
}
}
],
"node_id": "python-5-473"
}
}
],
"node_id": "python-4-825"
}
},
{
"Flask安装配置": {
"keywords": [],
"children": [],
"node_id": "python-4-826"
}
},
{
"Flask实现HTTP请求与响应": {
"keywords": [],
"children": [],
"node_id": "python-4-827"
}
},
{
"Flask cookie与session": {
"keywords": [],
"children": [],
"node_id": "python-4-828"
}
},
{
"Flask模板": {
"keywords": [],
"children": [],
"node_id": "python-4-829"
}
},
{
"Flask提交表单": {
"keywords": [],
"children": [],
"node_id": "python-4-830"
}
},
{
"Flask数据库操作": {
"keywords": [],
"children": [],
"node_id": "python-4-831"
}
},
{
"Bootstrap-Flask": {
"keywords": [],
"children": [],
"node_id": "python-4-832"
}
},
{
"Flask开发REST Web服务": {
"keywords": [],
"children": [],
"node_id": "python-4-833"
}
},
{
"部署日志与安全": {
"keywords": [],
"children": [],
"node_id": "python-4-834"
}
},
{
"Flask开发案例": {
"keywords": [],
"children": [],
"node_id": "python-4-835"
}
}
],
"node_id": "python-3-139"
}
\ No newline at end of file
{
"one_line": {
"pywsgi.WSGIServer((host, port), app)": [
"pywsgi.WSGIServer(host, port, app)"
],
"server.serve_forever()": [
"server.start()"
],
"methods=['GET']": [
"methods=[GET]"
]
},
"source": "server.py",
"depends": [],
"exercise_id": 212,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Flask简单使用
# 描述:用flask启动web服务
import sys
from flask import Flask
from flask_cors import CORS
from gevent import pywsgi, monkey
monkey.patch_all()
app = Flask(
__name__,
static_folder='web',
static_url_path=''
)
def after_request(resp):
resp.headers['Access-Control-Allow-Origin'] = '*'
return resp
app.after_request(after_request)
app.config['JSON_AS_ASCII'] = False
CORS(app, supports_credentials=True)
@app.route('/', methods=['GET'])
def home():
return "<p>Hello World!</p>"
if __name__ == '__main__':
host = '127.0.0.1'
port = 1024
print('@启动服务...')
print("@本地调试:http://{}:{}".format(host, port))
if len(sys.argv) > 1 and sys.argv[1] == 'debug':
app.run(host=host, port=port)
else:
server = pywsgi.WSGIServer((host, port), app)
server.serve_forever()
{
"node_id": "python-2-6",
"keywords": []
}
\ No newline at end of file
{
"export": [
"get_html.json",
"with_headers.json",
"post.json"
],
"keywords": [],
"children": [
{
"处理异常": {
"keywords": [],
"children": [],
"node_id": "python-4-868"
}
},
{
"解析链接": {
"keywords": [],
"children": [],
"node_id": "python-4-869"
}
},
{
"分析Robots协议": {
"keywords": [],
"children": [],
"node_id": "python-4-870"
}
}
],
"node_id": "python-3-147"
}
\ No newline at end of file
{
"one_line": {
"urllib.request.urlopen": [
"urllib.request"
],
"response.read()": [
"response.readline()"
],
"buff.decode(\"utf8\")": [
"buff.encode(\"utf8\")"
]
},
"source": "get_html.py",
"depends": [],
"exercise_id": 198,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:行走的人偶
# 标题:urlib 获取网页(1)
# 描述:将 url 对应的网页下载到本地
import urllib.request
def get_html(url):
response = urllib.request.urlopen(url)
buff = response.read()
html = buff.decode("utf8")
return html
if __name__ == '__main__':
url = "http://www.baidu.com"
html = get_html(url)
print(html)
{
"one_line": {
"bytes(urllib.parse.urlencode(data), encoding='utf8')": [
"bytes(urllib.parse.urlencode(data))",
"bytes(data, encoding='utf8')",
"urllib.parse.urlencode(data)"
]
},
"source": "post.py",
"depends": [],
"exercise_id": 202,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:行走的人偶
# 标题:urllib post请求
# 描述:urllib post请求
import urllib.request
import urllib.parse
def get_response(url, data):
data = bytes(urllib.parse.urlencode(data), encoding='utf8')
response = urllib.request.urlopen(url, data=data)
buff = response.read()
result = buff.decode("utf8")
return result
if __name__ == '__main__':
data = {
"key1": "value1",
"key2": "value2"
}
url = "http://httpbin.org/post"
html = get_response(url, data)
print(html)
{
"one_line": {
"req.add_header(key, headers[key])": [
"req.append(key, headers[key])"
],
"urllib.request.urlopen(req)": [
"urllib.request.urlopen(url)"
],
"urllib.request.Request(url)": [
"urllib.request.request(url)"
]
},
"source": "with_headers.py",
"depends": [],
"exercise_id": 247,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:行走的人偶
# 标题:urlib 获取网页(2) with header
# 描述:将 url 对应的网页下载到本地
import urllib.request
def get_html(url, headers=None):
req = urllib.request.Request(url)
if headers is not None:
for key in headers:
req.add_header(key, headers[key])
response = urllib.request.urlopen(req)
buff = response.read()
html = buff.decode("utf8")
return html
if __name__ == '__main__':
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36"
}
url = "http://www.baidu.com"
html = get_html(url, headers)
print(html)
{
"export": [],
"keywords": [],
"children": [
{
"Splash的使用": {
"keywords": [],
"children": [],
"node_id": "python-4-956"
}
},
{
"Splash负载均衡配置": {
"keywords": [],
"children": [],
"node_id": "python-4-957"
}
},
{
"使用Selenium爬取淘宝商品": {
"keywords": [],
"children": [],
"node_id": "python-4-958"
}
}
],
"node_id": "python-3-166"
}
\ No newline at end of file
{
"export": [],
"keywords": [],
"children": [
{
"模拟登录并爬取GitHub": {
"keywords": [],
"children": [],
"node_id": "python-4-968"
}
},
{
"Cookies池的搭建": {
"keywords": [],
"children": [],
"node_id": "python-4-969"
}
}
],
"node_id": "python-3-169"
}
\ No newline at end of file
{
"one_line": {
"findall": [
"find",
"finds",
"find_all"
]
},
"source": "chinese01.py",
"depends": [],
"exercise_id": 243,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:行走的人偶
# 标题:Python 中文处理(1)
# 描述:获取中文个数
import re
def getnum_of_cn(inputdata):
'''计算字符串中 中文字符 数量'''
chi = re.findall(r'[\u4E00-\u9FFF]', inputdata)
return len(chi)
def test():
n = getnum_of_cn('你好,lajfldkjaklda123')
print(n)
if __name__ == '__main__':
test()
{
"one_line": {
"search": [
"searchall",
"match",
"find"
]
},
"source": "chinese02.py",
"depends": [],
"exercise_id": 219,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:行走的人偶
# 标题:Python 中文处理(2)
# 描述:获取中文个数
import re
def search_text(inputdata):
'''search返回匹配到的一个'''
chi = re.search('nlp', inputdata)
return chi
def test():
n = search_text('你好,nlp先生!nlp先生!')
print(n)
if __name__ == '__main__':
test()
{
"export": [
"chinese01.json",
"chinese02.json",
"remove_html.json",
"find_ip_address.json"
],
"keywords": [],
"children": [
{
"RE(Regular Expression )": {
"keywords": [],
"children": [],
"node_id": "python-4-871"
}
},
{
"基础语法": {
"keywords": [],
"children": [],
"node_id": "python-4-872"
}
},
{
"标签匹配常用规则": {
"keywords": [],
"children": [],
"node_id": "python-4-873"
}
},
{
"简介/动机": {
"keywords": [],
"children": [],
"node_id": "python-4-874"
}
},
{
"特殊符号和字符": {
"keywords": [],
"children": [
{
"使用择一匹配符号匹配多个正则表达式模式": {
"keywords": [],
"children": [],
"node_id": "python-5-526"
}
},
{
"匹配任意单个字符": {
"keywords": [],
"children": [],
"node_id": "python-5-527"
}
},
{
"从字符串起始或者结尾或者单词边界匹配": {
"keywords": [],
"children": [],
"node_id": "python-5-528"
}
},
{
"创建字符集": {
"keywords": [],
"children": [],
"node_id": "python-5-529"
}
},
{
"限定范围和否定": {
"keywords": [],
"children": [],
"node_id": "python-5-530"
}
},
{
"使用闭包操作符实现存在性和频数匹配": {
"keywords": [],
"children": [],
"node_id": "python-5-531"
}
},
{
"表示字符集的特殊字符": {
"keywords": [],
"children": [],
"node_id": "python-5-532"
}
},
{
"使用圆括号指定分组": {
"keywords": [],
"children": [],
"node_id": "python-5-533"
}
},
{
"扩展表示法": {
"keywords": [],
"children": [],
"node_id": "python-5-534"
}
}
],
"node_id": "python-4-875"
}
},
{
"一些正则表达式示例": {
"keywords": [],
"children": [],
"node_id": "python-4-876"
}
},
{
"更长的正则表达式示例": {
"keywords": [],
"children": [],
"node_id": "python-4-877"
}
}
],
"node_id": "python-3-148"
}
\ No newline at end of file
{
"one_line": {
"findall": [
"search",
"match",
"sub"
]
},
"source": "find_ip_address.py",
"depends": [],
"exercise_id": 181,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:正则表达式实战(2)
# 描述:查找字符串里含有的全部 IPV4 和 IPV6 地址
import re
def find_all_ip(text):
result = []
ipv4 = r"((\b25[0-5]|\b2[0-4][0-9]|\b[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3})"
ret = re.findall(ipv4, text)
for m in ret:
result.append({'type': 'ipv4', 'value': m[0]})
ipv6 = r"(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))"
ret = re.finditer(ipv6, text)
for m in ret:
result.append({'type': 'ipv6', 'value': m[0]})
return result
if __name__ == '__main__':
input = 'IP地址有IPV4,例如:192.168.100.2,也有IPV6,例如:fe80:0000:0000:0000:0204:61ff:fe9d:f156,以及:fe80:0000:0000:0000:0204:61ff:fe9d:f156,还有 192.168.100.50'
results = find_all_ip(input)
for item in results:
print('type: {}, value: {}'.format(item['type'], item['value']))
{
"one_line": {
"<[^>]+>": [
"<.*>",
"<[^>]?>"
],
",re.S": [
""
]
},
"source": "remove_html.py",
"depends": [],
"exercise_id": 182,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:行走的人偶
# 标题:正则表达式实战(1)
# 描述:去除html标签
import re
from typing import Text
def remove_html(content):
pattern = re.compile(r'<[^>]+>', re.S)
result = pattern.sub('', content)
return result
def test():
html = '''
<html>
<head>
<title>这是一个简单的测试页面</title>
</head>
<body>
<p class="item-0">body 元素的内容会显示在浏览器中。</p>
<p class="item-1">title 元素的内容会显示在浏览器的标题栏中。</p>
</body>
</html>
'''
Text = remove_html(html)
print(Text)
if __name__ == '__main__':
test()
{
"export": [
"get_p.json",
"get_text.json",
"html_parer.json"
],
"keywords": [],
"children": [
{
"Beautiful Soup简介": {
"keywords": [],
"children": [],
"node_id": "python-4-878"
}
},
{
"安装配置": {
"keywords": [],
"children": [],
"node_id": "python-4-879"
}
},
{
"Beautiful Soup对象": {
"keywords": [],
"children": [],
"node_id": "python-4-880"
}
},
{
"元素定位": {
"keywords": [],
"children": [],
"node_id": "python-4-881"
}
},
{
"文档树遍历与搜索": {
"keywords": [],
"children": [],
"node_id": "python-4-882"
}
}
],
"node_id": "python-3-149"
}
\ No newline at end of file
{
"one_line": {
"find_all": [
"find",
"xpath",
"findall"
]
},
"source": "get_p.py",
"depends": [],
"exercise_id": 204,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:行走的人偶
# 标题:BeautifulSoup 获取所有p标签
# 描述:获取所有p标签
from bs4 import BeautifulSoup
def fetch_p(html):
soup = BeautifulSoup(html, 'lxml')
p_list = soup.find_all("p")
return [p.text for p in p_list]
def test():
html = '''
<html>
<head>
<title>这是一个简单的测试页面</title>
</head>
<body>
<p class="item-0">body 元素的内容会显示在浏览器中。</p>
<p class="item-1">title 元素的内容会显示在浏览器的标题栏中。</p>
</body>
</html>
'''
p_text = fetch_p(html)
print(p_text)
if __name__ == '__main__':
test()
\ No newline at end of file
{
"one_line": {
"text": [
"text()",
"find_text()",
"all_text()"
]
},
"source": "get_text.py",
"depends": [],
"exercise_id": 245,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:行走的人偶
# 标题:BeautifulSoup 获取text
# 描述:获取网页的text
from bs4 import BeautifulSoup
def fetch_text(html):
soup = BeautifulSoup(html, 'lxml')
return soup.text
def test():
html = '''
<html>
<head>
<title>这是一个简单的测试页面</title>
</head>
<body>
<p class="item-0">body 元素的内容会显示在浏览器中。</p>
<p class="item-1">title 元素的内容会显示在浏览器的标题栏中。</p>
</body>
</html>
'''
text = fetch_text(html)
print(text)
if __name__ == '__main__':
test()
\ No newline at end of file
{
"one_line": {
"html.parser": [
"html5"
],
"'img'": [
"'src'"
],
"BeautifulSoup": [
"beautifulsoup"
]
},
"source": "html_parer.py",
"depends": [],
"exercise_id": 226,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:行走的人偶
# 标题:BeautifulSoup
# 描述:获取代码
from bs4 import BeautifulSoup
def fetch_imgs(html):
soup = BeautifulSoup(html, 'html.parser')
imgs = [tag for tag in soup.find_all('img')]
return imgs
def test():
imgs = fetch_imgs(
'<p><img src="http://example.com"/><img src="http://example.com"/></p>')
print(imgs)
if __name__ == '__main__':
test()
{
"export": [
"get_html_p.json",
"get_html_text.json",
"get_html_appoint_p.json"
],
"keywords": [],
"children": [
{
"安装配置": {
"keywords": [],
"children": [],
"node_id": "python-4-883"
}
},
{
"lxml.etree": {
"keywords": [],
"children": [],
"node_id": "python-4-884"
}
},
{
"XPath选择器": {
"keywords": [],
"children": [],
"node_id": "python-4-885"
}
},
{
"find/findall": {
"keywords": [],
"children": [],
"node_id": "python-4-886"
}
},
{
"CSS选择器": {
"keywords": [],
"children": [],
"node_id": "python-4-887"
}
},
{
"解析HTML": {
"keywords": [],
"children": [],
"node_id": "python-4-888"
}
}
],
"node_id": "python-3-150"
}
\ No newline at end of file
{
"one_line": {
"xpath": [
"find"
],
"HTML": [
"html",
"Html"
],
"//p[@class='item-1']/text()": [
"//p[@class='item-1']",
"//p[@class='item-1']/text"
]
},
"source": "get_html_appoint_p.py",
"depends": [],
"exercise_id": 211,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:行走的人偶
# 标题:lxml解析网页
# 描述:获取指定p
from lxml import etree
def fetch_text(html):
html = etree.HTML(html)
result = html.xpath("//p[@class='item-1']/text()")
return result
def test():
html = '''
<html>
<head>
<title>这是一个简单的测试页面</title>
</head>
<body>
<p class="item-0">body 元素的内容会显示在浏览器中。</p>
<p class="item-1">title 元素的内容会显示在浏览器的标题栏中。</p>
</body>
</html>
'''
imgs = fetch_text(html)
print(imgs)
if __name__ == '__main__':
test()
\ No newline at end of file
{
"one_line": {
"//p/text()": [
"p/text()",
"//p",
"p.text"
]
},
"source": "get_html_p.py",
"depends": [],
"exercise_id": 191,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:行走的人偶
# 标题:lxml解析网页
# 描述:获取所有p
from lxml import etree
def fetch_text(html):
html = etree.HTML(html)
result = html.xpath("//p/text()")
return result
def test():
html = '''
<html>
<head>
<title>这是一个简单的测试页面</title>
</head>
<body>
<p class="item-0">body 元素的内容会显示在浏览器中。</p>
<p class="item-1">title 元素的内容会显示在浏览器的标题栏中。</p>
</body>
</html>
'''
imgs = fetch_text(html)
print(imgs)
if __name__ == '__main__':
test()
\ No newline at end of file
{
"one_line": {
"etree": [
"tree",
"btree"
],
"//text()": [
"text()",
"//text",
"/text()"
]
},
"source": "get_html_text.py",
"depends": [],
"exercise_id": 220,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:行走的人偶
# 标题:lxml解析网页
# 描述:获取text
from lxml import etree
def fetch_text(html):
html = etree.HTML(html)
result = html.xpath("//text()")
return result
def test():
html = '''
<html>
<head>
<title>这是一个简单的测试页面</title>
</head>
<body>
<p>body 元素的内容会显示在浏览器中。</p>
<p>title 元素的内容会显示在浏览器的标题栏中。</p>
</body>
</html>
'''
imgs = fetch_text(html)
print(imgs)
if __name__ == '__main__':
test()
\ No newline at end of file
{
"export": [
"get_html.json",
"with_headers.json",
"post.json"
],
"keywords": [],
"children": [
{
"安装配置": {
"keywords": [],
"children": [],
"node_id": "python-4-889"
}
},
{
"发送请求与HTTP请求类型": {
"keywords": [],
"children": [],
"node_id": "python-4-890"
}
},
{
"传递URL参数": {
"keywords": [],
"children": [],
"node_id": "python-4-891"
}
},
{
"响应内容": {
"keywords": [],
"children": [],
"node_id": "python-4-892"
}
},
{
"定制请求头": {
"keywords": [],
"children": [],
"node_id": "python-4-893"
}
},
{
"响应状态码": {
"keywords": [],
"children": [],
"node_id": "python-4-894"
}
},
{
"Cookie": {
"keywords": [],
"children": [],
"node_id": "python-4-895"
}
},
{
"POST请求": {
"keywords": [],
"children": [],
"node_id": "python-4-896"
}
},
{
"身份认证": {
"keywords": [],
"children": [],
"node_id": "python-4-897"
}
},
{
"基本用法": {
"keywords": [],
"children": [],
"node_id": "python-4-898"
}
},
{
"高级用法": {
"keywords": [],
"children": [],
"node_id": "python-4-899"
}
}
],
"node_id": "python-3-151"
}
\ No newline at end of file
{
"one_line": {
"get": [
"post",
"gets",
"fetch"
]
},
"source": "get_html.py",
"depends": [],
"exercise_id": 242,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:行走的人偶
# 标题:requests 获取网页(1)
# 描述:将url对应的网页下载到本地
import requests
def get_html(url):
response = requests.get(url=url)
return response.text
def test():
url = "http://www.baidu.com"
html = get_html(url)
print(html)
if __name__ == '__main__':
test()
{
"one_line": {
"post": [
"get",
"posts"
],
"response = requests.post(url, data, headers)": [
"response = requests.post(url, headers, data)",
"response = requests.post(data, url, headers)"
]
},
"source": "post.py",
"depends": [],
"exercise_id": 186,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:行走的人偶
# 标题:requests post 请求
# 描述:requests post 请求
import requests
def get_response(url, data, headers=None):
response = requests.post(url, data, headers)
return response.text
def test():
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36"
}
data = {
"key1": "value1",
"key2": "value2"
}
url = "http://httpbin.org/post"
html = get_response(url, data, headers)
print(html)
if __name__ == '__main__':
test()
{
"one_line": {
"response.text": [
"response.text()",
"response.gettext()",
"response.get_text()",
"response"
]
},
"source": "with_headers.py",
"depends": [],
"exercise_id": 210,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:行走的人偶
# 标题:requests 获取网页(2) with headers
# 描述:将url对应的网页下载到本地
import requests
def get_html(url, headers=None):
response = requests.get(url=url)
return response.text
def test():
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36"
}
url = "http://www.baidu.com"
html = get_html(url, headers)
print(html)
if __name__ == '__main__':
test()
{
"export": [],
"keywords": [],
"children": [
{
"Selenium简介": {
"keywords": [],
"children": [],
"node_id": "python-4-900"
}
},
{
"安装配置": {
"keywords": [],
"children": [],
"node_id": "python-4-901"
}
},
{
"单元素定位(find_element_id/name/xpath)": {
"keywords": [],
"children": [],
"node_id": "python-4-902"
}
},
{
"多元素定位(find_elements_id/name/xpath)": {
"keywords": [],
"children": [],
"node_id": "python-4-903"
}
},
{
"常用方法和属性": {
"keywords": [],
"children": [
{
"可管理属性创建": {
"keywords": [],
"children": [],
"node_id": "python-5-535"
}
},
{
"延迟计算属性": {
"keywords": [],
"children": [],
"node_id": "python-5-536"
}
},
{
"属性的代理访问": {
"keywords": [],
"children": [],
"node_id": "python-5-537"
}
},
{
"创建用于计算的属性": {
"keywords": [],
"children": [],
"node_id": "python-5-538"
}
},
{
"为属性添加安全保护机制": {
"keywords": [],
"children": [],
"node_id": "python-5-539"
}
}
],
"node_id": "python-4-904"
}
},
{
"键盘和鼠标操作": {
"keywords": [],
"children": [],
"node_id": "python-4-905"
}
},
{
"WebDriver API": {
"keywords": [],
"children": [],
"node_id": "python-4-906"
}
},
{
"表单交互": {
"keywords": [],
"children": [],
"node_id": "python-4-907"
}
}
],
"node_id": "python-3-152"
}
\ No newline at end of file
{
"export": [
"tag_pipeline.json",
"so_tag_spider.json"
],
"keywords": [],
"children": [
{
"Scrapy简介": {
"keywords": [],
"children": [],
"node_id": "python-4-908"
}
},
{
"安装配置": {
"keywords": [],
"children": [],
"node_id": "python-4-909"
}
},
{
"Scrapy框架组成": {
"keywords": [],
"children": [],
"node_id": "python-4-910"
}
},
{
"Item Pipeline": {
"keywords": [],
"children": [],
"node_id": "python-4-911"
}
},
{
"Downloader": {
"keywords": [],
"children": [],
"node_id": "python-4-912"
}
},
{
"Spiders": {
"keywords": [],
"children": [],
"node_id": "python-4-913"
}
},
{
"Scheduler": {
"keywords": [],
"children": [],
"node_id": "python-4-914"
}
},
{
"Scrapy框架介绍": {
"keywords": [],
"children": [],
"node_id": "python-4-915"
}
},
{
"Scrapy入门": {
"keywords": [],
"children": [],
"node_id": "python-4-916"
}
},
{
"Selector的用法": {
"keywords": [],
"children": [],
"node_id": "python-4-917"
}
},
{
"Spider的用法": {
"keywords": [],
"children": [],
"node_id": "python-4-918"
}
},
{
"Downloader Middleware的用法": {
"keywords": [],
"children": [],
"node_id": "python-4-919"
}
},
{
"Spider Middleware的用法": {
"keywords": [],
"children": [],
"node_id": "python-4-920"
}
},
{
"Item Pipeline的用法": {
"keywords": [],
"children": [],
"node_id": "python-4-921"
}
},
{
"Scrapy对接Selenium": {
"keywords": [],
"children": [],
"node_id": "python-4-922"
}
},
{
"Scrapy对接Splash": {
"keywords": [],
"children": [],
"node_id": "python-4-923"
}
},
{
"Scrapy通用爬虫": {
"keywords": [],
"children": [],
"node_id": "python-4-924"
}
},
{
"Scrapyrt的使用": {
"keywords": [],
"children": [],
"node_id": "python-4-925"
}
},
{
"Scrapy对接Docker": {
"keywords": [],
"children": [],
"node_id": "python-4-926"
}
},
{
"Scrapy爬取新浪微博": {
"keywords": [],
"children": [],
"node_id": "python-4-927"
}
}
],
"node_id": "python-3-153"
}
\ No newline at end of file
{
"one_line": {
"if self.page_count < self.totgal_pages:": [
"if self.page_count <= self.totgal_pages:"
],
"callback=self.parse": [
"callback=parse"
],
"yield": [
"return"
]
},
"source": "so_tag_spider.py",
"depends": [
"tag_pipeline.py"
],
"exercise_id": 206,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 爬虫
# 描述:爬取 stackoverflow 标签
import scrapy
from scrapy.crawler import CrawlerProcess
from scrapy.settings import Settings
BASE_DIR = __loader__.name
class StackOverflowTagSpider(scrapy.Spider):
name = "stackoverflow_tags"
allowed_domains = ["stackoverflow.com"]
start_urls = ['https://stackoverflow.com/tags/synonyms?page=1']
custom_settings = {
'ITEM_PIPELINES': {f'{BASE_DIR}.TagPipeline': 301},
'LOG_LEVEL': 'INFO'
}
def __init__(self):
self.totgal_pages = 45
self.page_count = 0
def parse(self, response):
self.page_count += 1
tags = response.css('.post-tag::text')
for tag in tags:
yield {'name': tag.get()}
if self.page_count < self.totgal_pages:
next_page_list = response.css('a.js-pagination-item::attr(href)')
if len(next_page_list) > 0:
next_page_item = next_page_list[len(next_page_list)-1]
next_page = next_page_item.get()
print('next_page:', next_page)
yield response.follow(next_page, callback=self.parse, dont_filter=True)
if __name__ == "__main__":
settings = Settings()
process = CrawlerProcess()
process.crawl(StackOverflowTagSpider)
process.start()
{
"one_line": {
"if self.count > 0:": [
"if self.count >= 0:"
],
"process_item(self, item, spider)": [
"process_item(self, spider, item)"
],
"self.file.close()": [
""
],
", 'w')": [
", 'r')"
]
},
"source": "tag_pipeline.py",
"depends": [],
"exercise_id": 187,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 爬虫(1)
# 描述:实现一个用以 scrapy 爬虫处理中保存 stackoverflow 标签数据的管道处理类
# 爬虫管道类必须实现3个方法
# <ul><li>open_spider(self, spider)</li><li>process_item(self, item, spider)</li><li>close_spider(self, spider)</li></ul>
# 本例最终输出的 json 文件格式请参考:https://codechina.csdn.net/csdn/csdn-tags/-/blob/master/src/dataset/stackoverflow.tag.json
import json
class StackOverflowTagPipeline(object):
def open_spider(self, spider):
''' 打开文件并写入'[\n' 到 json 文件'''
self.file = open('/tmp/stackoverflow.tag.json', 'w')
self.file.write('[\n')
self.count = 0
self.tags = {}
def process_item(self, item, spider):
''' 写入一个 {"name":xxx} 格式的元素,注意逗号拼接 '''
if self.tags.get(item['name']) is not None:
return
self.tags[item['name']] = True
words = []
if self.count > 0:
words.append(',\n')
words.append(' ')
words.append(json.dumps(item, ensure_ascii=False).strip())
line = ''.join(words)
self.file.write(line)
self.count += 1
def close_spider(self, spider):
''' 写入'\n]' 并关闭文件 '''
self.file.write('\n]')
self.file.close()
if __name__ == "__main__":
t = StackOverflowTagPipeline()
t.open_spider(None)
t.process_item({'name': 'c++'}, None)
t.close_spider(None)
{
"export": [],
"keywords": [],
"children": [
{
"pyspider框架介绍": {
"keywords": [],
"children": [],
"node_id": "python-4-976"
}
},
{
"pyspider的基本使用": {
"keywords": [],
"children": [],
"node_id": "python-4-977"
}
},
{
"pyspider用法详解": {
"keywords": [],
"children": [],
"node_id": "python-4-978"
}
}
],
"node_id": "python-3-171"
}
\ No newline at end of file
{
"export": [],
"keywords": [],
"children": [
{
"自动输入/OCR字符识别": {
"keywords": [],
"children": [],
"node_id": "python-4-934"
}
}
],
"node_id": "python-3-158"
}
\ No newline at end of file
{
"node_id": "python-2-7",
"keywords": []
}
\ No newline at end of file
{
"one_line": {
"if len(self.stack) == 0": [
"if len(self.stack) > 0",
"if len(self.stack) >= 0"
],
"if len(self.stack) > 0": [
"if len(self.stack) == 0"
],
"c.component_did_unmount()": [
"c.component_did_mount()"
],
"c.component_did_mount(*args)": [
"c.component_did_unmount(*args)"
]
},
"source": "app.py",
"depends": [],
"exercise_id": 2,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python Tkinter 开发应用
# 描述:设计GUI组件
from tkinter import Tk, Button
from tkinter import messagebox
from abc import ABC, abstractclassmethod
class Component:
def __init__(self, app) -> None:
self.app = app
@abstractclassmethod
def component_did_mount(self, *args):
pass
@abstractclassmethod
def component_did_unmount(self):
pass
@abstractclassmethod
def render(self):
pass
class About(Component):
def __init__(self, app) -> None:
super().__init__(app)
self.root = None
self.btn = None
def component_did_mount(self, root):
self.root = root
def component_did_unmount(self):
self.root = None
def render(self):
messagebox.showinfo("关于我", "python.csdn.net")
class Home(Component):
def __init__(self, app) -> None:
super().__init__(app)
self.app = app
self.root = None
self.btn = None
def component_did_mount(self):
self.text = "关于我"
def component_did_unmount(self):
self.root = None
def render(self):
self.root = Tk()
self.btn = Button(
self.root,
text=self.text,
command=lambda: self.app.navigate_to('About')
)
self.btn.pack()
self.root.mainloop()
class App:
def __init__(self, component_constructors) -> None:
self.root = None
self.component_constructors = component_constructors
self.components = {}
self.stack = []
def init(self):
for name in self.component_constructors:
component_constructor = self.component_constructors[name]
self.components[name] = component_constructor(self)
def navigate_to(self, name, *args):
if self.components.get(name) is None:
return
c = self.components[name]
self.stack.append(c)
if name == 'About':
c.component_did_mount(self.root)
elif name == "Home":
c.component_did_mount()
c.render()
def go_back(self):
if len(self.stack) == 0:
return
c = self.stack.pop()
c.component_did_unmount()
def render(self):
if len(self.stack) > 0:
return
self.navigate_to("Home", self.root)
if __name__ == '__main__':
app = App({
"Home": Home,
"About": About,
})
app.init()
app.render()
{
"multiline": [
{
"show.pack()": "",
"number.pack()": ""
},
{
"command=self.on_show": "command=self.on_show()"
},
{
"lambda: self.on_click(i)": "self.on_click(i)"
}
],
"source": "basic.py",
"depends": [],
"exercise_id": 1,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python Tkinter 开发应用基础
# 描述:基本的控件组装
from tkinter import Tk, Button, messagebox
class NumberRecorder:
def __init__(self) -> None:
self.numbers = []
def render(self):
self.main_window = Tk()
show = Button(
self.main_window,
text=f"查看结果",
command=self.on_show
)
show.pack()
for i in range(0, 9):
number = Button(
self.main_window,
text=f"{i}",
command=lambda: self.on_click(i)
)
number.pack()
self.main_window.mainloop()
def on_show(self):
messagebox.showinfo("输入数字", f"{','.join(self.numbers)}")
def on_click(self, i):
self.numbers.append(i)
if __name__ == '__main__':
app = NumberRecorder()
app.render()
{
"export": [
"basic.json",
"app.json"
],
"keywords": [],
"children": [
{
"Tkinter简介": {
"keywords": [],
"children": [],
"node_id": "python-4-988"
}
},
{
"安装配置": {
"keywords": [],
"children": [],
"node_id": "python-4-989"
}
},
{
"Tkinter模块": {
"keywords": [],
"children": [],
"node_id": "python-4-990"
}
},
{
"Tkinter控件": {
"keywords": [],
"children": [],
"node_id": "python-4-991"
}
},
{
"标准属性": {
"keywords": [],
"children": [],
"node_id": "python-4-992"
}
},
{
"几何管理": {
"keywords": [],
"children": [],
"node_id": "python-4-993"
}
}
],
"node_id": "python-3-174"
}
\ No newline at end of file
{
"export": [
"q_progress_thread.json",
"q_progress_bar.json",
"for_each_month.json"
],
"keywords": [],
"children": [
{
"PyQT简介": {
"keywords": [],
"children": [],
"node_id": "python-4-994"
}
},
{
"安装配置": {
"keywords": [],
"children": [],
"node_id": "python-4-995"
}
},
{
"PyQT模块": {
"keywords": [],
"children": [],
"node_id": "python-4-996"
}
},
{
"PyQT布局管理": {
"keywords": [],
"children": [],
"node_id": "python-4-997"
}
},
{
"PyQT菜单和工具栏": {
"keywords": [],
"children": [],
"node_id": "python-4-998"
}
},
{
"事件和信号": {
"keywords": [],
"children": [],
"node_id": "python-4-999"
}
},
{
"PyQT对话框": {
"keywords": [],
"children": [],
"node_id": "python-4-1000"
}
},
{
"PyQT控件": {
"keywords": [],
"children": [],
"node_id": "python-4-1001"
}
},
{
"PyQT拖拽与绘图": {
"keywords": [],
"children": [],
"node_id": "python-4-1002"
}
}
],
"node_id": "python-3-175"
}
\ No newline at end of file
{
"one_line": {
"self.__month_count()": [
"self.__month_count"
],
"self.__for_each_month": [
"self.__for_each_month()"
],
"sys.exit(app.exec_())": [
"sys.exit()"
]
},
"source": "for_each_month.py",
"depends": [
"q_progress_thread.py",
"q_progress_bar.py"
],
"exercise_id": 205,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python PyQt 进度条(3)
# 描述:请先完成上一题。使用封装好的 PyQT 进度条显示2008年1月到本月的每个月1号进度。经过层层封装,到这里主要是上层的组合逻辑了。
from datetime import date, timedelta
from calendar import monthrange
from datetime import timedelta
import sys
import time
from PyQt5.QtWidgets import QApplication
from q_progress_bar import QRunnerProgressBar
class MonthProgress:
def __init__(self, start_month, finish_month):
self.start = start_month
self.finish = finish_month
def __month_count(self):
count = 0
d1 = self.start
d2 = self.finish
while True:
mdays = monthrange(d1.year, d1.month)[1]
d1 += timedelta(days=mdays)
if d1 <= d2:
count += 1
else:
break
return count
def __for_each_month(self, on_progress):
d = self.start
finish = self.finish
progress = 0
while d < finish:
time.sleep(0.1)
on_progress(progress, d.__str__())
d = d+timedelta(monthrange(d.year, d.month)[1])
progress += 1
def run(self):
app = QApplication(sys.argv)
bar = QRunnerProgressBar(
self.__month_count(),
"如果每个月都有技能树进度条...",
self.__for_each_month
)
bar.show()
sys.exit(app.exec_())
if __name__ == "__main__":
month_progress = MonthProgress(
date(2008, 1, 1),
date.today(),
)
month_progress.run()
{
"one_line": {
"self.thread = None": [
"pass"
],
"self.setLayout(self.vbox)": [
"self.setLayout()"
],
"self.vbox.addWidget(self.pbar)": [
"self.vbox.addWidget()"
],
"self.vbox.addWidget(self.btn)": [
"self.vbox.addWidget()"
]
},
"source": "q_progress_bar.py",
"depends": [
"q_progress_thread.py"
],
"exercise_id": 228,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python PyQt 进度条(2)
# 描述:请先完成上一题。封装一个能显示进度条的 PyQT GUI 对话框
import sys
import math
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QProgressBar, QVBoxLayout, QMessageBox
from q_progress_thread import QProgressThread
class QRunnerProgressBar(QWidget):
def __init__(self, count, tip, runner):
super(QRunnerProgressBar, self).__init__()
self.setWindowTitle('QRunnerProgressBar')
self.vbox = QVBoxLayout()
self.btn = QPushButton(tip)
self.btn.clicked.connect(self.btnFunc)
self.vbox.addWidget(self.btn)
self.pbar = QProgressBar(self)
self.pbar.setValue(0)
self.vbox.addWidget(self.pbar)
self.setLayout(self.vbox)
self.resize(300, 100)
self.show()
self.count = count
self.runner = runner
def btnFunc(self):
self.thread = QProgressThread(self.runner)
self.thread._signal.connect(self.signal_accept)
self.thread.start()
self.btn.setEnabled(False)
def signal_accept(self, info):
percent_value = int(math.floor(info.progress*100/self.count))
self.pbar.setValue(int(percent_value))
self.setWindowTitle(info.msg)
if self.pbar.value() == 99:
self.pbar.setValue(0)
self.btn.setEnabled(True)
def closeEvent(self, event):
self.thread = None
if __name__ == "__main__":
app = QApplication(sys.argv)
p = QRunnerProgressBar(
100,
'看资料+做题,就有技能树进度',
lambda on_progress: on_progress(50, 'Python技能树->PyQT')
)
sys.exit(app.exec_())
{
"one_line": {
"self._signal.emit": [
"self.emit"
],
"QProgressThread, self": [
"self"
],
"sys.exit(app.exec_())": [
""
],
"QApplication.quit()": [
"sys.exit()"
],
"p._signal.connect(on_signal)": [
"p.connect(on_signal)"
]
},
"source": "q_progress_thread.py",
"depends": [],
"exercise_id": 233,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python PyQt 进度条(1)
# 描述:使用 QThread 发送信号,接收信号一方打印并结束程序
import sys
from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtWidgets import QApplication
class ProgressInfo:
def __init__(self, progress, msg):
self.progress = progress
self.msg = msg
class QProgressThread(QThread):
_signal = pyqtSignal(ProgressInfo)
def __init__(self, runner):
super(QProgressThread, self).__init__()
self.runner = runner
def __del__(self):
self.wait()
def run(self):
def on_progress(progress, info):
info = ProgressInfo(progress, info)
self._signal.emit(info)
self.runner(on_progress)
if __name__ == "__main__":
app = QApplication(sys.argv)
p = QProgressThread(
lambda on_progress: on_progress(0, "hello PyQT world!")
)
def on_signal(info):
print("accept info from signal:", info.msg)
QApplication.quit()
p._signal.connect(on_signal)
p.start()
sys.exit(app.exec_())
{
"export": [
"event.json"
],
"keywords": [],
"children": [
{
"WxPython简介": {
"keywords": [],
"children": [],
"node_id": "python-4-1003"
}
},
{
"安装配置": {
"keywords": [],
"children": [],
"node_id": "python-4-1004"
}
},
{
"WxPython常用类": {
"keywords": [],
"children": [],
"node_id": "python-4-1005"
}
},
{
"WxPython布局管理": {
"keywords": [],
"children": [],
"node_id": "python-4-1006"
}
},
{
"WxPython事件处理": {
"keywords": [],
"children": [],
"node_id": "python-4-1007"
}
},
{
"WxPython对话框": {
"keywords": [],
"children": [],
"node_id": "python-4-1008"
}
},
{
"WxPython组件": {
"keywords": [],
"children": [],
"node_id": "python-4-1009"
}
},
{
"WxPython拖拽处理": {
"keywords": [],
"children": [],
"node_id": "python-4-1010"
}
},
{
"WxPython绘图API": {
"keywords": [],
"children": [],
"node_id": "python-4-1011"
}
}
],
"node_id": "python-3-176"
}
\ No newline at end of file
{
"one_line": {
"dlg.Destroy()": [
""
],
"panel.Layout()": [
""
],
"panel.SetSizer(box)": [
""
],
"menuBar.Append(menu, \"&File\")": [
"menuBar.append(menu, \"&File\")"
]
},
"source": "event.py",
"depends": [],
"exercise_id": 0,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python WxPython 例子
# 描述:创建窗口、菜单、显示文本,关闭
import wx
class Frame(wx.Frame):
def __init__(self, title):
wx.Frame.__init__(self, None, title=title,
pos=(150, 150), size=(350, 200))
self.init_close_event()
self.init_menu_bar()
self.init_status_bar()
self.init_panel()
def init_close_event(self):
self.Bind(wx.EVT_CLOSE, self.OnClose)
def init_menu_bar(self):
menuBar = wx.MenuBar()
menu = wx.Menu()
m_exit = menu.Append(wx.ID_EXIT, "E&xit\tAlt-X",
"Close window and exit program.")
self.Bind(wx.EVT_MENU, self.OnClose, m_exit)
menuBar.Append(menu, "&File")
self.SetMenuBar(menuBar)
def init_status_bar(self):
self.statusbar = self.CreateStatusBar()
def init_panel(self):
panel = wx.Panel(self)
box = wx.BoxSizer(wx.VERTICAL)
m_text = wx.StaticText(panel, -1, "Hello World!")
m_text.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD))
m_text.SetSize(m_text.GetBestSize())
box.Add(m_text, 0, wx.ALL, 10)
m_close = wx.Button(panel, wx.ID_CLOSE, "Close")
m_close.Bind(wx.EVT_BUTTON, self.OnClose)
box.Add(m_close, 0, wx.ALL, 10)
panel.SetSizer(box)
panel.Layout()
def OnClose(self, event):
dlg = wx.MessageDialog(self,
"Do you really want to close this application?",
"Confirm Exit", wx.OK | wx.CANCEL | wx.ICON_QUESTION)
result = dlg.ShowModal()
dlg.Destroy()
if result == wx.ID_OK:
self.Destroy()
if __name__ == '__main__':
app = wx.App(redirect=True)
top = Frame("Hello World")
top.Show()
app.MainLoop()
{
"node_id": "python-2-8",
"keywords": []
}
\ No newline at end of file
{
"node_id": "python-1-1",
"keywords": []
}
\ No newline at end of file
{
"export": [
"top_n.json"
],
"keywords": [],
"children": [
{
"NumPy的前世今生": {
"keywords": [],
"children": [],
"node_id": "python-4-1120"
}
},
{
"NumPy数组vs Python列表": {
"keywords": [],
"children": [],
"node_id": "python-4-1121"
}
},
{
"NumPy数组类型和属性": {
"keywords": [],
"children": [],
"node_id": "python-4-1122"
}
},
{
"维、轴、秩": {
"keywords": [],
"children": [],
"node_id": "python-4-1123"
}
},
{
"广播和矢量化": {
"keywords": [],
"children": [],
"node_id": "python-4-1124"
}
}
],
"node_id": "python-3-195"
}
\ No newline at end of file
{
"one_line": {
"np.argsort(array)": [
"array.sort()"
],
":-(top_n+1):-1": [
":-top_n:-1",
"0:top_n"
]
},
"source": "top_n.py",
"depends": [],
"exercise_id": 43,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:numpy 应用之 topn
# 描述:取 list 的 topn
import numpy as np
def get_top_n(array, top_n):
top_n_indexs = np.argsort(array)[:-(top_n+1):-1]
results = [array[index] for index in top_n_indexs]
return results
if __name__ == '__main__':
ret = get_top_n(np.array([1, 3, 34, 4, 5, 6]), 3)
print(ret)
{
"export": [
"install.json"
],
"keywords": [],
"children": [],
"node_id": "python-3-196"
}
\ No newline at end of file
{
"one_line": {
"key=lambda i: i[0]": [
"key=lambda i: i[1]"
],
"sort": [
"argsort"
],
"step.split(\":\")": [
"step.split(\".\")"
]
},
"source": "install.py",
"depends": [],
"exercise_id": 40,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python numpy 安装
# 描述:正确打印安装顺序
def test():
installs = [
"1. pip install numpy",
"3. 还可以试试豆瓣的源:pip install numpy -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com",
"2. 如果装不了,就试试阿里的源:pip install numpy -i http://mirrors.aliyun.com/pypi/simple --trusted-host mirrors.aliyun.com",
]
installs.sort(key=lambda i: i[0])
for step in installs:
items = step.split(":")
print(items[0])
if len(items) > 1:
print(f" {items[1]}")
if __name__ == '__main__':
test()
{
"export": [
"create_1d.json",
"create_2d.json",
"convert_from_array.json"
],
"keywords": [],
"children": [],
"node_id": "python-3-197"
}
\ No newline at end of file
{
"one_line": {
"b.astype": [
"b.as_type"
],
"np.bool": [
"np.boolean"
],
"[True, False, True]": [
"[False, False, True]"
],
"[[1, 2], [3, 4]]": [
"[1, 2], [3, 4]"
]
},
"source": "convert_from_array.py",
"depends": [],
"exercise_id": 45,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:numpy应用之创建数组
# 描述:从其他结构转换数组
# 创建一维数组
# <code>
# [1 2 3 4]
# </code>
#
# 创建二维数组
# <code>
# [[1 2]
# [3 4]]
# </code>
#
# 创建三维数组
# <code>
# [[[1 2]
# [3 4]]
# [[5 6]
# [7 8]]]
# </code>
#
# 转换类型
# <code>
# [ True False True]
# </code>
import numpy as np
if __name__ == '__main__':
print('创建一维数组')
print(np.array([1, 2, 3, 4]))
print('创建二维数组')
print(np.array([[1, 2], [3, 4]]))
print("创建三维数组")
print(np.array([[[1, 2], [3, 4]],
[[5, 6], [7, 8]]]))
print("转换类型")
b = np.array([-1, 0, 7], dtype=np.int32)
assert b.astype(np.bool) == [True, False, True]
{
"one_line": {
"np.zeros": [
"np.zero"
],
"np.ones": [
"np.one"
],
"np.arange": [
"np.range"
],
"np.empty": [
"np.random"
]
},
"source": "create_1d.py",
"depends": [],
"exercise_id": 47,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:numpy应用之创建一数组
# 描述:几种创建一维数组的例子
#
# 创建0数组,元素全部为0,用dtype参数指定数据类型
# <code>
# [[0 0 0]
# [0 0 0]
# [0 0 0]]
# </code>
#
# 创建元素全为1的数组,用dtype指定数据类型
# <code>
# [[1 1 1]
# [1 1 1]
# [1 1 1]]
# </code>
#
# 创建范围序列,用dtype指定数据类型
# <code>[2. 3. 4. 5. 6. 7. 8. 9.]</code>
#
# 创建未初始化的数组,结果可能是任意的,例如:
# <code>
# [[1 1 1]
# [1 1 1]
# [1 1 1]]
# </code>
import numpy as np
if __name__ == '__main__':
shape = (3, 3)
print('创建0数组,元素全部为0,用dtype参数指定数据类型')
print(np.zeros(shape, dtype=int))
print('创建元素全为1的数组,用dtype指定数据类型')
print(np.ones(shape, dtype=int))
print('创建范围序列,用dtype指定数据类型')
print(np.arange(2, 10, dtype=float))
print('创建未初始化的数组')
print(np.empty(shape, dtype=int))
{
"one_line": {
"np.eye": [
"np.eyes"
],
"np.diag": [
"np.dialog"
],
"np.vander": [
"np.nokia"
]
},
"source": "create_2d.py",
"depends": [],
"exercise_id": 46,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:numpy应用之创建二数组
# 描述:几种创建二维数组的例子
import numpy as np
if __name__ == '__main__':
examples = np.array([
[
"创建单位矩阵",
"创建对角矩阵",
"创建范德蒙矩阵"
],
[
lambda: np.eye(3),
lambda: np.diag([1, 2, 3]),
lambda: np.vander(np.linspace(0, 2, 5), 2)
]
])
for i in range(examples.shape[1]):
tip = examples[0][i]
action = examples[1][i]
print(tip)
print(action())
{
"export": [
"operate_array.json"
],
"keywords": [],
"children": [
{
"索引": {
"keywords": [],
"children": [],
"node_id": "python-4-1125"
}
},
{
"切片": {
"keywords": [],
"children": [],
"node_id": "python-4-1126"
}
},
{
"改变数组结构": {
"keywords": [],
"children": [],
"node_id": "python-4-1127"
}
},
{
"合并和拆分": {
"keywords": [],
"children": [],
"node_id": "python-4-1128"
}
},
{
"复制": {
"keywords": [],
"children": [],
"node_id": "python-4-1129"
}
},
{
"排序": {
"keywords": [],
"children": [],
"node_id": "python-4-1130"
}
},
{
"查找": {
"keywords": [],
"children": [],
"node_id": "python-4-1131"
}
},
{
"筛选": {
"keywords": [],
"children": [],
"node_id": "python-4-1132"
}
},
{
"数组I/O": {
"keywords": [],
"children": [],
"node_id": "python-4-1133"
}
}
],
"node_id": "python-3-198"
}
\ No newline at end of file
{
"one_line": {
"subtract": [
"sub"
],
"multiply": [
"mul"
],
"divide": [
"div"
],
"x * y": [
"x ** y"
],
"x / y": [
"x // y"
]
},
"source": "operate_array.py",
"depends": [],
"exercise_id": 41,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:VegetableBirdNLPer
# 标题:numpy应用之操作数组
# 描述:数组运算
import numpy as np
def operate_array(operate, x, y):
if operate == '+':
print('数组相加:')
res = x + y
print(res)
print('数组相加:numpy方法:')
res = np.add(x, y)
print(res)
elif operate == '-':
print('数组相减:')
res = x - y
print(res)
print('数组相减,numpy方法:')
res = np.subtract(x, y)
print(res)
elif operate == '*':
print('数组相乘,逐元素矩阵乘法:')
res = x * y
print(res)
print('数组相乘,numpy方法:逐元素矩阵乘法:')
res = np.multiply(x, y)
print(res)
elif operate == '/':
print('数组相除,对应元素相除:')
res = x / y
print(res)
print('数组相除,numpy方法:对应元素相除:')
res = np.divide(x, y)
print(res)
if __name__ == '__main__':
x = np.array([[1, 2, 3], [4, 5, 6]])
y = np.array([[4, 5, 6], [7, 8, 9]])
operate_array('+', x, y)
operate_array('-', x, y)
operate_array('*', x, y)
operate_array('/', x, y)
{
"one_line": {
"np.sum": [
"sum"
],
"np.mean": [
"mean"
],
"np.std": [
"std"
],
"np.var": [
"var"
],
"np.min": [
"min"
],
"np.max": [
"max"
],
"np.median": [
"median"
],
"np.unique": [
"unique"
]
},
"source": "common_fun.py",
"depends": [],
"exercise_id": 48,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:VegetableBirdNLPer
# 标题:numpy的常用函数
# 描述:用numpy做数据分析
import numpy as np
if __name__ == '__main__':
data = np.random.randint(0, 10, size=(10))
print('输入数据: {}'.format(data))
data_sum = np.sum(data)
print('求和: {}'.format(data_sum))
data_mean = np.mean(data)
print('求平均: {}'.format(data_mean))
data_std = np.std(data)
print('求标准差: {}'.format(data_std))
data_var = np.var(data)
print('求方差: {}'.format(data_var))
data_min = np.min(data)
print('求最小值: {}'.format(data_min))
data_max = np.max(data)
print('求最大值: {}'.format(data_max))
data_median = np.median(data)
print('求中位数: {}'.format(data_median))
data_unique = np.unique(data)
print('找出数组中所有不同的值,并按从小打大排序: {}'.format(data_unique))
{
"export": [
"common_fun.json"
],
"keywords": [],
"children": [
{
"np.nan和np.inf": {
"keywords": [],
"children": [],
"node_id": "python-4-1134"
}
},
{
"函数命名空间": {
"keywords": [],
"children": [],
"node_id": "python-4-1135"
}
},
{
"数学函数": {
"keywords": [],
"children": [],
"node_id": "python-4-1136"
}
},
{
"统计函数": {
"keywords": [],
"children": [],
"node_id": "python-4-1137"
}
},
{
"插值函数": {
"keywords": [],
"children": [],
"node_id": "python-4-1138"
}
},
{
"多项式拟合函数": {
"keywords": [],
"children": [],
"node_id": "python-4-1139"
}
},
{
"自定义广播函数": {
"keywords": [],
"children": [],
"node_id": "python-4-1140"
}
}
],
"node_id": "python-3-199"
}
\ No newline at end of file
{
"export": [
"mask_array_01.json",
"mask_array_02.json",
"mask_array_03.json"
],
"keywords": [],
"children": [
{
"创建掩码数组": {
"keywords": [],
"children": [],
"node_id": "python-4-1141"
}
},
{
"访问掩码数组": {
"keywords": [],
"children": [],
"node_id": "python-4-1142"
}
}
],
"node_id": "python-3-200"
}
\ No newline at end of file
{
"one_line": {
"assert np.mean(y) == 2.75": [
"assert np.mean(y) == 2"
],
"np.ma.core.MaskedConstant": [
"np.int32"
],
"type(y[3]) is": [
"type(y[2])"
]
},
"source": "mask_array_01.py",
"depends": [],
"exercise_id": 241,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:VegetableBirdNLPer
# 标题:numpy掩码数组
# 描述:走进掩码数组
import numpy as np
def test():
x = np.array([1, 2, 3, -1, 5])
y = np.ma.masked_array(x, mask=[0, 0, 0, 1, 0])
print('查看y的值: ')
for idx, val in enumerate(y):
print('y[{}] = {}'.format(idx, val))
assert type(y[3]) is np.ma.core.MaskedConstant
print('y的平均值: {}'.format(np.mean(y)))
assert np.mean(y) == 2.75
if __name__ == '__main__':
test()
{
"one_line": {
"np.mean(a[5:])": [
"np.mean(a[4:])",
"np.mean(a[6:])"
],
" mask=mask": [
" mask=mask_list"
]
},
"source": "mask_array_02.py",
"depends": [],
"exercise_id": 224,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:VegetableBirdNLPer
# 标题:numpy掩码数组的创建
# 描述:创建掩码数组,将位置的值设置为无效
import numpy as np
def create_mask_array(array_a, mask_list):
mask = np.zeros(len(array_a), dtype=int)
for i in mask_list:
mask[i] = 1
y = np.ma.array(array_a, mask=mask)
return y
if __name__ == '__main__':
a = np.random.randint(0, 10, size=(10))
b = create_mask_array(a, [0, 1, 2, 3, 4])
assert np.mean(b) == np.mean(a[5:])
{
"one_line": {
"x < 5": [
"x >= 5"
],
"mask[i] = 1": [
"mask[i] = 0"
],
"not np.ma.core.MaskedConstant": [
"np.ma.core.MaskedConstant"
],
"na == nb": [
"na != nb"
]
},
"source": "mask_array_03.py",
"depends": [],
"exercise_id": 208,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:VegetableBirdNLPer
# 标题:numpy掩码数组的创建
# 描述:创建掩码数组,将大于等于指定值的数组元素掩盖
import numpy as np
def create_condition_mask_array(array_a, val):
mask = np.zeros(len(array_a), dtype=int)
for i in range(len(array_a)):
if array_a[i] >= val:
mask[i] = 1
y = np.ma.array(array_a, mask=mask)
return y
if __name__ == '__main__':
a = np.random.randint(0, 10, size=(10))
b = create_condition_mask_array(a, 5)
na = [x for x in a if x < 5]
nb = [x for x in b if type(x) is not np.ma.core.MaskedConstant]
assert na == nb
{
"export": [
"matrix.json"
],
"keywords": [],
"children": [
{
"创建矩阵": {
"keywords": [],
"children": [],
"node_id": "python-4-1143"
}
},
{
"矩阵特有属性": {
"keywords": [],
"children": [],
"node_id": "python-4-1144"
}
},
{
"矩阵乘法": {
"keywords": [],
"children": [],
"node_id": "python-4-1145"
}
}
],
"node_id": "python-3-201"
}
\ No newline at end of file
{
"one_line": {
"matrix_b.T": [
"matrix_b.t"
],
"matrix_b.I": [
"matrix_b.i"
],
"size=(3, 3)": [
"size=(3, 3, 3)"
]
},
"source": "matrix.py",
"depends": [],
"exercise_id": 44,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:VegetableBirdNLPer
# 标题:numpy之矩阵对象
# 描述:创建矩阵对象及矩阵对象的属性
# 数组 a:
# <code>
# [[3 9 4]
# [6 7 9]
# [3 5 7]]
# </code>
# 可以通过数组转为矩阵
# 矩阵 b :
# <code>
# [[3 9 4]
# [6 7 9]
# [3 5 7]]
# </code>
# b的转置矩阵为:
# <code>
# [[3 6 3]
# [9 7 5]
# [4 9 7]]
# </code>
# b的逆矩阵:
# <code>
# [[-0.04597701 0.49425287 -0.6091954 ]
# [ 0.17241379 -0.10344828 0.03448276]
# [-0.10344828 -0.13793103 0.37931034]]
# </code>
import numpy as np
if __name__ == '__main__':
a = np.random.randint(0, 10, size=(3, 3))
matrix_b = np.matrix(a)
print(matrix_b)
print(matrix_b.T)
print(matrix_b.I)
{
"one_line": {
"np.random.choice": [
"np.choice"
],
"assert ret is None": [
"assert ret is not None"
],
"assert len(ret) == 2": [
"assert len(ret) != 2"
]
},
"source": "binomial_distribution.py",
"depends": [],
"exercise_id": 42,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:VegetableBirdNLPer
# 标题:numpy随机抽样
# 描述:随机抽样函数
import numpy as np
def random_sample(array, num):
if num <= len(array):
return np.random.choice(array, num)
else:
return None
if __name__ == '__main__':
a = [i for i in range(10)]
print('输入的数据:{}'.format(a))
ret = random_sample(a, 11)
assert ret is None
print('随机抽样个数不能超过原始数组大小')
ret = random_sample(a, 2)
assert len(ret) == 2
print('随机抽样结果:{}'.format(ret))
{
"export": [
"binomial_distribution.json"
],
"keywords": [],
"children": [
{
"随机数": {
"keywords": [],
"children": [],
"node_id": "python-4-1146"
}
},
{
"随机抽样": {
"keywords": [],
"children": [],
"node_id": "python-4-1147"
}
},
{
"正态分布": {
"keywords": [],
"children": [],
"node_id": "python-4-1148"
}
},
{
"伪随机数的深度思考": {
"keywords": [],
"children": [],
"node_id": "python-4-1149"
}
}
],
"node_id": "python-3-202"
}
\ No newline at end of file
{
"node_id": "python-2-10",
"keywords": []
}
\ No newline at end of file
{
"export": [
"series.json",
"dataframe.json"
],
"keywords": [],
"children": [
{
"Panda的特点": {
"keywords": [],
"children": [],
"node_id": "python-4-1150"
}
},
{
"安装和使用": {
"keywords": [],
"children": [],
"node_id": "python-4-1151"
}
}
],
"node_id": "python-3-203"
}
\ No newline at end of file
{
"one_line": {
"pd.Index": [
"pd.index"
],
"if j < i:": [
"if j <= i:",
"if j > i:"
],
"range(1, 10)": [
"range(0, 9)"
]
},
"source": "dataframe.py",
"depends": [],
"exercise_id": 123,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:pandas DataFrame
# 描述:打印乘法表
import pandas as pd
if __name__ == '__main__':
index = pd.Index(range(1, 10))
d = {}
for i in range(1, 10):
columns = []
for j in range(1, 10):
if j < i:
columns.append('')
else:
columns.append(f"{i} x {j} = {i*j}")
d[f'{i}'] = columns
df = pd.DataFrame(index=index, data=d)
print(df.head(9))
{
"one_line": {
"i*step": [
"i+step"
],
"pd.Series": [
"pd.series"
],
"data=d,": [
"d,"
],
"index=index, ": [
""
]
},
"source": "series.py",
"depends": [],
"exercise_id": 124,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:pandas Series
# 描述:打印 cos 函数 0-3.14 区间内,步长 3.14/1000 的数值序列
import pandas as pd
import math
if __name__ == '__main__':
d = {}
count = 1000
step = 3.14/1000
index = []
for i in range(0, count):
x = i*step
y = math.cos(x)
index.append(x)
d[x] = y
ser = pd.Series(data=d, index=index, dtype=float)
print(ser)
{
"export": [
"series.json",
"dataframe.json"
],
"keywords": [],
"children": [
{
"索引数组Index": {
"keywords": [],
"children": [],
"node_id": "python-4-1152"
}
},
{
"带标签的一维同构数组Series": {
"keywords": [],
"children": [],
"node_id": "python-4-1153"
}
},
{
"带标签的二维异构表格DataFrame": {
"keywords": [],
"children": [],
"node_id": "python-4-1154"
}
}
],
"node_id": "python-3-204"
}
\ No newline at end of file
{
"source": "dataframe.py",
"depends": [],
"exercise_id": 119,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:pandas 创建dataframe
# 描述:创建dataframe的几种方式
import pandas as pd
import numpy as np
def create_dataframe(measure):
if measure == 1:
print('由数组list组成的字典创建dataframe:')
data = {
'cloumn_one': np.random.randint(0, 10, size=5),
'cloumn_two': np.random.randint(0, 10, size=5),
'cloumn_three': np.random.randint(0, 10, size=5)
}
data_df = pd.DataFrame(data)
print(data_df)
elif measure == 2:
print('由Series组成的字典创建dataframe:')
data = {
'cloumn_one': pd.Series(np.random.randint(0, 10, size=5)),
'cloumn_two': pd.Series(np.random.randint(0, 10, size=5)),
'cloumn_three': pd.Series(np.random.randint(0, 10, size=5))
}
data_df = pd.DataFrame(data)
print(data_df)
elif measure == 3:
print('通过二维数组直接创建dataframe:')
data = np.random.randint(0, 10, size=9).reshape(3, 3)
data_df = pd.DataFrame(
data, columns=['cloumn_one', 'cloumn_two', 'cloumn_three'])
print(data_df)
elif measure == 4:
print('由字典组成的列表创建dataframe:')
data = [{'cloumn_one': 1, 'cloumn_two': 2, 'cloumn_three': 3},
{'cloumn_one': 5, 'cloumn_two': 6, 'cloumn_three': 7}]
data_df = pd.DataFrame(data)
print(data_df)
else:
print('该参数不支持,可选参数为1,2,3,4')
if __name__ == '__main__':
create_dataframe(1)
create_dataframe(2)
create_dataframe(3)
create_dataframe(4)
create_dataframe(0)
{
"one_line": {
"pd.Series": [
"pd.series"
],
"index=": [
"Index="
],
"t.get(i)": [
"t[i]"
]
},
"source": "series.py",
"depends": [],
"exercise_id": 120,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:pandas Series 2
# 描述:类似字典的操作,比对两个Series的index,匹配相同key的值,输出匹配对
import pandas as pd
import numpy as np
def test():
s = pd.Series(np.random.randn(5), index=["a", "b", "c", "d", "e"])
t = pd.Series(np.random.randn(4), index=["a", "b", "c", "d"])
for i in s.index:
if t.get(i) is not None:
print(f"配对 <{s[i]}, {t[i]}>")
if __name__ == '__main__':
test()
{
"export": [
"iloc.json",
"loc.json"
],
"keywords": [],
"children": [
{
"数据预览": {
"keywords": [],
"children": [],
"node_id": "python-4-1155"
}
},
{
"数据选择": {
"keywords": [],
"children": [],
"node_id": "python-4-1156"
}
},
{
"改变数据结构": {
"keywords": [],
"children": [],
"node_id": "python-4-1157"
}
},
{
"改变数据类型": {
"keywords": [],
"children": [],
"node_id": "python-4-1158"
}
},
{
"广播与矢量化运算": {
"keywords": [],
"children": [],
"node_id": "python-4-1159"
}
},
{
"行列级广播函数": {
"keywords": [],
"children": [],
"node_id": "python-4-1160"
}
}
],
"node_id": "python-3-205"
}
\ No newline at end of file
{
"source": "iloc.py",
"depends": [],
"exercise_id": 122,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:pandas dataframe 3.2
# 描述:iloc 操作过滤掉中间人信息
# 输出:
# 0 Alice
# 1 Bob
# Name: 0, dtype: object
#
# 0 10
# 1 12
# Name: 1, dtype: object
#
# 0 在么
# 1 你说呢?
# Name: 2, dtype: object
import pandas as pd
def test():
d = [
['Alice', 'Bob', 'Middle'],
[10, 12, 0],
['在么', '你说呢?', '今晚有事']
]
df = pd.DataFrame(d)
for i in range(0, len(d)):
row = df.iloc[i][:2]
print(row)
print('')
if __name__ == '__main__':
test()
\ No newline at end of file
{
"source": "loc.py",
"depends": [],
"exercise_id": 121,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:pandas dataframe 3.1
# 描述:loc 操作过滤掉中间人信息
import pandas as pd
def test():
d = {
'name': ['Alice', 'Bob', 'Middle'],
'age': [10, 12, 0],
'send': ['在么', '你说呢?', '今晚有事']
}
df = pd.DataFrame(d, columns=['name', 'age', 'send'])
print("取出name不等于‘Middle'的数据")
alice_bob = df.loc[df['name'] != 'Middle']
print(alice_bob)
if __name__ == '__main__':
test()
\ No newline at end of file
{
"export": [
"stat.json"
],
"keywords": [],
"children": [
{
"分组": {
"keywords": [],
"children": [],
"node_id": "python-4-1161"
}
},
{
"聚合": {
"keywords": [],
"children": [],
"node_id": "python-4-1162"
}
},
{
"层次化索引": {
"keywords": [],
"children": [],
"node_id": "python-4-1163"
}
},
{
"表级广播函数": {
"keywords": [],
"children": [],
"node_id": "python-4-1164"
}
},
{
"日期时间索引对象": {
"keywords": [],
"children": [],
"node_id": "python-4-1165"
}
},
{
"透视表": {
"keywords": [],
"children": [],
"node_id": "python-4-1166"
}
},
{
"数据可视化": {
"keywords": [],
"children": [],
"node_id": "python-4-1167"
}
},
{
"数据I/O": {
"keywords": [],
"children": [],
"node_id": "python-4-1168"
}
}
],
"node_id": "python-3-206"
}
\ No newline at end of file
{
"source": "stat.py",
"depends": [],
"exercise_id": 125,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:pandas dataframe之apply
# 描述:apply的使用
import pandas as pd
import numpy as np
def add_val(num):
if num > 0:
return 1
else:
return 0
if __name__ == '__main__':
data = {
'cloumn_one': pd.Series(np.random.randint(-10,10, size=5)),
'cloumn_two': pd.Series(np.random.randint(0,10, size=5)),
'cloumn_three': pd.Series(np.random.randint(0,10, size=5))
}
data_df = pd.DataFrame(data)
data_df['label_one'] = data['cloumn_one'].apply(add_val)
print(data_df)
\ No newline at end of file
{
"node_id": "python-2-11",
"keywords": []
}
\ No newline at end of file
{
"export": [
"install.json"
],
"keywords": [],
"children": [],
"node_id": "python-3-207"
}
\ No newline at end of file
{
"source": "install.py",
"depends": [],
"exercise_id": 102,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python Matplot 安装
# 描述:正确打印安装顺序
def test():
installs = [
"1. pip install matplotlib",
"3. 还可以试试豆瓣的源:pip install matplotlib -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com",
"2. 如果装不了,就试试阿里的源:pip install matplotlib -i http://mirrors.aliyun.com/pypi/simple --trusted-host mirrors.aliyun.com",
]
installs.sort(key=lambda i: i[0])
for step in installs:
items = step.split(":")
print(items[0])
if len(items) > 1:
for i in range(1, len(items)):
print(f" {items[i]}")
if __name__ == '__main__':
test()
\ No newline at end of file
{
"export": [
"sin.json"
],
"keywords": [],
"children": [
{
"画布": {
"keywords": [],
"children": [],
"node_id": "python-4-1169"
}
},
{
"子图与子图布局": {
"keywords": [],
"children": [],
"node_id": "python-4-1170"
}
},
{
"坐标轴与刻度的名称": {
"keywords": [],
"children": [],
"node_id": "python-4-1171"
}
},
{
"图例和文本标注": {
"keywords": [],
"children": [],
"node_id": "python-4-1172"
}
},
{
"显示和保存": {
"keywords": [],
"children": [],
"node_id": "python-4-1173"
}
}
],
"node_id": "python-3-208"
}
\ No newline at end of file
{
"source": "sin.py",
"depends": [],
"exercise_id": 101,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python Matplot 绘制1
# 描述:绘制 cos(x)-sin(x)+2cos(x/2)-2sin(x/2) + ... + ncos(x/n)-nsin(x/n)
import numpy as np
import matplotlib.pyplot as plt
def sum(m, n, s):
if n < 1:
plt.show()
return
X = np.linspace(-s*np.pi, s*np.pi, m, endpoint=True)
C, S = np.cos(X), np.sin(X)
for i in range(1, n+1):
Cn, Sn = i*np.cos(X/i), i*np.sin(X/i)
C += Cn
S += Sn
return X, C+S
if __name__ == '__main__':
X, Y = sum(256, 10, 10)
plt.plot(X, Y)
X, Y = sum(256, 20, 10)
plt.plot(X, Y)
plt.show()
{
"export": [
"plot_love.json",
"plot_bezier.json"
],
"keywords": [],
"children": [
{
"曲线图": {
"keywords": [],
"children": [],
"node_id": "python-4-1174"
}
},
{
"散点图": {
"keywords": [],
"children": [],
"node_id": "python-4-1175"
}
},
{
"直方图": {
"keywords": [],
"children": [],
"node_id": "python-4-1176"
}
},
{
"饼图": {
"keywords": [],
"children": [],
"node_id": "python-4-1177"
}
},
{
"箱线图": {
"keywords": [],
"children": [],
"node_id": "python-4-1178"
}
},
{
"绘制图像": {
"keywords": [],
"children": [],
"node_id": "python-4-1179"
}
},
{
"极坐标绘图": {
"keywords": [],
"children": [],
"node_id": "python-4-1180"
}
}
],
"node_id": "python-3-209"
}
\ No newline at end of file
{
"source": "plot_bezier.py",
"depends": [],
"exercise_id": 98,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python Matplot 曲线绘制1
# 描述:10次进行割角细分,得到Bezier曲线
import bezier
import numpy as np
import matplotlib.pyplot as plt
def subdivision(nodes, depth, limit):
if depth >= limit:
return
curve = bezier.Curve(nodes, degree=2)
left, right = curve.subdivide()
plt.plot(left.nodes[0], left.nodes[1])
plt.plot(right.nodes[0], right.nodes[1])
subdivision(left.nodes, depth+1, limit)
subdivision(right.nodes, depth+1, limit)
if __name__ == '__main__':
nodes = np.asfortranarray([
[0.0, 1.25, 2.0],
[0.0, 3.0, 1.0],
])
plt.plot(nodes[0], nodes[1])
subdivision(nodes, 0, 10)
plt.show()
{
"source": "plot_love.py",
"depends": [],
"exercise_id": 99,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 绘制爱心
# 描述:使用参数曲线绘制10个爱心
import numpy as np
import matplotlib.pyplot as plt
def love_s(i, a, b, c):
s = np.array(np.sqrt(a-np.power((abs(i)-b), c)))
return s
def love_t(i, a, b, c):
t = -a*np.sqrt(b-c*abs(i))
return t
if __name__ == '__main__':
i = np.linspace(-2, 2, 100)
x = love_s(i, 1, 1, 2)
y = love_t(i, 2, 1, 0.5)
plt.plot(i, x, '--')
plt.plot(i, y, '--')
plt.show()
{
"export": [
"style.json"
],
"keywords": [],
"children": [
{
"画布设置": {
"keywords": [],
"children": [],
"node_id": "python-4-1181"
}
},
{
"子图布局": {
"keywords": [],
"children": [],
"node_id": "python-4-1182"
}
},
{
"颜色": {
"keywords": [],
"children": [],
"node_id": "python-4-1183"
}
},
{
"线条和点的样式": {
"keywords": [],
"children": [],
"node_id": "python-4-1184"
}
},
{
"坐标轴": {
"keywords": [],
"children": [],
"node_id": "python-4-1185"
}
},
{
"刻度": {
"keywords": [],
"children": [],
"node_id": "python-4-1186"
}
},
{
"文本": {
"keywords": [],
"children": [],
"node_id": "python-4-1187"
}
},
{
"图例": {
"keywords": [],
"children": [],
"node_id": "python-4-1188"
}
},
{
"网格设置": {
"keywords": [],
"children": [],
"node_id": "python-4-1189"
}
}
],
"node_id": "python-3-210"
}
\ No newline at end of file
{
"source": "style.py",
"depends": [],
"exercise_id": 100,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python Matplot 风格绘制
# 描述:风格绘制 cos(x)-sin(x)+2cos(x/2)-2sin(x/2) + ... + ncos(x/n)-nsin(x/n)
import numpy as np
import matplotlib.pyplot as plt
from random import randint
color_table = [
{"name": "Air Force blue", "value": "#5d8aa8", "lightness": "51.2"},
{"name": "Alice blue", "value": "#f0f8ff", "lightness": "97.1"},
{"name": "Alizarin crimson", "value": "#e32636", "lightness": "52"},
{"name": "Almond", "value": "#efdecd", "lightness": "87.1"},
{"name": "Amaranth", "value": "#e52b50", "lightness": "53.3"},
{"name": "Amber", "value": "#ffbf00", "lightness": "50"},
{"name": "American rose", "value": "#ff033e", "lightness": "50.6"},
{"name": "Amethyst", "value": "#9966cc", "lightness": "60"},
{"name": "Android Green", "value": "#a4c639", "lightness": "50"},
{"name": "Anti-flash white", "value": "#f2f3f4", "lightness": "95.3"},
]
def random_hex_colors():
index = randint(0, len(color_table))
return color_table[index]['value']
def sum(m, n, s):
if n < 1:
plt.show()
return
X = np.linspace(-s*np.pi, s*np.pi, m, endpoint=True)
C, S = np.cos(X), np.sin(X)
for i in range(1, n+1):
Cn, Sn = i*np.cos(X/i), i*np.sin(X/i)
C += Cn
S += Sn
return X, C+S
if __name__ == '__main__':
X, Y = sum(256, 10, 10)
plt.plot(X, Y, 'y', linewidth=1.0, linestyle="--",
label="y1", color=random_hex_colors())
X, Y = sum(256, 20, 10)
plt.plot(X, Y, 'y', linewidth=2.0, linestyle="-.",
label="y2", color=random_hex_colors())
X, Y = sum(256, 5, 10)
plt.plot(X, Y, 'y', linewidth=2.0, linestyle="-",
label="y2", color=random_hex_colors())
X, Y = sum(256, 15, 10)
plt.plot(X, Y, 'y', linewidth=2.0, linestyle=":",
label="y2", color=random_hex_colors())
plt.show()
{
"node_id": "python-2-12",
"keywords": []
}
\ No newline at end of file
{
"export": [
"scipy.json"
],
"keywords": [],
"children": [],
"node_id": "python-3-212"
}
\ No newline at end of file
{
"source": "scipy.py",
"depends": [],
"exercise_id": 146,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python SciPy
# 描述:正确打印 SciPy 中英对照介绍,输出:
#
# # Python 科学计算软件包
# # Scientific computing tools for Python
#
# * SciPy 指向一组相关但互相独立的软件包
# * SciPy refers to several related but distinct entities:
#
# * 描述:
# * SciPy 本身也是一个Python库, 属于 SciPy 技术栈的一员, 提供了许多数值计算程序.
# * The SciPy ecosystem, a collection of open source software for scientific computing in Python.
# ...
# * 相关Python 软件栈:
# * Python
# * NumPy
# ...
def test():
sci_py_meta = {
"title": "Scientific computing tools for Python",
"title_zh_cn": "Python 科学计算软件包",
"sub_title": 'SciPy refers to several related but distinct entities:',
"sub_title_zh_cn": 'SciPy 指向一组相关但互相独立的软件包',
"desc": [
'The SciPy ecosystem, a collection of open source software for scientific computing in Python.',
'The community of people who use and develop this stack.',
'Several conferences dedicated to scientific computing in Python - SciPy, EuroSciPy, and SciPy.in.',
'The SciPy library, one component of the SciPy stack, providing many numerical routines.',
],
"desc_zh_ch": [
'SciPy 本身也是一个Python库, 属于 SciPy 技术栈的一员, 提供了许多数值计算程序.',
'许多 Python 相关的科学计算会议,例如 SciPy, EuroSciPy, 和 SciPy 等',
'使用和开发这组技术栈的人',
'SciPy 生态是指一组开源 Python 科学计算软件',
],
"packages": [
"Python", "NumPy", "SciPy library", "Matplotlib", "pandas", "SymPy", "NetworkX", "scikit-image",
"scikit-learn", "h5py", "PyTables", "IPython", "Jupyter", "Cython", "Dask", "Joblib", "IPyParallel",
"nose", "numpydoc"
]
}
print()
print("# {}".format(sci_py_meta['title_zh_cn']))
print("# {}".format(sci_py_meta['title']))
print()
print("* {}".format(sci_py_meta['sub_title_zh_cn']))
print("* {}".format(sci_py_meta['sub_title']))
print()
print("* 描述:")
for i in range(0, len(sci_py_meta['desc'])):
print(" * {}".format(sci_py_meta['desc_zh_ch'][i]))
print(" * {}".format(sci_py_meta['desc'][i]))
print()
print("* 相关Python 软件栈:")
for pkg in sci_py_meta['packages']:
print(" * {}".format(pkg))
if __name__ == '__main__':
test()
\ No newline at end of file
{
"export": [],
"keywords": [],
"children": [
{
"k-means聚类": {
"keywords": [],
"children": [],
"node_id": "python-4-1215"
}
},
{
"层次聚类": {
"keywords": [],
"children": [],
"node_id": "python-4-1216"
}
}
],
"node_id": "python-3-221"
}
\ No newline at end of file
{
"export": [],
"keywords": [],
"children": [
{
"空间旋转的表述": {
"keywords": [],
"children": [],
"node_id": "python-4-1217"
}
},
{
"三维旋转": {
"keywords": [],
"children": [],
"node_id": "python-4-1218"
}
}
],
"node_id": "python-3-222"
}
\ No newline at end of file
{
"export": [
"install.json"
],
"keywords": [],
"children": [],
"node_id": "python-3-213"
}
\ No newline at end of file
{
"source": "install.py",
"depends": [],
"exercise_id": 141,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python SciPy
# 描述:编写 python 代码执行 pip 命令安装 SciPy 相关的包,出错后能重新执行断点续装
import os
import json
def load_json(file):
if not os.path.exists(file):
return None
with open(file, 'r') as f:
return json.loads(f.read())
def dump_json(file, obj):
with open(file, 'w') as f:
f.write(json.dumps(obj, indent=2, ensure_ascii=False))
def pip_install(pkg):
try:
ret = os.system(f'pip install {pkg}')
return {"err": 0, "msg": f"install {pkg} success, info:{ret}"}
except Exception as e:
return {"err": 1, "msg": f"install {pkg} exception: {str(e)}"}
def pip_install_list(name, packages):
save_point_file = f"/tmp/pip_install_{name}.json"
save_point = load_json(save_point_file)
index = save_point['index'] if save_point else 0
while index < len(packages):
ret = pip_install(packages[index])
print(ret['msg'])
if ret['err'] != 0:
break
dump_json(save_point_file, {"index": index})
index += 1
if __name__ == "__main__":
packages = [
"numpy", "scipy", "matplotlib", "ipython", "jupyter", "pandas", "sympy", "nose"
]
pip_install_list("[scipy]", packages)
{
"source": "b_spline.py",
"depends": [],
"exercise_id": 145,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 插值
# 描述:手工实现一个和 scipy.interpolate.BSpline 等价的B样条函数 bspline
from scipy.interpolate import BSpline
def B(x, k, i, t):
if k == 0:
return 1.0 if t[i] <= x < t[i+1] else 0.0
if t[i+k] == t[i]:
c1 = 0.0
else:
c1 = (x - t[i])/(t[i+k] - t[i]) * B(x, k-1, i, t)
if t[i+k+1] == t[i+1]:
c2 = 0.0
else:
c2 = (t[i+k+1] - x)/(t[i+k+1] - t[i+1]) * B(x, k-1, i+1, t)
return c1 + c2
def bspline(x, t, c, k):
n = len(t) - k - 1
assert (n >= k+1) and (len(c) >= n)
return sum(c[i] * B(x, k, i, t) for i in range(n))
if __name__ == "__main__":
k = 2
t = [0, 1, 2, 3, 4, 5, 6]
c = [-1, 2, 0, -1]
ret1 = bspline(2.5, t, c, k)
print("手工实现的B样条 bspline(2.5, t, c, k)", ret1)
spl = BSpline(t, c, k)
ret2 = spl(2.5)
print("SciPy的B样条 BSpline(t, c, k)(2.5)=", ret2)
assert ret1 == ret2
{
"export": [
"inter_1.json",
"b_spline.json"
],
"keywords": [],
"children": [
{
"一维插值": {
"keywords": [],
"children": [],
"node_id": "python-4-1192"
}
},
{
"二维插值": {
"keywords": [],
"children": [],
"node_id": "python-4-1193"
}
},
{
"离散数据插值到网格": {
"keywords": [],
"children": [],
"node_id": "python-4-1194"
}
}
],
"node_id": "python-3-214"
}
\ No newline at end of file
{
"source": "inter_1.py",
"depends": [],
"exercise_id": 144,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 插值
# 描述:封装一个便利的插值函数,支持 线性插值、三次插值、样条曲线 三种类型
import numpy as np
from scipy import interpolate
import matplotlib.pyplot as plt
def easy_inter(x, y, sample_count, kind):
f = None
if kind == 'linear':
f = interpolate.interp1d(x, y, kind='linear')
elif kind == 'cubic':
f = interpolate.interp1d(x, y, kind='cubic')
elif kind == 'spline':
f = interpolate.UnivariateSpline(x, y)
else:
return None
x = np.linspace(x.min(), x.max(), sample_count)
y = f(x)
return x, y
if __name__ == "__main__":
x = np.linspace(-12, 12, 10)
y = np.cos(x)+np.sin(x)
plt.plot(x, y, 'o')
x, y = easy_inter(x, y, 20, "linear")
plt.plot(x, y, '-')
x, y = easy_inter(x, y, 20, "cubic")
plt.plot(x, y, '--')
x, y = easy_inter(x, y, 20, "spline")
plt.plot(x, y, ':')
plt.show()
{
"export": [
"leastsq.json",
"curve_fit.json"
],
"keywords": [],
"children": [
{
"最小二乘法拟合": {
"keywords": [],
"children": [],
"node_id": "python-4-1195"
}
},
{
"使用curve_fit函数拟合": {
"keywords": [],
"children": [],
"node_id": "python-4-1196"
}
},
{
"多项式拟合函数": {
"keywords": [],
"children": [],
"node_id": "python-4-1197"
}
}
],
"node_id": "python-3-215"
}
\ No newline at end of file
{
"source": "curve_fit.py",
"depends": [],
"exercise_id": 142,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 曲线拟合
# 描述:使用 SciPy 拟合曲线
import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
def func(x, a, b, c):
return a * np.cos(x) - b*np.sin(x) + c*np.cos(2*x)
if __name__ == '__main__':
i = np.linspace(0, 4, 50)
x = func(i, 2.5, 1.3, 0.5)
np.random.seed(1729)
x_noise = 0.2 * np.random.normal(size=i.size)
popt, pcov = curve_fit(func, i, x+x_noise)
plt.plot(i, func(i, *popt), '-')
plt.show()
{
"source": "leastsq.py",
"depends": [],
"exercise_id": 143,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 最小二乘拟合
# 描述:分别使用 numpy 和 SciPy 实现最小二乘拟合,值应该相等
import numpy as np
from scipy.optimize import leastsq
import matplotlib.pyplot as plt
def cubic_leastsq_by_np(x, y, sample_count):
z = np.polyfit(x, y, 3)
f = np.poly1d(z)
x = np.linspace(x.min(), x.max(), sample_count)
y = f(x)
return x, y
def cubic_leastsq_by_scipy(x, y, sample_count):
z = leastsq(
lambda p, x, y: y - np.poly1d(p)(x),
np.random.rand(3+1),
args=(x, y)
)[0]
f = np.poly1d(z)
x = np.linspace(x.min(), x.max(), sample_count)
y = f(x)
return x, y
if __name__ == "__main__":
x = np.linspace(-3, 3, 10)
y = np.cos(x)
plt.plot(x, y, 'o')
x1, y1 = cubic_leastsq_by_np(x, y, 20)
plt.plot(x1, y1, '-')
x2, y2 = cubic_leastsq_by_scipy(x, y, 20)
plt.plot(x2, y2, '--')
assert np.array_equal(x1, x2)
assert np.array_equal(np.around(y1, decimals=2), np.around(y2, decimals=2))
plt.show()
{
"export": [
"fft.json",
"rfft.json"
],
"keywords": [],
"children": [
{
"时域到频域的转换": {
"keywords": [],
"children": [],
"node_id": "python-4-1198"
}
},
{
"一维傅里叶变换的应用": {
"keywords": [],
"children": [],
"node_id": "python-4-1199"
}
},
{
"二维傅里叶变换的应用": {
"keywords": [],
"children": [],
"node_id": "python-4-1200"
}
}
],
"node_id": "python-3-216"
}
\ No newline at end of file
{
"source": "fft.py",
"depends": [],
"exercise_id": 149,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 傅立叶变换
# 描述:傅立叶变换是可逆的,请在正向变换+反向变换后打印,曲线应该完全重合
import numpy as np
from scipy.fft import fft, fftfreq, ifft
import matplotlib.pyplot as plt
def wave(duration, sample_rate, freq):
x = np.linspace(0, duration, sample_rate*duration, endpoint=False)
w = np.sin((2 * np.pi) * freq*x)
return x, w
def transform(duration, sample_rate, w):
N = sample_rate*duration
xf = fftfreq(N, 1/sample_rate)
wf = fft(w)
return xf, wf
def inverse_transform(duration, sample_rate, wf):
w = ifft(wf)
return w
if __name__ == "__main__":
duration = 3
sample_rate = 30000
freq = 4
# 正玄波
x, w = wave(duration, sample_rate, freq)
# 傅立叶变换
xf, wf = transform(duration, sample_rate, w)
# 傅立叶逆变换
w2 = inverse_transform(duration, sample_rate, wf)
# 应该完全重合
plt.plot(w, 'o')
plt.plot(w2)
plt.show()
{
"source": "rfft.py",
"depends": [],
"exercise_id": 148,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 傅立叶变换
# 描述:计算实数序列的离散傅立叶变换,许多机器翻译把 real 翻译成 "实际",那都是错的!
import numpy as np
from scipy.fft import rfft, rfftfreq, irfft
import matplotlib.pyplot as plt
def wave(duration, sample_rate, freq):
x = np.linspace(0, duration, sample_rate*duration, endpoint=False)
w = np.sin((2 * np.pi) * freq*x)
return x, w
def rtransform(duration, sample_rate, w):
N = sample_rate*duration
xf = rfftfreq(N, 1/sample_rate)
wf = rfft(w)
return xf, wf
def inverse_rtransform(duration, sample_rate, wf):
w = irfft(wf)
return w
if __name__ == "__main__":
duration = 3
sample_rate = 30000
freq = 4
# 正玄波
x, w = wave(duration, sample_rate, freq)
# 傅立叶变换
xrf, wrf = rtransform(duration, sample_rate, w)
# 傅立叶逆变换
w2 = inverse_rtransform(duration, sample_rate, wrf)
# 打印离散傅立叶变换图
plt.plot(wrf)
plt.show()
{
"export": [
"mini_filter_ps.json"
],
"keywords": [],
"children": [
{
"图像卷积": {
"keywords": [],
"children": [],
"node_id": "python-4-1201"
}
},
{
"边缘检测": {
"keywords": [],
"children": [],
"node_id": "python-4-1202"
}
},
{
"侵蚀和膨胀": {
"keywords": [],
"children": [],
"node_id": "python-4-1203"
}
},
{
"图像测量": {
"keywords": [],
"children": [],
"node_id": "python-4-1204"
}
}
],
"node_id": "python-3-217"
}
\ No newline at end of file
{
"source": "mini_filter_ps.py",
"depends": [],
"exercise_id": 147,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 迷你滤镜PS
# 描述:实现一个包含 “高斯滤镜”/“中值滤波”/“维纳滤波”/“多维均匀过滤器” 的迷你PS软件,支持选择滤镜并将对比照片显示出来
from scipy import misc, ndimage, signal
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
def plot_two(left, right):
fig = plt.figure()
ax1 = fig.add_subplot(121)
ax2 = fig.add_subplot(122)
ax1.imshow(left)
ax2.imshow(right)
plt.show()
def select_filter(image):
print(image.shape)
filters = [
{
'option': 'g',
'name': '高斯滤镜( gaussian_filter )',
'filter': lambda: ndimage.gaussian_filter(image, sigma=6)
},
{
'option': 'm',
'name': '中值滤波( median_filter )',
'filter': lambda: ndimage.median_filter(image, size=6)
},
{
'option': 'w',
'name': '维纳滤波( wiener )',
'filter': lambda: signal.wiener(image, mysize=6)
},
{
'option': 'u',
'name': '多维均匀过滤器( uniform_filter )',
'filter': lambda: ndimage.uniform_filter(image, size=6)
},
]
print("本迷你PS软件支持以下滤镜:")
filter_dict = {}
for filter in filters:
filter_dict[filter['option']] = filter
print("* {} : {}".format(filter['option'], filter['name']))
options = '/'.join(list(map(lambda f: f['option'], filters)))
while True:
ret = input(f"请选择滤镜[ {options}]:")
filter = filter_dict.get(ret)
if filter is None:
print("不支持的选项,请重新选择。")
else:
return filter['filter']()
if __name__ == '__main__':
image = misc.face()
blurred = select_filter(image)
plot_two(image, blurred)
{
"export": [],
"keywords": [],
"children": [
{
"对给定函数的定积分": {
"keywords": [],
"children": [],
"node_id": "python-4-1205"
}
},
{
"对给定样本的定积分": {
"keywords": [],
"children": [],
"node_id": "python-4-1206"
}
},
{
"二重定积分": {
"keywords": [],
"children": [],
"node_id": "python-4-1207"
}
}
],
"node_id": "python-3-218"
}
\ No newline at end of file
{
"export": [],
"keywords": [],
"children": [
{
"非线性方程": {
"keywords": [],
"children": [],
"node_id": "python-4-1208"
}
},
{
"非线性方程组": {
"keywords": [],
"children": [],
"node_id": "python-4-1209"
}
}
],
"node_id": "python-3-219"
}
\ No newline at end of file
{
"export": [],
"keywords": [],
"children": [
{
"计算矩阵的行列式": {
"keywords": [],
"children": [],
"node_id": "python-4-1210"
}
},
{
"求解逆矩阵": {
"keywords": [],
"children": [],
"node_id": "python-4-1211"
}
},
{
"计算特征向量和特征值": {
"keywords": [],
"children": [],
"node_id": "python-4-1212"
}
},
{
"矩阵的奇异值分解": {
"keywords": [],
"children": [],
"node_id": "python-4-1213"
}
},
{
"求解线性方程组": {
"keywords": [],
"children": [],
"node_id": "python-4-1214"
}
}
],
"node_id": "python-3-220"
}
\ No newline at end of file
{
"node_id": "python-2-13",
"keywords": []
}
\ No newline at end of file
{
"export": [
"list.json",
"dict.json",
"panda.json"
],
"keywords": [],
"children": [
{
"筛选特定的行": {
"keywords": [],
"children": [
{
"行中的值满足某个条件": {
"keywords": [],
"children": [],
"node_id": "python-5-814"
}
},
{
"行中的值属于某个集合": {
"keywords": [],
"children": [],
"node_id": "python-5-815"
}
},
{
"行中的值匹配于某个模式/ 正则表达式": {
"keywords": [],
"children": [],
"node_id": "python-5-816"
}
}
],
"node_id": "python-4-1227"
}
},
{
"选取特定的列": {
"keywords": [],
"children": [
{
"列索引值": {
"keywords": [],
"children": [],
"node_id": "python-5-817"
}
},
{
"列标题": {
"keywords": [],
"children": [],
"node_id": "python-5-818"
}
}
],
"node_id": "python-4-1228"
}
},
{
"选取连续的行": {
"keywords": [],
"children": [],
"node_id": "python-4-1229"
}
},
{
"添加标题行": {
"keywords": [],
"children": [],
"node_id": "python-4-1230"
}
},
{
"读取多个CSV文件": {
"keywords": [],
"children": [],
"node_id": "python-4-1231"
}
},
{
"从多个文件中连接数据": {
"keywords": [],
"children": [],
"node_id": "python-4-1232"
}
},
{
"计算每个文件中值的总和与均值": {
"keywords": [],
"children": [],
"node_id": "python-4-1233"
}
}
],
"node_id": "python-3-224"
}
\ No newline at end of file
{
"source": "dict.py",
"depends": [],
"exercise_id": 39,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 读写csv
# 描述:csv 实现一个可追加和查询的 CSVTable
import os
import json
import csv
import logging
from enum import Enum
class ErrorCode(Enum):
# 基本错误码
SUCCESS = 0
FAILED = 1
NOT_FOUND = 2
ALREADY_EXIST = 3
# 数据库
DB_OPEN_FAILED = 100
DB_NOT_OPEN = 101
DB_QUERY_EXCEPT = 102
logger = logging.Logger(__name__)
class CSVTable():
def __init__(self, db_file, fieldnames) -> None:
self.db_file = db_file
self.fieldnames = fieldnames
self.has_open = False
def open(self):
try:
if self.has_open:
return {"err": ErrorCode.SUCCESS}
if not os.path.exists(self.db_file):
with open(self.db_file, 'w', newline='') as csvfile:
writer = csv.DictWriter(
csvfile, fieldnames=self.fieldnames)
writer.writeheader()
self.has_open = True
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):
return {'err': ErrorCode.SUCCESS}
def append(self, row):
if not self.has_open:
return {"err": ErrorCode.DB_NOT_OPEN}
assert type(row) == type({})
try:
with open(self.db_file, 'a', newline='') as csvfile:
writer = csv.DictWriter(csvfile, fieldnames=self.fieldnames)
writer.writerow(row)
return {'err': ErrorCode.SUCCESS}
except Exception as e:
logger.error(f'append exception:{str(e)}')
return {"err": ErrorCode.DB_QUERY_EXCEPT}
def select(self, filter):
if not self.has_open:
return {"err": ErrorCode.DB_NOT_OPEN}
try:
with open(self.db_file, newline='') as csvfile:
reader = csv.DictReader(csvfile, fieldnames=self.fieldnames)
results = []
for row in reader:
if filter(row):
results.append(row)
return {"err": ErrorCode.SUCCESS, "results": results}
except Exception as e:
logger.error(f'select exception:{str(e)}')
return {"err": ErrorCode.DB_QUERY_EXCEPT}
if __name__ == "__main__":
table = CSVTable('/tmp/csv_table.csv', ['name', 'age'])
ret = table.open()
assert ret['err'] == ErrorCode.SUCCESS
table.append({"name": "Alice", "age": 18})
table.append({"name": "Bob", "age": 18})
ret = table.select(lambda item: item['age'] == '18')
assert ret['err'] == ErrorCode.SUCCESS
table.close()
print(ret['results'])
{
"source": "list.py",
"depends": [],
"exercise_id": 37,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 读写csv
# 描述:csv文件读写二维数组
import csv
def dump_list(file, list):
with open(file, 'w', newline='') as csvfile:
spamwriter = csv.writer(csvfile, delimiter=' ',
quotechar='|', quoting=csv.QUOTE_MINIMAL)
for row in list:
spamwriter.writerow(row)
def load_list(file):
with open(file, 'r', newline='') as csvfile:
spamreader = csv.reader(csvfile, delimiter=' ', quotechar='|')
for row in spamreader:
yield row
if __name__ == "__main__":
rows = [
['Spam'] * 5 + ['Baked Beans'],
['Spam', 'Lovely Spam', 'Wonderful Spam']
]
list_file = '/tmp/list.csv'
dump_list(list_file, rows)
rows = load_list(list_file)
for row in rows:
for cell in row:
print(cell)
{
"source": "panda.py",
"depends": [],
"exercise_id": 38,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 读写csv
# 描述:通过 panda 读写 CSV
import pandas as pd
def dump_to_csv(file, table):
df = pd.DataFrame(data=table)
df.to_csv(file, encoding='utf_8_sig')
def load_from_csv(file):
return pd.read_csv(
file, encoding='utf_8_sig',
index_col=[0],
lineterminator="\n"
)
if __name__ == "__main__":
table = {
"name": ["Alice", "Bob"],
"age": [18, 20]
}
dump_to_csv('/tmp/panda_csv.csv', table)
ret = load_from_csv('/tmp/panda_csv.csv')
print(ret.head())
{
"export": [
"easy_excel.json"
],
"keywords": [],
"children": [
{
"内省Excel工作簿": {
"keywords": [],
"children": [],
"node_id": "python-4-1234"
}
},
{
"处理单个工作表": {
"keywords": [],
"children": [
{
"读写Excel文件": {
"keywords": [],
"children": [],
"node_id": "python-5-819"
}
},
{
"筛选特定行": {
"keywords": [],
"children": [],
"node_id": "python-5-820"
}
},
{
"选取特定列": {
"keywords": [],
"children": [],
"node_id": "python-5-821"
}
}
],
"node_id": "python-4-1235"
}
},
{
"读取工作簿中的所有工作表": {
"keywords": [],
"children": [
{
"在所有工作表中筛选特定行": {
"keywords": [],
"children": [],
"node_id": "python-5-822"
}
},
{
"在所有工作表中选取特定列": {
"keywords": [],
"children": [],
"node_id": "python-5-823"
}
}
],
"node_id": "python-4-1236"
}
},
{
"在Excel工作簿中读取一组工作表": {
"keywords": [],
"children": [],
"node_id": "python-4-1237"
}
},
{
"处理多个工作簿": {
"keywords": [],
"children": [
{
"工作表计数以及每个工作表中的行列计数": {
"keywords": [],
"children": [],
"node_id": "python-5-824"
}
},
{
"从多个工作簿中连接数据": {
"keywords": [],
"children": [],
"node_id": "python-5-825"
}
}
],
"node_id": "python-4-1238"
}
}
],
"node_id": "python-3-225"
}
\ No newline at end of file
{
"source": "easy_excel.py",
"depends": [],
"exercise_id": 35,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 读写Excel
# 描述:读写 Excel
import os
import pandas as pd
class EasyExcelWriter:
def __init__(self, excel_file) -> None:
self.excel_file = excel_file
def append_sheet(self, sheet_name, df):
if not os.path.exists(self.excel_file):
df.to_excel(self.excel_file, sheet_name=sheet_name)
else:
with pd.ExcelWriter(self.excel_file, mode='a') as writer:
df.to_excel(writer, sheet_name=sheet_name)
class EasyExcelReader:
def __init__(self, excel_file) -> None:
self.excel_file = excel_file
def load_sheet(self, sheet_name):
return pd.read_excel(excel_file, sheet_name=sheet_name)
if __name__ == '__main__':
df1 = pd.DataFrame(
[[1, 2, 3], [4, 5, 6], [7, 8, 9]],
index=['Alice', 'Bob', 'Middle'],
columns=['a', 'b', 'c']
)
df2 = pd.DataFrame([["AAA", "BBB"]], columns=["Spam", "Egg"])
df3 = pd.DataFrame([["ABC", "XYZ"]], columns=["Foo", "Bar"])
excel_file = '/tmp/panda_excel.xlsx'
w = EasyExcelWriter(excel_file)
w.append_sheet('table1', df1)
w.append_sheet('table2', df2)
w.append_sheet('table3', df3)
r = EasyExcelReader(excel_file)
df = r.load_sheet('table2')
print(df.head())
{
"source": "arma.py",
"depends": [],
"exercise_id": 36,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 时间序列分析
# 描述:ARMA模型
import numpy as np
import matplotlib.pyplot as plt
from statsmodels.graphics.tsaplots import plot_acf
from statsmodels.tsa.arima_process import ArmaProcess
def test():
# build a list MA parameters
ma = [0.8 ** i for i in range(30)]
# Simulate the MA(30) model
ar = np.array([1])
AR_object = ArmaProcess(ar, ma)
simulated_data = AR_object.generate_sample(nsample=5000)
# Plot the ACF
plot_acf(simulated_data, lags=30)
plt.savefig('/tmp/arma_acf.png')
if __name__ == '__main__':
test()
\ No newline at end of file
{
"keywords": [],
"export": [
"arma.json"
],
"时间序列": {
"keywords": [],
"children": [
{
"时间序列基础": {
"keywords": [],
"children": [
{
"含有重复索引的时间序列": {
"keywords": [],
"children": []
}
}
]
}
},
{
"时区处理": {
"keywords": [],
"children": [
{
"时区的本地化和转换": {
"keywords": [],
"children": []
}
},
{
"时区感知时间戳对象的操作": {
"keywords": [],
"children": []
}
},
{
"不同时区间的操作": {
"keywords": [],
"children": []
}
}
]
}
},
{
"时间区间和区间算术": {
"keywords": [],
"children": [
{
"区间频率转换": {
"keywords": [],
"children": []
}
},
{
"季度区间频率": {
"keywords": [],
"children": []
}
},
{
"将时间戳转换为区间(以及逆转换)": {
"keywords": [],
"children": []
}
},
{
"从数组生成PeriodIndex": {
"keywords": [],
"children": []
}
}
]
}
},
{
"重新采样与频率转换": {
"keywords": [],
"children": [
{
"向下采样": {
"keywords": [],
"children": []
}
},
{
"向上采样与插值": {
"keywords": [],
"children": []
}
},
{
"使用区间进行重新采样": {
"keywords": [],
"children": []
}
}
]
}
},
{
"移动窗口函数": {
"keywords": [],
"children": [
{
"指数加权函数": {
"keywords": [],
"children": []
}
},
{
"二元移动窗口函数": {
"keywords": [],
"children": []
}
},
{
"用户自定义的移动窗口函数": {
"keywords": [],
"children": []
}
}
]
}
}
]
},
"node_id": "python-3-241",
"children": [
{
"变化的分类": {
"keywords": [],
"children": [],
"node_id": "python-4-1402"
}
},
{
"包含趋势的序列分析": {
"keywords": [],
"children": [
{
"曲线拟合": {
"keywords": [],
"children": [],
"node_id": "python-5-1324"
}
},
{
"从时间序列中去除趋势": {
"keywords": [],
"children": [],
"node_id": "python-5-1325"
}
}
],
"node_id": "python-4-1403"
}
},
{
"包含周期性的序列数据分析": {
"keywords": [],
"children": [],
"node_id": "python-4-1404"
}
},
{
"从时间序列中去除周期性": {
"keywords": [],
"children": [
{
"滤波": {
"keywords": [],
"children": [],
"node_id": "python-5-1326"
}
},
{
"差分": {
"keywords": [],
"children": [],
"node_id": "python-5-1327"
}
}
],
"node_id": "python-4-1405"
}
},
{
"平稳时间序列": {
"keywords": [],
"children": [
{
"平稳过程": {
"keywords": [],
"children": [],
"node_id": "python-5-1328"
}
},
{
"自相关和相关图": {
"keywords": [],
"children": [],
"node_id": "python-5-1329"
}
},
{
"自协方差和自相关函数的估计": {
"keywords": [],
"children": [],
"node_id": "python-5-1330"
}
}
],
"node_id": "python-4-1406"
}
},
{
"使用Python进行时间序列分析": {
"keywords": [],
"children": [
{
"有用的方法": {
"keywords": [],
"children": [],
"node_id": "python-5-1331"
}
},
{
"自回归过程": {
"keywords": [],
"children": [],
"node_id": "python-5-1332"
}
},
{
"估计AR过程的参数": {
"keywords": [],
"children": [],
"node_id": "python-5-1333"
}
}
],
"node_id": "python-4-1407"
}
},
{
"混合ARMA模型": {
"keywords": [],
"children": [],
"node_id": "python-4-1408"
}
},
{
"集成ARMA模型": {
"keywords": [],
"children": [],
"node_id": "python-4-1409"
}
},
{
"一个特殊的场景": {
"keywords": [],
"children": [],
"node_id": "python-4-1410"
}
},
{
"数据缺失": {
"keywords": [],
"children": [],
"node_id": "python-4-1411"
}
}
]
}
\ No newline at end of file
{
"node_id": "python-2-14",
"keywords": []
}
\ No newline at end of file
{
"export": [
"linear.json"
],
"keywords": [],
"children": [
{
"Scikit-learn概览": {
"keywords": [],
"children": [],
"node_id": "python-4-1308"
}
},
{
"安装配置": {
"keywords": [],
"children": [],
"node_id": "python-4-1309"
}
},
{
"数据集": {
"keywords": [],
"children": [
{
"Scikit-learn自带的数据集": {
"keywords": [],
"children": [],
"node_id": "python-5-980"
}
},
{
"样本生成器": {
"keywords": [],
"children": [],
"node_id": "python-5-981"
}
},
{
"加载其他数据集": {
"keywords": [],
"children": [],
"node_id": "python-5-982"
}
}
],
"node_id": "python-4-1310"
}
},
{
"数据预处理Preprocessing": {
"keywords": [],
"children": [
{
"标准化": {
"keywords": [],
"children": [],
"node_id": "python-5-983"
}
},
{
"归一化": {
"keywords": [],
"children": [],
"node_id": "python-5-984"
}
},
{
"正则化": {
"keywords": [],
"children": [],
"node_id": "python-5-985"
}
},
{
"离散化": {
"keywords": [],
"children": [],
"node_id": "python-5-986"
}
},
{
"特征编码": {
"keywords": [],
"children": [],
"node_id": "python-5-987"
}
},
{
"缺失值补全": {
"keywords": [],
"children": [],
"node_id": "python-5-988"
}
}
],
"node_id": "python-4-1311"
}
},
{
"分类Classification": {
"keywords": [],
"children": [
{
"K-近邻分类": {
"keywords": [],
"children": [],
"node_id": "python-5-989"
}
},
{
"贝叶斯分类": {
"keywords": [],
"children": [],
"node_id": "python-5-990"
}
},
{
"决策树分类": {
"keywords": [],
"children": [],
"node_id": "python-5-991"
}
},
{
"支持向量机分类": {
"keywords": [],
"children": [],
"node_id": "python-5-992"
}
},
{
"随机森林分类": {
"keywords": [],
"children": [],
"node_id": "python-5-993"
}
},
{
"集成学习Bagging/Boosting": {
"keywords": [],
"children": [],
"node_id": "python-5-994"
}
},
{
"神经网络模型": {
"keywords": [],
"children": [],
"node_id": "python-5-995"
}
}
],
"node_id": "python-4-1312"
}
},
{
"回归Regression": {
"keywords": [],
"children": [
{
"线性回归": {
"keywords": [],
"children": [],
"node_id": "python-5-996"
}
},
{
"Lasso回归": {
"keywords": [],
"children": [],
"node_id": "python-5-997"
}
},
{
"支持向量机回归": {
"keywords": [],
"children": [],
"node_id": "python-5-998"
}
},
{
"K-近邻回归": {
"keywords": [],
"children": [],
"node_id": "python-5-999"
}
},
{
"决策树回归": {
"keywords": [],
"children": [],
"node_id": "python-5-1000"
}
},
{
"随机森林回归": {
"keywords": [],
"children": [],
"node_id": "python-5-1001"
}
},
{
"逻辑回归": {
"keywords": [],
"children": [],
"node_id": "python-5-1002"
}
}
],
"node_id": "python-4-1313"
}
},
{
"聚类Clustering": {
"keywords": [],
"children": [
{
"K-Means聚类": {
"keywords": [],
"children": [],
"node_id": "python-5-1003"
}
},
{
"均值漂移聚类": {
"keywords": [],
"children": [],
"node_id": "python-5-1004"
}
},
{
"基于密度的空间聚类": {
"keywords": [],
"children": [],
"node_id": "python-5-1005"
}
},
{
"谱聚类": {
"keywords": [],
"children": [],
"node_id": "python-5-1006"
}
},
{
"层次聚类": {
"keywords": [],
"children": [
{
"自下而上的方法": {
"keywords": [],
"children": [],
"node_id": "python-6-174"
}
},
{
"聚类之间的距离": {
"keywords": [],
"children": [],
"node_id": "python-6-175"
}
},
{
"自上而下的方法": {
"keywords": [],
"children": [],
"node_id": "python-6-176"
}
},
{
"图论方法": {
"keywords": [],
"children": [],
"node_id": "python-6-177"
}
}
],
"node_id": "python-5-1007"
}
}
],
"node_id": "python-4-1314"
}
},
{
"成分分解与降维": {
"keywords": [],
"children": [
{
"主成分分析": {
"keywords": [],
"children": [],
"node_id": "python-5-1008"
}
},
{
"因子分析": {
"keywords": [],
"children": [],
"node_id": "python-5-1009"
}
},
{
"截断奇异值分解": {
"keywords": [],
"children": [],
"node_id": "python-5-1010"
}
},
{
"独立成分分析ICA(Independent Component Analysis)": {
"keywords": [],
"children": [],
"node_id": "python-5-1011"
}
}
],
"node_id": "python-4-1315"
}
},
{
"模型评估与参数调优": {
"keywords": [],
"children": [
{
"估计器得分": {
"keywords": [],
"children": [],
"node_id": "python-5-1012"
}
},
{
"交叉验证": {
"keywords": [],
"children": [],
"node_id": "python-5-1013"
}
},
{
"评价指标": {
"keywords": [],
"children": [],
"node_id": "python-5-1014"
}
},
{
"参数调优": {
"keywords": [],
"children": [],
"node_id": "python-5-1015"
}
},
{
"模型持久化": {
"keywords": [],
"children": [],
"node_id": "python-5-1016"
}
}
],
"node_id": "python-4-1316"
}
}
],
"node_id": "python-3-245"
}
\ No newline at end of file
{
"source": "linear.py",
"depends": [],
"exercise_id": 133,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:SK-Learn 线性回归
# 描述:训练预测的基本套路
import numpy as np
from sklearn.linear_model import LinearRegression
def test():
X = np.array([[1, 1], [1, 2], [2, 2], [2, 3]])
y = np.dot(X, np.array([1, 2])) + 3
reg = LinearRegression().fit(X, y)
y_predict = reg.predict(np.array([[3, 5]]))
print(y_predict)
if __name__ == '__main__':
test()
\ No newline at end of file
{
"export": [
"tensor.json"
],
"keywords": [],
"children": [
{
"神经网络基础知识": {
"keywords": [],
"children": [
{
"人工智能发展历史": {
"keywords": [],
"children": [],
"node_id": "python-5-1017"
}
},
{
"神经元": {
"keywords": [],
"children": [],
"node_id": "python-5-1018"
}
},
{
"BP神经网络": {
"keywords": [],
"children": [],
"node_id": "python-5-1019"
}
},
{
"梯度下降": {
"keywords": [],
"children": [],
"node_id": "python-5-1020"
}
},
{
"激励函数": {
"keywords": [],
"children": [],
"node_id": "python-5-1021"
}
},
{
"过拟合、欠拟合": {
"keywords": [],
"children": [],
"node_id": "python-5-1022"
}
},
{
"优化器Optimizer": {
"keywords": [],
"children": [],
"node_id": "python-5-1023"
}
},
{
"常用开发工具": {
"keywords": [],
"children": [],
"node_id": "python-5-1024"
}
}
],
"node_id": "python-4-1317"
}
},
{
"环境配置": {
"keywords": [],
"children": [
{
"Windows搭建深度学习环境": {
"keywords": [],
"children": [],
"node_id": "python-5-1025"
}
},
{
"Linux搭建深度学习环境": {
"keywords": [],
"children": [],
"node_id": "python-5-1026"
}
},
{
"MacOS搭建深度学习环境": {
"keywords": [],
"children": [],
"node_id": "python-5-1027"
}
},
{
"CPU/GPU环境搭建": {
"keywords": [],
"children": [],
"node_id": "python-5-1028"
}
}
],
"node_id": "python-4-1318"
}
},
{
"Theano": {
"keywords": [],
"children": [
{
"Theano基础知识": {
"keywords": [],
"children": [],
"node_id": "python-5-1029"
}
},
{
"定义Layer": {
"keywords": [],
"children": [],
"node_id": "python-5-1030"
}
},
{
"CNN": {
"keywords": [],
"children": [],
"node_id": "python-5-1031"
}
},
{
"RNN(GRU/LSTM)": {
"keywords": [],
"children": [],
"node_id": "python-5-1032"
}
},
{
"Autoencoder": {
"keywords": [],
"children": [],
"node_id": "python-5-1033"
}
},
{
"神经网络参数保存": {
"keywords": [],
"children": [],
"node_id": "python-5-1034"
}
},
{
"神经网络性能评价": {
"keywords": [],
"children": [],
"node_id": "python-5-1035"
}
}
],
"node_id": "python-4-1319"
}
},
{
"TensorFlow": {
"keywords": [],
"children": [
{
"TensorFlow基础知识": {
"keywords": [],
"children": [],
"node_id": "python-5-1036"
}
},
{
"Tensor": {
"keywords": [],
"children": [],
"node_id": "python-5-1037"
}
},
{
"Session": {
"keywords": [],
"children": [],
"node_id": "python-5-1038"
}
},
{
"Variable": {
"keywords": [],
"children": [],
"node_id": "python-5-1039"
}
},
{
"Placeholder": {
"keywords": [],
"children": [],
"node_id": "python-5-1040"
}
},
{
"Dropout": {
"keywords": [],
"children": [],
"node_id": "python-5-1041"
}
},
{
"Tensorboard": {
"keywords": [],
"children": [],
"node_id": "python-5-1042"
}
},
{
"CNN": {
"keywords": [],
"children": [],
"node_id": "python-5-1043"
}
},
{
"RNN(GRU/LSTM)": {
"keywords": [],
"children": [],
"node_id": "python-5-1044"
}
},
{
"Autoencoder": {
"keywords": [],
"children": [],
"node_id": "python-5-1045"
}
},
{
"GNN": {
"keywords": [],
"children": [],
"node_id": "python-5-1046"
}
},
{
"神经网络参数保存": {
"keywords": [],
"children": [],
"node_id": "python-5-1047"
}
},
{
"神经网络性能评价": {
"keywords": [],
"children": [],
"node_id": "python-5-1048"
}
}
],
"node_id": "python-4-1320"
}
},
{
"Keras": {
"keywords": [],
"children": [
{
"Keras基础语法": {
"keywords": [],
"children": [],
"node_id": "python-5-1049"
}
},
{
"兼容Backend": {
"keywords": [],
"children": [],
"node_id": "python-5-1050"
}
},
{
"函数模型和序列模型": {
"keywords": [],
"children": [],
"node_id": "python-5-1051"
}
},
{
"定义Layer": {
"keywords": [],
"children": [],
"node_id": "python-5-1052"
}
},
{
"CNN": {
"keywords": [],
"children": [],
"node_id": "python-5-1053"
}
},
{
"RNN(GRU/LSTM)": {
"keywords": [],
"children": [],
"node_id": "python-5-1054"
}
},
{
"Autoencoder": {
"keywords": [],
"children": [],
"node_id": "python-5-1055"
}
},
{
"GNN": {
"keywords": [],
"children": [],
"node_id": "python-5-1056"
}
},
{
"迁移学习": {
"keywords": [],
"children": [],
"node_id": "python-5-1057"
}
},
{
"BiLSTM-Attention": {
"keywords": [],
"children": [],
"node_id": "python-5-1058"
}
},
{
"生成对抗网络GAN": {
"keywords": [],
"children": [],
"node_id": "python-5-1059"
}
},
{
"神经网络参数保存": {
"keywords": [],
"children": [],
"node_id": "python-5-1060"
}
},
{
"神经网络性能评价": {
"keywords": [],
"children": [],
"node_id": "python-5-1061"
}
}
],
"node_id": "python-4-1321"
}
},
{
"PyTorch": {
"keywords": [],
"children": [
{
"PyTorch基础知识": {
"keywords": [],
"children": [],
"node_id": "python-5-1062"
}
},
{
"Tensor": {
"keywords": [],
"children": [],
"node_id": "python-5-1063"
}
},
{
"Variable": {
"keywords": [],
"children": [],
"node_id": "python-5-1064"
}
},
{
"定义Layer": {
"keywords": [],
"children": [],
"node_id": "python-5-1065"
}
},
{
"可视化": {
"keywords": [],
"children": [],
"node_id": "python-5-1066"
}
},
{
"CNN(TextCNN)": {
"keywords": [],
"children": [],
"node_id": "python-5-1067"
}
},
{
"RNN(GRU/LSTM)": {
"keywords": [],
"children": [],
"node_id": "python-5-1068"
}
},
{
"Autoencoder": {
"keywords": [],
"children": [],
"node_id": "python-5-1069"
}
},
{
"GNN/GCN": {
"keywords": [],
"children": [],
"node_id": "python-5-1070"
}
},
{
"迁移学习": {
"keywords": [],
"children": [],
"node_id": "python-5-1071"
}
},
{
"生成对抗网络GAN": {
"keywords": [],
"children": [],
"node_id": "python-5-1072"
}
},
{
"神经网络参数保存": {
"keywords": [],
"children": [],
"node_id": "python-5-1073"
}
},
{
"神经网络性能评价": {
"keywords": [],
"children": [],
"node_id": "python-5-1074"
}
}
],
"node_id": "python-4-1322"
}
},
{
"强化学习": {
"keywords": [],
"children": [
{
"强化学习概念": {
"keywords": [],
"children": [],
"node_id": "python-5-1075"
}
},
{
"Q-Learning": {
"keywords": [],
"children": [],
"node_id": "python-5-1076"
}
},
{
"Sarsa": {
"keywords": [],
"children": [],
"node_id": "python-5-1077"
}
},
{
"DQN(Deep Q Network)": {
"keywords": [],
"children": [],
"node_id": "python-5-1078"
}
},
{
"Policy Gradients": {
"keywords": [],
"children": [],
"node_id": "python-5-1079"
}
},
{
"Actor Critic": {
"keywords": [],
"children": [],
"node_id": "python-5-1080"
}
}
],
"node_id": "python-4-1323"
}
}
],
"node_id": "python-3-246"
}
\ No newline at end of file
{
"source": "tensor.py",
"depends": [],
"exercise_id": 132,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:深度学习|mnist 数据集例子
# 描述:使用 tensorflow.keras 接口,组装神经网络层次,训练并预测
import tensorflow as tf
from tensorflow.keras.datasets import mnist
import os
class Classifier:
def __init__(self) -> None:
self.x_train = None
self.x_test = None
self.model_file = '/tmp/tensor.keras.model'
self.has_load = False
self.has_model_load = False
def load_or_train(self):
if self.has_load:
return {'err': 0}
try:
if os.path.exists(self.model_file):
self.__load_model()
else:
self.__train_model()
self.has_load = True
return {'err': 0}
except Exception as e:
return {'err': 1, 'msg': str(e)}
def __create_model(self):
model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28)),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dropout(0.2),
tf.keras.layers.Dense(10, activation='softmax')
])
model.compile(
optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy']
)
return model
def __train_model(self):
if self.has_model_load:
return
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
self.model = self.__create_model()
self.model.fit(x_train, y_train, epochs=5)
self.model.evaluate(x_test, y_test, verbose=2)
self.model.save(self.model_file)
self.has_model_load = True
def __load_model(self):
if self.has_model_load:
return
self.model = tf.keras.models.load_model(self.model_file)
self.model.summary()
self.has_model_load = True
def predict(self, test_images):
if not self.has_load:
return {'err': 1, 'msg': "分类器还没加载"}
result = self.model.predict(test_images)
return {'err': 0, 'result': result}
if __name__ == "__main__":
cl = Classifier()
# 加载或训练模型
ret = cl.load_or_train()
if ret['err'] != 0:
print(ret['msg'])
else:
# 测试数据
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
test_images = test_images[:1000].reshape(-1, 28 * 28) / 255.0
# 预测
ret = cl.predict(test_images)
if ret['err'] == 0:
print('预测结果:', ret['result'])
else:
print('预测失败:{}', ret['msg'])
{
"export": [
"cv.json"
],
"keywords": [],
"children": [
{
"数字图像处理基础": {
"keywords": [],
"children": [
{
"数字图像处理": {
"keywords": [],
"children": [],
"node_id": "python-5-1081"
}
},
{
"图像三要素": {
"keywords": [],
"children": [],
"node_id": "python-5-1082"
}
},
{
"像素及图像类型": {
"keywords": [],
"children": [],
"node_id": "python-5-1083"
}
},
{
"图像信号数字转换": {
"keywords": [],
"children": [],
"node_id": "python-5-1084"
}
}
],
"node_id": "python-4-1324"
}
},
{
"OpenCV基础": {
"keywords": [],
"children": [
{
"安装配置": {
"keywords": [],
"children": [],
"node_id": "python-5-1085"
}
},
{
"OpenCV基础语法": {
"keywords": [],
"children": [],
"node_id": "python-5-1086"
}
},
{
"几何图形绘制": {
"keywords": [],
"children": [],
"node_id": "python-5-1087"
}
}
],
"node_id": "python-4-1325"
}
},
{
"图像处理入门": {
"keywords": [],
"children": [
{
"读取显示图像": {
"keywords": [],
"children": [],
"node_id": "python-5-1088"
}
},
{
"读取修改像素": {
"keywords": [],
"children": [],
"node_id": "python-5-1089"
}
},
{
"创建复制保存图像": {
"keywords": [],
"children": [],
"node_id": "python-5-1090"
}
},
{
"获取图像属性及通道": {
"keywords": [],
"children": [],
"node_id": "python-5-1091"
}
}
],
"node_id": "python-4-1326"
}
},
{
"图像算数与逻辑运算": {
"keywords": [],
"children": [
{
"图像加法运算": {
"keywords": [],
"children": [],
"node_id": "python-5-1092"
}
},
{
"图像减法运算": {
"keywords": [],
"children": [],
"node_id": "python-5-1093"
}
},
{
"图像与运算": {
"keywords": [],
"children": [],
"node_id": "python-5-1094"
}
},
{
"图像或运算": {
"keywords": [],
"children": [],
"node_id": "python-5-1095"
}
},
{
"图像异或运算": {
"keywords": [],
"children": [],
"node_id": "python-5-1096"
}
},
{
"图像非运算": {
"keywords": [],
"children": [],
"node_id": "python-5-1097"
}
}
],
"node_id": "python-4-1327"
}
},
{
"图像几何变换": {
"keywords": [],
"children": [
{
"平移变换": {
"keywords": [],
"children": [],
"node_id": "python-5-1098"
}
},
{
"缩放变换": {
"keywords": [],
"children": [],
"node_id": "python-5-1099"
}
},
{
"旋转变换": {
"keywords": [],
"children": [],
"node_id": "python-5-1100"
}
},
{
"镜像变换": {
"keywords": [],
"children": [],
"node_id": "python-5-1101"
}
},
{
"仿射变换": {
"keywords": [],
"children": [],
"node_id": "python-5-1102"
}
},
{
"透视变换": {
"keywords": [],
"children": [],
"node_id": "python-5-1103"
}
}
],
"node_id": "python-4-1328"
}
},
{
"图像量化与采样": {
"keywords": [],
"children": [
{
"图像量化处理": {
"keywords": [],
"children": [],
"node_id": "python-5-1104"
}
},
{
"图像采样处理": {
"keywords": [],
"children": [],
"node_id": "python-5-1105"
}
},
{
"图像金字塔": {
"keywords": [],
"children": [],
"node_id": "python-5-1106"
}
},
{
"局部马赛克处理": {
"keywords": [],
"children": [],
"node_id": "python-5-1107"
}
}
],
"node_id": "python-4-1329"
}
},
{
"直方图统计": {
"keywords": [],
"children": [
{
"直方图概述": {
"keywords": [],
"children": [],
"node_id": "python-5-1108"
}
},
{
"直方图绘制": {
"keywords": [],
"children": [],
"node_id": "python-5-1109"
}
},
{
"掩膜直方图": {
"keywords": [],
"children": [],
"node_id": "python-5-1110"
}
},
{
"H-S直方图": {
"keywords": [],
"children": [],
"node_id": "python-5-1111"
}
},
{
"直方图对比": {
"keywords": [],
"children": [],
"node_id": "python-5-1112"
}
}
],
"node_id": "python-4-1330"
}
},
{
"图像增强": {
"keywords": [],
"children": [
{
"图像增强": {
"keywords": [],
"children": [],
"node_id": "python-5-1113"
}
},
{
"直方图均衡化": {
"keywords": [],
"children": [],
"node_id": "python-5-1114"
}
},
{
"局部直方图均衡化": {
"keywords": [],
"children": [],
"node_id": "python-5-1115"
}
},
{
"自动色彩均衡化": {
"keywords": [],
"children": [],
"node_id": "python-5-1116"
}
},
{
"图像去雾": {
"keywords": [],
"children": [],
"node_id": "python-5-1117"
}
}
],
"node_id": "python-4-1331"
}
},
{
"图像平滑": {
"keywords": [],
"children": [
{
"图像平滑概述": {
"keywords": [],
"children": [],
"node_id": "python-5-1118"
}
},
{
"均值滤波": {
"keywords": [],
"children": [],
"node_id": "python-5-1119"
}
},
{
"方框滤波": {
"keywords": [],
"children": [],
"node_id": "python-5-1120"
}
},
{
"高斯滤波": {
"keywords": [],
"children": [],
"node_id": "python-5-1121"
}
},
{
"中值滤波": {
"keywords": [],
"children": [],
"node_id": "python-5-1122"
}
},
{
"双边滤波": {
"keywords": [],
"children": [],
"node_id": "python-5-1123"
}
}
],
"node_id": "python-4-1332"
}
},
{
"图像锐化及边缘检测": {
"keywords": [],
"children": [
{
"一阶微分算法、二阶微分算子": {
"keywords": [],
"children": [],
"node_id": "python-5-1124"
}
},
{
"Roberts算子": {
"keywords": [],
"children": [],
"node_id": "python-5-1125"
}
},
{
"Prewitt算子": {
"keywords": [],
"children": [],
"node_id": "python-5-1126"
}
},
{
"Sobel算子": {
"keywords": [],
"children": [],
"node_id": "python-5-1127"
}
},
{
"Laplacian算子": {
"keywords": [],
"children": [],
"node_id": "python-5-1128"
}
},
{
"Scharr算子": {
"keywords": [],
"children": [],
"node_id": "python-5-1129"
}
},
{
"Canny算子": {
"keywords": [],
"children": [],
"node_id": "python-5-1130"
}
},
{
"LOG算子": {
"keywords": [],
"children": [],
"node_id": "python-5-1131"
}
}
],
"node_id": "python-4-1333"
}
},
{
"图像形态学处理": {
"keywords": [],
"children": [
{
"图像腐蚀": {
"keywords": [],
"children": [],
"node_id": "python-5-1132"
}
},
{
"图像膨胀": {
"keywords": [],
"children": [],
"node_id": "python-5-1133"
}
},
{
"图像开运算": {
"keywords": [],
"children": [],
"node_id": "python-5-1134"
}
},
{
"图像闭运算": {
"keywords": [],
"children": [],
"node_id": "python-5-1135"
}
},
{
"图像梯度运算": {
"keywords": [],
"children": [],
"node_id": "python-5-1136"
}
},
{
"图像顶帽运算": {
"keywords": [],
"children": [],
"node_id": "python-5-1137"
}
},
{
"图像底帽运算": {
"keywords": [],
"children": [],
"node_id": "python-5-1138"
}
}
],
"node_id": "python-4-1334"
}
},
{
"图像分割": {
"keywords": [],
"children": [
{
"基于阈值的图像分割": {
"keywords": [],
"children": [],
"node_id": "python-5-1139"
}
},
{
"基于边缘检测的图像分割": {
"keywords": [],
"children": [],
"node_id": "python-5-1140"
}
},
{
"基于纹理背景的图像分割": {
"keywords": [],
"children": [],
"node_id": "python-5-1141"
}
},
{
"基于K-Means聚类的区域分割": {
"keywords": [],
"children": [],
"node_id": "python-5-1142"
}
},
{
"基于均值漂移算法的图像分割": {
"keywords": [],
"children": [],
"node_id": "python-5-1143"
}
},
{
"基于分水岭算法的图像分割": {
"keywords": [],
"children": [],
"node_id": "python-5-1144"
}
},
{
"图像漫水填充分割": {
"keywords": [],
"children": [],
"node_id": "python-5-1145"
}
},
{
"文字区域分割及定位": {
"keywords": [],
"children": [],
"node_id": "python-5-1146"
}
}
],
"node_id": "python-4-1335"
}
},
{
"傅里叶变换": {
"keywords": [],
"children": [
{
"傅里叶变换": {
"keywords": [],
"children": [],
"node_id": "python-5-1147"
}
},
{
"傅里叶逆变换": {
"keywords": [],
"children": [],
"node_id": "python-5-1148"
}
},
{
"高通滤波器": {
"keywords": [],
"children": [],
"node_id": "python-5-1149"
}
},
{
"低通滤波器": {
"keywords": [],
"children": [],
"node_id": "python-5-1150"
}
}
],
"node_id": "python-4-1336"
}
},
{
"霍夫变换": {
"keywords": [],
"children": [
{
"霍夫变换": {
"keywords": [],
"children": [],
"node_id": "python-5-1151"
}
},
{
"霍夫线变换": {
"keywords": [],
"children": [],
"node_id": "python-5-1152"
}
},
{
"霍夫圆变换": {
"keywords": [],
"children": [],
"node_id": "python-5-1153"
}
}
],
"node_id": "python-4-1337"
}
},
{
"图像特效处理": {
"keywords": [],
"children": [
{
"图像毛玻璃特效": {
"keywords": [],
"children": [],
"node_id": "python-5-1154"
}
},
{
"图像浮雕特效": {
"keywords": [],
"children": [],
"node_id": "python-5-1155"
}
},
{
"图像素描特效": {
"keywords": [],
"children": [],
"node_id": "python-5-1156"
}
},
{
"图像怀旧特效": {
"keywords": [],
"children": [],
"node_id": "python-5-1157"
}
},
{
"图像流年特效": {
"keywords": [],
"children": [],
"node_id": "python-5-1158"
}
},
{
"图像滤镜特效": {
"keywords": [],
"children": [],
"node_id": "python-5-1159"
}
},
{
"图像水波特效": {
"keywords": [],
"children": [],
"node_id": "python-5-1160"
}
},
{
"图像卡通特效": {
"keywords": [],
"children": [],
"node_id": "python-5-1161"
}
}
],
"node_id": "python-4-1338"
}
},
{
"图像分类": {
"keywords": [],
"children": [
{
"图像分类概述": {
"keywords": [],
"children": [],
"node_id": "python-5-1162"
}
},
{
"基于机器学习的图像分类": {
"keywords": [],
"children": [],
"node_id": "python-5-1163"
}
},
{
"基于深度学习的图像分类": {
"keywords": [],
"children": [],
"node_id": "python-5-1164"
}
},
{
"LeNet": {
"keywords": [],
"children": [],
"node_id": "python-5-1165"
}
},
{
"VGG": {
"keywords": [],
"children": [],
"node_id": "python-5-1166"
}
},
{
"AlexNet": {
"keywords": [],
"children": [],
"node_id": "python-5-1167"
}
},
{
"ResNet": {
"keywords": [],
"children": [],
"node_id": "python-5-1168"
}
}
],
"node_id": "python-4-1339"
}
},
{
"人脸识别": {
"keywords": [],
"children": [],
"node_id": "python-4-1340"
}
},
{
"目标检测": {
"keywords": [],
"children": [
{
"目标检测概述": {
"keywords": [],
"children": [],
"node_id": "python-5-1169"
}
},
{
"RCNN": {
"keywords": [],
"children": [],
"node_id": "python-5-1170"
}
},
{
"Fast-RCNN": {
"keywords": [],
"children": [],
"node_id": "python-5-1171"
}
},
{
"SPPNet": {
"keywords": [],
"children": [],
"node_id": "python-5-1172"
}
},
{
"Mask-RCNN": {
"keywords": [],
"children": [],
"node_id": "python-5-1173"
}
},
{
"SSD": {
"keywords": [],
"children": [],
"node_id": "python-5-1174"
}
},
{
"YOLO系列算法": {
"keywords": [],
"children": [],
"node_id": "python-5-1175"
}
}
],
"node_id": "python-4-1341"
}
},
{
"深度神经网络概述": {
"keywords": [],
"children": [
{
"创建神经网络块": {
"keywords": [],
"children": [],
"node_id": "python-5-1176"
}
},
{
"TensorFlow介绍": {
"keywords": [],
"children": [],
"node_id": "python-5-1177"
}
},
{
"MNIST数据集介绍": {
"keywords": [],
"children": [],
"node_id": "python-5-1178"
}
},
{
"Keras深度学习库概述": {
"keywords": [],
"children": [],
"node_id": "python-5-1179"
}
},
{
"基于Keras和MNIST的手写数字识别": {
"keywords": [],
"children": [
{
"训练和测试数据的检索": {
"keywords": [],
"children": [],
"node_id": "python-6-178"
}
},
{
"训练数据的可视化": {
"keywords": [],
"children": [],
"node_id": "python-6-179"
}
},
{
"创建神经网络": {
"keywords": [],
"children": [],
"node_id": "python-6-180"
}
},
{
"训练神经网络": {
"keywords": [],
"children": [],
"node_id": "python-6-181"
}
},
{
"测试": {
"keywords": [],
"children": [],
"node_id": "python-6-182"
}
}
],
"node_id": "python-5-1180"
}
},
{
"理解反向传播": {
"keywords": [],
"children": [],
"node_id": "python-5-1181"
}
}
],
"node_id": "python-4-1342"
}
},
{
"卷积神经网络介绍": {
"keywords": [],
"children": [
{
"CNN历史": {
"keywords": [],
"children": [],
"node_id": "python-5-1182"
}
},
{
"卷积神经网络": {
"keywords": [],
"children": [
{
"计算机如何解释图像": {
"keywords": [],
"children": [],
"node_id": "python-6-183"
}
},
{
"编码实现图像可视化": {
"keywords": [],
"children": [],
"node_id": "python-6-184"
}
},
{
"dropout": {
"keywords": [],
"children": [],
"node_id": "python-6-185"
}
},
{
"输入层": {
"keywords": [],
"children": [],
"node_id": "python-6-186"
}
},
{
"卷积层": {
"keywords": [],
"children": [],
"node_id": "python-6-187"
}
},
{
"池化层": {
"keywords": [],
"children": [],
"node_id": "python-6-188"
}
}
],
"node_id": "python-5-1183"
}
}
],
"node_id": "python-4-1343"
}
},
{
"构建CNN并进行性能优化": {
"keywords": [],
"children": [
{
"CNN架构和DNN的缺点": {
"keywords": [],
"children": [
{
"卷积操作": {
"keywords": [],
"children": [],
"node_id": "python-6-189"
}
},
{
"池化、步长和填充操作": {
"keywords": [],
"children": [],
"node_id": "python-6-190"
}
}
],
"node_id": "python-5-1184"
}
},
{
"TensorFlow中的卷积和池化操作": {
"keywords": [],
"children": [
{
"在TensorFlow中应用池化操作": {
"keywords": [],
"children": [],
"node_id": "python-6-191"
}
},
{
"TensorFlow中的卷积操作": {
"keywords": [],
"children": [],
"node_id": "python-6-192"
}
}
],
"node_id": "python-5-1185"
}
},
{
"训练CNN": {
"keywords": [],
"children": [
{
"初始化权重和偏置": {
"keywords": [],
"children": [],
"node_id": "python-6-193"
}
},
{
"正则化": {
"keywords": [],
"children": [],
"node_id": "python-6-194"
}
},
{
"激活函数": {
"keywords": [],
"children": [],
"node_id": "python-6-195"
}
}
],
"node_id": "python-5-1186"
}
},
{
"模型性能优化": {
"keywords": [],
"children": [
{
"隐含层数量": {
"keywords": [],
"children": [],
"node_id": "python-6-196"
}
},
{
"每个隐含层的神经元个数": {
"keywords": [],
"children": [],
"node_id": "python-6-197"
}
},
{
"批标准化": {
"keywords": [],
"children": [],
"node_id": "python-6-198"
}
},
{
"高级正则化及过拟合的避免": {
"keywords": [],
"children": [],
"node_id": "python-6-199"
}
},
{
"运用哪个优化器": {
"keywords": [],
"children": [],
"node_id": "python-6-200"
}
},
{
"内存调优": {
"keywords": [],
"children": [],
"node_id": "python-6-201"
}
},
{
"层的位置调优": {
"keywords": [],
"children": [],
"node_id": "python-6-202"
}
},
{
"综合所有操作创建第二个CNN": {
"keywords": [],
"children": [],
"node_id": "python-6-203"
}
},
{
"数据集描述和预处理": {
"keywords": [],
"children": [],
"node_id": "python-6-204"
}
},
{
"创建CNN模型": {
"keywords": [],
"children": [],
"node_id": "python-6-205"
}
}
],
"node_id": "python-5-1187"
}
}
],
"node_id": "python-4-1344"
}
},
{
"经典的CNN模型架构": {
"keywords": [],
"children": [
{
"ImageNet介绍": {
"keywords": [],
"children": [],
"node_id": "python-5-1188"
}
},
{
"AlexNet架构": {
"keywords": [],
"children": [],
"node_id": "python-5-1189"
}
},
{
"VGGNet架构": {
"keywords": [],
"children": [],
"node_id": "python-5-1190"
}
},
{
"GoogLeNet架构": {
"keywords": [],
"children": [
{
"架构洞察": {
"keywords": [],
"children": [],
"node_id": "python-6-206"
}
},
{
"inception模块": {
"keywords": [],
"children": [],
"node_id": "python-6-207"
}
}
],
"node_id": "python-5-1191"
}
},
{
"ResNet架构": {
"keywords": [],
"children": [],
"node_id": "python-5-1192"
}
}
],
"node_id": "python-4-1345"
}
},
{
"转移学习": {
"keywords": [],
"children": [
{
"特征提取方法": {
"keywords": [],
"children": [
{
"目标数据集较小且与原始训练集相似": {
"keywords": [],
"children": [],
"node_id": "python-6-208"
}
},
{
"目标数据集较小且与原始训练集不同": {
"keywords": [],
"children": [],
"node_id": "python-6-209"
}
},
{
"目标数据集很大且与原始训练集相似": {
"keywords": [],
"children": [],
"node_id": "python-6-210"
}
},
{
"目标数据集很大且与原始训练集不同": {
"keywords": [],
"children": [],
"node_id": "python-6-211"
}
}
],
"node_id": "python-5-1193"
}
},
{
"转移学习示例": {
"keywords": [],
"children": [],
"node_id": "python-5-1194"
}
},
{
"多任务学习": {
"keywords": [],
"children": [],
"node_id": "python-5-1195"
}
}
],
"node_id": "python-4-1346"
}
},
{
"CNN自编码器": {
"keywords": [],
"children": [
{
"自编码器介绍": {
"keywords": [],
"children": [],
"node_id": "python-5-1196"
}
},
{
"卷积自编码器": {
"keywords": [],
"children": [],
"node_id": "python-5-1197"
}
},
{
"应用": {
"keywords": [],
"children": [],
"node_id": "python-5-1198"
}
}
],
"node_id": "python-4-1347"
}
},
{
"GAN:使用CNN生成新图像": {
"keywords": [],
"children": [
{
"Pix2pix:基于GAN的图像翻译": {
"keywords": [],
"children": [
{
"CycleGAN": {
"keywords": [],
"children": [],
"node_id": "python-6-212"
}
},
{
"训练GAN模型": {
"keywords": [],
"children": [],
"node_id": "python-6-213"
}
}
],
"node_id": "python-5-1199"
}
},
{
"GAN的代码示例": {
"keywords": [],
"children": [
{
"计算损失": {
"keywords": [],
"children": [],
"node_id": "python-6-214"
}
},
{
"半监督学习和GAN": {
"keywords": [],
"children": [],
"node_id": "python-6-215"
}
}
],
"node_id": "python-5-1200"
}
},
{
"特征匹配": {
"keywords": [],
"children": [
{
"基于半监督分类的GAN示例": {
"keywords": [],
"children": [],
"node_id": "python-6-216"
}
},
{
"深度卷积GAN": {
"keywords": [],
"children": [],
"node_id": "python-6-217"
}
}
],
"node_id": "python-5-1201"
}
}
],
"node_id": "python-4-1348"
}
},
{
"CNN和视觉模型的注意力机制": {
"keywords": [],
"children": [
{
"图像描述中的注意力机制": {
"keywords": [],
"children": [],
"node_id": "python-5-1202"
}
},
{
"注意力类型": {
"keywords": [],
"children": [
{
"硬注意力": {
"keywords": [],
"children": [],
"node_id": "python-6-218"
}
},
{
"软注意力": {
"keywords": [],
"children": [],
"node_id": "python-6-219"
}
}
],
"node_id": "python-5-1203"
}
},
{
"运用注意力改善视觉模型": {
"keywords": [],
"children": [
{
"视觉CNN模型次优性能的原因": {
"keywords": [],
"children": [],
"node_id": "python-6-220"
}
},
{
"循环视觉注意力模型": {
"keywords": [],
"children": [],
"node_id": "python-6-221"
}
}
],
"node_id": "python-5-1204"
}
},
{
"参考文献": {
"keywords": [],
"children": [],
"node_id": "python-5-1205"
}
}
],
"node_id": "python-4-1349"
}
}
],
"node_id": "python-3-247"
}
\ No newline at end of file
{
"source": "cv.py",
"depends": [],
"exercise_id": 126,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:滤镜2
# 描述:迷你滤镜 PS 版本2
import numpy as np
import cv2
from scipy import misc, ndimage, signal
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
def plot_two(left, right):
fig = plt.figure()
ax1 = fig.add_subplot(121)
ax2 = fig.add_subplot(122)
ax1.imshow(left)
ax2.imshow(right)
plt.show()
def cv_2d_conv_lower_pass_filer(img_src):
# prepare the 5x5 shaped filter
kernel = np.array([[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1]])
kernel = kernel/sum(kernel)
# filter the source image
img_rst = cv2.filter2D(img_src, -1, kernel)
return img_rst
def cv_2d_conv_high_pass_filter(img_src):
# edge detection filter
kernel = np.array([[0.0, -1.0, 0.0],
[-1.0, 4.0, -1.0],
[0.0, -1.0, 0.0]])
kernel = kernel/(np.sum(kernel) if np.sum(kernel) != 0 else 1)
# filter the source image
img_rst = cv2.filter2D(img_src, -1, kernel)
return img_rst
def cv_2d_conv_customer_filter(img_src):
# edge detection filter
kernel = np.array([[-1.0, -1.0],
[2.0, 2.0],
[-1.0, -1.0]])
kernel = kernel/(np.sum(kernel) if np.sum(kernel) != 0 else 1)
# filter the source image
img_rst = cv2.filter2D(img_src, -1, kernel)
return img_rst
def select_filter(image):
print(image.shape)
filters = [
{
'option': 'lcov',
'name': '2维卷积低通滤镜( filter2D )',
'filter': lambda: cv_2d_conv_lower_pass_filer(image)
},
{
'option': 'hcov',
'name': '2维卷积高通滤镜( filter2D )',
'filter': lambda: cv_2d_conv_high_pass_filter(image)
},
{
'option': 'ccov',
'name': '2维卷积自定义滤镜( filter2D )',
'filter': lambda: cv_2d_conv_customer_filter(image)
},
]
print("本迷你PS软件支持以下滤镜:")
filter_dict = {}
for filter in filters:
filter_dict[filter['option']] = filter
print("* {} : {}".format(filter['option'], filter['name']))
options = '/'.join(list(map(lambda f: f['option'], filters)))
while True:
ret = input(f"请选择滤镜[ {options}]:")
filter = filter_dict.get(ret)
if filter is None:
print("不支持的选项,请重新选择。")
else:
return filter['filter']()
if __name__ == '__main__':
image = misc.face()
blurred = select_filter(image)
plot_two(image, blurred)
{
"export": [
"tfidf.json",
"word_2_vec.json"
],
"keywords": [],
"children": [
{
"自然语言处理概览": {
"keywords": [],
"children": [
{
"自然语言处理的基本概念": {
"keywords": [],
"children": [],
"node_id": "python-5-1206"
}
},
{
"自然语言处理的面临困难": {
"keywords": [],
"children": [],
"node_id": "python-5-1207"
}
},
{
"自然语言处理的研究现状": {
"keywords": [],
"children": [],
"node_id": "python-5-1208"
}
}
],
"node_id": "python-4-1350"
}
},
{
"预备知识": {
"keywords": [],
"children": [
{
"概率论基础知识": {
"keywords": [],
"children": [],
"node_id": "python-5-1209"
}
},
{
"最大似然估计": {
"keywords": [],
"children": [],
"node_id": "python-5-1210"
}
},
{
"隐马尔可夫模型": {
"keywords": [],
"children": [],
"node_id": "python-5-1211"
}
},
{
"贝叶斯网络": {
"keywords": [],
"children": [],
"node_id": "python-5-1212"
}
},
{
"条件概率分布": {
"keywords": [],
"children": [],
"node_id": "python-5-1213"
}
},
{
"信息论基础知识": {
"keywords": [],
"children": [],
"node_id": "python-5-1214"
}
},
{
"熵": {
"keywords": [],
"children": [],
"node_id": "python-5-1215"
}
},
{
"困惑度": {
"keywords": [],
"children": [],
"node_id": "python-5-1216"
}
},
{
"互信息": {
"keywords": [],
"children": [],
"node_id": "python-5-1217"
}
},
{
"神经网络基础知识": {
"keywords": [],
"children": [],
"node_id": "python-5-1218"
}
},
{
"CRF": {
"keywords": [],
"children": [],
"node_id": "python-5-1219"
}
},
{
"BiLSTM+Attention": {
"keywords": [],
"children": [],
"node_id": "python-5-1220"
}
},
{
"迁移学习": {
"keywords": [],
"children": [],
"node_id": "python-5-1221"
}
},
{
"常用语料库和知识库": {
"keywords": [],
"children": [],
"node_id": "python-5-1222"
}
}
],
"node_id": "python-4-1351"
}
},
{
"jieba": {
"keywords": [],
"children": [
{
"jieba概述": {
"keywords": [],
"children": [],
"node_id": "python-5-1223"
}
},
{
"jieba分词": {
"keywords": [],
"children": [],
"node_id": "python-5-1224"
}
},
{
"jieba添加自定义词典": {
"keywords": [],
"children": [],
"node_id": "python-5-1225"
}
},
{
"jieba词性标注": {
"keywords": [],
"children": [],
"node_id": "python-5-1226"
}
},
{
"jieba关键词抽取": {
"keywords": [],
"children": [],
"node_id": "python-5-1227"
}
}
],
"node_id": "python-4-1352"
}
},
{
"nltk": {
"keywords": [],
"children": [
{
"nltk概述": {
"keywords": [],
"children": [],
"node_id": "python-5-1228"
}
},
{
"nltk字符串处理": {
"keywords": [],
"children": [],
"node_id": "python-5-1229"
}
},
{
"nltk词性标注": {
"keywords": [],
"children": [],
"node_id": "python-5-1230"
}
},
{
"nltk词干提取": {
"keywords": [],
"children": [],
"node_id": "python-5-1231"
}
},
{
"nltk命名实体识别": {
"keywords": [],
"children": [],
"node_id": "python-5-1232"
}
},
{
"nltk分块处理": {
"keywords": [],
"children": [],
"node_id": "python-5-1233"
}
},
{
"nltk文本分类": {
"keywords": [],
"children": [],
"node_id": "python-5-1234"
}
},
{
"nltk情感分析": {
"keywords": [],
"children": [],
"node_id": "python-5-1235"
}
}
],
"node_id": "python-4-1353"
}
},
{
"Genism": {
"keywords": [],
"children": [
{
"TF-IDF": {
"keywords": [],
"children": [],
"node_id": "python-5-1236"
}
},
{
"similarities": {
"keywords": [],
"children": [],
"node_id": "python-5-1237"
}
},
{
"LSA": {
"keywords": [],
"children": [],
"node_id": "python-5-1238"
}
},
{
"LDA": {
"keywords": [],
"children": [],
"node_id": "python-5-1239"
}
},
{
"Word2vec": {
"keywords": [],
"children": [],
"node_id": "python-5-1240"
}
}
],
"node_id": "python-4-1354"
}
},
{
"词法分析": {
"keywords": [],
"children": [
{
"分词(英文分词/中文分词)": {
"keywords": [],
"children": [],
"node_id": "python-5-1241"
}
},
{
"词干提取": {
"keywords": [],
"children": [],
"node_id": "python-5-1242"
}
},
{
"词形还原": {
"keywords": [],
"children": [],
"node_id": "python-5-1243"
}
},
{
"词性标注": {
"keywords": [],
"children": [],
"node_id": "python-5-1244"
}
},
{
"命名实体识别": {
"keywords": [],
"children": [],
"node_id": "python-5-1245"
}
}
],
"node_id": "python-4-1355"
}
},
{
"句法分析": {
"keywords": [],
"children": [
{
"短语结构分析": {
"keywords": [],
"children": [],
"node_id": "python-5-1246"
}
},
{
"依存句法分析": {
"keywords": [],
"children": [],
"node_id": "python-5-1247"
}
}
],
"node_id": "python-4-1356"
}
},
{
"语义分析": {
"keywords": [],
"children": [
{
"命名实体消歧": {
"keywords": [],
"children": [],
"node_id": "python-5-1248"
}
},
{
"指代消解": {
"keywords": [],
"children": [],
"node_id": "python-5-1249"
}
},
{
"语义角色标注": {
"keywords": [],
"children": [],
"node_id": "python-5-1250"
}
},
{
"语义关系抽取": {
"keywords": [],
"children": [],
"node_id": "python-5-1251"
}
},
{
"语义依存分析": {
"keywords": [],
"children": [],
"node_id": "python-5-1252"
}
},
{
"抽象语义表示": {
"keywords": [],
"children": [],
"node_id": "python-5-1253"
}
}
],
"node_id": "python-4-1357"
}
},
{
"词嵌入": {
"keywords": [],
"children": [
{
"Word2Vec": {
"keywords": [],
"children": [],
"node_id": "python-5-1254"
}
},
{
"GloVe": {
"keywords": [],
"children": [],
"node_id": "python-5-1255"
}
},
{
"fastText": {
"keywords": [],
"children": [],
"node_id": "python-5-1256"
}
},
{
"ELMo": {
"keywords": [],
"children": [],
"node_id": "python-5-1257"
}
},
{
"BERT": {
"keywords": [],
"children": [],
"node_id": "python-5-1258"
}
},
{
"XLNet": {
"keywords": [],
"children": [],
"node_id": "python-5-1259"
}
}
],
"node_id": "python-4-1358"
}
},
{
"文本挖掘": {
"keywords": [],
"children": [
{
"文本相似度计算": {
"keywords": [],
"children": [],
"node_id": "python-5-1260"
}
},
{
"文本聚类": {
"keywords": [],
"children": [],
"node_id": "python-5-1261"
}
},
{
"文本分类": {
"keywords": [],
"children": [],
"node_id": "python-5-1262"
}
},
{
"文本摘要": {
"keywords": [],
"children": [],
"node_id": "python-5-1263"
}
}
],
"node_id": "python-4-1359"
}
},
{
"情感分析": {
"keywords": [],
"children": [
{
"基于情感词典的情感分析": {
"keywords": [],
"children": [],
"node_id": "python-5-1264"
}
},
{
"基于深度学习的情感分析": {
"keywords": [],
"children": [],
"node_id": "python-5-1265"
}
}
],
"node_id": "python-4-1360"
}
},
{
"主题模型": {
"keywords": [],
"children": [
{
"LSA": {
"keywords": [],
"children": [],
"node_id": "python-5-1266"
}
},
{
"LDA": {
"keywords": [],
"children": [],
"node_id": "python-5-1267"
}
}
],
"node_id": "python-4-1361"
}
},
{
"机器翻译": {
"keywords": [],
"children": [
{
"IBM统计翻译模型": {
"keywords": [],
"children": [],
"node_id": "python-5-1268"
}
},
{
"短语抽取": {
"keywords": [],
"children": [],
"node_id": "python-5-1269"
}
},
{
"语言模型": {
"keywords": [],
"children": [],
"node_id": "python-5-1270"
}
},
{
"GNMT": {
"keywords": [],
"children": [],
"node_id": "python-5-1271"
}
},
{
"Seq2Seq": {
"keywords": [],
"children": [],
"node_id": "python-5-1272"
}
},
{
"Transformer": {
"keywords": [],
"children": [],
"node_id": "python-5-1273"
}
}
],
"node_id": "python-4-1362"
}
},
{
"语言模型": {
"keywords": [],
"children": [
{
"n-gram": {
"keywords": [],
"children": [],
"node_id": "python-5-1274"
}
},
{
"Pitman-Yor过程模型": {
"keywords": [],
"children": [],
"node_id": "python-5-1275"
}
},
{
"AWD-LSTM": {
"keywords": [],
"children": [],
"node_id": "python-5-1276"
}
},
{
"Transformer-XL": {
"keywords": [],
"children": [],
"node_id": "python-5-1277"
}
},
{
"Gated CNN": {
"keywords": [],
"children": [],
"node_id": "python-5-1278"
}
}
],
"node_id": "python-4-1363"
}
},
{
"智能问答": {
"keywords": [],
"children": [
{
"基于知识的问答": {
"keywords": [],
"children": [],
"node_id": "python-5-1279"
}
},
{
"基于检索的问答": {
"keywords": [],
"children": [],
"node_id": "python-5-1280"
}
},
{
"阅读理解": {
"keywords": [],
"children": [],
"node_id": "python-5-1281"
}
},
{
"完形填空": {
"keywords": [],
"children": [],
"node_id": "python-5-1282"
}
}
],
"node_id": "python-4-1364"
}
},
{
"智能对话": {
"keywords": [],
"children": [
{
"对话行为分类": {
"keywords": [],
"children": [],
"node_id": "python-5-1283"
}
},
{
"对话状态跟踪": {
"keywords": [],
"children": [],
"node_id": "python-5-1284"
}
},
{
"检索式聊天机器人": {
"keywords": [],
"children": [],
"node_id": "python-5-1285"
}
},
{
"生成式聊天机器人": {
"keywords": [],
"children": [],
"node_id": "python-5-1286"
}
},
{
"意图识别": {
"keywords": [],
"children": [],
"node_id": "python-5-1287"
}
},
{
"槽填充(Slot Filling)": {
"keywords": [],
"children": [],
"node_id": "python-5-1288"
}
}
],
"node_id": "python-4-1365"
}
},
{
"语音识别": {
"keywords": [],
"children": [
{
"傅里叶变换": {
"keywords": [],
"children": [],
"node_id": "python-5-1289"
}
},
{
"声学模型": {
"keywords": [],
"children": [],
"node_id": "python-5-1290"
}
},
{
"隐马尔可夫模型": {
"keywords": [],
"children": [],
"node_id": "python-5-1291"
}
},
{
"CNN": {
"keywords": [],
"children": [],
"node_id": "python-5-1292"
}
},
{
"LSTM-HMM": {
"keywords": [],
"children": [],
"node_id": "python-5-1293"
}
},
{
"神经网络语言模型": {
"keywords": [],
"children": [],
"node_id": "python-5-1294"
}
},
{
"MFCC": {
"keywords": [],
"children": [],
"node_id": "python-5-1295"
}
}
],
"node_id": "python-4-1366"
}
},
{
"知识图谱": {
"keywords": [],
"children": [
{
"知识图谱构建": {
"keywords": [],
"children": [],
"node_id": "python-5-1296"
}
},
{
"知识计算": {
"keywords": [],
"children": [],
"node_id": "python-5-1297"
}
},
{
"知识存储": {
"keywords": [],
"children": [],
"node_id": "python-5-1298"
}
},
{
"知识服务与应用": {
"keywords": [],
"children": [],
"node_id": "python-5-1299"
}
}
],
"node_id": "python-4-1367"
}
}
],
"node_id": "python-3-248"
}
\ No newline at end of file
{
"source": "tfidf.py",
"depends": [],
"exercise_id": 131,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:相似匹配1
# 描述:简单的 TF-IDF 的相似匹配
import jieba
import numpy as np
import os
import jieba
import numpy as np
import joblib
import json
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
class Dataset:
def __init__(self, dataset_file) -> None:
self.dataset_file = dataset_file
self.train_sentences = None
self.test_sentences = None
def generate(self):
return [
'今天 天气 很 好',
'今天很 好',
'今天 天气 很 好',
'今天 天气 很 好',
'今天 天',
'今天 天气 很 好',
'今天 天气 很 好',
'今天 天气 很 好',
'今天 天气 很 好',
'今天 天',
'今天 天气 很 好',
'气 很 好',
'今天 天气 很 差',
'不错',
'还行'
]
def load(self):
if os.path.exists(self.dataset_file):
with open(self.dataset_file, 'r') as f:
ret = json.loads(f.read())
self.train_sentences = ret['train']
self.test_sentences = ret['test']
else:
sentences = self.generate()
with open(self.dataset_file, 'w') as f:
cut = len(sentences)-5
ret = {
'train': sentences[:cut],
'test': sentences[cut:],
}
f.write(json.dumps(ret))
class TFIDFSimilar:
def __init__(self, tfidf_vectorizer=None, tfidf_matrix=None) -> None:
self.tfidf_vectorizer = tfidf_vectorizer
self.tfidf_matrix = tfidf_matrix
def __train_model(self, sentences):
for s in sentences:
if s.strip() != '':
vec = [" ".join(jieba.cut(str(s), cut_all=False))]
self.tfidf_vectorizer = TfidfVectorizer()
self.tfidf_matrix = self.tfidf_vectorizer.fit_transform(vec)
@staticmethod
def load_model(model_file):
model_obj = joblib.load(model_file)
return TFIDFSimilar(model_obj['vec'], model_obj['matrix'])
def save(self, model_file):
model_obj = {
'vec': self.tfidf_vectorizer,
'matrix': self.tfidf_matrix
}
joblib.dump(model_obj, model_file)
def fit(self, sentences):
self.__train_model(sentences)
def predict(self, sentence, topk):
v = ' '.join(jieba.cut(sentence, cut_all=False))
v_q = self.tfidf_vectorizer.transform([v])
cosine_similarities = cosine_similarity(
v_q, self.tfidf_matrix).flatten()
extend_top_k = min(3*topk, len(cosine_similarities))
topk_idx = cosine_similarities.argsort()[:-extend_top_k-1:-1]
return topk_idx
if __name__ == "__main__":
# 准备数据集
dataset_file = '/tmp/nlp_tfidf.dataset'
dataset = Dataset(dataset_file)
dataset.load()
# 训练模型
model_file = '/tmp/nlp_tfidf.model'
if os.path.exists(model_file):
model = TFIDFSimilar.load_model(model_file)
else:
print(dataset.train_sentences)
model = TFIDFSimilar()
model.fit(dataset.train_sentences)
model.save(model_file)
# 预测
print("目标句子:", dataset.test_sentences[1])
topk = 2
topk_idx = model.predict(dataset.test_sentences[2], topk)
for idx in topk_idx:
print(dataset.train_sentences[idx])
{
"source": "word_2_vec.py",
"depends": [],
"exercise_id": 130,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:相似匹配2
# 描述:Word2Vec 词向量化,查询相近词
import os
import json
import jieba
from gensim.models import word2vec
class Dataset:
def __init__(self, dataset_file) -> None:
self.dataset_file = dataset_file
self.train_sentences = None
self.test_sentences = None
def generate(self):
input = [
'今天 天气 很 好',
'今天很 好',
'今天 天气 很 好',
'今天 天气 很 好',
'今天 天',
'今天 天气 很 好',
'今天 天气 很 好',
'今天 天气 很 好',
'今天 天气 很 好',
'今天 天',
'今天 天气 很 好',
'气 很 好',
'今天 天气 很 差',
'不错',
'还行'
]
sentences = []
for s in input:
sentences.append(Dataset.cut_sentence(s))
return sentences
@staticmethod
def cut_sentence(s):
return [s for s in list(jieba.cut(str(s), cut_all=True)) if s.strip() != '']
def load(self):
if os.path.exists(self.dataset_file):
with open(self.dataset_file, 'r') as f:
ret = json.loads(f.read())
self.train_sentences = ret['train']
self.test_sentences = ret['test']
else:
sentences = self.generate()
with open(self.dataset_file, 'w') as f:
cut = len(sentences)-5
ret = {
'train': sentences[:cut],
'test': sentences[cut:],
}
self.train_sentences = ret['train']
self.test_sentences = ret['test']
f.write(json.dumps(ret))
class Word2VecSimilar:
def __init__(self, model=None) -> None:
self.model = model
def fit(self, train_sentences):
model = word2vec.Word2Vec(
train_sentences,
workers=2,
size=300,
min_count=1,
window=5,
sample=1e-3
)
model.init_sims(replace=True)
self.model = model
def predict(self, sentence):
print('=>', sentence)
more_sentences = Dataset.cut_sentence(sentence)
print(more_sentences)
self.model.train(
more_sentences,
total_examples=self.model.corpus_count,
epochs=self.model.iter,
)
try:
ret = self.model.wv.most_similar(more_sentences[0], topn=3)
return ret
except:
return None
def save(self, model_file):
self.model.save(model_file)
@staticmethod
def load_model(model_file):
model = word2vec.Word2Vec.load(model_file)
return Word2VecSimilar(model)
if __name__ == '__main__':
# 准备数据集
dataset_file = '/tmp/nlp_word2vec.dataset'
dataset = Dataset(dataset_file)
dataset.load()
# 训练模型
model_file = '/tmp/nlp_word2vec.model'
if os.path.exists(model_file):
model = Word2VecSimilar.load_model(model_file)
else:
model = Word2VecSimilar()
model.fit(dataset.train_sentences)
model.save(model_file)
# 预测
for s in dataset.test_sentences:
for w in s:
print(w)
ret = model.predict(w)
if ret:
print(ret)
{
"export": [
"linear_egression_by_np.json",
"kmeans.json"
],
"keywords": [],
"children": [
{
"使用Python实现降维": {
"keywords": [],
"children": [
{
"相关性分析": {
"keywords": [],
"children": [],
"node_id": "python-5-1316"
}
}
],
"node_id": "python-4-1385"
}
},
{
"使用Python进行分类": {
"keywords": [],
"children": [],
"node_id": "python-4-1386"
}
},
{
"决策树": {
"keywords": [],
"children": [
{
"哪个属性优先": {
"keywords": [],
"children": [],
"node_id": "python-5-1317"
}
},
{
"随机森林分类器": {
"keywords": [],
"children": [],
"node_id": "python-5-1318"
}
}
],
"node_id": "python-4-1387"
}
},
{
"朴素贝叶斯分类器": {
"keywords": [],
"children": [],
"node_id": "python-4-1388"
}
},
{
"支持向量机": {
"keywords": [],
"children": [],
"node_id": "python-4-1389"
}
},
{
"最近邻分类器": {
"keywords": [],
"children": [],
"node_id": "python-4-1390"
}
},
{
"情绪分析": {
"keywords": [],
"children": [],
"node_id": "python-4-1391"
}
},
{
"图像识别": {
"keywords": [],
"children": [],
"node_id": "python-4-1392"
}
},
{
"使用Python进行回归": {
"keywords": [],
"children": [
{
"最小二乘估计": {
"keywords": [],
"children": [],
"node_id": "python-5-1319"
}
}
],
"node_id": "python-4-1393"
}
},
{
"分类和回归": {
"keywords": [],
"children": [],
"node_id": "python-4-1394"
}
},
{
"使模型高估或低估": {
"keywords": [],
"children": [],
"node_id": "python-4-1395"
}
},
{
"处理分类型数据": {
"keywords": [],
"children": [],
"node_id": "python-4-1396"
}
}
],
"node_id": "python-3-251"
}
\ No newline at end of file
{
"source": "kmeans.py",
"depends": [],
"exercise_id": 128,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:SK-Learn HelloWorld
# 描述:使用 TF-IDF+Kmeans 对文本聚类
from sklearn.cluster import KMeans
from sklearn.feature_extraction.text import TfidfTransformer, TfidfVectorizer
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
import random
def plot_result(data, cluster_res, cluster_num, algorithm='None'):
nPoints = len(data)
scatter_colors = ['blue', 'green', 'yellow',
'red', 'purple', 'orange', 'brown']
for i in range(cluster_num):
color = scatter_colors[i % len(scatter_colors)]
x1 = []
y1 = []
for j in range(nPoints):
if cluster_res[j] == i:
x1.append(data[j, 0])
y1.append(data[j, 1])
plt.scatter(x1, y1, c=color, alpha=1, marker='o')
plt.plot(marksize=10)
plt.savefig('/tmp/' + algorithm + '-' +
str(random.randint(10, 100)) + str(cluster_num) + '.png')
plt.show()
def kmeans(sentences, num_of_class):
# tfidf 向量化
vertorizer = TfidfVectorizer(sublinear_tf=True, max_df=0.46)
transformer = TfidfTransformer()
freq_words_matrix = vertorizer.fit_transform(sentences)
# 获取词袋
words = vertorizer.get_feature_names()
tfidf = transformer.fit_transform(freq_words_matrix)
weight = freq_words_matrix.toarray()
trainingData = weight
# K-Means 聚类
clf = KMeans(
n_clusters=num_of_class,
max_iter=10000,
init="k-means++",
tol=1e-6
)
result = clf.fit(trainingData)
source = list(clf.predict(trainingData))
labels = clf.labels_
# # 显示聚类结果
plot_result(trainingData, source, num_of_class)
if __name__ == "__main__":
sentences = [
'今天 天气 很 好',
'今天很 好',
'今天 天气 很 好',
'今天 天气 很 好',
'今天 天',
'今天 天气 很 好',
'今天 天气 很 好',
'今天 天气 很 好',
'今天 天气 很 好',
'今天 天',
'今天 天气 很 好',
'气 很 好',
'今天 天气 很 差',
'不错',
'还行'
]
kmeans(sentences, 3)
{
"source": "linear_egression_by_np.py",
"depends": [],
"exercise_id": 127,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:线性回归
# 描述:使用 numpy 手工实现线性回归,迷你数据集、迷你模型,同时考虑工程细节
import os
import joblib
import numpy as np
class Dataset:
def __init__(self, data=None) -> None:
self.x_train = None
self.y_train = None
self.x_test = None
self.y_test = None
if data:
self.x_train = data['x_train']
self.y_train = data['y_train']
self.x_test = data['x_test']
self.y_test = data['y_test']
@staticmethod
def load_data(dataset_file):
data = joblib.load(dataset_file)
return Dataset(data)
def generate(self):
x = np.random.rand(100, 1)
y = 3 + 6 * x + .1 * np.random.randn(100, 1)
# split
order = np.random.permutation(len(x))
portion = 20
x_train, y_train = x[order[portion:]], y[order[portion:]]
x_test, y_test = x[order[:portion]], y[order[:portion]]
self.data = {
'x_train': x_train,
'y_train': y_train,
'x_test': x_test,
'y_test': y_test
}
def save(self, dataset_file):
joblib.dump(self.data, dataset_file)
class Model:
def __init__(self, w0=None, w1=None) -> None:
self.w0 = w0
self.w1 = w1
def fit(self, x_train, y_train, epoch_count=100):
np.random.seed(42)
w0 = np.random.randn(1)
w1 = np.random.randn(1)
learning_rate = 1e-1
for epoch in range(epoch_count):
y_new = w0 + w1 * x_train
error = (y_train - y_new)
w1_grad = -2 * error.mean()
w2_grad = -2 * (x_train * error).mean()
w0 -= learning_rate * w1_grad
w1 -= learning_rate * w2_grad
self.w0 = w0
self.w1 = w1
def predict(self, x):
return self.w0+self.w1*x
def save(self, model_file):
joblib.dump({"w0": self.w0, "w1": self.w1}, model_file)
@staticmethod
def load_model(model_file):
model_obj = joblib.load(model_file)
return Model(model_obj['w0'], model_obj['w1'])
if __name__ == "__main__":
# load dataset
dataset_file = '/tmp/np_linear_regression.dataset'
if os.path.exists(dataset_file):
dataset = Dataset.load_data(dataset_file)
else:
dataset = Dataset()
dataset.generate()
dataset.save(dataset_file)
# load model
model_file = '/tmp/np_linear_regression.model'
if os.path.exists(model_file):
print(model_file)
model = Model.load_model(model_file)
else:
model = Model()
model.fit(dataset.x_train, dataset.y_train)
model.save(model_file)
# predict
y_predict = model.predict(dataset.x_test)
# compare
print(y_predict)
print(dataset.y_test)
{
"export": [
"knn.json"
],
"keywords": [],
"children": [
{
"K均值聚类": {
"keywords": [],
"children": [],
"node_id": "python-4-1397"
}
},
{
"选择K—肘部法则": {
"keywords": [],
"children": [],
"node_id": "python-4-1398"
}
},
{
"距离或相似性度量": {
"keywords": [],
"children": [
{
"属性": {
"keywords": [],
"children": [],
"node_id": "python-5-1320"
}
},
{
"一般及欧氏距离": {
"keywords": [],
"children": [],
"node_id": "python-5-1321"
}
},
{
"平方欧氏距离": {
"keywords": [],
"children": [],
"node_id": "python-5-1322"
}
},
{
"字符串之间的编辑距离": {
"keywords": [],
"children": [],
"node_id": "python-5-1323"
}
}
],
"node_id": "python-4-1399"
}
},
{
"文档上下文的相似性": {
"keywords": [],
"children": [],
"node_id": "python-4-1400"
}
},
{
"如何判断聚类结果是否良好": {
"keywords": [],
"children": [],
"node_id": "python-4-1401"
}
}
],
"node_id": "python-3-252"
}
\ No newline at end of file
{
"source": "knn.py",
"depends": [],
"exercise_id": 129,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙,VegetableBirdNLPer
# 标题:无监督聚类
# 描述:KNN 聚类,近朱者赤,近墨者黑
import numpy as np
import matplotlib.pyplot as plt
from sklearn.neighbors import KNeighborsClassifier
def generate_data(class1_num, class2_num):
np.random.seed(2021)
data_size_1 = class1_num
x1_1 = np.random.normal(loc=2, scale=1.0, size=data_size_1)
x2_1 = np.random.normal(loc=3, scale=1.0, size=data_size_1)
y_1 = [0 for _ in range(data_size_1)]
data_size_2 = class2_num
x1_2 = np.random.normal(loc=6, scale=2.0, size=data_size_2)
x2_2 = np.random.normal(loc=8, scale=2.0, size=data_size_2)
y_2 = [1 for _ in range(data_size_2)]
x1 = np.concatenate((x1_1, x1_2), axis=0)
x2 = np.concatenate((x2_1, x2_2), axis=0)
x = np.hstack((x1.reshape(-1,1), x2.reshape(-1,1)))
y = np.concatenate((y_1, y_2), axis=0)
data_size_all = data_size_1+data_size_2
shuffled_index = np.random.permutation(data_size_all)
x = x[shuffled_index]
y = y[shuffled_index]
split_index = int(data_size_all*0.7)
x_train = x[:split_index]
y_train = y[:split_index]
x_test = x[split_index:]
y_test = y[split_index:]
return x_train, y_train, x_test, y_test
def show_data(x_train, y_train, x_test, y_test):
plt.scatter(x_train[:,0], x_train[:,1], c=y_train, marker='.')
plt.show()
plt.scatter(x_test[:,0], x_test[:,1], c=y_test, marker='.')
plt.show()
def train_and_predict(is_show = False):
x_train, y_train, x_test, y_test = generate_data(300, 500)
if is_show:
show_data(x_train, y_train, x_test, y_test)
neigh = KNeighborsClassifier(n_neighbors=2)
neigh.fit(x_train, y_train)
acc_count = 0
for idx, x_test_ in enumerate(x_test):
res = neigh.predict(x_test_.reshape(1,-1))
if res[0] == y_test[idx]:
acc_count += 1
acc = acc_count / len(x_test)
print('准确率为: {}'.format(acc))
if __name__ == '__main__':
train_and_predict()
{
"node_id": "python-2-15",
"keywords": []
}
\ No newline at end of file
{
"export": [
"filter.json",
"map.json",
"reduce.json",
"zip.json",
"decorator.json",
"route.json"
],
"keywords": [],
"children": [
{
"参数": {
"keywords": [],
"children": [
{
"规划时的灵活性": {
"keywords": [],
"children": [],
"node_id": "python-5-1412"
}
},
{
"可变位置参数": {
"keywords": [],
"children": [],
"node_id": "python-5-1413"
}
},
{
"可变关键字参数": {
"keywords": [],
"children": [],
"node_id": "python-5-1414"
}
},
{
"组合不同类型的参数": {
"keywords": [],
"children": [],
"node_id": "python-5-1415"
}
},
{
"调用具有可变参数的函数": {
"keywords": [],
"children": [],
"node_id": "python-5-1416"
}
},
{
"传递参数": {
"keywords": [],
"children": [],
"node_id": "python-5-1417"
}
},
{
"自省": {
"keywords": [],
"children": [],
"node_id": "python-5-1418"
}
}
],
"node_id": "python-4-1429"
}
},
{
"装饰器": {
"keywords": [],
"children": [
{
"闭包": {
"keywords": [],
"children": [],
"node_id": "python-5-1419"
}
},
{
"包装器": {
"keywords": [],
"children": [],
"node_id": "python-5-1420"
}
},
{
"带参数的装饰器": {
"keywords": [],
"children": [],
"node_id": "python-5-1421"
}
},
{
"带参数或不带参数的装饰器": {
"keywords": [],
"children": [],
"node_id": "python-5-1422"
}
}
],
"node_id": "python-4-1430"
}
},
{
"函数注解": {
"keywords": [],
"children": [
{
"提取样板": {
"keywords": [],
"children": [],
"node_id": "python-5-1423"
}
},
{
"用装饰器进行注解": {
"keywords": [],
"children": [],
"node_id": "python-5-1424"
}
}
],
"node_id": "python-4-1431"
}
},
{
"生成器": {
"keywords": [],
"children": [],
"node_id": "python-4-1432"
}
},
{
"lambda": {
"keywords": [],
"children": [],
"node_id": "python-4-1433"
}
},
{
"自省": {
"keywords": [],
"children": [
{
"标识对象类型": {
"keywords": [],
"children": [],
"node_id": "python-5-1425"
}
},
{
"模块和软件包": {
"keywords": [],
"children": [],
"node_id": "python-5-1426"
}
},
{
"文档字符串": {
"keywords": [],
"children": [
{
"描述函数的作用": {
"keywords": [],
"children": [],
"node_id": "python-6-222"
}
},
{
"返回值": {
"keywords": [],
"children": [],
"node_id": "python-6-223"
}
},
{
"包含预期的异常": {
"keywords": [],
"children": [],
"node_id": "python-6-224"
}
}
],
"node_id": "python-5-1427"
}
}
],
"node_id": "python-4-1434"
}
}
],
"node_id": "python-3-257"
}
\ No newline at end of file
{
"source": "decorator.py",
"depends": [],
"exercise_id": 189,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:函数式编程
# 描述:高阶函数, 使用 Python 装饰器,实现自动日志记录
from functools import wraps
def auto_log(func):
@wraps(func)
def wrapper(*args, **kwargs):
print(f'函数:{func.__name__}, 参数:{str(args)}, 命名参数:{str(kwargs)}')
return func(*args, **kwargs)
return wrapper
class Test(object):
def __init__(self):
pass
@auto_log
def test(self, a, b, c, d, x=None):
print("test")
if __name__ == '__main__':
t = Test()
c = t.test("你好", "世界", 1, 2, x="xxx")
{
"source": "filter.py",
"depends": [],
"exercise_id": 231,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:函数式编程
# 描述:高阶函数, filter 过滤偶数
def test():
list = [1, 2, 3, 4, 5, 6]
for v in filter(lambda v: v % 2 == 0, list):
print(v)
if __name__ == '__main__':
test()
\ No newline at end of file
{
"source": "map.py",
"depends": [],
"exercise_id": 179,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:函数式编程
# 描述:高阶函数, map 求平方
def test():
list = [1, 2, 3, 4, 5, 6]
for v in map(lambda v: v*v, list):
print(v)
if __name__ == '__main__':
test()
\ No newline at end of file
{
"source": "reduce.py",
"depends": [],
"exercise_id": 216,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:函数式编程
# 描述:高阶函数, reduce 求和,求连乘,手工实现一个正确的 reduce
from functools import reduce
def my_reduce(accumulate, list, init):
total = init
for e in list:
total = accumulate(total, e)
return total
if __name__ == '__main__':
list = [1, 2, 3, 4, 5, 6]
sum = reduce(lambda x, y: x+y, list)
print(sum)
prod = reduce(lambda x, y: x*y, list)
print(prod)
print(my_reduce(lambda x, y: x+y, list, 0))
print(my_reduce(lambda x, y: x*y, list, 1))
{
"source": "route.py",
"depends": [],
"exercise_id": 180,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:函数式编程
# 描述:实现一个路由器,路由器在路由到的节点上执行命令
# 依次输入:
# "a"
# "a.b"
# "a.b.c"
# "a.b.c.d"
#
# 会依次输出:
# "A"
# "A.B"
# "A.B.C"
# "A.B.C.D"
def dispatch(actions, targets):
action_len = len(actions)
index = 0
next = targets
action = actions[index]
while action_len >= index:
if type(next) == type({}):
if index == action_len:
if next.get('run') != None:
next['run']()
break
action = actions[index]
if next.get(action) != None:
next = next[action]
index += 1
else:
index += 1
else:
next()
index += 1
break
def route(input):
# 路由器在路由到的节点上执行命令
dispatch(input.split('.'), {
"a": {
"run": lambda: print("A"),
"b": {
"run": lambda: print("A.B"),
"c": {
"run": lambda: print("A.B.C"),
"d": lambda: print("A.B.C.D"),
}
}
}
})
if __name__ == "__main__":
route("a")
route("a.b")
route("a.b.c")
route("a.b.c.d")
{
"source": "zip.py",
"depends": [],
"exercise_id": 234,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:函数式编程
# 描述:高阶函数, 两个数组分别全排列后再配对,
# 例如:
# * [1,2]的全排列是[[1,2],[2,1]]
# * [3,4]的全排列是[[3,4],[4,3]]
# 配对后是:
# * [([1, 2], [3, 4]), ([2, 1], [4, 3])]
a = [1, 2, 3]
b = [3, 4, 5]
def permutation(s, nums, p, q):
if p == q:
s.append(list(nums))
else:
for i in range(p, q):
nums[i], nums[p] = nums[p], nums[i]
permutation(s, nums, p+1, q)
nums[i], nums[p] = nums[p], nums[i]
if __name__ == '__main__':
all_a = []
permutation(all_a, a, 0, len(a))
all_b = []
permutation(all_b, b, 0, len(b))
z = list(zip(all_a, all_b))
print(z)
{
"export": [
"singleton.json"
],
"keywords": [],
"children": [
{
"继承": {
"keywords": [],
"children": [
{
"多重继承": {
"keywords": [],
"children": [],
"node_id": "python-5-1428"
}
},
{
"方法解析顺序": {
"keywords": [],
"children": [],
"node_id": "python-5-1429"
}
},
{
"使用super函数将控制权传递给其他类": {
"keywords": [],
"children": [],
"node_id": "python-5-1430"
}
},
{
"自省": {
"keywords": [],
"children": [],
"node_id": "python-5-1431"
}
}
],
"node_id": "python-4-1435"
}
},
{
"如何创建类": {
"keywords": [],
"children": [
{
"在运行时创建类": {
"keywords": [],
"children": [],
"node_id": "python-5-1432"
}
},
{
"元类": {
"keywords": [],
"children": [],
"node_id": "python-5-1433"
}
},
{
"控制命名空间": {
"keywords": [],
"children": [],
"node_id": "python-5-1434"
}
}
],
"node_id": "python-4-1436"
}
},
{
"成员变量": {
"keywords": [],
"children": [
{
"属性": {
"keywords": [],
"children": [],
"node_id": "python-5-1435"
}
},
{
"描述器": {
"keywords": [],
"children": [],
"node_id": "python-5-1436"
}
}
],
"node_id": "python-4-1437"
}
},
{
"方法": {
"keywords": [],
"children": [
{
"非绑定方法": {
"keywords": [],
"children": [],
"node_id": "python-5-1437"
}
},
{
"绑定方法": {
"keywords": [],
"children": [],
"node_id": "python-5-1438"
}
}
],
"node_id": "python-4-1438"
}
},
{
"魔术方法": {
"keywords": [],
"children": [
{
"处理成员变量": {
"keywords": [],
"children": [],
"node_id": "python-5-1439"
}
},
{
"字符串表示": {
"keywords": [],
"children": [
{
"字节字符串": {
"keywords": [],
"children": [
{
"借助chr和ord进行简单的转换": {
"keywords": [],
"children": [],
"node_id": "python-7-34"
}
},
{
"借助struct模块进行复杂的转换": {
"keywords": [],
"children": [],
"node_id": "python-7-35"
}
}
],
"node_id": "python-6-225"
}
},
{
"文本": {
"keywords": [],
"children": [
{
"Unicode": {
"keywords": [],
"children": [],
"node_id": "python-7-36"
}
},
{
"编码": {
"keywords": [],
"children": [],
"node_id": "python-7-37"
}
}
],
"node_id": "python-6-226"
}
},
{
"简单的替换": {
"keywords": [],
"children": [],
"node_id": "python-6-227"
}
},
{
"格式化": {
"keywords": [],
"children": [
{
"在对象中查找值": {
"keywords": [],
"children": [],
"node_id": "python-7-38"
}
},
{
"区分字符串类型": {
"keywords": [],
"children": [],
"node_id": "python-7-39"
}
},
{
"标准格式规范": {
"keywords": [],
"children": [],
"node_id": "python-7-40"
}
},
{
"为文本文档制作目录": {
"keywords": [],
"children": [],
"node_id": "python-7-41"
}
},
{
"自定义格式规范": {
"keywords": [],
"children": [],
"node_id": "python-7-42"
}
}
],
"node_id": "python-6-228"
}
}
],
"node_id": "python-5-1440"
}
}
],
"node_id": "python-4-1439"
}
}
],
"node_id": "python-3-258"
}
\ No newline at end of file
{
"source": "singleton.py",
"depends": [],
"exercise_id": 223,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:设计模式
# 描述:单例模式,输出一次“创建”,三次“返回”
import threading
class Singleton(type):
__singleton_lock = threading.Lock()
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
with Singleton.__singleton_lock:
if cls not in cls._instances:
instance = super().__call__(*args, **kwargs)
cls._instances[cls] = instance
print("创建")
print("返回")
return cls._instances[cls]
class SingleClient(metaclass=Singleton):
def __init__(self) -> None:
pass
if __name__ == "__main__":
s = SingleClient()
s = SingleClient()
s = SingleClient()
{
"one_line": {
"async def ": [
"def "
],
"asyncio.wait(tasks)": [
"tasks"
],
"loop.run_until_complete(asyncio.wait(tasks))": [
"asyncio.wait(tasks)"
]
},
"source": "async.py",
"depends": [],
"exercise_id": 193,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 协程
# 描述:async 和 await 语法基本用法,下载图片
import os
import hashlib
import requests
import asyncio
def url_file_name(url):
ext = os.path.splitext(url)[-1]
hash_name = hashlib.md5(url.encode('utf-8')).hexdigest()
return hash_name+ext
async def download_img(img_url):
img_bytes = requests.get(img_url).content
file_name = url_file_name(img_url)
output = f'/tmp/{file_name}'
with open(output, 'wb') as f:
f.write(img_bytes)
print(f'img downloaed at: {output}')
await asyncio.sleep(1)
def test():
urls = [
"https://img-ask.csdnimg.cn/upload/1623844642974.jpg",
"https://img-ask.csdnimg.cn/upload/1623844642974.jpg",
"https://img-mid.csdnimg.cn/release/static/image/mid/ask/754909759626128.jpg",
"https://img-ask.csdn.net/upload/201510/22/1445491909_384819.jpg",
]
tasks = [download_img(url) for url in urls]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
if __name__ == '__main__':
test()
{
"version": "0.0.2",
"export": [
"counter.json",
"lock_counter.json",
"thread_free.json",
"image_download.json",
"thread_executor.json",
"producer_consumer.json",
"async.json",
"multi_process.json"
],
"keywords": [],
"children": [
{
"基础概念": {
"keywords": [],
"children": [],
"node_id": "python-4-763"
}
},
{
"加锁和解锁": {
"keywords": [],
"children": [],
"node_id": "python-4-764"
}
},
{
"threading": {
"keywords": [],
"children": [],
"node_id": "python-4-765"
}
},
{
"multiprocessing": {
"keywords": [],
"children": [],
"node_id": "python-4-766"
}
},
{
"queue": {
"keywords": [],
"children": [],
"node_id": "python-4-767"
}
},
{
"gevent": {
"keywords": [],
"children": [],
"node_id": "python-4-768"
}
}
],
"node_id": "python-3-132"
}
\ No newline at end of file
{
"one_line": {
"ThreadPoolExecutor": [
"ThreadPool"
],
"count += 1": [
"count++"
],
"with ThreadPoolExecutor(max_workers=5) as exe": [
"exe = ThreadPoolExecutor(max_workers=5)"
]
},
"source": "counter.py",
"depends": [],
"exercise_id": 200,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 计数器(1)
# 描述:非线程安全计数器
from concurrent.futures import ThreadPoolExecutor
import time
class Counter:
def __init__(self) -> None:
self.count = 0
def step(self):
count = self.count
count += 1
time.sleep(0.1)
self.count = count
print(f'count: {self.count}')
if __name__ == '__main__':
counter = Counter()
for i in range(0, 5):
counter.step()
assert counter.count == 5
with ThreadPoolExecutor(max_workers=5) as exe:
for i in range(0, 5):
exe.submit(counter.step)
{
"one_line": {
"requests.get(url).content": [
"requests.get(url)"
],
"os.path.splitext(url)[-1]": [
"os.path.splitext(url)[-2]"
],
"with open(output, 'wb')": [
"with open(output, 'r')"
]
},
"source": "image_download.py",
"depends": [],
"exercise_id": 232,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 图片下载
# 描述:下载图片函数,图片url通过hash转成合适的文件名
import os
import hashlib
import requests
def download_img(url):
img_bytes = requests.get(url).content
ext = os.path.splitext(url)[-1]
hash_name = hashlib.md5(url.encode('utf-8')).hexdigest()
file_name = hash_name+ext
output = f'/tmp/{file_name}'
with open(output, 'wb') as f:
f.write(img_bytes)
print('[image] downnload image: {}'.format(output))
if __name__ == '__main__':
urls = [
"https://img-ask.csdnimg.cn/upload/1623844642974.jpg",
"https://img-ask.csdnimg.cn/upload/1623844642974.jpg",
"https://img-mid.csdnimg.cn/release/static/image/mid/ask/754909759626128.jpg",
"https://img-ask.csdn.net/upload/201510/22/1445491909_384819.jpg",
]
for url in urls:
download_img(url)
{
"one_line": {
"lock_counter.count == 5": [
"lock_counter.count == 10"
],
"with self.lock:": [
"if self.lock is not None:"
],
"self.lock = threading.Lock()": [
"self.lock = None"
]
},
"source": "lock_counter.py",
"depends": [],
"exercise_id": 217,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 计数器(2)
# 描述:线程安全计数器
from concurrent.futures import ThreadPoolExecutor
import threading
import time
class LockCounter:
def __init__(self) -> None:
self.count = 0
self.lock = threading.Lock()
def step(self):
with self.lock:
count = self.count
count += 1
time.sleep(0.1)
self.count = count
print(f'lock_counter: {self.count}')
def size(self):
count = 0
with self.lock:
count = self.count
return count
if __name__ == '__main__':
lock_counter = LockCounter()
with ThreadPoolExecutor(max_workers=5) as exe:
for i in range(0, 5):
exe.submit(lock_counter.step)
assert lock_counter.count == 5
{
"one_line": {
"args=(10+i,)": [
"args=(10+i)"
],
"multiprocessing": [
"threading"
],
"Process(target=fact": [
"Process(fact"
],
"p.start()": [
"p.run()"
]
},
"source": "multi_process.py",
"depends": [],
"exercise_id": 218,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 多进程
# 描述:多进程分别计算阶乘
from multiprocessing import Process
def fact(n):
sum = 1
for i in range(0, n):
sum *= (i+1)
print(sum)
if __name__ == '__main__':
process_list = []
for i in range(5):
p = Process(target=fact, args=(10+i,))
p.start()
process_list.append(p)
for i in process_list:
p.join()
{
"one_line": {
"lambda count: count == len(urls)": [
"lambda count: count < len(urls)"
],
"self.pool.submit(self.__consumer)": [
"self.pool.map(self.__consumer)"
],
"if not self.queue.empty()": [
"if self.queue.empty()"
],
"self.event.wait()": [
"self.event.set()"
],
"if self.event.is_set()": [
"if not self.event.is_set()"
]
},
"source": "producer_consumer.py",
"depends": [
"image_download.py",
"lock_counter.py"
],
"exercise_id": 246,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 生产者消费者
# 描述:实用生产者消费者例子,使用 post 接口投递下载每个图片,下载完退出程序
from concurrent.futures import ThreadPoolExecutor
from queue import Queue
from lock_counter import LockCounter
from image_download import download_img
import threading
class ImageDownloader:
def __init__(self, worker_count, progress) -> None:
self.queue = Queue(1024)
self.event = threading.Event()
self.worker_count = worker_count
self.counter = LockCounter()
self.progress = progress
self.pool = ThreadPoolExecutor(max_workers=self.worker_count+2)
def __consumer(self):
while not self.event.is_set():
if not self.queue.empty():
url = self.queue.get()
print(f"[consumer] get url:{url}")
download_img(url)
self.counter.step()
else:
print("[consumer] queue is empty, just wait")
self.event.wait()
if self.event.is_set():
self.event.clear()
if self.progress(self.counter.size()):
print('done')
self.event.set()
break
def post(self, url):
print(f"[producer] put url:{url}")
self.queue.put(url)
self.event.set()
def start(self):
for i in range(0, self.worker_count):
self.pool.submit(self.__consumer)
if __name__ == '__main__':
urls = [
"https://img-ask.csdnimg.cn/upload/1623844642974.jpg",
"https://img-ask.csdn.net/upload/201510/22/1445491909_384819.jpg",
]
downloader = ImageDownloader(3, lambda count: count == len(urls))
downloader.start()
for url in urls:
downloader.post(url)
{
"one_line": {
"with ThreadPoolExecutor(max_workers=5) as exe": [
"with ThreadPool(max_workers=5) as exe"
],
"exe.map(download_img, urls)": [
"exe.submit(download_img, urls)",
"exe.map(urls, download_img)"
]
},
"source": "thread_executor.py",
"depends": [
"image_download.py"
],
"exercise_id": 227,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 线程池
# 描述:使用线程池并发下载图片
from concurrent.futures import ThreadPoolExecutor
from image_download import download_img
def test():
urls = [
"https://img-ask.csdnimg.cn/upload/1623844642974.jpg",
"https://img-ask.csdnimg.cn/upload/1623844642974.jpg",
"https://img-mid.csdnimg.cn/release/static/image/mid/ask/754909759626128.jpg",
"https://img-ask.csdn.net/upload/201510/22/1445491909_384819.jpg",
]
with ThreadPoolExecutor(max_workers=5) as exe:
exe.map(download_img, urls)
if __name__ == '__main__':
test()
{
"one_line": {
"args=(n,)": [
"args=(n)"
],
"threading.Thread": [
"threading"
],
"x.start()": [
"x.join()"
]
},
"source": "thread_free.py",
"depends": [],
"exercise_id": 192,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 多线程
# 描述:多线程打印 n
import threading
import time
def map_process(n):
time.sleep(n)
print(n)
def test():
numbers = range(0, 3)
for n in numbers:
x = threading.Thread(target=map_process, args=(n,))
x.start()
if __name__ == '__main__':
test()
{
"export": [
"match_01.json",
"match_02.json"
],
"keywords": [],
"children": [],
"node_id": "python-insert-5"
}
\ No newline at end of file
{
"source": "match_01.py",
"depends": [],
"exercise_id": 221,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 结构化模式匹配(1)
# 描述:Python 3.10 引入了结构化模式匹配。请使用 Python 3.10+ 版本测试本代码。
import argparse
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('command', choices=['push', 'pull', 'commit'])
args = parser.parse_args()
match args.command:
case 'push':
print('pushing')
case 'pull':
print('pulling')
case _:
parser.error(f'{args.command!r} not yet implemented')
{
"source": "match_02.py",
"depends": [],
"exercise_id": 229,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 结构化模式匹配(2)
# 描述:结构化模式匹配支持对各种Python数据类型进行匹配。请使用 Python 3.10+ 版本测试本代码。
class Car:
__match_args__ = ('key', 'name')
def __init__(self, key, name):
self.key = key
self.name = name
if __name__ == '__main__':
while True:
try:
expr = eval(input('Expr: '))
except:
print('无效的Python代码,请输入合法的Python数据类型')
continue
match expr:
case(0, x):
print(f'(0, {x})')
case['a', x, 'c']:
print(f"'a', {x!r}, 'c'")
case {'foo': bar}:
print(f"{{'foo': {bar}}}")
case[1, 2, *rest]:
print(f'[1, 2, *{rest}]')
case {'x': x, **kw}:
print(f"{{'x': {x}, **{kw}}}")
case Car(key=key, name='Tesla'):
print(f"Car({key!r}, 'TESLA!')")
case Car(key, name):
print(f"Car({key!r}, {name!r})")
case 1 | 'one' | 'I':
print('one')
case['a' | 'b' as ab, c]:
print(f'{ab!r}, {c!r}')
case(x, y) if x == y:
print(f'({x}, {y}) with x==y')
case 'q':
print('quit')
break
case _:
print('no match')
{
"multiline": [
{
"print(\"Hello, world!\")": " print(\"Hello, world!\")"
},
{
"'exec')": "'eval')"
},
{
"compile": "exec",
"exec(code_obj)": ""
}
],
"source": "code_obj.py",
"depends": [],
"exercise_id": 185,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python code object
# 描述:动态编译 Python 字符串代码,并执行,输出两次 Hello,world!
if __name__ == "__main__":
code_str = """
print("Hello,world!")
print("Hello,world!")
"""
code_obj = compile(code_str, '<string>', 'exec')
exec(code_obj)
print(code_obj.co_name)
print(code_obj.co_filename)
print(code_obj.co_argcount)
print(code_obj.co_varnames)
{
"export": [
"code_obj.json",
"func_code.json",
"disa.json"
],
"keywords": [],
"children": [],
"node_id": "python-insert-6"
}
\ No newline at end of file
{
"one_line": {
"dis.get_instructions": [
"dis.dis"
],
"assert hello_world_il_count == 2": [
"assert hello_world_il_count == 1"
],
"argval": [
"arg"
]
},
"source": "disa.py",
"depends": [],
"exercise_id": 188,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python 汇编
# 描述:输出 Python 代码的汇编,找到含有"Hello,world!"的指令
import dis
if __name__ == "__main__":
code_str = """
print("Hello,world!")
print("Hello,world!")
"""
code_obj = compile(code_str, '<string>', 'exec')
ins = dis.get_instructions(code_obj)
hello_world_il_count = 0
for il in ins:
if il.argval == 'Hello,world!':
print(il)
hello_world_il_count += 1
assert hello_world_il_count == 2
{
"one_line": {
"code_obj.co_varnames[0]+','+code_obj.co_varnames[1]+'!'": [
"code_obj.co_varnames",
"','.join(code_obj.co_varnames)"
],
"hello, world": [
"x='Hello', y='world'"
]
},
"source": "func_code.py",
"depends": [],
"exercise_id": 225,
"type": "code_options"
}
\ No newline at end of file
# -*- coding: UTF-8 -*-
# 作者:幻灰龙
# 标题:Python func code
# 描述:获取函数的 code object,从而获得函数参数的名字元素,打印出 "Hello,world!"
def test(Hello, world):
pass
if __name__ == "__main__":
code_obj = test.__code__
print(code_obj.co_varnames[0]+','+code_obj.co_varnames[1]+'!')
{
"node_id": "python-2-16",
"keywords": []
}
\ No newline at end of file
{
"node_id": "python-1-2",
"keywords": []
}
\ No newline at end of file
{
"tree_name": "python",
"node_id": "python-0-0",
"keywords": []
}
\ No newline at end of file
因为 它太大了无法显示 source diff 。你可以改为 查看blob
from json import load
from src.tree import TreeWalker, load_json, dump_json
import os
import re
if __name__ == '__main__':
walker = TreeWalker("data", "python", "python")
walker.walk()
import logging
from genericpath import exists
import json
import os
import uuid
import sys
import re
id_set = set()
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
handler = logging.StreamHandler(sys.stdout)
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
def load_json(p):
with open(p, 'r') as f:
return json.loads(f.read())
def dump_json(p, j, exist_ok=False, override=False):
if os.path.exists(p):
if exist_ok:
if not override:
return
else:
logger.error(f"{p} already exist")
sys.exit(0)
with open(p, 'w+') as f:
f.write(json.dumps(j, indent=2, ensure_ascii=False))
def ensure_config(path):
config_path = os.path.join(path, "config.json")
if not os.path.exists(config_path):
node = {"keywords": []}
dump_json(config_path, node, exist_ok=True, override=False)
return node
else:
return load_json(config_path)
def parse_no_name(d):
p = r'(\d+)\.(.*)'
m = re.search(p, d)
try:
no = int(m.group(1))
dir_name = m.group(2)
except:
sys.exit(0)
return no, dir_name
def check_export(base, cfg):
flag = False
exports = []
for export in cfg.get('export', []):
ecfg_path = os.path.join(base, export)
if os.path.exists(ecfg_path):
exports.append(export)
else:
flag = True
if flag:
cfg["export"] = exports
return flag
def gen_node_id():
return "oceanbase-" + uuid.uuid4().hex
class TreeWalker:
def __init__(self, root, tree_name, title=None, log=None):
self.name = tree_name
self.root = root
self.title = tree_name if title is None else title
self.tree = {}
self.logger = logger if log is None else log
def walk(self):
root = self.load_root()
root_node = {
"node_id": root["node_id"],
"keywords": root["keywords"],
"children": []
}
self.tree[root["tree_name"]] = root_node
self.load_levels(root_node)
self.load_chapters(self.root, root_node)
for index, level in enumerate(root_node["children"]):
level_title = list(level.keys())[0]
level_node = list(level.values())[0]
level_path = os.path.join(self.root, f"{index+1}.{level_title}")
self.load_chapters(level_path, level_node)
for index, chapter in enumerate(level_node["children"]):
chapter_title = list(chapter.keys())[0]
chapter_node = list(chapter.values())[0]
chapter_path = os.path.join(
level_path, f"{index+1}.{chapter_title}")
self.load_sections(chapter_path, chapter_node)
for index, section_node in enumerate(chapter_node["children"]):
section_title = list(section_node.keys())[0]
full_path = os.path.join(
chapter_path, f"{index}.{section_title}")
if os.path.isdir(full_path):
self.ensure_exercises(full_path)
tree_path = os.path.join(self.root, "tree.json")
dump_json(tree_path, self.tree, exist_ok=True, override=True)
return self.tree
def load_levels(self, root_node):
levels = []
for level in os.listdir(self.root):
if not os.path.isdir(level):
continue
level_path = os.path.join(self.root, level)
num, config = self.load_level_node(level_path)
levels.append((num, config))
levels.sort(key=lambda item: item[0])
root_node["children"] = [item[1] for item in levels]
return root_node
def load_level_node(self, level_path):
config = self.ensure_level_config(level_path)
num, name = self.extract_node_env(level_path)
result = {
name: {
"node_id": config["node_id"],
"keywords": config["keywords"],
"children": [],
}
}
return num, result
def load_chapters(self, base, level_node):
chapters = []
for name in os.listdir(base):
full_name = os.path.join(base, name)
if os.path.isdir(full_name):
num, chapter = self.load_chapter_node(full_name)
chapters.append((num, chapter))
chapters.sort(key=lambda item: item[0])
level_node["children"] = [item[1] for item in chapters]
return level_node
def load_sections(self, base, chapter_node):
sections = []
for name in os.listdir(base):
full_name = os.path.join(base, name)
if os.path.isdir(full_name):
num, section = self.load_section_node(full_name)
sections.append((num, section))
sections.sort(key=lambda item: item[0])
chapter_node["children"] = [item[1] for item in sections]
return chapter_node
def ensure_chapters(self):
for subdir in os.listdir(self.root):
self.ensure_level_config(subdir)
def load_root(self):
config_path = os.path.join(self.root, "config.json")
if not os.path.exists(config_path):
config = {
"tree_name": self.name,
"keywords": [],
"node_id": self.gen_node_id(),
}
dump_json(config_path, config, exist_ok=True, override=True)
else:
config = load_json(config_path)
flag, result = self.ensure_node_id(config)
if flag:
dump_json(config_path, result, exist_ok=True, override=True)
return config
def ensure_level_config(self, path):
config_path = os.path.join(path, "config.json")
if not os.path.exists(config_path):
config = {
"node_id": self.gen_node_id()
}
dump_json(config_path, config, exist_ok=True, override=True)
else:
config = load_json(config_path)
flag, result = self.ensure_node_id(config)
if flag:
dump_json(config_path, config, exist_ok=True, override=True)
return config
def ensure_chapter_config(self, path):
config_path = os.path.join(path, "config.json")
if not os.path.exists(config_path):
config = {
"node_id": self.gen_node_id(),
"keywords": []
}
dump_json(config_path, config, exist_ok=True, override=True)
else:
config = load_json(config_path)
flag, result = self.ensure_node_id(config)
if flag:
dump_json(config_path, config, exist_ok=True, override=True)
return config
def ensure_section_config(self, path):
config_path = os.path.join(path, "config.json")
if not os.path.exists(config_path):
config = {
"node_id": self.gen_node_id(),
"keywords": [],
"children": [],
"export": []
}
dump_json(config_path, config, exist_ok=True, override=True)
else:
config = load_json(config_path)
flag, result = self.ensure_node_id(config)
if flag:
dump_json(config_path, config, exist_ok=True, override=True)
return config
def ensure_node_id(self, config):
if "node_id" not in config:
config["node_id"] = self.gen_node_id()
return True, config
else:
return False, config
def gen_node_id(self):
return f"{self.name}-{uuid.uuid4().hex}"
def extract_node_env(self, path):
try:
_, dir = os.path.split(path)
self.logger.info(path)
number, title = dir.split(".", 1)
return int(number), title
except Exception as error:
self.logger.error(f"目录 [{path}] 解析失败,结构不合法,可能是缺少序号")
sys.exit(1)
def load_chapter_node(self, full_name):
config = self.ensure_chapter_config(full_name)
num, name = self.extract_node_env(full_name)
result = {
name: {
"node_id": config["node_id"],
"keywords": config["keywords"],
"children": [],
}
}
return num, result
def load_section_node(self, full_name):
config = self.ensure_section_config(full_name)
num, name = self.extract_node_env(full_name)
result = {
name: {
"node_id": config["node_id"],
"keywords": config["keywords"],
"children": config.get("children", [])
}
}
# if "children" in config:
# result["children"] = config["children"]
return num, result
def ensure_exercises(self, section_path):
config = self.ensure_section_config(section_path)
for e in config.get("export", []):
full_name = os.path.join(section_path, e)
exercise = load_json(full_name)
if "exercise_id" not in exercise:
exercise["exercise_id"] = uuid.uuid4().hex
dump_json(full_name, exercise)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册