hufengguo 1.3.3
A small example package from Hufengguo, CUC
Requires Python: >=3.6

# 扩展库介绍

这是中国传媒大学胡凤国老师上课分享的自定义函数库，其中包含几个常用的文本处理函数。发布本扩展库主要是方便上课学生练习Python程序，顺便分享给其他需要的Pythoner。

刚学会发布扩展库，PyPI很多东西还不熟，如有问题，请多提宝贵意见。

本次更新要点：

2026年2月1日，在20260131更新的基础上又添加了一个PDF处理函数，用来进行PDF文件分割。


# 安装说明

## 环境要求
- **Python版本**：Python 3.6+
- **推荐版本**：Python 3.8+

## 初次安装
```bash
# 仅安装核心模块
pip install hufengguo

# 安装 PDF 处理功能
pip install "hufengguo[pdf]"
```

## 更新安装
```bash
# 仅更新核心模块
pip install -U hufengguo

# 更新并保留 PDF 功能
pip install -U "hufengguo[pdf]"
```


# 用法说明

基本用法见胡凤国老师的上课教材：《Python程序设计（基于计算思维和新文科建设）》，ISBN：9787121435577，胡凤国，电子工业出版社，2022年6月。

这里举一些简单的例子。


## 产生1到100之内的素数

```bash
# 导入
from hufengguo import isprime

# 产生素数列表
x = [i for i in range(101) if isprime(i)]

# 输出
print(x)
```

## 去掉多行文本中的空白行和每行首尾空白符

```bash
# 导入
from hufengguo import remove_white_from_text

# 赋值
s = " 12345\t\n  上山打老虎\n \n\n"

# 变换
t = remove_white_from_text(s)

# 输出
print("字符串s：", "-"*20, s, "-"*20, "\n字符串t：", "-"*20, t, "-"*20, sep="\n")
```

## 随机生成若干个长度介于指定范围内的密码字符串
```bash
from hufengguo import gen_pwd

print(gen_pwd(6))
print(gen_pwd(4, 8))
print(gen_pwd(4, 8, punct=True))
print(gen_pwd(4, 8, count=5))
print(gen_pwd(4, 8, count=5, samelen=True))
```

## 调用jieba扩展库对一个文本文件进行分词和词性标注

```bash
# 导入
from hufengguo import segtag_by_jieba

# 对单文件进行分词和词性标注操作
segtag_by_jieba(r"in.txt", r"out.txt")
```
本函数会自动判断文本文件的编码并进行读取，生成文件的默认编码是utf-8-sig。


## 调用jieba扩展库对一个目录下的文本文件进行分词和词性标注

```bash
# 导入
from hufengguo import my_path2path, segtag_by_jieba

# 批量进行分词和词性标注操作
my_path2path(r"in", [".txt"], r"out", segtag_by_jieba)
```
本函数会自动搜索目录及子目录下的所有文本文件，进行分词和词性标注操作之后保存到目标目录，目标目录会保持跟源目录相同的目录结构。

本库提供的函数my_path2path()功能很强，它把目录对目录的多文件操作转化为单文件对单文件的操作。第二个参数可以换成其它的扩展名，第四个参数是一个函数名，我们可以换成其它的自定义函数来完成其它文本处理任务（要求自定义函数具有两个参数，第1个参数是源文件名，第2个参数是目标文件名，自定义函数的功能是对源文件进行自定义操作，操作结果写入目标文件）。


## 数字与汉字读法互转

本库采用我国传统数学的大数体系：零一二三四五六七八九十百千万亿兆京垓秭穰沟涧正载极。从十开始，逢十进位；从万开始，逢万进位，1兆等于1万亿（10的12次方），1京等于1万兆（10的16次方），……，1极等于1万载（10的48次方），传统大数体系可以表示长达96位数字。本库既支持长达96位数字的传统大数体系，又支持目前只通过万和亿循环的大数表示方法。

```bash
# 导入
from hufengguo import digit2hanzi, hanzi2digit

# 汉字转数字
print(hanzi2digit("一百二十三"))
print(hanzi2digit("壹佰贰拾叁"))
print(hanzi2digit("三兆")
print(hanzi2digit("三万亿"))

# 数字转汉字
print(digit2hanzi(123))
print(digit2hanzi(123, daxieflag=True))
print(digit2hanzi(3*10**12))
print(digit2hanzi(3*10**12, wanyiflag=True))
print(digit2hanzi(1234500000000))
print(digit2hanzi(1234500000000, wanyiflag=True))
print(digit2hanzi(12345000000000000))
print(digit2hanzi(12345000000000000, wanyiflag=True))

```

## 人民币金额的正常汉字写法与大写写法互转

```bash
# 导入
from hufengguo import xiao2da, da2xiao

# 转换
print(xiao2da("一万二千三百零六"))
print(da2xiao("壹万贰仟叁佰零陆"))
```

## 分节格式化数字

```bash
# 导入
from hufengguo import fenjie_nummber

# 分节格式化操作
print(fenjie_nummber(12345678901, group=3))
print(fenjie_nummber(12345678901, group=3, sep="_"))
print(fenjie_nummber(12345678901))
print(fenjie_nummber(12345678901, group=4))
print(fenjie_nummber(12345678901, group=5, sep=","))
print(fenjie_nummber(-1234567))
```

## 创建目录和文件、生成和读取文件、删除文件和目录

本库给出的函数功能比os.makedirs()、os.remove()、shutil.rmtree()、os.path.exists()、open()都要好，它们都处理不了目录名和文件名的最后一个字符是空格的情况，但本库给出的几个函数是可以的，具体请看代码示例。

