forked from p46318075/CodePattern
Compare commits
124 Commits
Author | SHA1 | Date |
---|---|---|
|
74b622ee04 | 2 weeks ago |
|
27c8e450c9 | 2 weeks ago |
|
464471282f | 2 weeks ago |
|
ca6f8d97ee | 2 weeks ago |
|
a8200ff225 | 2 weeks ago |
|
56d6c04878 | 2 weeks ago |
|
7d03c9e5f0 | 2 weeks ago |
|
068c0f9bb8 | 2 weeks ago |
|
3c919aa5b6 | 2 weeks ago |
|
f2729b414f | 2 weeks ago |
|
2398743ab9 | 2 weeks ago |
|
6b1604413a | 2 weeks ago |
|
c29f01ece2 | 3 weeks ago |
|
cc841ffaae | 3 weeks ago |
|
a270414ff0 | 3 weeks ago |
|
8e7c4a3117 | 3 weeks ago |
|
e7f73ef2f4 | 3 weeks ago |
|
d727f0cba2 | 3 weeks ago |
|
dd11216128 | 3 weeks ago |
|
9845e7f38c | 3 weeks ago |
|
29c7d4a635 | 3 weeks ago |
|
aaba98303b | 3 weeks ago |
|
29f26846a0 | 1 month ago |
|
3f03b9014d | 3 months ago |
|
d782d65fb5 | 3 months ago |
|
5e83716c4d | 3 months ago |
|
d339ef454b | 3 months ago |
|
654dabbb69 | 3 months ago |
|
59ea2b479b | 3 months ago |
|
0c531354ce | 3 months ago |
|
dc44e0be4b | 3 months ago |
|
3ea3cbaa23 | 3 months ago |
|
0eb30e470f | 3 months ago |
|
4abad6851f | 3 months ago |
|
129f1aaa3f | 3 months ago |
|
617465cec6 | 3 months ago |
|
35e58525f1 | 3 months ago |
|
e5b9607dce | 3 months ago |
|
49bf182cf8 | 3 months ago |
|
ea53899bbd | 3 months ago |
|
0606fc586c | 3 months ago |
|
b77d297f3e | 3 months ago |
|
1712e964cf | 3 months ago |
|
8b9e813ee2 | 3 months ago |
|
7365ebb312 | 3 months ago |
|
524a65e492 | 3 months ago |
|
94800c4b9e | 4 months ago |
|
3d0220d49b | 10 months ago |
|
36afa1d669 | 10 months ago |
|
15736d7393 | 10 months ago |
|
f170c936d8 | 10 months ago |
|
ceb9955051 | 10 months ago |
|
4606a87618 | 10 months ago |
|
2a27a2c748 | 1 year ago |
|
26b6f4c88b | 1 year ago |
|
fa3e01dedc | 1 year ago |
|
850a3eb772 | 1 year ago |
|
8d5c578da8 | 1 year ago |
|
88606f2bce | 1 year ago |
|
ebe28f7670 | 1 year ago |
|
c8946209bf | 1 year ago |
|
2d46194636 | 1 year ago |
|
5099345721 | 1 year ago |
|
cd8186dd68 | 1 year ago |
|
50952795a8 | 1 year ago |
|
2cac3f2788 | 1 year ago |
|
44b0c00567 | 1 year ago |
|
83c156a3d5 | 1 year ago |
|
31a4dfc8e5 | 1 year ago |
|
e27ecadb25 | 1 year ago |
|
9d74a5c184 | 1 year ago |
|
a3bc46dae3 | 1 year ago |
|
f2ff5c8d4e | 1 year ago |
|
18f3901592 | 1 year ago |
|
44c1f9eb1e | 1 year ago |
|
b86f626e94 | 1 year ago |
|
fe94d8ed1b | 1 year ago |
|
b15c7505f6 | 1 year ago |
|
cab45b3281 | 1 year ago |
|
4aa6f8469d | 1 year ago |
|
f8f3f10d2e | 1 year ago |
|
7db531d2fc | 1 year ago |
|
41a14b6705 | 1 year ago |
|
ac7fb13827 | 1 year ago |
|
1920e47a1c | 1 year ago |
|
c5932334fa | 1 year ago |
|
239c0188d0 | 1 year ago |
|
c22c921cf8 | 1 year ago |
|
bfcaab3439 | 1 year ago |
|
f52645e7b2 | 1 year ago |
|
b6fc9ef4c3 | 1 year ago |
|
28f60e8216 | 1 year ago |
|
fdf6166100 | 1 year ago |
|
ffdae7d329 | 1 year ago |
|
0b9d4a63d6 | 1 year ago |
|
ada14b9a7b | 1 year ago |
|
c8cd7bbc0c | 1 year ago |
|
c99a655997 | 1 year ago |
|
950cb41e08 | 1 year ago |
|
f131c63ff4 | 1 year ago |
|
2518a5cd85 | 1 year ago |
|
e993c23ed1 | 1 year ago |
|
fb95636bb1 | 1 year ago |
|
285b016a30 | 1 year ago |
|
1ebf2a45fe | 1 year ago |
|
740f5aabff | 1 year ago |
|
2288c18e8a | 1 year ago |
|
028c7ddb07 | 1 year ago |
|
9bf690d62c | 1 year ago |
|
041fced368 | 1 year ago |
|
254c11c3c9 | 1 year ago |
|
29dbff26cc | 1 year ago |
|
4134d794ab | 1 year ago |
|
d54c43b459 | 1 year ago |
|
365c8bb76a | 1 year ago |
|
f8055c0044 | 1 year ago |
|
726a8795c7 | 1 year ago |
|
b4a280c55c | 1 year ago |
|
bfbc1120ec | 1 year ago |
|
3c439ef8d7 | 1 year ago |
|
445088fde8 | 1 year ago |
|
0e55cabe5c | 1 year ago |
|
856fdcc1e1 | 1 year ago |
|
8545ada6c2 | 1 year ago |
@ -0,0 +1,39 @@
|
||||
from cppy.cp_util import *
|
||||
from dataclasses import dataclass
|
||||
from collections import Counter
|
||||
import re
|
||||
|
||||
# 对象属性是现代 Python编程喜欢的风格
|
||||
# 这里使用了dataclass来简化代码
|
||||
|
||||
@dataclass
|
||||
class WordFrequency:
|
||||
text: str
|
||||
stop_words: set = None
|
||||
|
||||
def __post_init__(self):
|
||||
# 如果未提供停用词表
|
||||
if self.stop_words is None:
|
||||
self.stop_words = get_stopwords()
|
||||
|
||||
def tokenize(self):
|
||||
# 分词并去除停用词
|
||||
words = re.findall(r'\b\w+\b', self.text.lower())
|
||||
filtered_words = [word for word in words if word not in self.stop_words and len(word)>2]
|
||||
return filtered_words
|
||||
|
||||
def get_top_n(self, n=10):
|
||||
# 计算词频
|
||||
word_freqs = Counter(self.tokenize())
|
||||
return word_freqs.most_common(n)
|
||||
|
||||
|
||||
# 使用示例
|
||||
if __name__ == '__main__':
|
||||
# 创建WordFrequency实例
|
||||
text = read_file()
|
||||
word_freq = WordFrequency( text )
|
||||
|
||||
# 获取并打印词频
|
||||
top_words = word_freq.get_top_n()
|
||||
print_word_freqs(top_words)
|
@ -0,0 +1,20 @@
|
||||
from cppy.cp_util import *
|
||||
|
||||
#
|
||||
# 生成器 是一种简单异步实现
|
||||
#
|
||||
def non_stop_words(testfilepath):
|
||||
stopwords = get_stopwords()
|
||||
data_str = read_file(testfilepath)
|
||||
wordlist = re_split( data_str )
|
||||
for word in wordlist:
|
||||
if word not in stopwords:
|
||||
yield word # 弹出一个非停用词
|
||||
|
||||
|
||||
freqs = {}
|
||||
for word in non_stop_words(testfilepath):
|
||||
freqs[word] = freqs.get(word, 0) + 1
|
||||
|
||||
data = sort_dict(freqs)
|
||||
print_word_freqs(data)
|
@ -0,0 +1,3 @@
|
||||
from cppy.cp_util import *
|
||||
|
||||
print_word_freqs( sort_dict ( get_frequencies ( extract_file_words(testfilepath) )))
|
@ -0,0 +1,24 @@
|
||||
from cppy.cp_util import *
|
||||
|
||||
# 这个例子没有实际意义,是用来帮助理解其他例子
|
||||
# 主程序只需要启动第一个动作,后面的顺序逻辑写到各个函数里面了
|
||||
|
||||
def readfile(file_path, func):
|
||||
data = read_file(file_path)
|
||||
func(data, frequencies)
|
||||
|
||||
def extractwords(str_data,func):
|
||||
func(extract_str_words(str_data), sort)
|
||||
|
||||
def frequencies(word_list, func):
|
||||
wf = get_frequencies(word_list)
|
||||
func(wf, printall)
|
||||
|
||||
def sort(wf, func):
|
||||
func(sort_dict(wf), None)
|
||||
|
||||
def printall(word_freqs, _ ):
|
||||
print_word_freqs(word_freqs)
|
||||
|
||||
if __name__ == "__main__":
|
||||
readfile(testfilepath, extractwords)
|
@ -0,0 +1 @@
|
||||
异常主要发生在参数传递和代码块执行过程。一种原则是:软件不能挂掉。检查参数合理性、检查代码块执行可能的错误,并进行合理结果补齐,保持程序继续运行【 1 软件不能挂掉 】,另外一种情况是发生异常就抛出然后终止程序【 2 时间停止在那一刻 】,或者由上层函数接住,集中统一处理。【 3 预判可能的错误 】。
|
@ -1,27 +1,29 @@
|
||||
from collections import Counter
|
||||
from cppy.cp_util import *
|
||||
|
||||
|
||||
#
|
||||
# 遇到异常,退出程序
|
||||
#
|
||||
def extract_words(path_to_file):
|
||||
assert(type(path_to_file) is str), "I need a string!"
|
||||
assert(path_to_file), "I need a non-empty string!"
|
||||
assert(type(path_to_file) is str), "Must be a string!"
|
||||
assert(path_to_file), "Must be a non-empty string!"
|
||||
|
||||
try:
|
||||
with open(path_to_file,encoding='utf-8') as f:
|
||||
str_data = f.read()
|
||||
except IOError as e:
|
||||
print("I/O error({0}) when opening {1}: {2}! I quit!".format(e.errno, path_to_file, e.strerror))
|
||||
print("I/O error({0}) when opening {1}: {2}".format(e.errno, path_to_file, e.strerror))
|
||||
raise e
|
||||
|
||||
return re_split(str_data)
|
||||
|
||||
def remove_stop_words(word_list):
|
||||
assert(type(word_list) is list), "I need a list!"
|
||||
assert(type(word_list) is list), "Must be a list!"
|
||||
|
||||
try:
|
||||
stop_words = get_stopwords()
|
||||
except IOError as e:
|
||||
print("I/O error({0}) opening stops_words.txt: {1}! I quit!".format(e.errno, e.strerror))
|
||||
print("I/O error({0}) opening stops_words.txt: {1}".format(e.errno, e.strerror))
|
||||
raise e
|
||||
|
||||
return [w for w in word_list if not w in stop_words]
|
@ -0,0 +1,27 @@
|
||||
from cppy.cp_util import *
|
||||
|
||||
#
|
||||
# 用断言从事发点给出出错的准确信息
|
||||
#
|
||||
def extractWords(path_to_file):
|
||||
assert(type(path_to_file) is str), "Must be a string"
|
||||
assert(path_to_file), "Must be a non-empty string"
|
||||
return extract_file_words(path_to_file)
|
||||
|
||||
def frequencies(word_list):
|
||||
assert(type(word_list) is list), "Must be a list"
|
||||
assert(word_list != []), "Must be a non-empty list"
|
||||
return get_frequencies(word_list)
|
||||
|
||||
def sort(word_freqs):
|
||||
assert(type(word_freqs) is dict), "Must be a dictionary"
|
||||
assert(word_freqs != {}), "Must be a non-empty dictionary"
|
||||
return sort_dict(word_freqs)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
word_freqs = sort(frequencies(extractWords( testfilepath )))
|
||||
print_word_freqs(word_freqs)
|
||||
except Exception as e:
|
||||
print(" Something wrong: {0}".format(e) )
|
@ -0,0 +1,36 @@
|
||||
# 创建对象是消耗资源的,如果发现对象已经存在,可以返回引用,不创造新对象 。设计模式中这个做法叫享元
|
||||
# 可以降低资源需求和提升响应速度。更常见的该模式使用场景是各种资源池。
|
||||
|
||||
from cppy.cp_util import *
|
||||
|
||||
#享元类
|
||||
class WordFrequencyController():
|
||||
def __init__(self, controllertype,filepath ):
|
||||
word_list = extract_file_words(filepath)
|
||||
word_freq = get_frequencies(word_list)
|
||||
self.word_freq = sort_dict(word_freq)
|
||||
self.number = controllertype
|
||||
def print_word_freqs( self ):
|
||||
print_word_freqs( self.word_freq,self.number)
|
||||
|
||||
#享元工厂
|
||||
class WordFrequencyControllerFactory():
|
||||
def __init__(self):
|
||||
self.types = {}
|
||||
|
||||
def get_WordFrequencyController(self, number,testfilepath):
|
||||
if number not in self.types:
|
||||
self.types[number] = WordFrequencyController(number,testfilepath) # 创建新的对象
|
||||
print('new obj: ','*'*30,number)
|
||||
else:
|
||||
print('ref obj: ','*'*30,number)
|
||||
return self.types[number] # 重复使用已存在的对象
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
factory = WordFrequencyControllerFactory()
|
||||
for number in [ 1,3,5,3,5,7 ]:
|
||||
WordFrequency = factory.get_WordFrequencyController(number,testfilepath)
|
||||
# print(flush=True)
|
||||
WordFrequency.print_word_freqs()
|
||||
|
@ -0,0 +1,105 @@
|
||||
'''
|
||||
把观察者挂到自己的处理队列上
|
||||
'''
|
||||
|
||||
import os
|
||||
import re
|
||||
import threading
|
||||
from queue import Queue
|
||||
from collections import Counter
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
# 观察者接口
|
||||
class Observer(ABC):
|
||||
@abstractmethod
|
||||
def update(self, word_counts: Counter):
|
||||
pass
|
||||
|
||||
# 具体观察者:打印前 10 高频词
|
||||
class PrintTopWordsObserver(Observer):
|
||||
def update(self, word_counts: Counter):
|
||||
print("Top 10 高频词:")
|
||||
for word, count in word_counts.most_common(10):
|
||||
print(f"{word}: {count}")
|
||||
|
||||
# 具体观察者:保存词频到文件
|
||||
class SaveToFileObserver(Observer):
|
||||
def __init__(self, output_file):
|
||||
self.output_file = output_file
|
||||
|
||||
def update(self, word_counts: Counter):
|
||||
try:
|
||||
with open(self.output_file, 'w', encoding='utf-8') as f:
|
||||
for word, count in word_counts.most_common(10):
|
||||
f.write(f"{word}: {count}\n")
|
||||
print(f"词频已保存到 {self.output_file}")
|
||||
except Exception as e:
|
||||
print(f"保存失败: {e}")
|
||||
|
||||
# 词频统计器(主题)
|
||||
class WordFrequencyCounter:
|
||||
def __init__(self):
|
||||
self.observers = []
|
||||
self.counter = Counter()
|
||||
self.queue = Queue()
|
||||
self.lock = threading.Lock()
|
||||
|
||||
def add_observer(self, observer: Observer):
|
||||
self.observers.append(observer)
|
||||
|
||||
def remove_observer(self, observer: Observer):
|
||||
self.observers.remove(observer)
|
||||
|
||||
def notify_observers(self):
|
||||
for observer in self.observers:
|
||||
observer.update(self.counter)
|
||||
|
||||
def process_file(self):
|
||||
while True:
|
||||
try:
|
||||
file_path = self.queue.get_nowait()
|
||||
except:
|
||||
break
|
||||
try:
|
||||
with open(file_path, 'r', encoding='utf-8') as f:
|
||||
text = f.read().lower()
|
||||
words = re.findall(r'\b\w+\b', text)
|
||||
with self.lock:
|
||||
self.counter.update(words)
|
||||
except Exception as e:
|
||||
print(f"Error processing {file_path}: {e}")
|
||||
finally:
|
||||
self.queue.task_done()
|
||||
|
||||
def count_words(self, files, num_threads=4):
|
||||
# 将文件路径放入队列
|
||||
for file_path in files:
|
||||
self.queue.put(file_path)
|
||||
|
||||
# 创建并启动线程
|
||||
threads = [threading.Thread(target=self.process_file) for _ in range(num_threads)]
|
||||
for t in threads:
|
||||
t.start()
|
||||
for t in threads:
|
||||
t.join()
|
||||
|
||||
# 通知所有观察者
|
||||
self.notify_observers()
|
||||
|
||||
def main():
|
||||
# 获取文件列表
|
||||
data_dir = 'data'
|
||||
files = [os.path.join(data_dir, f) for f in os.listdir(data_dir) if f.endswith('.txt')]
|
||||
|
||||
# 创建词频统计器
|
||||
counter = WordFrequencyCounter()
|
||||
|
||||
# 添加观察者
|
||||
counter.add_observer(PrintTopWordsObserver())
|
||||
counter.add_observer(SaveToFileObserver("word_frequency.txt"))
|
||||
|
||||
# 统计词频并通知观察者
|
||||
counter.count_words(files)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -0,0 +1,5 @@
|
||||
|
||||
|
||||
[Plugins]
|
||||
;; Options: plugins/f1.pyc, plugins/f2.pyc
|
||||
frequencies = plugins/f2.pyc
|
@ -0,0 +1,34 @@
|
||||
|
||||
# 插件模式提供一种个别扩展性开发和系统核心开发无关的松耦合结构。
|
||||
# 简单说,第三方开发者在没有核心框架源码下也能扩展或者改造系统功能
|
||||
|
||||
import configparser, importlib.machinery
|
||||
from cppy.cp_util import *
|
||||
|
||||
class PluginManager:
|
||||
def __init__(self):
|
||||
self.plugins = {}
|
||||
|
||||
def load_plugins(self):
|
||||
_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
os.chdir(_dir)
|
||||
|
||||
config = configparser.ConfigParser()
|
||||
config.read("config.ini")
|
||||
|
||||
frequencies_plugin = config.get("Plugins", "frequencies")
|
||||
|
||||
# 加载插件
|
||||
self.plugins['word_freqs'] = importlib.machinery.SourcelessFileLoader('', frequencies_plugin).load_module()
|
||||
|
||||
def get_plugin(self, name):
|
||||
return self.plugins.get(name)
|
||||
|
||||
|
||||
# 创建 PluginManager 实例
|
||||
plugin_manager = PluginManager()
|
||||
plugin_manager.load_plugins()
|
||||
|
||||
wordlist = extract_file_words(testfilepath) # 提取文件中的单词
|
||||
word_freqs = plugin_manager.get_plugin('word_freqs').top_word(wordlist) # 调用实例方法
|
||||
print_word_freqs(word_freqs) # 打印词频
|
@ -0,0 +1,28 @@
|
||||
import py_compile
|
||||
|
||||
py_compile.compile('f1.py')
|
||||
py_compile.compile('f2.py')
|
||||
|
||||
import os
|
||||
import shutil
|
||||
|
||||
# 设置源目录和目标目录
|
||||
source_dir = os.path.join(os.path.dirname(__file__), '__pycache__') # 当前目录下的 __pycache__ 目录
|
||||
target_dir = os.path.join(os.path.dirname(__file__), '..', 'plugins') # 上一级目录下的 plugins 目录
|
||||
|
||||
# 确保目标目录存在
|
||||
os.makedirs(target_dir, exist_ok=True)
|
||||
|
||||
# 遍历源目录中的所有 .pyc 文件
|
||||
for filename in os.listdir(source_dir):
|
||||
if filename.endswith('.pyc'):
|
||||
# 提取文件名的前两个字符
|
||||
new_filename = filename[:2]
|
||||
# 构建源文件和目标文件的完整路径
|
||||
source_file = os.path.join(source_dir, filename)
|
||||
target_file = os.path.join(target_dir, new_filename + '.pyc')
|
||||
# 拷贝文件
|
||||
shutil.copyfile(source_file, target_file)
|
||||
# 删除原始文件
|
||||
os.remove(source_file)
|
||||
print(f"Copied {filename} to {target_file} and removed original file.")
|
@ -1,6 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import operator
|
||||
|
||||
def top25(word_list):
|
||||
def top_word(word_list):
|
||||
word_freqs = {}
|
||||
for w in word_list:
|
||||
if w in word_freqs:
|
@ -0,0 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import collections
|
||||
|
||||
def top_word(word_list):
|
||||
counts = collections.Counter( word_list )
|
||||
return counts.most_common(10)
|
||||
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1,25 @@
|
||||
import requests
|
||||
from cppy.cp_util import *
|
||||
|
||||
def main():
|
||||
# 读测试文件的内容
|
||||
content = read_file()
|
||||
|
||||
# 抽词
|
||||
tokenize_response = requests.post("http://localhost:7770/tokenize", json={"text": content})
|
||||
words = tokenize_response.json()["words"]
|
||||
|
||||
# 计算词频
|
||||
count_response = requests.post("http://localhost:7771/count", json={"words": words})
|
||||
word_count = count_response.json()["word_count"]
|
||||
|
||||
# 排序
|
||||
sort_response = requests.post("http://localhost:7772/sort", json={"word_count": word_count})
|
||||
top_10_words = sort_response.json()["top_10_words"]
|
||||
|
||||
print("Top 10 words:")
|
||||
print_word_freqs(top_10_words)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -0,0 +1,14 @@
|
||||
from fastapi import FastAPI
|
||||
from collections import Counter
|
||||
from cppy.cp_util import *
|
||||
import uvicorn
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
@app.post("/count")
|
||||
async def count(words_list: dict): # {"words": ["word1", "word2", ...]}
|
||||
word_count = Counter(words_list["words"])
|
||||
return {"word_count": dict(word_count)}
|
||||
|
||||
if __name__ == "__main__":
|
||||
uvicorn.run(app, host="127.0.0.1", port= 7771)
|
@ -0,0 +1,13 @@
|
||||
from fastapi import FastAPI
|
||||
import uvicorn
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
@app.post("/sort")
|
||||
async def sort(word_count_dict: dict):
|
||||
sorted_word_count = sorted(word_count_dict["word_count"].items(), key=lambda x: x[1], reverse=True)
|
||||
top_10_words = sorted_word_count[:10]
|
||||
return {"top_10_words": top_10_words}
|
||||
|
||||
if __name__ == "__main__":
|
||||
uvicorn.run(app, host="127.0.0.1", port= 7772)
|
@ -0,0 +1,13 @@
|
||||
from fastapi import FastAPI
|
||||
from cppy.cp_util import *
|
||||
import uvicorn
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
@app.post("/tokenize")
|
||||
async def tokenize(text: str):
|
||||
words = extract_str_words(text)
|
||||
return {"words": words}
|
||||
|
||||
if __name__ == "__main__":
|
||||
uvicorn.run(app, host="127.0.0.1", port= 7770)
|
Binary file not shown.
@ -1,6 +1,9 @@
|
||||
import time
|
||||
import cppy.cp_util as util
|
||||
|
||||
'''
|
||||
用反射实现装饰器的效果
|
||||
'''
|
||||
|
||||
# 工具函数
|
||||
def extract_words(path_to_file):
|
@ -0,0 +1,20 @@
|
||||
|
||||
# Python 作为弱类型语言希望拥有强类型语言类似的规范工整工程性的优点,牺牲一些代码的自由度。
|
||||
# 可以理解为更好的代码注释和更多的工程约束 。
|
||||
|
||||
import cppy.cp_util as util
|
||||
|
||||
|
||||
def extract_words(path_to_file:str) -> list:
|
||||
return util.extract_file_words(path_to_file)
|
||||
|
||||
def frequencies( word_list:list ) -> dict :
|
||||
return util.get_frequencies(word_list)
|
||||
|
||||
def sort(word_freq:dict) -> list :
|
||||
return util.sort_dict(word_freq)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
word_freqs = sort( frequencies(extract_words( util.testfilepath )) )
|
||||
util.print_word_freqs(word_freqs)
|
@ -0,0 +1,51 @@
|
||||
import re
|
||||
from collections import Counter
|
||||
|
||||
# 提供一个命令行交互方式来驱动程序运行
|
||||
|
||||
|
||||
# 清洗文本,移除标点符号并转换为小写
|
||||
def clean_text(text):
|
||||
return re.sub(r'[^\w\s]', '', text).lower()
|
||||
|
||||
# 统计词频
|
||||
def count_frequencies(text):
|
||||
return Counter(word for word in clean_text(text).split())
|
||||
|
||||
# 交互式提示用户输入文件路径和前n个单词的数量
|
||||
def interactive_mode():
|
||||
file_path = input("请输入文件路径 >> ")
|
||||
try:
|
||||
n = int(input("请输入你想要输出的前n个最常见单词的数量 >> "))
|
||||
if n <= 0:
|
||||
raise ValueError("数量必须大于0。")
|
||||
except ValueError as e:
|
||||
print(f"输入错误:{e}")
|
||||
return
|
||||
|
||||
try:
|
||||
# 打开文件并读取内容
|
||||
with open(file_path, 'r', encoding='utf-8') as file:
|
||||
text = file.read()
|
||||
|
||||
# 统计词频
|
||||
frequencies = count_frequencies(text)
|
||||
|
||||
# 获取前n个最常见的单词
|
||||
most_common = frequencies.most_common(n)
|
||||
|
||||
# 输出结果
|
||||
for word, freq in most_common:
|
||||
print(f"{word}: {freq}")
|
||||
except FileNotFoundError:
|
||||
print(f"文件未找到: {file_path}")
|
||||
except Exception as e:
|
||||
print(f"发生错误: {e}")
|
||||
|
||||
# 主函数
|
||||
def main():
|
||||
print("欢迎使用词频统计工具。")
|
||||
interactive_mode()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -1,3 +1,7 @@
|
||||
|
||||
# 命令行菜单驱动程序
|
||||
# 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
|
@ -0,0 +1,30 @@
|
||||
from flask import Flask, render_template, request, redirect, url_for
|
||||
from collections import Counter
|
||||
from cppy.cp_util import *
|
||||
import os
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route('/', methods=['GET', 'POST'])
|
||||
def index():
|
||||
if request.method == 'POST':
|
||||
# 获取上传的文件
|
||||
file = request.files['file']
|
||||
|
||||
# 保存临时文件并读取内容
|
||||
filename = os.path.join('/temp', file.filename)
|
||||
file.save(filename)
|
||||
|
||||
# 计算词频
|
||||
words = extract_file_words(filename)
|
||||
word_counts = Counter(words)
|
||||
|
||||
# 删除临时文件
|
||||
os.remove(filename)
|
||||
|
||||
return render_template('result.html', word_counts=word_counts.most_common())
|
||||
|
||||
return render_template('index.html')
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(debug=True)
|
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Upload Text File</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Upload a Text File to Count Word Frequencies</h1>
|
||||
<form action="/" method="post" enctype="multipart/form-data">
|
||||
<input type="file" name="file">
|
||||
<input type="submit" value="Submit">
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Word Frequencies</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Top Word Frequencies:</h1>
|
||||
<ul>
|
||||
{% for word, count in word_counts %}
|
||||
<li>{{ word }}: {{ count }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<a href="{{ url_for('index') }}">Back to Upload</a>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,23 @@
|
||||
# 装饰器模式允许我们在不修改原有类的基础上,动态地添加额外的功能。
|
||||
# 就增加功能来说,装饰器模式比生成子类更为灵活。
|
||||
# 餐吧的顾客可以选择为他们的咖啡添加额外的调料。
|
||||
class Beverage:
|
||||
def __init__(self, description):
|
||||
self.description = description
|
||||
self.price = 0.0
|
||||
|
||||
def cost(self):
|
||||
return self.price
|
||||
|
||||
class CondimentDecorator(Beverage): # 进行装饰
|
||||
def __init__(self, beverage, description, price_increase):
|
||||
self.beverage = beverage
|
||||
self.description = f"{beverage.description}, {description}"
|
||||
self.price_increase = price_increase
|
||||
|
||||
def cost(self):
|
||||
return self.beverage.cost() + self.price_increase
|
||||
|
||||
# 使用装饰器模式
|
||||
coffee = Beverage("Espresso")
|
||||
coffee_with_chocolate = CondimentDecorator(coffee, "Chocolate", 0.50)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue