Compare commits
	
		
			16 Commits 
		
	
	
		
			master
			...
			Bug393-Tan
		
	
	| Author | SHA1 | Date | 
|---|---|---|
|  | e19d1ae51b | |
|  | 782783040a | |
|  | 9a95842b7c | |
|  | 3e0b8a0235 | |
|  | b22c654f0f | |
|  | d402bb45cb | |
|  | cdf6180901 | |
|  | 38837c9c2f | |
|  | a0ddf4bdad | |
|  | df64065dcc | |
|  | ce28b91bd5 | |
|  | d6bd24ee1c | |
|  | e9e2bd3d23 | |
|  | 320a99d479 | |
|  | 3eca9234a9 | |
|  | 8924166975 | 
|  | @ -1,14 +1,8 @@ | |||
| from WordFreq import WordFreq | ||||
| from wordfreqCMD import youdao_link, sort_in_descending_order | ||||
| from UseSqlite import InsertQuery, RecordQuery | ||||
| import pickle_idea, pickle_idea2 | ||||
| import os | ||||
| import random, glob | ||||
| import hashlib | ||||
| from datetime import datetime | ||||
| from flask import Flask, request, redirect, render_template, url_for, session, abort, flash, get_flashed_messages | ||||
| import random | ||||
| import pickle_idea | ||||
| from difficulty import get_difficulty_level_for_user, text_difficulty_level, user_difficulty_level | ||||
| 
 | ||||
| from UseSqlite import RecordQuery | ||||
| 
 | ||||
| path_prefix = '/var/www/wordfreq/wordfreq/' | ||||
| path_prefix = './'  # comment this line in deployment | ||||
|  | @ -33,19 +27,26 @@ def get_article_body(s): | |||
| 
 | ||||
| 
 | ||||
