# e0401-file-io **Repository Path**: zhang-jiaxuan21/e0401-file-io ## Basic Information - **Project Name**: e0401-file-io - **Description**: 供学生练习 Python 文件读写操作所使用的仓库。 - **Primary Language**: Python - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 152 - **Created**: 2022-04-06 - **Last Updated**: 2022-04-06 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 练习0401: 用 Python 读写文件 这道练习题以读写文件的操作为例, 帮助同学们理解 Python 语言较为宏观的一部分基本概念, 同时介绍文本的二进制编码方面的基础知识。 我们编写 Python 程序, 基本上就是进行 “读取——计算——写入” 这三类工作。最核心也最复杂的当然是 “计算” 工作。但不 “读取”, 计算所需的数据无从获得; 不 “写入”, 计算得出的结果不能持久地保留与分享。所以这周我们先理解文件的读写, 而计算方面的更多知识将留在后面几周展开。 ```plain 阿里云盘: https://www.aliyundrive.com/s/UkFhves7zkJ 百度网盘: https://pan.baidu.com/s/1WjZIlAVEHX8ivDhE0gEzJg?pwd=6ndq ``` 首先, 请同学们从以上地址 (任选其一) 下载完整版视频讲解 (或用下面的链接逐个下载分段视频讲解), 理解下列基本概念。这些概念都是解决本练习题所必须的。 开场白 [百度网盘](https://pan.baidu.com/s/1JGX1ubNX7Sy0lc68Jr048A?pwd=r5w4) 1. Python 是一门解释型 (interpreted), 交互式 (interactive), 面向对象 (object-oriented) 的编程语言, 功能 (power) 强大, 语法 (syntax) 清晰 [百度网盘](https://pan.baidu.com/s/1yRVSnpwSftbLj-Nh97V2jg?pwd=i1e2) 1. IPython ([官方文档](https://ipython.readthedocs.io/)) 是在终端命令行使用 Python 的一种 REPL (Read-Evaluate-Print-Loop) 工具 [百度网盘](https://pan.baidu.com/s/146eKSxkbZYCDDXIMV-jU3w?pwd=liu8) 1. IPython 的主要用途: 学习、试验、检验自己对 Python 解释器行为的理解 [百度网盘](https://pan.baidu.com/s/10H8OdaIVYRI5C1X5YX-nVw?pwd=kj8r) 1. `import` 语句 (statement); 软件包 (package); 模块 (module) [百度网盘](https://pan.baidu.com/s/1YtltYy4xMJVGYJ_dp-Utfg?pwd=how0) 1. 内置函数/类 ([built-ins](https://docs.python.org/3/library/functions.html)); 标准库 ([standard library](https://docs.python.org/3/library/)); 第三方软件包 ([site packages](https://pypi.org/)) [百度网盘](https://pan.baidu.com/s/12OhB751-lgkGp6QTlcEqjg?pwd=0pwr) 1. 变量 (variable) / 命名 (name) / 标识符 (identifier); `import ... as ...` [百度网盘](https://pan.baidu.com/s/1FfappLRapLe4QsGI2u8RjQ?pwd=e2mk) 1. 关键字 (keywords) / 保留字 (reserved words); [全部 Python 关键字](https://docs.python.org/3/reference/lexical_analysis.html#keywords) [百度网盘](https://pan.baidu.com/s/1RV2DMUA4-7-l9TKdSr14cw?pwd=p8ou) 1. 赋值语句 (assignment statement); `=`; 字面值 (literals); [百度网盘](https://pan.baidu.com/s/1mUSIkMhMiTR_IuTrfI4h5w?pwd=d33b) 1. 进程 (process); `ps`; `top`; `htop` [百度网盘](https://pan.baidu.com/s/1elgK2Z2M6EfhuJTtHV58Jw?pwd=3k5j) 1. 内存管理 (memory management); 垃圾回收 (GC, garbage collection) [百度网盘](https://pan.baidu.com/s/1xHXn7zOZXsWQ3JAF64Ulwg?pwd=n8kq) 1. 对象 (object); ID (`id`); 类型 (type) (`type`); 属性 (attribute) (`dir`); 文档 (docstring) (`help`) [百度网盘](https://pan.baidu.com/s/19eR7gC-ssugJtMQUDZqgTw?pwd=vnve) 1. 最基础的原子级 (atomic) 数据类型及其字面值: `str`, `int`, `float`, `bool`, `bytes`, `None` [百度网盘](https://pan.baidu.com/s/1Aq9-hzo69zTPr1NANMH8yw?pwd=5hfm) 1. 最基础的容器 (container) 数据类型及其字面值: `tuple`, `list`, `dict`, `set` [百度网盘](https://pan.baidu.com/s/1GWFS9SpZ17RcbgZJk1H8Vg?pwd=slie) 1. 命名空间 (namespace); 限定名称 (qualified name) [百度网盘](https://pan.baidu.com/s/1_wYe_seyLptIRjj-S9Xx_g?pwd=aki1) 1. `import a.b`; `from a import b`; `from a import *` [百度网盘](https://pan.baidu.com/s/1B_0PB-dByq95CmJU4G8QZw?pwd=l2t1) 1. 函数 (function); 形参 (parameters); 实参 (arguments); 返回值 (return value); 动态类型 (dynamic typing / duck typing) vs. 静态类型 (static typing); 类型注解 (type annotations) [百度网盘](https://pan.baidu.com/s/1S82nnK1xLu8NQQp33Y4GlA?pwd=has6) 1. Python 函数所支持的形参共有 6 种 (足够灵活): [百度网盘](https://pan.baidu.com/s/1CY9VCi1ni6TycD0U4nutVA?pwd=pk2t) 1. 位置形参 (positional parameter); `def f(a):`; eg. `os.chdir`, `random.randint` 1. 关键字形参 (keyword parameter) / 命名形参 (named parameter); 默认值 (default value); `def f(a=None):`; eg. `os.listdir` 1. 仅限位置形参 (positional-only parameter); `def f(a, /):`; eg. `format` 1. 仅限关键字形参 (keyword-only parameter); `def f(*, a):`; eg. `sorted` 1. 任意数量的位置形参 (arbitrary positional parameters); `def f(*args):`; eg. `print` 1. 任意数量的关键字形参 (arbitrary keyword parameters); `def f(**kwargs):`; eg. `functools.partial` 1. 类 (class); 实例 (instance); 方法 (method) [百度网盘](https://pan.baidu.com/s/1PIoBYAYvXWwBFBgGgKsn_A?pwd=k9g5) 1. Python 最底层的文件读写操作: `open`, `mode`, `read`, `write`, `seek`, `flush`, `close` [百度网盘](https://pan.baidu.com/s/1O55GTb7dZsZt3MDAC63GOg?pwd=7qtp) 1. 比特 (bit); 字节 (byte); 二进制 (binary); 十六进制 (hexadecimal) [百度网盘](https://pan.baidu.com/s/1tnE3_WEYt4EEUe6Uq6iDpA?pwd=w3sh) 1. 字符编码 (`encoding`) / [编解码器 codecs](https://docs.python.org/3/library/codecs.html) [百度网盘](https://pan.baidu.com/s/1-a0S6NL3I9Jtoz4JfCdQHw?pwd=fg5l) 1. [ASCII](https://www.ascii-code.com) 1. ANSI: GB2312/GBK/GB18030/Big5/JIS 1. UNICODE: Utf8/Utf16/Utf32; 字节序标记 (BOM, byte order mark); 大小端序 (BE / LE, big endian / little endian) 1. 换行符 (`newline`); Unix: `"\n"` (LF); Win: `"\r\n"` (CRLF); Mac (Old): `"\r"` (CR) [百度网盘](https://pan.baidu.com/s/1w3WEoSbnxtDFkDgwgyckNQ?pwd=kick) 在学习理解上述概念之后, 请同学们依次完成下列任务: [百度网盘](https://pan.baidu.com/s/1qW8gHv0pxx_coOxXAT3Oqg?pwd=0kmd) ### 任务1: 解码神秘文本 1. Fork 本代码仓库到你个人的 gitee 账户之下 1. 将你个人 gitee 账户下的本仓库 `git clone` 至你的本地计算机 1. 使用 `cp` 命令将 `unknown.txt` 文件复制至 Windows 容易访问的目录 (比如 `C:\mydata\`), 鼠标双击用记事本打开 `unknown.txt`, 观察出现乱码 1. 使用 `cat` 命令尝试在终端查看 `unknown.txt` 文件, 观察出现乱码 1. 使用 IPython 自己进行探索, 以二进制模式从 `unknown.txt` 中读取出 `bytes`, 然后反复调用其 `decode` 方法, 看使用哪一个 `encoding` 才能够正确地解码出有效文本 1. 使用 IPython 自己进行探索, 看如何才能够将读取出来的文本, 另存写入为 `known.txt` 文件, (要求采用 CRLF 换行, UTF-8 编码), 完成后可以用 `cp` 和 Windows 记事本打开验证, 应该能显示出有效文本 1. 使用 VS Code (或者 `nano`) 编辑器, 将以上 “读取——写入” 的 Python 代码编辑保存为 `convert.py` 脚本, 使得运行该脚本将能够完成以上 “从 `unknown.txt` 文件读取文本, 然后写入文本至 `known.txt` 文件” 的全部工作, 而且对换行符和编码的要求均与以上相同 1. 运行 `pytest tests/test_task1.py` 将可以检测是否完成了题目的要求 ### 任务2: 保存 Unix 风格的 csv 文件 1. 阅读 Python 标准库中 [`csv`](https://docs.python.org/3/library/csv.html) 模块的文档, 理解 csv 文件的概念, 及其存在的问题 1. 在 IPython 中使用以下代码创建一个 `pandas.DataFrame` 实例 (可能需要另外打开一个终端, 先在虚拟环境下安装 [`pandas`](https://pypi.org/project/pandas/) 软件包) ```python import pandas as pd df = pd.DataFrame( { "国家": ["中国", "美国", "俄罗斯"], "首都": ["北京", "华盛顿", "莫斯科"], } ) ``` 1. 在 IPython 中键入 `df` 查看其表现 (repr), 注意中文对不齐的问题 > 可以修改 `pandas` 的设置, 使得 `DataFrame` 在终端的中文表现能够对齐, > 但这会使 `DataFrame` 在 `print` 时速度降低 2 倍, 不推荐 > ([参考](https://pandas.pydata.org/docs/user_guide/options.html#unicode-formatting)) 1. 在 IPython 中键入以下代码, 将 `pandas.DataFrame` 更好地以表格形式展现 (可能需要另外打开一个终端, 先在虚拟环境下安装 [`tabulate`](https://pypi.org/project/tabulate/) 软件包) ```python from tabulate import tabulate print(tabulate(df, headers="keys")) ``` 使用 `help(tabulate)` 或者 `tabulate?` 阅读学习其文档 (docstring), 从而能够更自如地使用这一强大工具 1. 在 IPython 中键入以下代码, 将 `pandas.DataFrame` 保存为 Unix 风格的 csv 文件 ```python df.to_csv("data_unix.csv", index=False) ``` 1. 可以再次使用 `cp`, 在 Windows (或 Mac) 下用 Excel 打开 `data_unix.csv` 文件, 观察出现乱码 (Windows、Office 等软件与 Unix 在许多方面都不兼容) 1. 然而, 在 Unix 终端下使用 `cat data_unix.csv` 命令, 能够查看到正确的文本 1. 运行 `pytest tests/test_task2.py` 将可以检测是否完成了题目的要求 ### 任务3: 保存 Excel 风格的 csv 文件 1. 在 IPython 中, 尝试给 `pandas.DataFrame.to_csv` 传入恰当的参数, 将 `df` 保存为 `data_excel.csv` 文件, 需要满足以下条件, 以符合 Excel 对 “CSV UTF-8 (逗号分隔) (*.csv)” 的格式要求: 1. 采用 UTF-8 with BOM 编码 1. 采用 CRLF 作为换行符 1. 输出的 csv 文件中不包含 `pandas.DataFrame` 自动添加的行号索引 具体应传入什么实参, 请阅读 [`pandas.DataFrame.to_csv`](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.to_csv.html) 文档, 靠自己学习和摸索 1. 要检查是否成功, 可以 `cp` 之后在 Windows 下用 Excel 打开, 至少不应该出现乱码 1. 将以上制作 `data_excel.csv` 文件的代码编辑保存为 `make_excel_csv.py` 脚本, 使得运行该脚本将能够完成以上 “创建 `data_excel.csv` 文件” 的全部工作, 而且对换行符和编码的要求均与以上相同 1. 运行 `pytest tests/test_task3.py` 将可以检测是否完成了题目的要求 如果运行 `pytest` 能够通过全部测试, 就可以像之前的练习题一样, add, commit, 然后 push, 最后提交 PR。 --- 知识共享许可协议
本作品由首都经济贸易大学-高强采用知识共享署名-禁止演绎 4.0 国际许可协议进行许可。