# 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 国际许可协议进行许可。