```bash
# 导入
from os import chmod
from os.path import exists, join
from stat import S_IREAD
from hufengguo import make_dir_exists, my_exists, my_os_remove, my_shutil_rmtree, my_read_from_txtfile, my_write_to_txtfile

# 创建目录(123后面有个空格)
# 注意os.makedirs(r"abc\123 ")创建的目录123后面没有空格
p = r"abc\123 "
print(make_dir_exists(p))

# 判断目录p是否存在
print(f"判定目录“{p}”的存在性：")
print(exists(p))      # 输出 False
print(my_exists(p))   # 输出 (True, 'dir')

# 生成文件
fn = join(p, "test.txt")
with open(fn, "wt") as fpw:
    fpw.write("上山打老虎")

# 判断文件fn是否存在
print(f"判定文件“{fn}”的存在性：")
print(exists(fn))      # 输出 True
print(my_exists(fn))   # 输出 (True, 'file')

# 为文件添加只读属性
chmod(fn, S_IREAD)

# 删除文件（注意os.remove(fn)会报错）
print(my_os_remove(fn))

# 生成第二个文件，注意该文件名最后一个字符是空格
# 由于文件名特殊，用open语句打开文件写入字符串会报错
fn2 = join(p, "xyz ")
my_write_to_txtfile(fn2, "老虎不吃饭")

# 判断文件fn2是否存在
print(f"判定文件“{fn2}”的存在性：")
print(exists(fn2))     # 输出 False
print(my_exists(fn2))  # 输出 (True, 'file')

# 读取第二个文件
# 由于文件名特殊，用open语句打开读取会报错
print(my_read_from_txtfile(fn2))

# 删除目录（注意shutil.rmtree(r"abc")会报错）
print(exists(r"abc"))
print(my_shutil_rmtree(r"abc"))
print(exists(r"abc"))
```

## 调用路径选择窗口类

### 独立调用

```bash
# 导入
from hufengguo import my_path2path, segtag_by_jieba
from hufengguo import MyFilePathWindow

# 自定义函数
def segtag(fnin, fnout):
    print(f"正在处理 {fnin} ……")
    segtag_by_jieba(fnin, fnout)

# 赋值
pin, pout = MyFilePathWindow(
        "分词和词性标注路径选择",
        file1flag=False,
        file2flag=False,
    ).show()

# 调用
if pin is None or pout is None:
    print("用户取消了操作。")
else:
    my_path2path(pin, [".txt"], pout, segtag)
```

### 集成调用

```bash
# 导入
from hufengguo import my_path2path, segtag_by_jieba, MyFilePathWindow
from tkinter import Button, Tk
from tkinter.messagebox import showinfo

# 自定义函数：对单个文本文件进行分词和词性标注
def segtag(fnin, fnout):
    # print(f"正在处理 {fnin} ……")
    segtag_by_jieba(fnin, fnout)

# 自定义函数，按钮响应函数
def do_segtag():
    fpin, fpout = MyFilePathWindow(
        "分词和词性标注路径选择",
        file1flag=False,
        file2flag=False,
        parent=main_app  # 指定父窗口
    ).show()
    
    if fpin and fpout:
        my_path2path(fpin, [".txt"], fpout, segtag)
        showinfo(title="信息反馈", message="操作完毕")
    else:
        showinfo(title="信息反馈", message="您取消了操作。")

# 界面
main_app = Tk()
main_app.title("主应用程序")
main_app.geometry("300x160")

Button(main_app, text="分词和词性标注", command=do_segtag).pack(pady=20)
Button(main_app, text="退出程序", command=main_app.destroy).pack()
main_app.mainloop()

```

## PDF操作

### 保护PDF

```bash
from hufengguo import protect_pdf

fnin = r"test.pdf"
protect_pdf(fnin, r"test_默认保护.pdf")
protect_pdf(fnin, r"test_默认保护_用户密码12345.pdf", user_pwd="12345")
protect_pdf(fnin, r"test_默认保护_用户密码12345_所有者密码abcde.pdf",
            user_pwd="12345", owner_pwd="abcde")
protect_pdf(fnin, r"test_完全保护.pdf", -4096)
```

### 读取PDF的权限值

```bash
from hufengguo import get_pdf_permissions

fn = r"test.pdf"
r = get_pdf_permissions(fn)    # 如有密码，加第二个参数
print(*r.items(), sep="\n")
```

### 解密PDF文件并取消保护
```bash
from hufengguo import protect_pdf, get_pdf_permissions, decrypt_pdf

fnin, fntmp, fnout = r"test.pdf", r"tmp.pdf", r"test_out.pdf"
protect_pdf(fnin, fntmp, -4096, "12345")
decrypt_pdf(fntmp, fnout, "12345")
r = get_pdf_permissions(fnin)
print(*r.items(), sep="\n", end="\n\n")
r = get_pdf_permissions(fntmp, "12345")   # 如无密码，第二个参数省略
print(*r.items(), sep="\n", end="\n\n")
r = get_pdf_permissions(fnout, "12345")
print(*r.items(), sep="\n", end="\n\n")
```

### 分割PDF文件
```bash
from hufengguo import split_pdf

fnin, fnout = r"test.pdf", r"test_out.pdf"
split_pdf(fnin, fnout, 10, 15, pwd="你的密码")  # 如PDF文件有打开有密码，必须加pwd参数
split_pdf(fnin, None, 10, 15)      # 如省略输出文件名，则会构造输出文件名：test_10_15.pdf
split_pdf(fnin, None, 10, None)    # 如省略结束页编号，则认为是从第10页到结束
split_pdf(fnin, None, None, 10)    # 如省略开始页编号，则认为是从第1页到第10页
```