zj3D 2 weeks ago
parent 56d6c04878
commit a8200ff225

@ -1,4 +1,5 @@
# 引入停用词表和测试文件的路径
# -*- coding: utf-8 -*-
from cppy.cp_util import stopwordfilepath, testfilepath
# 准备停用词表
@ -52,4 +53,6 @@ for tf in word_freqs[:10]:
'''
想到哪里写到哪里只会Python语言最基础的语法C语言编程风格
所有逻辑所有细节一盘大棋摆在面前
这样的代码,很难维护后来的阅读者会进入一个一望无际的泥塘.
'''

@ -1,3 +1,6 @@
'''
给代码片段命名打包成函数用函数名概括问题求解的过程方便阅读理解
'''
import string
from collections import Counter
from cppy.cp_util import *

@ -1,7 +1,13 @@
'''
消除全局变量限定函数只有输入输出来和外界打交道
如果消除无用的中间变量那么就是典型的数据处理流水线风格:我要在一个函数中完成某个操作然后调用下一个函数进行处理
流水线风格阅读方便提供栈性能优化的可能
如果需要加参数那么需要柯里化方法即Python里面的闭包函数结构
'''
import re
from cppy.cp_util import *
def extractwords(str_data):
pattern = re.compile('[\W_]+')
word_list = pattern.sub(' ', str_data).lower().split()

@ -1,3 +1,8 @@
'''
把一些公共函数分离出去保留中间变量来增加代码可读性
jupyter notebook 做分析常常如此
'''
import re
from collections import Counter
from cppy.cp_util import *

@ -1,3 +1,5 @@
''' 递归是基础编程思维产生的代码结构 。注意递归深度限制只能解决小规模问题 '''
from cppy.cp_util import *
from collections import Counter

@ -1,3 +1,10 @@
'''
对象化的视角看待问题是抽象出问题中的实体
实体有方法属性程序执行过程就是调动这些实体的交互行为
作为彻底的面向对象的风格主逻辑常常也写做一个类init 产生各个工具run 运行逻辑
本例中实体可理解为几个工具
'''
from collections import Counter
from cppy.cp_util import *