| def get_today_article(user_word_list, visited_articles): | ||||
|     ''' | ||||
|     根据用户的单词列表和阅读过的文章返回需要的文章的全部信息 | ||||
|     ''' | ||||
|     rq = RecordQuery(path_prefix + 'static/wordfreqapp.db') | ||||
|     if visited_articles is None: | ||||
|         visited_articles = { | ||||
|             "index" : 0,  # 为 article_ids 的索引 | ||||
|             "index": 0,  # 为 article_ids 的索引 | ||||
|             "article_ids": []  # 之前显示文章的id列表,越后越新 | ||||
|         } | ||||
|     if visited_articles["index"] > len(visited_articles["article_ids"])-1:  # 生成新的文章,因此查找所有的文章 | ||||
|         rq.instructions("SELECT * FROM article") | ||||
|     else:  # 生成阅读过的文章,因此查询指定 article_id 的文章 | ||||
|         if visited_articles["article_ids"][visited_articles["index"]] == 'null':  # 可能因为直接刷新页面导致直接去查询了'null',因此当刷新的页面的时候,需要直接进行“上一篇”操作 | ||||
|         # 可能因为直接刷新页面导致直接去查询了'null',因此当刷新的页面的时候,需要直接进行“上一篇”操作 | ||||
|         if visited_articles["article_ids"][visited_articles["index"]] == 'null': | ||||
|             visited_articles["index"] -= 1 | ||||
|             visited_articles["article_ids"].pop() | ||||
|         rq.instructions('SELECT * FROM article WHERE article_id=%d' % (visited_articles["article_ids"][visited_articles["index"]])) | ||||
|         rq.instructions( | ||||
|             f'SELECT * FROM article WHERE article_id=' | ||||
|             f'{visited_articles["article_ids"][visited_articles["index"]]}' | ||||
|         ) | ||||
|     rq.do() | ||||
|     result = rq.get_results() | ||||
|     random.shuffle(result) | ||||
|  | @ -58,19 +59,23 @@ def get_today_article(user_word_list, visited_articles): | |||
|     d = None | ||||
|     result_of_generate_article = "not found" | ||||
|     d_user = load_freq_history(user_word_list) | ||||
|     user_level = user_difficulty_level(d_user, d3)  # more consideration as user's behaviour is dynamic. Time factor should be considered. | ||||
|     # 更多的考虑,因为用户的行为是动态的。应考虑时间因素。 | ||||
|     user_level = user_difficulty_level(d_user, d3) | ||||
|     text_level = 0 | ||||
|     if visited_articles["index"] > len(visited_articles["article_ids"])-1:  # 生成新的文章 | ||||
|         amount_of_visited_articles = len(visited_articles["article_ids"]) | ||||
|         amount_of_existing_articles = result.__len__() | ||||
|         if amount_of_visited_articles == amount_of_existing_articles:  # 如果当前阅读过的文章的数量 == 存在的文章的数量,即所有的书本都阅读过了 | ||||
|         amount_of_existing_articles = len(result) | ||||
|         # 如果当前阅读过的文章的数量 == 存在的文章的数量,即所有的书本都阅读过了 | ||||
|         if amount_of_visited_articles == amount_of_existing_articles: | ||||
|             result_of_generate_article = "had read all articles" | ||||
|         else: | ||||
|             for k in range(3):  # 最多尝试3次 | ||||
|                 for reading in result: | ||||
|                     text_level = text_difficulty_level(reading['text'], d3) | ||||
|                     factor = random.gauss(0.8, 0.1)  # a number drawn from Gaussian distribution with a mean of 0.8 and a stand deviation of 1 | ||||
|                     if reading['article_id'] not in visited_articles["article_ids"] and within_range(text_level, user_level, (8.0 - user_level) * factor):  # 新的文章之前没有出现过且符合一定范围的水平 | ||||
|                     # 从高斯分布中得出的平均值为 0.8,站位偏差为 1 的数字 | ||||
|                     factor = random.gauss(0.8, 0.1) | ||||
|                     # 新的文章之前没有出现过且符合一定范围的水平 | ||||
|                     if reading['article_id'] not in visited_articles["article_ids"] and within_range(text_level, user_level, (8.0 - user_level) * factor): | ||||
|                         d = reading | ||||
|                         visited_articles["article_ids"].append(d['article_id'])  # 列表添加新的文章id;下面进行 | ||||
|                         result_of_generate_article = "found" | ||||
|  | @ -87,8 +92,8 @@ def get_today_article(user_word_list, visited_articles): | |||
|     today_article = None | ||||
|     if d: | ||||
|         today_article = { | ||||
|             "user_level": '%4.2f' % user_level, | ||||
|             "text_level": '%4.2f' % text_level, | ||||
|             "user_level": f'{user_level:4.2f}', | ||||
|             "text_level": f'{text_level:4.2f}', | ||||
|             "date": d['date'], | ||||
|             "article_title": get_article_title(d['text']), | ||||
|             "article_body": get_article_body(d['text']), | ||||
|  |  | |||
							
								
								
									
										13
									
								
								app/Login.py
								
								
								
								
							
							
						
						
									
										13
									
								
								app/Login.py
								
								
								
								
							|  | @ -1,7 +1,6 @@ | |||
| import hashlib | ||||
| import string | ||||
| from datetime import datetime, timedelta | ||||
| from UseSqlite import InsertQuery, RecordQuery | ||||
| 
 | ||||
| def md5(s): | ||||
|     ''' | ||||
|  | @ -12,14 +11,13 @@ def md5(s): | |||
|     h = hashlib.md5(s.encode(encoding='utf-8')) | ||||
|     return h.hexdigest() | ||||
| 
 | ||||
| # import model.user after the defination of md5(s) to avoid circular import | ||||
| from model.user import get_user_by_username, insert_user, update_password_by_username | ||||
| from app.model.user import get_user_by_username, insert_user, update_password_by_username | ||||
| 
 | ||||
| path_prefix = '/var/www/wordfreq/wordfreq/' | ||||
| path_prefix = './'  # comment this line in deployment | ||||
| 
 | ||||
| def verify_pass(newpass,oldpass): | ||||
|     if(newpass==oldpass): | ||||
|     if newpass==oldpass: | ||||
|         return True | ||||
| 
 | ||||
| 
 | ||||
|  | @ -63,8 +61,7 @@ def get_expiry_date(username): | |||
|     user = get_user_by_username(username) | ||||
|     if user is None: | ||||
|         return '20191024' | ||||
|     else: | ||||
|         return user.expiry_date | ||||
|     return user.expiry_date | ||||
| 
 | ||||
| class UserName: | ||||
|     def __init__(self, username): | ||||
|  | @ -77,6 +74,7 @@ class UserName: | |||
|             return 'Period (.) is not allowed as the first letter in the user name.' | ||||
|         if ' ' in self.username: # a user name must not include a whitespace | ||||
|             return 'Whitespace is not allowed in the user name.' | ||||
| 
 | ||||
|         for c in self.username: # a user name must not include special characters, except non-leading periods or underscores | ||||
|             if c in string.punctuation and c != '.' and c != '_': | ||||
|                 return f'{c} is not allowed in the user name.' | ||||
|  | @ -91,5 +89,4 @@ class WarningMessage: | |||
|         self.s = s | ||||
| 
 | ||||
|     def __str__(self): | ||||
|         return UserName(self.s).validate() | ||||
| 
 | ||||
|         return UserName(self.s).validate() | ||||
|  | @ -2,9 +2,9 @@ | |||
| # Copyright 2019 (C) Hui Lan <hui.lan@cantab.net> | ||||
| # Written permission must be obtained from the author for commercial uses. | ||||
| ########################################################################### | ||||
| 
 | ||||
| from wordfreqCMD import remove_punctuation, freq, sort_in_descending_order | ||||
| import string | ||||
| from wordfreqCMD import remove_punctuation, freq, sort_in_descending_order | ||||
| 
 | ||||
| 
 | ||||
| class WordFreq: | ||||
|     def __init__(self, s): | ||||
|  | @ -17,7 +17,7 @@ class WordFreq: | |||
|             if len(word) > 0 and word[0] in string.ascii_letters: | ||||
|                 lst.append(t) | ||||
|         return sort_in_descending_order(lst) | ||||
|      | ||||
| 
 | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
|     f = WordFreq('BANANA; Banana, apple ORANGE Banana banana.') | ||||
|  |  | |||
|  | @ -6,7 +6,6 @@ Yaml.py | |||
|     ./layout/partial/footer.html | ||||
| ''' | ||||
| import yaml as YAML | ||||
| import os | ||||
| 
 | ||||
| path_prefix = './'  # comment this line in deployment | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,46 +1,44 @@ | |||
| from flask import * | ||||
| from Login import check_username_availability, verify_user, add_user, get_expiry_date, change_password, WarningMessage | ||||
| 
 | ||||
| from flask import Blueprint, request, render_template, jsonify,session,redirect, url_for,escape | ||||
| from Login import check_username_availability, verify_user, add_user,get_expiry_date, change_password, WarningMessage | ||||
| 
 | ||||
| # 初始化蓝图 | ||||
| accountService = Blueprint("accountService", __name__) | ||||
| 
 | ||||
| ### Sign-up, login, logout ### | ||||
| ### sign-up, login, logout, reset### | ||||
| @accountService.route("/signup", methods=['GET', 'POST']) | ||||
| def signup(): | ||||
|     ''' | ||||
|     注册 | ||||
|     :return: 根据注册是否成功返回不同界面 | ||||
|     ''' | ||||
|     # GET方法直接返回注册页面 | ||||
|     if request.method == 'GET': | ||||
|         # GET方法直接返回注册页面 | ||||
|         return render_template('signup.html') | ||||
|     elif request.method == 'POST': | ||||
|         # POST方法需判断是否注册成功,再根据结果返回不同的内容 | ||||
|         username = escape(request.form['username']) | ||||
|         password = escape(request.form['password']) | ||||
|          | ||||
|         #! 添加如下代码为了过滤注册时的非法字符 | ||||
|         warn = WarningMessage(username) | ||||
|         if str(warn) != 'OK': | ||||
|             return jsonify({'status': '3', 'warn': str(warn)}) | ||||
|          | ||||
|         available = check_username_availability(username) | ||||
|         if not available: # 用户名不可用 | ||||
|             return jsonify({'status': '0'}) | ||||
|         else: # 添加账户信息 | ||||
|             add_user(username, password) | ||||
|             verified = verify_user(username, password) | ||||
|             if verified: | ||||
|                 # 写入session | ||||
|                 session['logged_in'] = True | ||||
|                 session[username] = username | ||||
|                 session['username'] = username | ||||
|                 session['expiry_date'] = get_expiry_date(username) | ||||
|                 session['visited_articles'] = None | ||||
|                 return jsonify({'status': '2'}) | ||||
|             else: | ||||
|                 return jsonify({'status': '1'}) | ||||
| 
 | ||||
|     # POST方法需判断是否注册成功,再根据结果返回不同的内容 | ||||
|     username = escape(request.form['username']) | ||||
|     password = escape(request.form['password']) | ||||
|     #! 添加如下代码为了过滤注册时的非法字符 | ||||
|     warn = WarningMessage(username) | ||||
|     if str(warn) != 'OK': | ||||
|         return jsonify({'status': '3', 'warn': str(warn)}) | ||||
|     available = check_username_availability(username) | ||||
|     # 用户名不可用 | ||||
|     if not available: | ||||
|         return jsonify({'status': '0'}) | ||||
|     # 用户名可用,添加账户信息 | ||||
|     add_user(username, password) | ||||
|     verified = verify_user(username, password) | ||||
|     # 注册成功,写入session | ||||
|     if verified: | ||||
|         session['logged_in'] = True | ||||
|         session[username] = username | ||||
|         session['username'] = username | ||||
|         session['expiry_date'] = get_expiry_date(username) | ||||
|         session['visited_articles'] = None | ||||
|         return jsonify({'status': '2'}) | ||||
|     # 验证失败 | ||||
|     return jsonify({'status': '1'}) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  | @ -50,26 +48,25 @@ def login(): | |||
|     登录 | ||||
|     :return: 根据登录是否成功返回不同页面 | ||||
|     ''' | ||||
|     # GET方法直接返回登录页面 | ||||
|     if request.method == 'GET': | ||||
|         # GET请求 | ||||
|         return render_template('login.html') | ||||
|     elif request.method == 'POST': | ||||
|         # POST方法用于判断登录是否成功 | ||||
|         # check database and verify user | ||||
|         username = escape(request.form['username']) | ||||
|         password = escape(request.form['password']) | ||||
|         verified = verify_user(username, password) | ||||
|         if verified: | ||||
|             # 登录成功,写入session | ||||
|             session['logged_in'] = True | ||||
|             session[username] = username | ||||
|             session['username'] = username | ||||
|             user_expiry_date = get_expiry_date(username) | ||||
|             session['expiry_date'] = user_expiry_date | ||||
|             session['visited_articles'] = None | ||||
|             return jsonify({'status': '1'}) | ||||
|         else: | ||||
|             return jsonify({'status': '0'}) | ||||
| 
 | ||||
|     # POST方法用于判断登录是否成功,检查数据库并验证用户,再根据结果返回不同的内容 | ||||
|     username = escape(request.form['username']) | ||||
|     password = escape(request.form['password']) | ||||
|     verified = verify_user(username, password) | ||||
|     # 登录成功,写入session | ||||
|     if verified: | ||||
|         session['logged_in'] = True | ||||
|         session[username] = username | ||||
|         session['username'] = username | ||||
|         user_expiry_date = get_expiry_date(username) | ||||
|         session['expiry_date'] = user_expiry_date | ||||
|         session['visited_articles'] = None | ||||
|         return jsonify({'status': '1'}) | ||||
|     #验证失败 | ||||
|     return jsonify({'status': '0'}) | ||||
| 
 | ||||
| 
 | ||||
| @accountService.route("/logout", methods=['GET', 'POST']) | ||||
|  | @ -95,16 +92,18 @@ def reset(): | |||
|     username = session['username'] | ||||
|     if username == '': | ||||
|         return redirect('/login') | ||||
| 
 | ||||
|     # GET请求返回修改密码页面 | ||||
|     if request.method == 'GET': | ||||
|         # GET请求返回修改密码页面 | ||||
|         return render_template('reset.html', username=session['username'], state='wait') | ||||
|     else: | ||||
|         # POST请求用于提交修改后信息 | ||||
|         old_password = escape(request.form['old-password']) | ||||
|         new_password = escape(request.form['new-password']) | ||||
|         flag = change_password(username, old_password, new_password) # flag表示是否修改成功 | ||||
|         if flag: | ||||
|             session['logged_in'] = False | ||||
|             return jsonify({'status':'1'})  # 修改成功 | ||||
|         else: | ||||
|             return jsonify({'status':'2'})  # 修改失败 | ||||
| 
 | ||||
|     # POST请求用于提交修改后信息 | ||||
|     old_password = escape(request.form['old-password']) | ||||
|     new_password = escape(request.form['new-password']) | ||||
|     flag = change_password(username, old_password, new_password) # flag表示是否修改成功 | ||||
|     # 修改成功 | ||||
|     if flag: | ||||
|         session['logged_in'] = False | ||||
|         return jsonify({'status':'1'}) | ||||
|     # 修改失败 | ||||
|     return jsonify({'status':'2'}) | ||||
|  |  | |||
|  | @ -1,17 +1,17 @@ | |||
| # System Library | ||||
| from flask import * | ||||
| from flask import Blueprint, session, render_template, request, flash | ||||
| 
 | ||||
| # Personal library | ||||
| from Yaml import yml | ||||
| from model.user import * | ||||
| from model.article import * | ||||
| 
 | ||||
| from model.user import get_users, update_password_by_username | ||||
| from model.user import update_expiry_time_by_username, get_user_by_username | ||||
| from model.article import get_number_of_articles, get_page_articles | ||||
| from model.article import delete_article_by_id, add_article | ||||
| ADMIN_NAME = "lanhui"  # unique admin name | ||||
| _cur_page = 1  # current article page | ||||
| _page_size = 5  # article sizes per page | ||||
| adminService = Blueprint("admin_service", __name__) | ||||
| 
 | ||||
| 
 | ||||
| def check_is_admin(): | ||||
|     # 未登录,跳转到未登录界面 | ||||
|     if not session.get("logged_in"): | ||||
|  | @ -26,6 +26,10 @@ def check_is_admin(): | |||
| 
 | ||||
| @adminService.route("/admin", methods=["GET"]) | ||||
| def admin(): | ||||
|     ''' | ||||
|     判断是否是管理员登录 | ||||
|     :return:不同页面 | ||||
|     ''' | ||||
|     is_admin = check_is_admin() | ||||
|     if is_admin != "pass": | ||||
|         return is_admin | ||||
|  | @ -37,6 +41,11 @@ def admin(): | |||
| 
 | ||||
| @adminService.route("/admin/article", methods=["GET", "POST"]) | ||||
| def article(): | ||||
|     ''' | ||||
|     管理文章 | ||||
|     可添加文章、删除文章 | ||||
|     return:不同页面 | ||||
|     ''' | ||||
|     global _cur_page, _page_size | ||||
| 
 | ||||
|     is_admin = check_is_admin() | ||||
|  | @ -49,16 +58,15 @@ def article(): | |||
|             max(1, int(request.args.get("size", 5))), _article_number | ||||
|         )  # 最小的size是1 | ||||
|         _cur_page = min( | ||||
|             max(1, int(request.args.get("page", 1))), _article_number // _page_size + (_article_number % _page_size > 0) | ||||
|             max(1, int(request.args.get("page", 1))), | ||||
|             _article_number // _page_size + (_article_number % _page_size > 0) | ||||
|         )  # 最小的page是1 | ||||
|     except ValueError: | ||||
|         return "page parmas must be int!" | ||||
|      | ||||
|     _articles = get_page_articles(_cur_page, _page_size) | ||||
|     for article in _articles:   # 获取每篇文章的title | ||||
|         article.title = article.text.split("\n")[0] | ||||
|         article.content = '<br/>'.join(article.text.split("\n")[1:]) | ||||
|      | ||||
|     for _article in _articles:   # 获取每篇文章的title | ||||
|         _article.title = _article.text.split("\n")[0] | ||||
|         _article.content = '<br/>'.join(_article.text.split("\n")[1:]) | ||||
|     context = { | ||||
|         "article_number": _article_number, | ||||
|         "text_list": _articles, | ||||
|  | @ -72,19 +80,19 @@ def article(): | |||
|         context["article_number"] = article_len | ||||
|         context["text_list"] = get_page_articles(_cur_page, _page_size) | ||||
|         _articles = get_page_articles(_cur_page, _page_size) | ||||
|         for article in _articles:   # 获取每篇文章的title | ||||
|             article.title = article.text.split("\n")[0] | ||||
|         for _article in _articles:   # 获取每篇文章的title | ||||
|             _article.title = _article.text.split("\n")[0] | ||||
|         context["text_list"] = _articles | ||||
| 
 | ||||
|     if request.method == "GET": | ||||
|         try: | ||||
|             delete_id = int(request.args.get("delete_id", 0)) | ||||
|         except: | ||||
|         except ValueError: | ||||
|             return "Delete article ID must be int!" | ||||
|         if delete_id:  # delete article | ||||
|             delete_article_by_id(delete_id) | ||||
|             _update_context() | ||||
|     elif request.method == "POST": | ||||
|     else: | ||||
|         data = request.form | ||||
|         content = data.get("content", "") | ||||
|         source = data.get("source", "") | ||||
|  | @ -102,17 +110,21 @@ def article(): | |||
| 
 | ||||
| @adminService.route("/admin/user", methods=["GET", "POST"]) | ||||
| def user(): | ||||
|     ''' | ||||
|     用户管理 | ||||
|     可修改用户密码,过期日期 | ||||
|     return:不同页面 | ||||
|     ''' | ||||
|     is_admin = check_is_admin() | ||||
|     if is_admin != "pass": | ||||
|         return is_admin | ||||
|      | ||||
|     context = { | ||||
|         "user_list": get_users(), | ||||
|         "username": session.get("username"), | ||||
|     } | ||||
|     if request.method == "POST": | ||||
|         data = request.form | ||||
|         username = data.get("username","") | ||||
|         username = data.get("username", "") | ||||
|         new_password = data.get("new_password", "") | ||||
|         expiry_time = data.get("expiry_time", "") | ||||
|         if username: | ||||
|  | @ -127,6 +139,9 @@ def user(): | |||
| 
 | ||||
| @adminService.route("/admin/expiry", methods=["GET"]) | ||||
| def user_expiry_time(): | ||||
|     ''' | ||||
|     返回用户的过期日期 | ||||
|     ''' | ||||
|     is_admin = check_is_admin() | ||||
|     if is_admin != "pass": | ||||
|         return is_admin | ||||
|  | @ -135,8 +150,7 @@ def user_expiry_time(): | |||
|     if not username: | ||||
|         return "Username can't be empty." | ||||
| 
 | ||||
|     user = get_user_by_username(username) | ||||
|     if not user: | ||||
|     existed_user = get_user_by_username(username) | ||||
|     if not existed_user: | ||||
|         return "User does not exist." | ||||
| 
 | ||||
|     return user.expiry_date | ||||
|     return existed_user.expiry_date | ||||
|  |  | |||
|  | @ -6,15 +6,14 @@ | |||
| # Purpose: compute difficulty level of a English text | ||||
| 
 | ||||
| import pickle | ||||
| import math | ||||
| from wordfreqCMD import remove_punctuation, freq, sort_in_descending_order, sort_in_ascending_order | ||||
| import snowballstemmer | ||||
| from wordfreqCMD import remove_punctuation, freq, sort_in_descending_order, sort_in_ascending_order | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| def load_record(pickle_fname): | ||||
|     f = open(pickle_fname, 'rb') | ||||
|     d = pickle.load(f) | ||||
|     f.close() | ||||
|     with open(pickle_fname, 'rb') as f: | ||||
|         d = pickle.load(f) | ||||
|     return d | ||||
| 
 | ||||
| 
 | ||||
|  | @ -53,9 +52,7 @@ def get_difficulty_level_for_user(d1, d2): | |||
|     stemmer = snowballstemmer.stemmer('english') | ||||
| 
 | ||||
|     for k in d1:  # 用户的词 | ||||
|         if k in d2:  # 如果用户的词以原型的形式存在于词库d2中 | ||||
|             continue  # 无需评级,跳过 | ||||
|         else: | ||||
|         if k not in d2:  # 如果用户的词以原型的形式不存在于词库d2中 | ||||
|             stem = stemmer.stemWord(k) | ||||
|             if stem in d2:  # 如果用户的词的词根存在于词库d2的词根库中 | ||||
|                 d2[k] = d2[stem]  # 按照词根进行评级 | ||||
|  | @ -88,6 +85,9 @@ def revert_dict(d): | |||
| 
 | ||||
| 
 | ||||
| def user_difficulty_level(d_user, d): | ||||
|     ''' | ||||
|     得到用户词汇的难度水平 | ||||
|     ''' | ||||
|     d_user2 = revert_dict(d_user)  # key is date, and value is a list of words added in that date | ||||
|     count = 0 | ||||
|     geometric = 1 | ||||
|  | @ -242,10 +242,7 @@ We need — for our farmers, our manufacturers, for, frankly, unions and non-uni | |||
| ''' | ||||
| 
 | ||||
|     # f = open('bbc-fulltext/bbc/entertainment/001.txt') | ||||
|     f = open('wordlist.txt') | ||||
|     s = f.read() | ||||
|     f.close() | ||||
| 
 | ||||
|     print(text_difficulty_level(s, d3)) | ||||
| 
 | ||||
|     with open('wordlist.txt', encoding='utf-8') as f: | ||||
|         s = f.read() | ||||
| 
 | ||||
|     print(text_difficulty_level(s, d3)) | ||||
							
								
								
									
										22
									
								
								app/main.py
								
								
								
								
							
							
						
						
									
										22
									
								
								app/main.py
								
								
								
								
							|  | @ -1,17 +1,24 @@ | |||
| #! /usr/bin/python3 | ||||
| # -*- coding: utf-8 -*- | ||||
| import os | ||||
| import random | ||||
| 
 | ||||
| ########################################################################### | ||||
| # Copyright 2019 (C) Hui Lan <hui.lan@cantab.net> | ||||
| # Written permission must be obtained from the author for commercial uses. | ||||
| ########################################################################### | ||||
| from flask import escape | ||||
| from Login import * | ||||
| from Article import * | ||||
| import glob | ||||
| from flask import Flask, request, redirect, render_template, url_for, escape | ||||
| from WordFreq import WordFreq | ||||
| import pickle_idea | ||||
| from wordfreqCMD import  sort_in_descending_order | ||||
| from Article import load_freq_history, total_number_of_essays | ||||
| import Yaml | ||||
| from user_service import userService | ||||
| from account_service import accountService | ||||
| from admin_service import adminService, ADMIN_NAME | ||||
| 
 | ||||
| 
 | ||||
| app = Flask(__name__) | ||||
| app.secret_key = 'lunch.time!' | ||||
| 
 | ||||
|  | @ -51,8 +58,7 @@ def appears_in_test(word, d): | |||
|     ''' | ||||
|     if not word in d: | ||||
|         return '' | ||||
|     else: | ||||
|         return ','.join(d[word]) | ||||
|     return ','.join(d[word]) | ||||
| 
 | ||||
| 
 | ||||
| @app.route("/mark", methods=['GET', 'POST']) | ||||
|  | @ -70,8 +76,8 @@ def mark_word(): | |||
|         d = pickle_idea.merge_frequency(lst, lst_history) | ||||
|         pickle_idea.save_frequency_to_pickle(d, path_prefix + 'static/frequency/frequency.p') | ||||
|         return redirect(url_for('mainpage')) | ||||
|     else: # 不回应GET请求 | ||||
|         return 'Under construction' | ||||
|     # 不回应GET请求 | ||||
|     return 'Under construction' | ||||
| 
 | ||||
| 
 | ||||
| @app.route("/", methods=['GET', 'POST']) | ||||
|  | @ -91,7 +97,7 @@ def mainpage(): | |||
|         pickle_idea.save_frequency_to_pickle(d, path_prefix + 'static/frequency/frequency.p') | ||||
|         return render_template('mainpage_post.html', lst=lst, yml=Yaml.yml) | ||||
| 
 | ||||
|     elif request.method == 'GET':  # when we load a html page | ||||
|     if request.method == 'GET':  # when we load a html page | ||||
|         random_ads = get_random_ads() | ||||
|         number_of_essays = total_number_of_essays() | ||||
|         d = load_freq_history(path_prefix + 'static/frequency/frequency.p') | ||||
|  |  | |||
|  | @ -19,15 +19,15 @@ def lst2dict(lst, d): | |||
|     for x in lst: | ||||
|         word = x[0] | ||||
|         freq = x[1] | ||||
|         if not word in d: | ||||
|             d[word] = freq  | ||||
|         if word not in d: | ||||
|             d[word] = freq | ||||
|         else: | ||||
|             d[word] += freq | ||||
| 
 | ||||
| 
 | ||||
| def dict2lst(d): | ||||
|     return list(d.items()) # a list of (key, value) pairs | ||||
|          | ||||
| 
 | ||||
| 
 | ||||
| def merge_frequency(lst1, lst2): | ||||
|     d = {} | ||||
|  | @ -37,29 +37,27 @@ def merge_frequency(lst1, lst2): | |||
| 
 | ||||
| 
 | ||||
| def load_record(pickle_fname): | ||||
|     f = open(pickle_fname, 'rb') | ||||
|     d = pickle.load(f) | ||||
|     f.close() | ||||
|     with open(pickle_fname, 'rb') as f: | ||||
|         d = pickle.load(f) | ||||
|     return d | ||||
| 
 | ||||
| 
 | ||||
| def save_frequency_to_pickle(d, pickle_fname): | ||||
|     f = open(pickle_fname, 'wb') | ||||
|     #exclusion_lst = ['one', 'no', 'has', 'had', 'do', 'that', 'have', 'by', 'not', 'but', 'we', 'this', 'my', 'him', 'so', 'or', 'as', 'are', 'it', 'from', 'with', 'be', 'can', 'for', 'an', 'if', 'who', 'whom', 'whose', 'which', 'the', 'to', 'a', 'of', 'and', 'you', 'i', 'he', 'she', 'they', 'me', 'was', 'were', 'is', 'in', 'at', 'on', 'their', 'his', 'her', 's', 'said', 'all', 'did', 'been', 'w'] | ||||
|     exclusion_lst = [] | ||||
|     d2 = {} | ||||
|     for k in d: | ||||
|         if not k in exclusion_lst and not k.isnumeric() and len(k) > 1: | ||||
|             d2[k] = d[k] | ||||
|     pickle.dump(d2, f) | ||||
|     f.close() | ||||
|     with open(pickle_fname, 'wb') as f: | ||||
|         #exclusion_lst = ['one', 'no', 'has', 'had', 'do', 'that', 'have', 'by', 'not', 'but', 'we', 'this', 'my', 'him', 'so', 'or', 'as', 'are', 'it', 'from', 'with', 'be', 'can', 'for', 'an', 'if', 'who', 'whom', 'whose', 'which', 'the', 'to', 'a', 'of', 'and', 'you', 'i', 'he', 'she', 'they', 'me', 'was', 'were', 'is', 'in', 'at', 'on', 'their', 'his', 'her', 's', 'said', 'all', 'did', 'been', 'w'] | ||||
|         exclusion_lst = [] | ||||
|         d2 = {} | ||||
|         for k in d: | ||||
|             if not k in exclusion_lst and not k.isnumeric() and len(k) > 1: | ||||
|                 d2[k] = d[k] | ||||
|         pickle.dump(d2, f) | ||||
| 
 | ||||
| def unfamiliar(path,word): | ||||
|     f = open(path,"rb") | ||||
|     dic = pickle.load(f) | ||||
|     with open(path,"rb") as f: | ||||
|         dic = pickle.load(f) | ||||
|     dic[word] += [datetime.now().strftime('%Y%m%d%H%M')] | ||||
|     fp = open(path,"wb") | ||||
|     pickle.dump(dic,fp) | ||||
|     with open(path,"wb") as fp: | ||||
|         pickle.dump(dic,fp) | ||||
| 
 | ||||
| def familiar(path,word): | ||||
|     f = open(path,"rb") | ||||
|  | @ -68,8 +66,8 @@ def familiar(path,word): | |||
|         del dic[word][0] | ||||
|     else: | ||||
|         dic.pop(word) | ||||
|     fp = open(path,"wb") | ||||
|     pickle.dump(dic,fp) | ||||
|     with open(path,"wb") as f: | ||||
|         pickle.dump(dic,f) | ||||
| 
 | ||||
| if __name__ == '__main__': | ||||
| 
 | ||||
|  |  | |||
|  | @ -33,7 +33,7 @@ def deleteRecord(path,word): | |||
|     except KeyError: | ||||
|         print("sorry") | ||||
|     with open(path, 'wb') as ff: | ||||
|             pickle.dump(db, ff) | ||||
|         pickle.dump(db, ff) | ||||
| 
 | ||||
| def dict2lst(d): | ||||
|     if len(d) > 0: | ||||
|  | @ -43,7 +43,7 @@ def dict2lst(d): | |||
|             for k in d: | ||||
|                 lst.append((k, [datetime.now().strftime('%Y%m%d%H%M')])) | ||||
|             return lst | ||||
|         elif isinstance(d[keys[0]], list): | ||||
|         if isinstance(d[keys[0]], list): | ||||
|             return list(d.items()) # a list of (key, value) pairs | ||||
| 
 | ||||
|     return [] | ||||
|  | @ -56,21 +56,19 @@ def merge_frequency(lst1, lst2): | |||
| 
 | ||||
| 
 | ||||
| def load_record(pickle_fname): | ||||
|     f = open(pickle_fname, 'rb') | ||||
|     d = pickle.load(f) | ||||
|     f.close() | ||||
|     with open(pickle_fname, 'rb') as f: | ||||
|         d = pickle.load(f) | ||||
|     return d | ||||
| 
 | ||||
| 
 | ||||
| def save_frequency_to_pickle(d, pickle_fname): | ||||
|     f = open(pickle_fname, 'wb') | ||||
|     exclusion_lst = ['one', 'no', 'has', 'had', 'do', 'that', 'have', 'by', 'not', 'but', 'we', 'this', 'my', 'him', 'so', 'or', 'as', 'are', 'it', 'from', 'with', 'be', 'can', 'for', 'an', 'if', 'who', 'whom', 'whose', 'which', 'the', 'to', 'a', 'of', 'and', 'you', 'i', 'he', 'she', 'they', 'me', 'was', 'were', 'is', 'in', 'at', 'on', 'their', 'his', 'her', 's', 'said', 'all', 'did', 'been', 'w'] | ||||
|     d2 = {} | ||||
|     for k in d: | ||||
|         if not k in exclusion_lst and not k.isnumeric() and not len(k) < 2: | ||||
|             d2[k] = list(sorted(d[k])) # 原先这里是d2[k] = list(sorted(set(d[k]))) | ||||
|     pickle.dump(d2, f) | ||||
|     f.close() | ||||
|     with open(pickle_fname, 'wb') as f: | ||||
|         exclusion_lst = ['one', 'no', 'has', 'had', 'do', 'that', 'have', 'by', 'not', 'but', 'we', 'this', 'my', 'him', 'so', 'or', 'as', 'are', 'it', 'from', 'with', 'be', 'can', 'for', 'an', 'if', 'who', 'whom', 'whose', 'which', 'the', 'to', 'a', 'of', 'and', 'you', 'i', 'he', 'she', 'they', 'me', 'was', 'were', 'is', 'in', 'at', 'on', 'their', 'his', 'her', 's', 'said', 'all', 'did', 'been', 'w'] | ||||
|         d2 = {} | ||||
|         for k in d: | ||||
|             if not k in exclusion_lst and not k.isnumeric() and not len(k) < 2: | ||||
|                 d2[k] = list(sorted(d[k])) # 原先这里是d2[k] = list(sorted(set(d[k]))) | ||||
|         pickle.dump(d2, f) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  | @ -86,4 +84,4 @@ if __name__ == '__main__': | |||
|     d = load_record('frequency.p') | ||||
|     lst1 = dict2lst(d) | ||||
|     d = merge_frequency(lst2, lst1) | ||||
|     print(d) | ||||
|     print(d) | ||||
|  | @ -29,3 +29,7 @@ function onReadClick() { | |||
| function onChooseClick() { | ||||
|     isChoose = !isChoose; | ||||
| } | ||||
| 
 | ||||
| if (performance.navigation.type == 1) {        //如果网页刷新,停止播放声音
 | ||||
|     Reader.stopRead(); | ||||
| } | ||||
|  | @ -22,33 +22,19 @@ function getWord() { | |||
| 
 | ||||
| function highLight() { | ||||
|     if (!isHighlight) return; | ||||
|     let articleContent = document.getElementById("article").innerText; //将原来的.innerText改为.innerHtml,使用innerText会把原文章中所包含的<br>标签去除,导致处理后的文章内容失去了原来的格式
 | ||||
|     let articleContent = document.getElementById("article").innerText; | ||||
|     let pickedWords = document.getElementById("selected-words");  // words picked to the text area
 | ||||
|     let dictionaryWords = document.getElementById("selected-words2"); // words appearing in the user's new words list
 | ||||
|     let allWords = "";  //初始化allWords的值,避免进入判断后编译器认为allWords未初始化的问题
 | ||||
|     if(dictionaryWords != null){//增加一个判断,检查生词本里面是否为空,如果为空,allWords只添加选中的单词
 | ||||
|         allWords = pickedWords.value + " " + dictionaryWords.value; | ||||
|     } | ||||
|     else{ | ||||
|         allWords = pickedWords.value + " "; | ||||
|     } | ||||
|     const list = allWords.split(" ");//将所有的生词放入一个list中,用于后续处理
 | ||||
|     let allWords = dictionaryWords === null ? pickedWords.value + " " : pickedWords.value + " " + dictionaryWords.value; | ||||
|     const list = allWords.split(" "); // 将所有的生词放入一个list中,用于后续处理
 | ||||
|     for (let i = 0; i < list.length; ++i) { | ||||
|         list[i] = list[i].replace(/(^\s*)|(\s*$)/g, ""); //消除单词两边的空字符
 | ||||
|         list[i] = list[i].replace('|', ""); | ||||
|         list[i] = list[i].replace('?', ""); | ||||
|         if (list[i] !== "" && "<mark>".indexOf(list[i]) === -1 && "</mark>".indexOf(list[i]) === -1) { | ||||
|            //将文章中所有出现该单词word的地方改为:"<mark>" + word + "<mark>"。 正则表达式RegExp()中,"\\b"代表单词边界匹配。
 | ||||
| 
 | ||||
|             //修改代码
 | ||||
|             let articleContent_fb = articleContent;  //文章副本
 | ||||
|             while(articleContent_fb.toLowerCase().indexOf(list[i].toLowerCase()) !== -1 && list[i]!=""){ | ||||
|                 //找到副本中和list[i]匹配的第一个单词(第一种匹配情况),并赋值给list[i]。
 | ||||
|                 const index = articleContent_fb.toLowerCase().indexOf(list[i].toLowerCase()); | ||||
|                 list[i] = articleContent_fb.substring(index, index + list[i].length); | ||||
| 
 | ||||
|                 articleContent_fb = articleContent_fb.substring(index + list[i].length);    // 使用副本中list[i]之后的子串替换掉副本
 | ||||
|                 articleContent = articleContent.replace(new RegExp("\\b"+list[i]+"\\b","g"),"<mark>" + list[i] + "</mark>"); | ||||
|         list[i] = list[i].replace(/(^\W*)|(\W*$)/g, ""); // 消除单词两边的非单词字符
 | ||||
|         if (list[i] != "" && "<mark>".indexOf(list[i]) === -1 && "</mark>".indexOf(list[i]) === -1) { | ||||
|             // 返回所有匹配单词的集合, 正则表达式RegExp()中, "\b"匹配一个单词的边界, g 表示全局匹配, i 表示对大小写不敏感。
 | ||||
|             let matches = new Set(articleContent.match(new RegExp("\\b" + list[i] + "\\b", "gi"))); | ||||
|             for (let word of matches) { | ||||
|                 // 将文章中所有出现该单词word的地方改为:"<mark>" + word + "<mark>"。 
 | ||||
|                 articleContent = articleContent.replace(new RegExp("\\b" + word + "\\b", "g"), "<mark>" + word + "</mark>"); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  |  | |||
|  | @ -49,8 +49,8 @@ | |||
| {#        <div class="alert alert-warning" role="alert">Congratulations! {{ message }}</div>#} | ||||
| {#    {% endfor %}#} | ||||
| 
 | ||||
|         <button class="btn btn-success" id="load_next_article" onclick="load_next_article()"> 下一篇 Next Article </button> | ||||
|         <button class="btn btn-success" id="load_pre_article" onclick="load_pre_article()" > 上一篇 Previous Article </button> | ||||
|         <button class="btn btn-success" id="load_next_article" onclick="load_next_article();Reader.stopRead()"> 下一篇 Next Article </button> | ||||
|         <button class="btn btn-success" id="load_pre_article" onclick="load_pre_article();Reader.stopRead()" > 上一篇 Previous Article </button> | ||||
| 
 | ||||
|     <p><b>阅读文章并回答问题</b></p> | ||||
|     <div id="text-content"> | ||||
|  | @ -97,7 +97,7 @@ | |||
|     <p><b>收集生词吧</b> (可以在正文中划词,也可以复制黏贴)</p> | ||||
|     <form method="post" action="/{{ username }}/userpage"> | ||||
|         <textarea name="content" id="selected-words" rows="10" cols="120"></textarea><br/> | ||||
|         <input type="submit" value="把生词加入我的生词库"/> | ||||
|         <input type="submit" value="把生词加入我的生词库" onclick="Reader.stopRead()"/> | ||||
|         <input type="reset" value="清除"/> | ||||
|     </form> | ||||
|     {% if session.get['thisWord'] %} | ||||
|  |  | |||
|  | @ -1,17 +1,10 @@ | |||
| from datetime import datetime | ||||
| from flask import render_template, session, url_for, redirect, request, json, escape, Blueprint | ||||
| from admin_service import ADMIN_NAME | ||||
| from flask import * | ||||
| 
 | ||||
| # from app import Yaml | ||||
| # from app.Article import get_today_article, load_freq_history | ||||
| # from app.WordFreq import WordFreq | ||||
| # from app.wordfreqCMD import sort_in_descending_order | ||||
| 
 | ||||
| import Yaml | ||||
| from Article import get_today_article, load_freq_history | ||||
| from WordFreq import WordFreq | ||||
| from wordfreqCMD import sort_in_descending_order | ||||
| 
 | ||||
| import pickle_idea | ||||
| import pickle_idea2 | ||||
| 
 | ||||
|  | @ -23,7 +16,7 @@ path_prefix = './'  # comment this line in deployment | |||
| 
 | ||||
| @userService.route("/get_next_article/<username>",methods=['GET','POST']) | ||||
| def get_next_article(username): | ||||
|     user_freq_record = path_prefix + 'static/frequency/' + 'frequency_%s.pickle' % (username) | ||||
|     user_freq_record = path_prefix + 'static/frequency/' + 'frequency_{username}.pickle' | ||||
|     session['old_articleID'] = session.get('articleID') | ||||
|     if request.method == 'GET': | ||||
|         visited_articles = session.get("visited_articles") | ||||
|  | @ -44,7 +37,7 @@ def get_next_article(username): | |||
| 
 | ||||
| @userService.route("/get_pre_article/<username>",methods=['GET']) | ||||
| def get_pre_article(username): | ||||
|     user_freq_record = path_prefix + 'static/frequency/' + 'frequency_%s.pickle' % (username) | ||||
|     user_freq_record = path_prefix + 'static/frequency/' + f'frequency_{username}.pickle' | ||||
|     if request.method == 'GET': | ||||
|         visited_articles = session.get("visited_articles") | ||||
|         if(visited_articles["index"]==0): | ||||
|  | @ -85,7 +78,7 @@ def familiar(username, word): | |||
|     :param word: | ||||
|     :return: | ||||
|     ''' | ||||
|     user_freq_record = path_prefix + 'static/frequency/' + 'frequency_%s.pickle' % (username) | ||||
|     user_freq_record = path_prefix + 'static/frequency/' + f'frequency_{username}.pickle' | ||||
|     pickle_idea.familiar(user_freq_record, word) | ||||
|     session['thisWord'] = word  # 1. put a word into session | ||||
|     session['time'] = 1 | ||||
|  | @ -100,7 +93,7 @@ def deleteword(username, word): | |||
|     :param word: 单词 | ||||
|     :return: 重定位到用户界面 | ||||
|     ''' | ||||
|     user_freq_record = path_prefix + 'static/frequency/' + 'frequency_%s.pickle' % (username) | ||||
|     user_freq_record = path_prefix + 'static/frequency/' + f'frequency_{username}.pickle' | ||||
|     pickle_idea2.deleteRecord(user_freq_record, word) | ||||
|     # 模板userpage_get.html中删除单词是异步执行,而flash的信息后续是同步执行的,所以注释这段代码;同时如果这里使用flash但不提取信息,则会影响 signup.html的显示。bug复现:删除单词后,点击退出,点击注册,注册页面就会出现提示信息 | ||||
|     # flash(f'{word} is no longer in your word list.') | ||||
|  | @ -126,7 +119,7 @@ def userpage(username): | |||
|     # 获取session里的用户名 | ||||
|     username = session.get('username') | ||||
| 
 | ||||
|     user_freq_record = path_prefix + 'static/frequency/' + 'frequency_%s.pickle' % (username) | ||||
|     user_freq_record = path_prefix + 'static/frequency/' + f'frequency_{username}.pickle' | ||||
| 
 | ||||
|     if request.method == 'POST':  # when we submit a form | ||||
|         content = escape(request.form['content']) | ||||
|  | @ -134,7 +127,7 @@ def userpage(username): | |||
|         lst = f.get_freq() | ||||
|         return render_template('userpage_post.html',username=username,lst = lst, yml=Yaml.yml) | ||||
| 
 | ||||
|     elif request.method == 'GET':  # when we load a html page | ||||
|     if request.method == 'GET':  # when we load a html page | ||||
|         d = load_freq_history(user_freq_record) | ||||
|         lst = pickle_idea2.dict2lst(d) | ||||
|         lst2 = [] | ||||
|  | @ -167,7 +160,7 @@ def user_mark_word(username): | |||
|     :return: 重定位到用户界面 | ||||
|     ''' | ||||
|     username = session[username] | ||||
|     user_freq_record = path_prefix + 'static/frequency/' + 'frequency_%s.pickle' % (username) | ||||
|     user_freq_record = path_prefix + 'static/frequency/' + f'frequency_{username}.pickle' | ||||
|     if request.method == 'POST': | ||||
|         # 提交标记的单词 | ||||
|         d = load_freq_history(user_freq_record) | ||||
|  | @ -178,13 +171,11 @@ def user_mark_word(username): | |||
|         d = pickle_idea2.merge_frequency(lst, lst_history) | ||||
|         pickle_idea2.save_frequency_to_pickle(d, user_freq_record) | ||||
|         return redirect(url_for('user_bp.userpage', username=username)) | ||||
|     else: | ||||
|         return 'Under construction' | ||||
|     return 'Under construction' | ||||
| 
 | ||||
| def get_time(): | ||||
|     ''' | ||||
|     获取当前时间 | ||||
|     :return: 当前时间 | ||||
|     ''' | ||||
|     return datetime.now().strftime('%Y%m%d%H%M')  # upper to minutes | ||||
| 
 | ||||
|     return datetime.now().strftime('%Y%m%d%H%M')  # upper to minutes | ||||
|  | @ -5,8 +5,8 @@ | |||
| 
 | ||||
| import collections | ||||
| import string | ||||
| import operator | ||||
| import os, sys # 引入模块sys,因为我要用里面的sys.argv列表中的信息来读取命令行参数。 | ||||
| import os | ||||
| import sys # 引入模块sys,因为我要用里面的sys.argv列表中的信息来读取命令行参数。 | ||||
| import pickle_idea | ||||
| 
 | ||||
| def freq(fruit): | ||||
|  | @ -18,7 +18,7 @@ def freq(fruit): | |||
|     ''' | ||||
| 
 | ||||
|     result = [] | ||||
|      | ||||
| 
 | ||||
|     fruit = fruit.lower() # 字母转小写 | ||||
|     flst = fruit.split()  # 字符串转成list | ||||
|     c = collections.Counter(flst) | ||||
|  | @ -32,19 +32,18 @@ def youdao_link(s): # 有道链接 | |||
| 
 | ||||
| 
 | ||||
| def file2str(fname):#文件转字符 | ||||
|     f = open(fname) #打开 | ||||
|     s = f.read()    #读取 | ||||
|     f.close()       #关闭 | ||||
|     with open(fname, encoding="utf-8") as f: | ||||
|         s = f.read() | ||||
|     return s | ||||
| 
 | ||||
| 
 | ||||
| def remove_punctuation(s): # 这里是s是形参 (parameter)。函数被调用时才给s赋值。 | ||||
|     special_characters = '\_©~<=>+/[]*&$%^@.,?!:;#()"“”—‘’{}|' # 把里面的字符都去掉 | ||||
|     special_characters = r'\_©~<=>+/[]*&$%^@.,?!:;#()"“”—‘’{}|' # 把里面的字符都去掉 | ||||
|     for c in special_characters: | ||||
|         s = s.replace(c, ' ') # 防止出现把 apple,apple 移掉逗号后变成 appleapple 情况 | ||||
|     s = s.replace('--', ' ') | ||||
|     s = s.strip() # 去除前后的空格 | ||||
|      | ||||
| 
 | ||||
|     if '\'' in s: | ||||
|         n = len(s) | ||||
|         t = '' # 用来收集我需要保留的字符 | ||||
|  | @ -78,11 +77,10 @@ def make_html_page(lst, fname):  # 只是在wordfreqCMD.py中的main函数中调 | |||
|     count = 1 | ||||
|     for x in lst: | ||||
|         # <a href="">word</a> | ||||
|         s += '<p>%d <a href="%s">%s</a> (%d)</p>' % (count, youdao_link(x[0]), x[0], x[1]) | ||||
|         s += f'<p>{count} <a href="{youdao_link(x[0])}">{x[0]}</a> ({x[1]})</p>' | ||||
|         count += 1 | ||||
|     f = open(fname, 'w') | ||||
|     f.write(s) | ||||
|     f.close() | ||||
|     with open(fname, 'w', encoding="utf-8") as f: | ||||
|         f.write(s) | ||||
| 
 | ||||
| 
 | ||||
| ## main(程序入口) | ||||
|  | @ -101,10 +99,10 @@ if __name__ == '__main__': | |||
|     s = remove_punctuation(s) # 这里是s是实参(argument),里面有值 | ||||
|     L = freq(s) | ||||
|     for x in sort_in_descending_order(L): | ||||
|         print('%s\t%d\t%s' % (x[0], x[1], youdao_link(x[0])))#函数导出 | ||||
|         print(f'{x[0]}\t{x[1]}\t{youdao_link(x[0])}' )#函数导出 | ||||
| 
 | ||||
|     # 把频率的结果放result.html中 | ||||
|     make_html_page(sort_in_descending_order(L), 'result.html')  | ||||
|     make_html_page(sort_in_descending_order(L), 'result.html') | ||||
| 
 | ||||
|     print('\nHistory:\n') | ||||
|     if os.path.exists('frequency.p'): | ||||
|  | @ -118,6 +116,3 @@ if __name__ == '__main__': | |||
|     lst_history = pickle_idea.dict2lst(d) | ||||
|     d = pickle_idea.merge_frequency(L, lst_history) | ||||
|     pickle_idea.save_frequency_to_pickle(d, 'frequency.p') | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue