DONE: Bug533-Yuyikai #131
|
@ -1,19 +1,48 @@
|
||||||
from WordFreq import WordFreq
|
import csv
|
||||||
from wordfreqCMD import youdao_link, sort_in_descending_order
|
|
||||||
import pickle_idea, pickle_idea2
|
from app.WordFreq import WordFreq
|
||||||
|
from app.UseSqlite import RecordQuery
|
||||||
|
from app.wordfreqCMD import youdao_link, sort_in_descending_order
|
||||||
|
from app import pickle_idea, pickle_idea2
|
||||||
import os
|
import os
|
||||||
import random, glob
|
import random, glob
|
||||||
import hashlib
|
import hashlib
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from flask import Flask, request, redirect, render_template, url_for, session, abort, flash, get_flashed_messages
|
from flask import Flask, request, redirect, render_template, url_for, session, abort, flash, get_flashed_messages
|
||||||
from difficulty import get_difficulty_level_for_user, text_difficulty_level, user_difficulty_level
|
from app.difficulty import get_difficulty_level_for_user, text_difficulty_level, user_difficulty_level
|
||||||
from model.article import get_all_articles, get_article_by_id, get_number_of_articles
|
from app.model.article import get_all_articles, get_article_by_id, get_number_of_articles
|
||||||
import logging
|
import logging
|
||||||
|
import re
|
||||||
|
|
||||||
path_prefix = './'
|
path_prefix = './'
|
||||||
db_path_prefix = './db/' # comment this line in deployment
|
db_path_prefix = './db/' # comment this line in deployment
|
||||||
|
|
||||||
|
|
||||||
|
def load_text_list_from_db(db_file):
|
||||||
|
rq = RecordQuery(db_file)
|
||||||
|
rq.instructions("SELECT text FROM article")
|
||||||
|
rq.do()
|
||||||
|
result = rq.get_results()
|
||||||
|
text_list = [row['text'] for row in result if 'text' in row]
|
||||||
|
return text_list
|
||||||
|
|
||||||
|
def load_word_list(csv_file):
|
||||||
|
with open(csv_file, 'r', encoding='utf-8') as f:
|
||||||
|
reader = csv.reader(f)
|
||||||
|
word_set = set()
|
||||||
|
for row in reader:
|
||||||
|
for word in row[0].split(','):
|
||||||
|
clean_word = re.sub(r'\W+', '', word.strip().lower())
|
||||||
|
if clean_word:
|
||||||
|
word_set.add(clean_word)
|
||||||
|
return word_set
|
||||||
|
|
||||||
|
def calculate_coverage(text_list, word_set):
|
||||||
|
total_words = sum(len(article.split()) for article in text_list)
|
||||||
|
covered_words = sum(len(set(article.split()).intersection(word_set)) for article in text_list)
|
||||||
|
return (covered_words / total_words) * 10000 if total_words else 0
|
||||||
|
|
||||||
|
|
||||||
def total_number_of_essays():
|
def total_number_of_essays():
|
||||||
return get_number_of_articles()
|
return get_number_of_articles()
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
###########################################################################
|
||||||
|
# Copyright 2019 (C) Hui Lan <hui.lan@cantab.net>
|
||||||
|
# Written permission must be obtained from the author for commercial uses.
|
||||||
|
###########################################################################
|
||||||
|
|
||||||
|
|
||||||
|
# Reference: Dusty Phillips. Python 3 Objected-oriented Programming Second Edition. Pages 326-328.
|
||||||
|
# Copyright (C) 2019 Hui Lan
|
||||||
|
|
||||||
|
import sqlite3
|
||||||
|
|
||||||
|
class Sqlite3Template:
|
||||||
|
def __init__(self, db_fname):
|
||||||
|
self.db_fname = db_fname
|
||||||
|
|
||||||
|
def connect(self, db_fname):
|
||||||
|
self.conn = sqlite3.connect(self.db_fname)
|
||||||
|
|
||||||
|
def instructions(self, query_statement):
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def operate(self):
|
||||||
|
self.conn.row_factory = sqlite3.Row
|
||||||
|
self.results = self.conn.execute(self.query) # self.query is to be given in the child classes
|
||||||
|
self.conn.commit()
|
||||||
|
|
||||||
|
def format_results(self):
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def do(self):
|
||||||
|
self.connect(self.db_fname)
|
||||||
|
self.instructions(self.query)
|
||||||
|
self.operate()
|
||||||
|
|
||||||
|
def instructions_with_parameters(self, query_statement, parameters):
|
||||||
|
self.query = query_statement
|
||||||
|
self.parameters = parameters
|
||||||
|
|
||||||
|
def do_with_parameters(self):
|
||||||
|
self.connect(self.db_fname)
|
||||||
|
self.instructions_with_parameters(self.query, self.parameters)
|
||||||
|
self.operate_with_parameters()
|
||||||
|
|
||||||
|
def operate_with_parameters(self):
|
||||||
|
self.conn.row_factory = sqlite3.Row
|
||||||
|
self.results = self.conn.execute(self.query, self.parameters) # self.query is to be given in the child classes
|
||||||
|
self.conn.commit()
|
||||||
|
|
||||||
|
|
||||||
|
class InsertQuery(Sqlite3Template):
|
||||||
|
def instructions(self, query):
|
||||||
|
self.query = query
|
||||||
|
|
||||||
|
|
||||||
|
class RecordQuery(Sqlite3Template):
|
||||||
|
def instructions(self, query):
|
||||||
|
self.query = query
|
||||||
|
|
||||||
|
def format_results(self):
|
||||||
|
output = []
|
||||||
|
for row_dict in self.results.fetchall():
|
||||||
|
lst = []
|
||||||
|
for k in dict(row_dict):
|
||||||
|
lst.append( row_dict[k] )
|
||||||
|
output.append(', '.join(lst))
|
||||||
|
return '\n\n'.join(output)
|
||||||
|
|
||||||
|
def get_results(self):
|
||||||
|
result = []
|
||||||
|
for row_dict in self.results.fetchall():
|
||||||
|
result.append( dict(row_dict) )
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
#iq = InsertQuery('RiskDB.db')
|
||||||
|
#iq.instructions("INSERT INTO inspection Values ('FoodSupplies', 'RI2019051301', '2019-05-13', '{}')")
|
||||||
|
#iq.do()
|
||||||
|
#iq.instructions("INSERT INTO inspection Values ('CarSupplies', 'RI2019051302', '2019-05-13', '{[{\"risk_name\":\"elevator\"}]}')")
|
||||||
|
#iq.do()
|
||||||
|
rq = RecordQuery('wordfreqapp.db')
|
||||||
|
rq.instructions("SELECT * FROM article WHERE level=3")
|
||||||
|
rq.do()
|
||||||
|
#print(rq.format_results())
|
|
@ -3,7 +3,7 @@
|
||||||
# Written permission must be obtained from the author for commercial uses.
|
# Written permission must be obtained from the author for commercial uses.
|
||||||
###########################################################################
|
###########################################################################
|
||||||
|
|
||||||
from wordfreqCMD import remove_punctuation, freq, sort_in_descending_order
|
from app.wordfreqCMD import remove_punctuation, freq, sort_in_descending_order
|
||||||
import string
|
import string
|
||||||
|
|
||||||
class WordFreq:
|
class WordFreq:
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
import pickle
|
import pickle
|
||||||
import math
|
import math
|
||||||
from wordfreqCMD import remove_punctuation, freq, sort_in_descending_order, sort_in_ascending_order
|
from app.wordfreqCMD import remove_punctuation, freq, sort_in_descending_order, sort_in_ascending_order
|
||||||
import snowballstemmer
|
import snowballstemmer
|
||||||
|
|
||||||
|
|
||||||
|
|
29
app/main.py
29
app/main.py
|
@ -1,19 +1,23 @@
|
||||||
|
#! /usr/bin/python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
###########################################################################
|
###########################################################################
|
||||||
# Copyright 2019 (C) Hui Lan <hui.lan@cantab.net>
|
# Copyright 2019 (C) Hui Lan <hui.lan@cantab.net>
|
||||||
# Written permission must be obtained from the author for commercial uses.
|
# Written permission must be obtained from the author for commercial uses.
|
||||||
###########################################################################
|
###########################################################################
|
||||||
from flask import abort
|
from flask import escape
|
||||||
from markupsafe import escape
|
|
||||||
from Login import *
|
from Login import *
|
||||||
from Article import *
|
from Article import *
|
||||||
import Yaml
|
import Yaml
|
||||||
|
from app import pickle_idea
|
||||||
|
from app.wordfreqCMD import sort_in_descending_order
|
||||||
from user_service import userService
|
from user_service import userService
|
||||||
from account_service import accountService
|
from account_service import accountService
|
||||||
from admin_service import adminService, ADMIN_NAME
|
from admin_service import adminService, ADMIN_NAME
|
||||||
import os
|
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.secret_key = os.urandom(32)
|
app.secret_key = 'lunch.time!'
|
||||||
|
|
||||||
# 将蓝图注册到Lab app
|
# 将蓝图注册到Lab app
|
||||||
app.register_blueprint(userService)
|
app.register_blueprint(userService)
|
||||||
|
@ -23,6 +27,7 @@ app.register_blueprint(adminService)
|
||||||
path_prefix = '/var/www/wordfreq/wordfreq/'
|
path_prefix = '/var/www/wordfreq/wordfreq/'
|
||||||
path_prefix = './' # comment this line in deployment
|
path_prefix = './' # comment this line in deployment
|
||||||
|
|
||||||
|
|
||||||
def get_random_image(path):
|
def get_random_image(path):
|
||||||
'''
|
'''
|
||||||
返回随机图
|
返回随机图
|
||||||
|
@ -54,6 +59,7 @@ def appears_in_test(word, d):
|
||||||
else:
|
else:
|
||||||
return ','.join(d[word])
|
return ','.join(d[word])
|
||||||
|
|
||||||
|
|
||||||
@app.route("/mark", methods=['GET', 'POST'])
|
@app.route("/mark", methods=['GET', 'POST'])
|
||||||
def mark_word():
|
def mark_word():
|
||||||
'''
|
'''
|
||||||
|
@ -79,6 +85,15 @@ def mainpage():
|
||||||
根据GET或POST方法来返回不同的主界面
|
根据GET或POST方法来返回不同的主界面
|
||||||
:return: 主界面
|
:return: 主界面
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
db_file = "db\wordfreqapp.db"
|
||||||
|
csv_file = "db\The_Oxford.csv"
|
||||||
|
text_list = load_text_list_from_db(db_file)
|
||||||
|
word_set = load_word_list(csv_file)
|
||||||
|
coverage_percentage = "{:.2f}".format(calculate_coverage(text_list, word_set))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if request.method == 'POST': # when we submit a form
|
if request.method == 'POST': # when we submit a form
|
||||||
content = escape(request.form['content'])
|
content = escape(request.form['content'])
|
||||||
f = WordFreq(content)
|
f = WordFreq(content)
|
||||||
|
@ -88,7 +103,7 @@ def mainpage():
|
||||||
lst_history = pickle_idea.dict2lst(d)
|
lst_history = pickle_idea.dict2lst(d)
|
||||||
d = pickle_idea.merge_frequency(lst, lst_history)
|
d = pickle_idea.merge_frequency(lst, lst_history)
|
||||||
pickle_idea.save_frequency_to_pickle(d, path_prefix + 'static/frequency/frequency.p')
|
pickle_idea.save_frequency_to_pickle(d, path_prefix + 'static/frequency/frequency.p')
|
||||||
return render_template('mainpage_post.html', lst=lst, yml=Yaml.yml)
|
return render_template('mainpage_post.html', lst=lst, yml=Yaml.yml,coverage_percentage=coverage_percentage)
|
||||||
|
|
||||||
elif request.method == 'GET': # when we load a html page
|
elif request.method == 'GET': # when we load a html page
|
||||||
random_ads = get_random_ads()
|
random_ads = get_random_ads()
|
||||||
|
@ -102,8 +117,8 @@ def mainpage():
|
||||||
d_len=d_len,
|
d_len=d_len,
|
||||||
lst=lst,
|
lst=lst,
|
||||||
yml=Yaml.yml,
|
yml=Yaml.yml,
|
||||||
number_of_essays=number_of_essays)
|
number_of_essays=number_of_essays,
|
||||||
|
coverage_percentage=coverage_percentage)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
'''
|
'''
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from model import *
|
from app.model import *
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
def add_article(content, source="manual_input", level="5", question="No question"):
|
def add_article(content, source="manual_input", level="5", question="No question"):
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from model import *
|
from app.model import *
|
||||||
from Login import md5
|
from Login import md5
|
||||||
from pony import orm
|
from pony import orm
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=0.5, maximum-scale=3.0, user-scalable=yes" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=0.5, maximum-scale=3.0, user-scalable=yes" />
|
||||||
|
|
||||||
{{ yml['header'] | safe }}
|
{{ yml['header'] | safe }}
|
||||||
{% if yml['css']['item'] %}
|
{% if yml['css']['item'] %}
|
||||||
{% for css in yml['css']['item'] %}
|
{% for css in yml['css']['item'] %}
|
||||||
|
@ -31,8 +30,9 @@
|
||||||
<p><a href="/login">登录</a> <a href="/signup">注册</a> <a href="/static/usr/instructions.html">使用说明</a></p >
|
<p><a href="/login">登录</a> <a href="/signup">注册</a> <a href="/static/usr/instructions.html">使用说明</a></p >
|
||||||
<p><b> {{ random_ads }}。 <a href="/signup">试试</a>吧!</b></p>
|
<p><b> {{ random_ads }}。 <a href="/signup">试试</a>吧!</b></p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="alert alert-success" role="alert">共有文章 <span class="badge bg-success"> {{ number_of_essays }} </span> 篇</div>
|
|
||||||
<p>粘贴1篇文章 (English only)</p>
|
<div class="alert alert-success" role="alert">共有文章 <span class="badge bg-success"> {{ number_of_essays }} </span> 篇 其中Oxford覆盖率为: <span class="badge bg-success"> {{ coverage_percentage }}% </span></div>
|
||||||
|
<p>粘贴1篇文章 (<E></E>nglish only)</p>
|
||||||
<form method="post" action="/">
|
<form method="post" action="/">
|
||||||
<textarea name="content" id="article" rows="10" cols="120"></textarea><br/>
|
<textarea name="content" id="article" rows="10" cols="120"></textarea><br/>
|
||||||
<input type="submit" value="get文章中的词频"/>
|
<input type="submit" value="get文章中的词频"/>
|
||||||
|
@ -44,7 +44,6 @@
|
||||||
<a href="http://youdao.com/w/eng/{{x[0]}}/#keyfrom=dict2.index">{{x[0]}}</a> {{x[1]}}
|
<a href="http://youdao.com/w/eng/{{x[0]}}/#keyfrom=dict2.index">{{x[0]}}</a> {{x[1]}}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<p class="text-muted">Version: 20230810</p>
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
|
||||||
</div>
|
</div>
|
||||||
{{ yml['footer'] | safe }}
|
{{ yml['footer'] | safe }}
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
from app.Article import load_text_list_from_db, load_word_list, calculate_coverage
|
||||||
|
|
||||||
|
|
||||||
|
def test_coverage_percentage():
|
||||||
|
try:
|
||||||
|
text_list = load_text_list_from_db("db\wordfreqapp.db")
|
||||||
|
word_set = load_word_list("db\The_Oxford.csv")
|
||||||
|
coverage_percentage = calculate_coverage(text_list, word_set)
|
||||||
|
assert 0 <= coverage_percentage <= 100, "Coverage percentage is not within the range [0, 100]"
|
||||||
|
print("coverage_percentage:", coverage_percentage)
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
test_coverage_percentage()
|
|
@ -47,6 +47,8 @@ def get_next_article(username):
|
||||||
return 'Under construction'
|
return 'Under construction'
|
||||||
return json.dumps(data)
|
return json.dumps(data)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@userService.route("/get_pre_article/<username>",methods=['GET'])
|
@userService.route("/get_pre_article/<username>",methods=['GET'])
|
||||||
def get_pre_article(username):
|
def get_pre_article(username):
|
||||||
user_freq_record = path_prefix + 'static/frequency/' + 'frequency_%s.pickle' % (username)
|
user_freq_record = path_prefix + 'static/frequency/' + 'frequency_%s.pickle' % (username)
|
||||||
|
|
|
@ -8,7 +8,7 @@ import html
|
||||||
import string
|
import string
|
||||||
import operator
|
import operator
|
||||||
import os, sys # 引入模块sys,因为我要用里面的sys.argv列表中的信息来读取命令行参数。
|
import os, sys # 引入模块sys,因为我要用里面的sys.argv列表中的信息来读取命令行参数。
|
||||||
import pickle_idea
|
from app import pickle_idea
|
||||||
|
|
||||||
def freq(fruit):
|
def freq(fruit):
|
||||||
'''
|
'''
|
||||||
|
|
Loading…
Reference in New Issue