@ -1,8 +1,11 @@
from cppy.cp_util import *
#
# 简单使用字典,也能满足对象的一些应用场景。而且更省资源
#
'''
如果认为基于数据和函数的封装就是对象化编程那么类并不是必要的扩展的函数字典也有这个能力
函数利用属性存数据字典有的value是函数有的是value是数据
字典进行对象化程序设计只是缺乏权限控制机制而继承方面可以是通过一个代理模式包装实现
简单使用字典也能满足对象的一些应用场景而且更省资源
'''
def extract_words(obj, path_to_file):
"""

@ -1,9 +1,13 @@
import abc, re
from cppy.cp_util import *
#
# 接口
#
'''
如果在基类层面上进行设计这样就能获得多个子类同一层面上的抽象操作
在一些语言里面这种模式叫基于接口的编程接口要求纯抽象类
Python 因为对象协议的缘故所以抽象接口设计不是必须
沿用抽象接口设计是为工程性规整
'''
class IDataStorage (metaclass=abc.ABCMeta):
@abc.abstractmethod
def words(self):

@ -1,7 +1,7 @@
from cppy.cp_util import *
#
# 生成器
# 生成器 是一种简单异步实现
#
def non_stop_words(testfilepath):
stopwords = get_stopwords()

@ -3,10 +3,16 @@ import aiofiles
from collections import Counter
from cppy.cp_util import *
'''
异步指程序运行期间具有挂起然后等待唤醒继续执行的能力
典型应用场景如数据
源源不断产生,比如网络监听
太大,可能大于内存
有连续处理动作当某一环得到想要结果立刻终止后续数据不需要处理
本例读文件的Io还是太快的爬虫
'''
#
# 协程: 有点复杂; 读文件的Io还是太快的爬虫
#
async def read_file(file_path):
async with aiofiles.open(file_path, 'r', encoding='utf-8') as file:
content = await file.read()

@ -1,5 +1,7 @@
from cppy.cp_util import *
# 内省Introspection在编程中是指程序在运行时检查对象变量类型或属性的能力。
# 这是一种动态地了解对象的方法,非常有利于调试、优化代码、实现泛型编程等场景。
class Calculator:
def frequencies(self,word_list):

@ -1,3 +1,8 @@
'''
反射是一种动态地访问或修改对象状态和行为的能力包括其属性方法等
有被 Hacker 攻击的风险
'''
import cppy.cp_util as util
import operator

@ -1,7 +1,11 @@
from collections import Counter
from cppy.cp_util import *
# 缓存系统,使用字典来存储文件路径和对应的词频结果; 可以存到本地磁盘,就可重复利用计算结果
'''
如果函数设计干净没有修改全局变量那么相同的调用参数就会得到必然相同的结果
缓存把每次计算输入输出存起来如果后面有相同的任务调用参数相同就不用重复计算了
'''
word_freq_cache = {}
def calculate_word_frequency(file_path):

@ -1,4 +1,6 @@
# 创建对象是消耗资源的,如果发现对象已经存在,可以返回引用,不创造新对象 。设计模式中这个做法叫享元
# 可以降低资源需求和提升响应速度。更常见的该模式使用场景是各种资源池。
from cppy.cp_util import *
#享元类

@ -1,3 +1,7 @@
# 插件模式提供一种个别扩展性开发和系统核心开发无关的松耦合结构。
# 简单说,第三方开发者在没有核心框架源码下也能扩展或者改造系统功能
import configparser, importlib.machinery
from cppy.cp_util import *

@ -1,3 +1,7 @@
'''
REST 风格是把数据资源拓展到了互联网环境用Web协议访问
组件可以用任何环境任何语言开发, 只需要遵循共同的 rest 协议
'''
# -*- coding: utf-8 -*-
from flask import Flask, request, jsonify, abort
from functools import lru_cache

@ -1,3 +1,10 @@
'''
以查询和独立组件并发操作数据为中心的思路建数据库围绕数据库做查询操作
现代开发模式中编程语言很少直接用 SQL 操作数据库了常常有个隔离具体数据库更方便编程的ORM层
用工具把表数据映射为对象(ORM)
createDb 创建数据对象processData 处理数据DataQuery 查询输出数据相对 共享内存数据 它慢一些
'''
import sqlite3, os.path
from cppy.cp_util import testfilepath,db_filename,extract_file_words

@ -1,5 +1,8 @@
################ 待整理
'''
每个对象只公开一个接受和发送消息的接口隐藏所有数据和函数
适合分布式系统的远程组件之间无法直接调用只能传递消息
应用场景针对各个组件的 notify 方法发指令来驱动所有工作
这是一个示例性质的原型具体分布式环境下需要调整

@ -1,8 +1,14 @@
'''
每个对象运行于独立线程每个对象只暴露一个队伍消息队列的接口
这种模式除了分布式也适合多线程的环境
各个组件完全不能互操作仅依靠队列发消息进行协作
适合环节多数据可分块有IO-计算性能设计考量要求让各个模块自己适应调整
在某些情况下可以避免复杂的控制流设计使代码简洁
消息队列来共享数据空间相比较传统数据库共享方式访问更快
'''
from threading import Thread

@ -1,3 +1,6 @@
# 自己设计类装饰器,类方法做进行类型申明和检查
from collections import Counter
from cppy.cp_util import *

@ -1,3 +1,7 @@
# Python 作为弱类型语言希望拥有强类型语言类似的规范工整工程性的优点,牺牲一些代码的自由度。
# 可以理解为更好的代码注释和更多的工程约束 。
import cppy.cp_util as util

@ -0,0 +1 @@
尾调用方式调用函数做连续的数据处理。代码好读方便栈资源优化一些语言已经实现了这种调用方式释放前面的函数栈但Python当前还没做如此优化

@ -1,4 +1,6 @@
# 命令行菜单驱动程序
# while 循环体中出现一个 case 菜单,每个菜单调用对应函数
import os
import cppy.cp_util as util

@ -1,3 +1,6 @@
# 应用基于一个窗口,窗口基于操作系统的消息机制
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QVBoxLayout, QTextEdit, QFileDialog
import cppy.cp_util as util

@ -1,3 +1,13 @@
'''
Web的MVC三层结构是互联网最火的应用框架
系统需要切分为模型视图控制三层
Python 中最简单的 Web服务器是 flask
app.py - Flask应用的主文件控制器Controller
models.py - 模型Model文件包含词频统计的逻辑
templates/index.html - 视图View文件用于展示结果
'''
from flask import Flask, render_template, request
from models import WordFrequencyModel

@ -0,0 +1 @@
异常主要发生在参数传递和代码块执行过程。一种原则是:软件不能挂掉。检查参数合理性、检查代码块执行可能的错误,并进行合理结果补齐,保持程序继续运行【 1 软件不能挂掉 】,另外一种情况是发生异常就抛出然后终止程序【 2 时间停止在那一刻 】,或者由上层函数接住,集中统一处理。【 3 预判可能的错误 】。

@ -2,9 +2,12 @@
import cppy.cp_util as util
from collections import Counter
# 古老的编码风格:使用状态机来计算词频
# 这种方法在Python中并不常见但它展示了如何使用状态机来管理程序的状态和流程
'''
状态机是计算机程序运行的基础理论
使用状态机的风格来处理文件并计算词频我们可以将整个过程分解为一系列状态转移
每个状态代表处理过程中的一个阶段比如读取文件分割单词计算词频
这种方法在Python中并不常见但它展示了如何使用状态机来管理程序的状态和流程
'''
class WordFrequencyStateMachine:
def __init__(self, file_path):

@ -1,4 +1,9 @@
## 任务
本项目的主要功能任务:做文本文件的分词,过滤常见词,求词频,并排序输出。
本项目的主要功能任务对指定文件读取文本在停用词过滤后按降序输出前10个高频词
我们研究这个问题的解法在各种情景下的表现形式
将 cppy整个目录转移到 anaconda3\Lib\site-packages 下面。里面放了一些共同的代码片段(函数),这样使得模式代码更短小简洁,便于更能集中理解各种模式的核心思想 。

@ -1,11 +1,13 @@
## Python 工程师的代码工具箱
初学编程者完成一门学校的标准课程学习后,会发现成熟的开源项目代码使用了完全不同课堂教学练习的代码风格。本项目主要用来回答这个问题:
<div align="center">
<big><big> 代码为啥要这样写,我要这样写代码 </big></big>
</div>
初学编程者完成一门学校的标准课程学习后,会发现成熟的开源项目代码使用了完全不同课堂教学练习的代码风格。而且总有一些模式(或者叫风格等等)反复出现。这些重复的模式是集体智慧的结晶,工程学上的最佳实践。本代码仓库对此做简单探索,用以提升 “编程思维” 之外的另外一个重要基础编码能力。
### 本项目的模块说明
A 代码模式
用一个简单任务,展示各种软件工程需求(完成任务简单、可读性强、可复用高、维护成本低等)下的代码写法

Loading…
Cancel
Save