summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorHui Lan <lanhui@zjnu.edu.cn>2021-08-31 21:38:22 +0800
committerHui Lan <lanhui@zjnu.edu.cn>2021-08-31 21:38:22 +0800
commitd463e5715c2bf26be01c033d7a225fcd39776590 (patch)
tree61059227c22efcbabbeaa0c2bf9bb19fc3c84556 /app
parent26ec40f634201ae72a910cd826e4eaaca9e20135 (diff)
Prepre to use more recent stuff from Gitea
Diffstat (limited to 'app')
-rwxr-xr-xapp/build.sh17
-rw-r--r--app/difficulty.py492
-rw-r--r--app/main.py77
-rw-r--r--app/static/wordfreqapp.sql22
4 files changed, 334 insertions, 274 deletions
diff --git a/app/build.sh b/app/build.sh
deleted file mode 100755
index 52cc695..0000000
--- a/app/build.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/sh
-
-cd /home/lanhui/englishpal
-
-# Stop service
-sudo service docker restart
-
-# Rebuild container. Run this after modifying the source code.
-sudo docker build -t englishpal .
-
-# Run the application
-sudo docker run -d -p 90:80 -v /home/lanhui/englishpal/app/static/frequency:/app/static/frequency -t englishpal # for permanently saving data
-
-# Save space. Run it after sudo docker run
-sudo docker system prune -a -f
-
-
diff --git a/app/difficulty.py b/app/difficulty.py
index ccd9b6f..471bd6c 100644
--- a/app/difficulty.py
+++ b/app/difficulty.py
@@ -1,243 +1,249 @@
-###########################################################################
-# Copyright 2019 (C) Hui Lan <hui.lan@cantab.net>
-# Written permission must be obtained from the author for commercial uses.
-###########################################################################
-
-# 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
-
-
-def load_record(pickle_fname):
- f = open(pickle_fname, 'rb')
- d = pickle.load(f)
- f.close()
- return d
-
-
-def difficulty_level_from_frequency(word, d):
- level = 1
- if not word in d:
- return level
-
- if 'what' in d:
- ratio = (d['what']+1)/(d[word]+1) # what is a frequent word
- level = math.log( max(ratio, 1), 2)
-
- level = min(level, 8)
- return level
-
-
-def get_difficulty_level(d1, d2):
- d = {}
- L = list(d1.keys()) # in d1, we have freuqence for each word
- L2 = list(d2.keys()) # in d2, we have test types (e.g., CET4,CET6,BBC) for each word
- L.extend(L2)
- L3 = list(set(L)) # L3 contains all words
- for k in L3:
- if k in d2:
- if 'CET4' in d2[k]:
- d[k] = 4 # CET4 word has level 4
- elif 'CET6' in d2[k]:
- d[k] = 6
- elif 'BBC' in d2[k]:
- d[k] = 8
- if k in d1: # BBC could contain easy words that are not in CET4 or CET6. So 4 is not reasonable. Recompute difficulty level.
- d[k] = min(difficulty_level_from_frequency(k, d1), d[k])
- elif k in d1:
- d[k] = difficulty_level_from_frequency(k, d1)
-
- return d
-
-
-
-def revert_dict(d):
- '''
- In d2, time is the key, and the value is a list of words picked at that time.
- '''
- d2 = {}
- for k in d:
- lst = d[k]
- for time_info in lst:
- date = time_info[:10] # until hour
- if not date in d2:
- d2[date] = [k]
- else:
- d2[date].append(k)
- return d2
-
-
-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
- for date in sorted(d_user2.keys(), reverse=True): # most recently added words are more important while determining user's level
- lst = d_user2[date] # a list of words
- lst2 = [] # a list of tuples, (word, difficulty level)
- for word in lst:
- if word in d:
- lst2.append((word, d[word]))
-
- lst3 = sort_in_ascending_order(lst2) # easiest tuple first
- #print(lst3)
- for t in lst3:
- word = t[0]
- hard = t[1]
- #print('WORD %s HARD %4.2f' % (word, hard))
- geometric = geometric * (hard)
- count += 1
- if count >= 10:
- return geometric**(1/count)
-
- return geometric**(1/max(count,1))
-
-
-def text_difficulty_level(s, d):
- s = remove_punctuation(s)
- L = freq(s)
-
- lst = [] # a list of tuples, each tuple being (word, difficulty level)
- for x in L:
- word = x[0]
- if word in d:
- lst.append((word, d[word]))
-
- lst2 = sort_in_descending_order(lst) # most difficult words on top
- #print(lst2)
- count = 0
- geometric = 1
- for t in lst2:
- word = t[0]
- hard = t[1]
- geometric = geometric * (hard)
- count += 1
- if count >= 20: # we look for n most difficult words
- return geometric**(1/count)
-
- return geometric**(1/max(count,1))
-
-
-
-if __name__ == '__main__':
-
-
- d1 = load_record('frequency.p')
- #print(d1)
-
- d2 = load_record('words_and_tests.p')
- #print(d2)
-
-
- d3 = get_difficulty_level(d1, d2)
-
- s = '''
-South Lawn
-11:53 A.M. EDT
-THE PRESIDENT: Hi, everybody. Hi. How are you? So, the stock market is doing very well.
-The economy is booming. We have a new record in sight. It could happen even today.
-But we have a new stock market record. I think it’ll be about 118 times that we’ve broken the record.
-Jobs look phenomenal.
- '''
- s = '''
-By the authority vested in me as President by the Constitution and the laws of the United States, after carefully considering the reports submitted to the Congress by the Energy Information Administration, including the report submitted in October 2019, and other relevant factors, including global economic conditions, increased oil production by certain countries, the global level of spare petroleum production capacity, and the availability of strategic reserves, I determine, pursuant to section 1245(d)(4)(B) and (C) of the National Defense Authorization Act for Fiscal Year 2012, Public Law 112-81, and consistent with prior determinations, that there is a sufficient supply of petroleum and petroleum products from countries other than Iran to permit a significant reduction in the volume of petroleum and petroleum products purchased from Iran by or through foreign financial institutions.
-
-'''
-
- s = '''
-Democrats keep their witnesses locked behind secure doors, then flood the press with carefully sculpted leaks and accusations, driving the Trump-corruption narrative. And so the party goes, galloping toward an impeachment vote that would overturn the will of the American voters—on a case built in secret.
-
-Conservative commentators keep noting that Mrs. Pelosi’s refusal to hold a vote on the House floor to authorize an official impeachment inquiry helps her caucus’s vulnerable members evade accountability. But there’s a more practical and uglier reason for Democrats to skip the formalities. Normally an authorization vote would be followed by official rules on how the inquiry would proceed. Under today’s process, Mr. Schiff gets to make up the rules as he goes along. Behold the Lord High Impeacher.
-
-Democrats view control over the narrative as essential, having learned from their Russia-collusion escapade the perils of transparency. They banked on special counsel Robert Mueller’s investigation proving impeachment fodder, but got truth-bombed. Their subsequent open hearings on the subject—featuring Michael Cohen, Mr. Mueller and Corey Lewandowski —were, for the Democrats, embarrassing spectacles, at which Republicans punched gaping holes in their story line.
-
-Mr. Schiff is making sure that doesn’t happen again; he’ll present the story, on his terms. His rules mean he can issue that controlling decree about “only one” transcript and Democratic staff supervision of Republican members. It means he can bar the public, the press and even fellow representatives from hearings, even though they’re unclassified.
-'''
-
- s = '''
-Unemployment today is at a 50-year low. There are more Americans working today than ever before. Median household income in the last two and half years has risen by more than $5,000. And that doesn’t even account for the savings from the President’s tax cuts or energy reforms for working families.
-
-Because of the President’s policies, America has added trillions of dollars of wealth to our economy while China’s economy continues to fall behind.
-
-To level the playing field for the American worker against unethical trade practices, President Trump levied tariffs on $250 billion in Chinese goods in 2018. And earlier this year, the President announced we would place tariffs on another $300 billion of Chinese goods if significant issues in our trading relationship were not resolved by December of this year.
-'''
- s = '''
-Needless to say, we see it very differently. Despite the great power competition that is underway, and America’s growing strength, we want better for China. That’s why, for the first time in decades, under President Donald Trump’s leadership, the United States is treating China’s leaders exactly how the leaders of any great world power should be treated — with respect, yes, but also with consistency and candor.
-'''
- s = '''
-Brexit is the scheduled withdrawal of the United Kingdom from the European Union. Following a June 2016 referendum, in which 51.9% voted to leave, the UK government formally announced the country's withdrawal in March 2017, starting a two-year process that was due to conclude with the UK withdrawing on 29 March 2019. As the UK parliament thrice voted against the negotiated withdrawal agreement, that deadline has been extended twice, and is currently 31 October 2019. The Benn Act, passed in September 2019, requires the government to seek a third extension.
-'''
-
- s = '''
-The argument for Brexit
-According to the BBC, the push to leave the EU was advocated mostly by the UK Independence Party and was not supported by the Prime Minister, David Cameron. Members of the UK Independence Party argued that Britain’s participation in the EU was a restrictive element for the country.
-
-As one of the EU’s primary initiatives is free movement within the region the party’s main arguments centered around regaining border control and reclaiming business rights. In addition, supporters of Brexit cited the high EU membership fees as a negative aspect of participation in the EU. It was argued that if the UK separates itself from the EU, these fees can be used to benefit the UK.
-
-The argument against Brexit
-The Conservative Party and the Prime Minister were strongly in favor of remaining with the EU. As a result of the decision to discontinue its participation in the EU, the Prime Minister has made a public statement that he will be relinquishing his position. He believes that the country needs a leader with the same goals as the majority of the country. He has promised a new PM will be in place by early September.
-
-The argument against Brexit pertains mostly to the business benefits. The argument is that the UK receives business benefits by being able to participate in the single market system established by the EU. In response to the criticism against the open borders, proponents believe that the influx of immigrants helps develop an eager workforce and fuels public service projects.
-
-Leaders in favor of staying also worry about the political backlash that could possibly result from other countries who favored staying with the EU. In addition, proponents of remaining with the EU believe that being part of a wider community of nations provides economic and cultural strength, as well as an additional element of security.
-
-What does Brexit mean for the future?
-While the decision marked a huge statement for the UK, the referendum vote is not legally binding. There are still many hurdles that must be dealt with before Brexit can become a reality.
-
-The UK is still subject to the laws of the EU until Britain’s exit becomes legal. In order for the UK to make its break official, the country needs to invoke Article 50. It is unclear exactly what this process will entail or how long it will take as Britain is the first country to take its leave of the EU. Once Article 50 has been formally invoked, the UK has two years to negotiate its departure with the other member states. But according to the BBC, “Extricating the UK from the EU will be extremely complex, and the process could drag on longer than that.”
-
-Amidst the aftermath of this shocking referendum vote, there is great uncertainty as political leaders decide what this means for the UK.
-
-'''
-
-
- s = '''
-British Prime Minister Boris Johnson walks towards a voting station during the Brexit referendum in Britain, June 23, 2016. (Photo: EPA-EFE)
-
-LONDON – British Prime Minister Boris Johnson said Thursday he will likely ask Parliament to approve an election as part of an effort to break a Brexit deadlock.
-
-It is not clear if the vote, which Johnson wants to hold on Dec. 12, will take place as opposition lawmakers must also back the move.
-
-They are expected to vote on the measure on Monday.
-
-Johnson's announcement comes ahead of an expected decision Friday from the European Union over whether to delay Britain's exit from the bloc for three months.
-
-Britain's leader has been steadfastly opposed to any extension to the nation's scheduled Oct. 31 departure date from the EU, although in a letter to the leader of the opposition Labour Party this week he said he would accept a short technical postponement, "say to 15 or 30 November," to allow lawmakers to implement an EU withdrawal bill.
-
-Johnson's decision to offer to call an election follows lawmakers' rejection of his plan to rush through an EU exit bill that runs to hundreds of pages in just three days. They want more time to scrutinize the legislation and to make sure it does not leave the door open to a possible "no-deal" Brexit during future exit negotiations with the EU that will run through next year. A "no-deal" Brexit could dramatically harm Britain's economy.
-
-The prime minister was forced to ask for an extension to Britain's EU departure date after Britain's Parliament passed a law to ward off the threat of a "no-deal" Brexit.
-
-Johnson has repeatedly pledged to finalize the first stage, a transition deal, of Britain's EU divorce battle by Oct. 31. A second stage will involve negotiating its future relationship with the EU on trade, security and other salient issues.
-'''
-
-
- s = '''
-Thank you very much. We have a Cabinet meeting. We’ll have a few questions after grace. And, if you would, Ben, please do the honors.
-
-THE PRESIDENT: All right, thank you, Ben. That was a great job. Appreciate it.
-
-The economy is doing fantastically well. It’s getting very close to another record. We’ve had many records since we won office. We’re getting very close to another record. I don’t know if anybody saw it: The household median income for eight years of President Bush, it rose $400. For eight years of President Obama, it rose $975. And for two and half years of President Trump — they have it down as two and a half years — it rose $5,000, not including $2,000 for taxes. So it rose, let’s say, $7,000. So in two and a half years, we’re up $7,000, compared to $1,000, compared to $400. And that’s for eight years and eight years.
-
-That’s a number that just came out, but that’s a number that I don’t know how there could be any dispute or any — I’ve never heard a number like that, meaning the economy is doing fantastically well.
-
-We need — for our farmers, our manufacturers, for, frankly, unions and non-unions, we need USMCA to be voted on. If it’s voted on, it’ll pass. It’s up to Nancy Pelosi to put it up. If she puts it up, it’s going to pass. It’s going to be very bipartisan. It’s something that’s very much needed. It’ll be hundreds of thousands of jobs.
-
-
-'''
-
-
-
-
- #f = open('bbc-fulltext/bbc/entertainment/001.txt')
- f = open('wordlist.txt')
- s = f.read()
- f.close()
-
-
-
-
- print(text_difficulty_level(s, d3))
-
-
+###########################################################################
+# Copyright 2019 (C) Hui Lan <hui.lan@cantab.net>
+# Written permission must be obtained from the author for commercial uses.
+###########################################################################
+
+# 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
+
+
+def load_record(pickle_fname):
+ f = open(pickle_fname, 'rb')
+ d = pickle.load(f)
+ f.close()
+ return d
+
+
+def difficulty_level_from_frequency(word, d):
+ level = 1
+ if not word in d:
+ return level
+
+ if 'what' in d:
+ ratio = (d['what']+1)/(d[word]+1) # what is a frequent word
+ level = math.log( max(ratio, 1), 2)
+
+ level = min(level, 8)
+ return level
+
+
+def get_difficulty_level(d1, d2):
+ d = {}
+ L = list(d1.keys()) # in d1, we have freuqence for each word
+ L2 = list(d2.keys()) # in d2, we have test types (e.g., CET4,CET6,BBC) for each word
+ L.extend(L2)
+ L3 = list(set(L)) # L3 contains all words
+ for k in L3:
+ if k in d2:
+ if 'CET4' in d2[k]:
+ d[k] = 4 # CET4 word has level 4
+ elif 'CET6' in d2[k]:
+ d[k] = 6
+ elif 'BBC' in d2[k]:
+ d[k] = 8
+ if k in d1: # BBC could contain easy words that are not in CET4 or CET6. So 4 is not reasonable. Recompute difficulty level.
+ d[k] = min(difficulty_level_from_frequency(k, d1), d[k])
+ elif k in d1:
+ d[k] = difficulty_level_from_frequency(k, d1)
+
+ return d
+
+
+
+def revert_dict(d):
+ '''
+ In d, word is the key, and value is a list of dates.
+ In d2 (the returned value of this function), time is the key, and the value is a list of words picked at that time.
+ '''
+ d2 = {}
+ for k in d:
+ if type(d[k]) is list: # d[k] is a list of dates.
+ lst = d[k]
+ elif type(d[k]) is int: # for backward compatibility. d was sth like {'word':1}. The value d[k] is not a list of dates, but a number representing how frequent this word had been added to the new word book.
+ freq = d[k]
+ lst = freq*['2021082019'] # why choose this date? No particular reasons. I fix the bug in this date.
+
+ for time_info in lst:
+ date = time_info[:10] # until hour
+ if not date in d2:
+ d2[date] = [k]
+ else:
+ d2[date].append(k)
+ return d2
+
+
+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
+ for date in sorted(d_user2.keys(), reverse=True): # most recently added words are more important while determining user's level
+ lst = d_user2[date] # a list of words
+ lst2 = [] # a list of tuples, (word, difficulty level)
+ for word in lst:
+ if word in d:
+ lst2.append((word, d[word]))
+
+ lst3 = sort_in_ascending_order(lst2) # easiest tuple first
+ #print(lst3)
+ for t in lst3:
+ word = t[0]
+ hard = t[1]
+ #print('WORD %s HARD %4.2f' % (word, hard))
+ geometric = geometric * (hard)
+ count += 1
+ if count >= 10:
+ return geometric**(1/count)
+
+ return geometric**(1/max(count,1))
+
+
+def text_difficulty_level(s, d):
+ s = remove_punctuation(s)
+ L = freq(s)
+
+ lst = [] # a list of tuples, each tuple being (word, difficulty level)
+ for x in L:
+ word = x[0]
+ if word in d:
+ lst.append((word, d[word]))
+
+ lst2 = sort_in_descending_order(lst) # most difficult words on top
+ #print(lst2)
+ count = 0
+ geometric = 1
+ for t in lst2:
+ word = t[0]
+ hard = t[1]
+ geometric = geometric * (hard)
+ count += 1
+ if count >= 20: # we look for n most difficult words
+ return geometric**(1/count)
+
+ return geometric**(1/max(count,1))
+
+
+
+if __name__ == '__main__':
+
+
+ d1 = load_record('frequency.p')
+ #print(d1)
+
+ d2 = load_record('words_and_tests.p')
+ #print(d2)
+
+
+ d3 = get_difficulty_level(d1, d2)
+
+ s = '''
+South Lawn
+11:53 A.M. EDT
+THE PRESIDENT: Hi, everybody. Hi. How are you? So, the stock market is doing very well.
+The economy is booming. We have a new record in sight. It could happen even today.
+But we have a new stock market record. I think it’ll be about 118 times that we’ve broken the record.
+Jobs look phenomenal.
+ '''
+ s = '''
+By the authority vested in me as President by the Constitution and the laws of the United States, after carefully considering the reports submitted to the Congress by the Energy Information Administration, including the report submitted in October 2019, and other relevant factors, including global economic conditions, increased oil production by certain countries, the global level of spare petroleum production capacity, and the availability of strategic reserves, I determine, pursuant to section 1245(d)(4)(B) and (C) of the National Defense Authorization Act for Fiscal Year 2012, Public Law 112-81, and consistent with prior determinations, that there is a sufficient supply of petroleum and petroleum products from countries other than Iran to permit a significant reduction in the volume of petroleum and petroleum products purchased from Iran by or through foreign financial institutions.
+
+'''
+
+ s = '''
+Democrats keep their witnesses locked behind secure doors, then flood the press with carefully sculpted leaks and accusations, driving the Trump-corruption narrative. And so the party goes, galloping toward an impeachment vote that would overturn the will of the American voters—on a case built in secret.
+
+Conservative commentators keep noting that Mrs. Pelosi’s refusal to hold a vote on the House floor to authorize an official impeachment inquiry helps her caucus’s vulnerable members evade accountability. But there’s a more practical and uglier reason for Democrats to skip the formalities. Normally an authorization vote would be followed by official rules on how the inquiry would proceed. Under today’s process, Mr. Schiff gets to make up the rules as he goes along. Behold the Lord High Impeacher.
+
+Democrats view control over the narrative as essential, having learned from their Russia-collusion escapade the perils of transparency. They banked on special counsel Robert Mueller’s investigation proving impeachment fodder, but got truth-bombed. Their subsequent open hearings on the subject—featuring Michael Cohen, Mr. Mueller and Corey Lewandowski —were, for the Democrats, embarrassing spectacles, at which Republicans punched gaping holes in their story line.
+
+Mr. Schiff is making sure that doesn’t happen again; he’ll present the story, on his terms. His rules mean he can issue that controlling decree about “only one” transcript and Democratic staff supervision of Republican members. It means he can bar the public, the press and even fellow representatives from hearings, even though they’re unclassified.
+'''
+
+ s = '''
+Unemployment today is at a 50-year low. There are more Americans working today than ever before. Median household income in the last two and half years has risen by more than $5,000. And that doesn’t even account for the savings from the President’s tax cuts or energy reforms for working families.
+
+Because of the President’s policies, America has added trillions of dollars of wealth to our economy while China’s economy continues to fall behind.
+
+To level the playing field for the American worker against unethical trade practices, President Trump levied tariffs on $250 billion in Chinese goods in 2018. And earlier this year, the President announced we would place tariffs on another $300 billion of Chinese goods if significant issues in our trading relationship were not resolved by December of this year.
+'''
+ s = '''
+Needless to say, we see it very differently. Despite the great power competition that is underway, and America’s growing strength, we want better for China. That’s why, for the first time in decades, under President Donald Trump’s leadership, the United States is treating China’s leaders exactly how the leaders of any great world power should be treated — with respect, yes, but also with consistency and candor.
+'''
+ s = '''
+Brexit is the scheduled withdrawal of the United Kingdom from the European Union. Following a June 2016 referendum, in which 51.9% voted to leave, the UK government formally announced the country's withdrawal in March 2017, starting a two-year process that was due to conclude with the UK withdrawing on 29 March 2019. As the UK parliament thrice voted against the negotiated withdrawal agreement, that deadline has been extended twice, and is currently 31 October 2019. The Benn Act, passed in September 2019, requires the government to seek a third extension.
+'''
+
+ s = '''
+The argument for Brexit
+According to the BBC, the push to leave the EU was advocated mostly by the UK Independence Party and was not supported by the Prime Minister, David Cameron. Members of the UK Independence Party argued that Britain’s participation in the EU was a restrictive element for the country.
+
+As one of the EU’s primary initiatives is free movement within the region the party’s main arguments centered around regaining border control and reclaiming business rights. In addition, supporters of Brexit cited the high EU membership fees as a negative aspect of participation in the EU. It was argued that if the UK separates itself from the EU, these fees can be used to benefit the UK.
+
+The argument against Brexit
+The Conservative Party and the Prime Minister were strongly in favor of remaining with the EU. As a result of the decision to discontinue its participation in the EU, the Prime Minister has made a public statement that he will be relinquishing his position. He believes that the country needs a leader with the same goals as the majority of the country. He has promised a new PM will be in place by early September.
+
+The argument against Brexit pertains mostly to the business benefits. The argument is that the UK receives business benefits by being able to participate in the single market system established by the EU. In response to the criticism against the open borders, proponents believe that the influx of immigrants helps develop an eager workforce and fuels public service projects.
+
+Leaders in favor of staying also worry about the political backlash that could possibly result from other countries who favored staying with the EU. In addition, proponents of remaining with the EU believe that being part of a wider community of nations provides economic and cultural strength, as well as an additional element of security.
+
+What does Brexit mean for the future?
+While the decision marked a huge statement for the UK, the referendum vote is not legally binding. There are still many hurdles that must be dealt with before Brexit can become a reality.
+
+The UK is still subject to the laws of the EU until Britain’s exit becomes legal. In order for the UK to make its break official, the country needs to invoke Article 50. It is unclear exactly what this process will entail or how long it will take as Britain is the first country to take its leave of the EU. Once Article 50 has been formally invoked, the UK has two years to negotiate its departure with the other member states. But according to the BBC, “Extricating the UK from the EU will be extremely complex, and the process could drag on longer than that.”
+
+Amidst the aftermath of this shocking referendum vote, there is great uncertainty as political leaders decide what this means for the UK.
+
+'''
+
+
+ s = '''
+British Prime Minister Boris Johnson walks towards a voting station during the Brexit referendum in Britain, June 23, 2016. (Photo: EPA-EFE)
+
+LONDON – British Prime Minister Boris Johnson said Thursday he will likely ask Parliament to approve an election as part of an effort to break a Brexit deadlock.
+
+It is not clear if the vote, which Johnson wants to hold on Dec. 12, will take place as opposition lawmakers must also back the move.
+
+They are expected to vote on the measure on Monday.
+
+Johnson's announcement comes ahead of an expected decision Friday from the European Union over whether to delay Britain's exit from the bloc for three months.
+
+Britain's leader has been steadfastly opposed to any extension to the nation's scheduled Oct. 31 departure date from the EU, although in a letter to the leader of the opposition Labour Party this week he said he would accept a short technical postponement, "say to 15 or 30 November," to allow lawmakers to implement an EU withdrawal bill.
+
+Johnson's decision to offer to call an election follows lawmakers' rejection of his plan to rush through an EU exit bill that runs to hundreds of pages in just three days. They want more time to scrutinize the legislation and to make sure it does not leave the door open to a possible "no-deal" Brexit during future exit negotiations with the EU that will run through next year. A "no-deal" Brexit could dramatically harm Britain's economy.
+
+The prime minister was forced to ask for an extension to Britain's EU departure date after Britain's Parliament passed a law to ward off the threat of a "no-deal" Brexit.
+
+Johnson has repeatedly pledged to finalize the first stage, a transition deal, of Britain's EU divorce battle by Oct. 31. A second stage will involve negotiating its future relationship with the EU on trade, security and other salient issues.
+'''
+
+
+ s = '''
+Thank you very much. We have a Cabinet meeting. We’ll have a few questions after grace. And, if you would, Ben, please do the honors.
+
+THE PRESIDENT: All right, thank you, Ben. That was a great job. Appreciate it.
+
+The economy is doing fantastically well. It’s getting very close to another record. We’ve had many records since we won office. We’re getting very close to another record. I don’t know if anybody saw it: The household median income for eight years of President Bush, it rose $400. For eight years of President Obama, it rose $975. And for two and half years of President Trump — they have it down as two and a half years — it rose $5,000, not including $2,000 for taxes. So it rose, let’s say, $7,000. So in two and a half years, we’re up $7,000, compared to $1,000, compared to $400. And that’s for eight years and eight years.
+
+That’s a number that just came out, but that’s a number that I don’t know how there could be any dispute or any — I’ve never heard a number like that, meaning the economy is doing fantastically well.
+
+We need — for our farmers, our manufacturers, for, frankly, unions and non-unions, we need USMCA to be voted on. If it’s voted on, it’ll pass. It’s up to Nancy Pelosi to put it up. If she puts it up, it’s going to pass. It’s going to be very bipartisan. It’s something that’s very much needed. It’ll be hundreds of thousands of jobs.
+
+
+'''
+
+
+
+
+ #f = open('bbc-fulltext/bbc/entertainment/001.txt')
+ f = open('wordlist.txt')
+ s = f.read()
+ f.close()
+
+
+
+
+ print(text_difficulty_level(s, d3))
+
+
diff --git a/app/main.py b/app/main.py
index 50b2146..b2145cb 100644
--- a/app/main.py
+++ b/app/main.py
@@ -13,7 +13,7 @@ import pickle_idea, pickle_idea2
import os
import random, glob
from datetime import datetime
-from flask import Flask, request, redirect, render_template, url_for, session, abort, flash
+from flask import Flask, request, redirect, render_template, url_for, session, abort, flash, get_flashed_messages
from difficulty import get_difficulty_level, text_difficulty_level, user_difficulty_level
app = Flask(__name__)
@@ -30,6 +30,13 @@ def get_random_ads():
ads = random.choice(['个性化分析精准提升', '你的专有单词本', '智能捕捉阅读弱点,针对性提高你的阅读水平'])
return ads + '。 <a href="/signup">试试</a>吧!'
+def total_number_of_essays():
+ rq = RecordQuery(path_prefix + 'static/wordfreqapp.db')
+ rq.instructions("SELECT * FROM article")
+ rq.do()
+ result = rq.get_results()
+ return len(result)
+
def load_freq_history(path):
d = {}
if os.path.exists(path):
@@ -74,6 +81,15 @@ def within_range(x, y, r):
return x > y and abs(x - y) <= r
+def get_article_title(s):
+ return s.split('\n')[0]
+
+
+def get_article_body(s):
+ lst = s.split('\n')
+ lst.pop(0) # remove the first line
+ return '\n'.join(lst)
+
def get_today_article(user_word_list, articleID):
rq = RecordQuery(path_prefix + 'static/wordfreqapp.db')
@@ -83,6 +99,7 @@ def get_today_article(user_word_list, articleID):
rq.instructions('SELECT * FROM article WHERE article_id=%d' % (articleID))
rq.do()
result = rq.get_results()
+ random.shuffle(result)
# Choose article according to reader's level
d1 = load_freq_history(path_prefix + 'static/frequency/frequency.p')
@@ -98,18 +115,23 @@ def get_today_article(user_word_list, articleID):
if articleID == None:
for reading in result:
text_level = text_difficulty_level(reading['text'], d3)
- #print('TEXT_LEVEL %4.2f' % (text_level))
- if within_range(text_level, user_level, 0.5):
+ 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 within_range(text_level, user_level, (8.0 - user_level)*factor):
d = reading
break
- s = '<p><i>According to your word list, your level is <b>%4.2f</b> and we have chosen an article with a difficulty level of <b>%4.2f</b> for you.</i></p>' % (user_level, text_level)
- s += '<p><b>%s</b></p>' % (d['date'])
- s += '<p><font size=+2>%s</font></p>' % (d['text'])
- s += '<p><i>%s</i></p>' % (d['source'])
+ s = '<div class="alert alert-success" role="alert">According to your word list, your level is <span class="badge bg-success">%4.2f</span> and we have chosen an article with a difficulty level of <span class="badge bg-success">%4.2f</span> for you.</div>' % (user_level, text_level)
+ s += '<p class="text-muted">Article added on: %s</p>' % (d['date'])
+ s += '<div class="p-3 mb-2 bg-light text-dark">'
+ article_title = get_article_title(d['text'])
+ article_body = get_article_body(d['text'])
+ s += '<p class="display-3">%s</p>' % (article_title)
+ s += '<p class="lead">%s</p>' % (article_body)
+ s += '<p><small class="text-muted">%s</small></p>' % (d['source'])
s += '<p><b>%s</b></p>' % (get_question_part(d['question']))
s = s.replace('\n', '<br/>')
s += '%s' % (get_answer_part(d['question']))
+ s += '</div>'
session['articleID'] = d['article_id']
return s
@@ -171,6 +193,15 @@ def get_answer_part(s):
return html_code
+def get_flashed_messages_if_any():
+ messages = get_flashed_messages()
+ s = ''
+ for message in messages:
+ s += '<div class="alert alert-warning" role="alert">'
+ s += f'Congratulations! {message}'
+ s += '</div>'
+ return s
+
@app.route("/<username>/reset", methods=['GET', 'POST'])
def user_reset(username):
@@ -223,11 +254,14 @@ def mainpage():
<head>
<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" />
+ <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
+
<title>EnglishPal 英文单词高效记</title>
</head>
<body>
'''
+ page += '<div class="container-fluid">'
page += '<p><b><font size="+3" color="red">English Pal - Learn English smartly!</font></b></p>'
if session.get('logged_in'):
page += ' <a href="%s">%s</a></p>\n' % (session['username'], session['username'])
@@ -235,6 +269,7 @@ def mainpage():
page += '<p><a href="/login">登录</a> <a href="/signup">成为会员</a> <a href="/static/usr/instructions.html">使用说明</a></p>\n'
#page += '<p><img src="%s" width="400px" alt="advertisement"/></p>' % (get_random_image(path_prefix + 'static/img/'))
page += '<p><b>%s</b></p>' % (get_random_ads())
+ page += '<div class="alert alert-success" role="alert">共有文章 <span class="badge bg-success"> %d </span> 篇</div>' % (total_number_of_essays())
page += '<p>粘帖1篇文章 (English only)</p>'
page += '<form method="post" action="/">'
page += ' <textarea name="content" rows="10" cols="120"></textarea><br/>'
@@ -249,6 +284,8 @@ def mainpage():
break
page += '<a href="%s">%s</a> %d\n' % (youdao_link(x[0]), x[0], x[1])
+ page += ' <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>'
+ page += '</div>'
page += '</body></html>'
return page
@@ -275,6 +312,7 @@ def unfamiliar(username,word):
user_freq_record = path_prefix + 'static/frequency/' + 'frequency_%s.pickle' % (username)
pickle_idea.unfamiliar(user_freq_record,word)
session['thisWord'] = word # 1. put a word into session
+ session['time'] = 1
return redirect(url_for('userpage', username=username))
@app.route("/<username>/<word>/familiar", methods=['GET', 'POST'])
@@ -282,12 +320,14 @@ def familiar(username,word):
user_freq_record = path_prefix + 'static/frequency/' + 'frequency_%s.pickle' % (username)
pickle_idea.familiar(user_freq_record,word)
session['thisWord'] = word # 1. put a word into session
+ session['time'] = 1
return redirect(url_for('userpage', username=username))
@app.route("/<username>/<word>/del", methods=['GET', 'POST'])
def deleteword(username,word):
user_freq_record = path_prefix + 'static/frequency/' + 'frequency_%s.pickle' % (username)
pickle_idea2.deleteRecord(user_freq_record,word)
+ flash(f'<strong>{word}</strong> is no longer in your word list.')
return redirect(url_for('userpage', username=username))
@app.route("/<username>", methods=['GET', 'POST'])
@@ -326,10 +366,13 @@ def userpage(username):
page = '<meta charset="UTF8">\n'
page += '<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=0.5, maximum-scale=3.0, user-scalable=yes" />\n'
page += '<meta name="format-detection" content="telephone=no" />\n' # forbid treating numbers as cell numbers in smart phones
+ page += '<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">'
page += '<title>EnglishPal Study Room for %s</title>' % (username)
- page += '<p><b>English Pal for <font color="red">%s</font></b> <a href="/logout">登出</a></p>' % (username)
- page += '<p><a href="/%s/reset">下一篇</a></p>' % (username)
+ page += '<div class="container-fluid">'
+ page += '<p><b>English Pal for <font color="red">%s</font></b> <a class="btn btn-secondary" href="/logout" role="button">登出</a></p>' % (username)
+ page += get_flashed_messages_if_any()
page += '<p><b>阅读文章并回答问题</b></p>\n'
+ page += '<p><a class="btn btn-success" href="/%s/reset" role="button"> 下一篇 Next Article </a></p>' % (username)
page += '<div id="text-content">%s</div>' % (get_today_article(user_freq_record, session['articleID']))
page += '<p><b>收集生词吧</b> (可以在正文中划词,也可以复制黏贴)</p>'
page += '<form method="post" action="/%s">' % (username)
@@ -354,7 +397,12 @@ def userpage(username):
if session.get('thisWord'):
page += '''
<script type="text/javascript">
- location.href = "#aaa" // 2. define a anchor URL and point to the anchor in the page whose id is aaa
+ //point to the anchor in the page whose id is aaa if it exists
+ window.onload = function(){
+ var element = document.getElementsByName("aaa");
+ if (element != null)
+ document.getElementsByName("aaa")[0].scrollIntoView(true);
+ }
</script>
'''
@@ -368,15 +416,18 @@ def userpage(username):
for x in sort_in_descending_order(lst2):
word = x[0]
freq = x[1]
- if session.get('thisWord') == x[0]:
+ if session.get('thisWord') == x[0] and session.get('time') == 1:
page += '<a name="aaa"></a>' # 3. anchor
+ session['time'] = 0 # discard anchor
if isinstance(d[word], list): # d[word] is a list of dates
if freq > 1:
- page += '<p class="new-word"> <a href="%s">%s</a>(<a title="%s">%d</a>) <a href="%s/%s/familiar">熟悉</a> <a href="%s/%s/unfamiliar">不熟悉</a> <a href="%s/%s/del">删除</a> </p>\n' % (youdao_link(word), word, '; '.join(d[word]), freq,username, word,username,word, username,word)
+ page += '<p class="new-word"> <a class="btn btn-light" href="%s" role="button">%s</a>(<a title="%s">%d</a>) <a class="btn btn-success" href="%s/%s/familiar" role="button">熟悉</a> <a class="btn btn-warning" href="%s/%s/unfamiliar" role="button">不熟悉</a> <a class="btn btn-danger" href="%s/%s/del" role="button">删除</a> </p>\n' % (youdao_link(word), word, '; '.join(d[word]), freq,username, word,username,word, username,word)
else:
- page += '<p class="new-word"> <a href="%s">%s</a>(<a title="%s">%d</a>) <a href="%s/%s/familiar">熟悉</a> <a href="%s/%s/unfamiliar">不熟悉</a> <a href="%s/%s/del" >删除</a> </p>\n' % (youdao_link(word), word, '; '.join(d[word]), freq,username, word,username,word, username,word)
+ page += '<p class="new-word"> <a class="btn btn-light" href="%s" role="button">%s</a>(<a title="%s">%d</a>) <a class="btn btn-success" href="%s/%s/familiar" role="button">熟悉</a> <a class="btn btn-warning" href="%s/%s/unfamiliar" role="button">不熟悉</a> <a class="btn btn-danger" href="%s/%s/del" role="button">删除</a> </p>\n' % (youdao_link(word), word, '; '.join(d[word]), freq,username, word,username,word, username,word)
elif isinstance(d[word], int): # d[word] is a frequency. to migrate from old format.
page += '<a href="%s">%s</a>%d\n' % (youdao_link(word), word, freq)
+ page += '<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>'
+ page += '</div>'
return page
### Sign-up, login, logout ###
diff --git a/app/static/wordfreqapp.sql b/app/static/wordfreqapp.sql
index 6966c11..76bf322 100644
--- a/app/static/wordfreqapp.sql
+++ b/app/static/wordfreqapp.sql
@@ -47,6 +47,22 @@ INSERT INTO user VALUES('ValuedCustomer','l0ve1t','20190928','20190928');
INSERT INTO user VALUES('lanhui1025','l0ve1t','20191025','20191025');
INSERT INTO user VALUES('cool','test','20191025','20191025');
INSERT INTO user VALUES('lanhui1025b','l0ve1t','20191025','20191025');
+INSERT INTO user VALUES('lanhui20210428','l0ve1t','20210428','20211230');
+INSERT INTO user VALUES('laijingtao','l0ve1t','20210428','20211230');
+INSERT INTO user VALUES('13173817032','123456','20210510','20211230');
+INSERT INTO user VALUES('984472450','984472450','20210510','20211230');
+INSERT INTO user VALUES('1292164003@qq.com','ljj123','20210510','20211230');
+INSERT INTO user VALUES('0987654321','Ca11MeLW!','20210516','20211230');
+INSERT INTO user VALUES('17858992909','123456','20210517','20211230');
+INSERT INTO user VALUES('98765','98765','20210519','20211230');
+INSERT INTO user VALUES('1359178602@qq.com','123456','20210520','20211230');
+INSERT INTO user VALUES('214660032@qq.com','ZHUWENQI','20210526','20211230');
+INSERT INTO user VALUES('admin@qq.com','‘ or ‘1’=‘1’','20210527','20211230');
+INSERT INTO user VALUES('1021844583','GGMU1234','20210610','20211230');
+INSERT INTO user VALUES('CZY_chenzhiyuan@outlook.com','Ca11MeCZY!','20210622','20211230');
+INSERT INTO user VALUES('chenzhiyuan0920@gmail.com','Ca11MeCZY!','20210622','20211230');
+INSERT INTO user VALUES('zwq','123456','20210622','20211230');
+INSERT INTO user VALUES('lanhui713','l0ve1t','20210713','20211230');
CREATE TABLE IF NOT EXISTS "article" (
"article_id" INTEGER PRIMARY KEY AUTOINCREMENT,
"text" TEXT,
@@ -101,6 +117,10 @@ INSERT INTO article VALUES(43,replace('How to Learn to Program\n\nOctober 9, 201
INSERT INTO article VALUES(44,replace('McConnell backs Trump legal fight in election results\n\n10 November 2020\n\nSenate Majority Leader Mitch McConnell backed the Trump campaign’s legal challenge of voting results in several battleground states on Monday in his first public comments on the floor since Election Day.\n\nIn his remarks, McConnell, R-Ky., said, “no states have yet certified their election results” and that recounts are already expected to occur in “at least one or two states.” The longtime senator argued that President Trump is “100 percent within his rights to look into allegations of irregularities and weigh his legal options.”\n\nMeanwhile, Attorney General William Barr on Monday gave federal prosecutors the green light to pursue "substantial allegations" of voting irregularities before the 2020 presidential election is certified next month, even though little evidence of fraud has been put forth.','\n',char(10)),'Source: https://www.foxnews.com/politics/live-updates-mcconnell-backs-trump-legal-fight-in-election-results','20 Nov 2020','4',replace('QUESTION\n\nThe election results are official at the time of writing this news. Is this statement true?\n\n\nANSWER\n\nFalse.\n','\n',char(10)));
INSERT INTO article VALUES(45,replace('Meet Minimum Requirements: Anything More is Too Much\n\nSeptember 1, 1998\n\nCommit to a project plan that only includes essential function, with a “closet plan” for nonessential function.\n\nby Neal Whitten, PMP, Contributing Editor\n\nDoes this conversation between a project manager and a project outsider sound familiar? It’s a Y2K project, but it could be any project.\n\nOutsider: “Will your project complete on time?”\nPM: “We have no choice.”\nOutsider: “I didn’t ask if you had a choice. I asked will you complete on time?”\nPM: “This is an important project. There’s a lot riding on the success of this project. We must complete on time.”\n\n(Translation: “No, we won’t complete on time. Anybody with any project experience knows this.”)\n\nIs this a Y2K-unique problem? No—it’s common on most projects. The primary reason it’s so common on Y2K projects is that most of the project managers and other project leaders on these projects were trained on pre-Y2K projects. Let me explain.\n\nOne of the most common problems with projects is taking on too much work—attempting to exceed requirements rather than meet minimum requirements. This contributes to a plethora of ill effects, including late deliveries, budget overruns, low morale and poor quality. Attempting to cram the proverbial 10 pounds into a 5-pound sack is a common occurrence.\n\nOne solution is to build products that meet minimum requirements. You may be thinking that such a product would have low appeal to your client or customers, but it’s not what you think.\n\n“Meet minimum requirements” means give the client what he or she needs to be successful; but don’t provide unessential function. Additional function is what future releases and future business opportunities are all about. It is important to earn the reputation for being reliable in meeting customer commitments and then be trusted to continue to upgrade on a routine, predictable basis. This is good business.\n\nYou say you always only provide essential function? For most of us, most times, that’s not true. Have you ever faced slipped delivery dates and chosen to remove some of the function originally planned? When the project began, everyone swore that all the planned function was essential. Yet, as the project progressed—and got further behind schedule—some of that essential function no longer looked so essential.\n\nWe’ll use a Y2K project as an example, because Y2K projects are at a heightened focus these days—and, interestingly enough, the No. 2 problem with Y2K projects is that they are taking on too much work (the No. 1 problem is that too many projects are starting too late). Here’s what should occur.\nLet’s say you’ve identified 100 functions (enhancements or changes) that need to be made in your company’s programs. You know that all 100 functions are desirable, but you recognize that your limited resources won’t allow all the functions to be ready by the hoped-for date. You find that 40 functions fall within the high-priority category, 30 as medium and 30 as low. You build a project plan to implement only the 40 high priorities. Why? Because you don’t want to jeopardize the timely completion of these 40 by building a plan to include the other 60 functions—all of lesser importance and, for purposes of illustration, deemed nonessential.\n\nYou might be thinking that you should build a plan with all 100 functions and later, if (actually, when) the project gets into trouble, you can always back out of lesser-priority function. Don’t go there! This foolish plan requires spending valuable time, dollars and resources working on other-than-the-most-important functions. Moreover, when you back out, it costs again. What needs to be done is to build a plan that significantly reduces rework. This means the original plan must be only essential function.\n\nWhat about the other 60? You carefully look these over and put work-arounds in place that, although not optimal, can get you through until more substantial actions can occur.\n\nBut there is something else you do. You decide on the most important of the 60 functions—maybe it’s all of the 30 medium functions or some subset thereof—and you create multiple, independent small projects with any and all resources you can muster. I call these small projects collectively a “closet plan.” These small projects are managed with the same care and attention to quality as the primary project. If any of these small projects can complete by a predetermined date (e.g., system test) and the risk to the primary project is judged to be acceptable, then the completed small projects are merged in with the primary project. There are many advantages to this technique: from reducing risk to the primary project, to motivating the members of the small projects to complete by a predetermined date, to setting customer expectations that are most likely to be met or exceeded.\n\nMost of us have been conditioned to believe that “meets minimum requirements” is unexciting and noncompetitive. I believe it to be the opposite. Deliberately practicing meeting minimum requirements helps an organization or company to be first-to-market, earn increasing credibility from their client(s), and strongly posture their enterprise for taking on new business opportunities. Adopting the concept of meeting minimum requirements can set your organization up for exceptional performance.','\n',char(10)),'Source: https://nealwhittengroup.com/articles/meet-minimum-requirements-anything-more-is-too-much/','20 Nov 2020','4',replace('QUESTION\n\nMeeting the minimum requirements is not exciting.\nIs this statement true?\n\nANSWER\n\nFalse\n','\n',char(10)));
INSERT INTO article VALUES(46,replace('Text of a statement from President Donald Trump on the election result\n\nNov 7, 2020 12:48 PM EST\n\n\n“We all know why Joe Biden is rushing to falsely pose as the winner, and why his media allies are trying so hard to help him: they don’t want the truth to be exposed. The simple fact is this election is far from over. Joe Biden has not been certified as the winner of any states, let alone any of the highly contested states headed for mandatory recounts, or states where our campaign has valid and legitimate legal challenges that could determine the ultimate victor. In Pennsylvania, for example, our legal observers were not permitted meaningful access to watch the counting process. Legal votes decide who is president, not the news media.\n\n“Beginning Monday, our campaign will start prosecuting our case in court to ensure election laws are fully upheld and the rightful winner is seated. The American People are entitled to an honest election: that means counting all legal ballots, and not counting any illegal ballots. This is the only way to ensure the public has full confidence in our election. It remains shocking that the Biden campaign refuses to agree with this basic principle and wants ballots counted even if they are fraudulent, manufactured, or cast by ineligible or deceased voters. Only a party engaged in wrongdoing would unlawfully keep observers out of the count room – and then fight in court to block their access.\n\n“So what is Biden hiding? I will not rest until the American People have the honest vote count they deserve and that Democracy demands.”\n\nThe statement was issued while Trump was golfing at his club in Virginia.','\n',char(10)),'Source: https://www.pbs.org/newshour/politics/read-president-donald-trumps-full-statement-on-the-election-results-vowing-to-head-to-the-courts','20 Nov 2020','4',replace('QUESTION\n\nWho wrote the above text?\n\nANSWER\n\nTrump.\n','\n',char(10)));
+INSERT INTO article VALUES(47,replace('My typical day\n\nJanuary 12, 2021\n\nDave Rupert\n\n6:30am — My cat headbutts me awake asking for food. I get up and feed the cat. He has a bad thyroid and meows obnoxiously throughout the whole process, but it gets done. I push a button to start my first cup of coffee on our Jura and start browsing headlines.\n6:50am — Kids wake up, get them watching a Netflix while I make breakfast.\n7:45am — Get son logged onto Zoom School. Occasionally I’ll write or play Barbie with my daughter during this time.\n8:45am — Wife and son take daughter to preschool. I shower and get ready for work.\n9:00am — Begin work. Work is broken up by numerous coffee breaks, bathroom breaks, and meetings throughout the day. I tend to hit a productivity stride starting around 2pm, so mornings are spent catching up on projects, blogs, and emails while reserving the afternoon for more focused deep work.\n??:?? — I regularly forget to eat lunch. This is a bad habit. Whenever I do eat lunch, it’s usually at my desk while watching some YouTubes. Look, I ain’t proud of this, but it’s what we got going on.\n5:15pm — Leave work, walk twelve steps to the kitchen.\n5:30pm — Eat dinner at the dining table with kids. They peel off mid-meal.\n6:00pm — Walk the dog, listen to audiobooks.\n6:40pm — Get kids bath’d and ready for bed.\n8:15pm — Wash dishes, listen to audiobooks, minimal tidying.\n9:30pm — Leisure time. Most nights I’ll hop onto Discord with friends and play video games. Currently it’s a mix of Overwatch and Call of Duty: Warzone. When not playing video games, it’s a mix of reading, writing, DnD, recording Aside Quest, or watching Star Trek with my wife.\n12:00am — Read until I fall asleep.','\n',char(10)),'Source: https://daverupert.com/2021/01/my-typical-day/','28 April 2021','4',replace('QUESTION\n\nWhen does the author get up in his typical day?\n\nANSWER\n\n6:30am.\n','\n',char(10)));
+INSERT INTO article VALUES(48,replace('5 A Day: what counts?\n-Eat well\n\n\n\nAlmost all fruit and vegetables count towards your 5 A Day, so it may be easier than you think to get your recommended daily amount.\n\nAt a glance: what counts?\n--------------------------\n \n- 80g of fresh, canned or frozen fruit and vegetables counts as 1 portion of your 5 A Day. Opt for tinned or canned fruit and vegetables in natural juice or water, with no added sugar or salt.\n\n- 30g of dried fruit (this is equivalent to around 80g of fresh fruit) counts as 1 portion of your 5 A Day. Dried fruit should be eaten at mealtimes, not as a between-meal snack, to reduce the risk of tooth decay.\n\nSome portions only count once in a day:\n\n- 150ml of fruit juice, vegetable juice or smoothie. Limit the amount you drink to a combined total of 150ml a day. Crushing fruit and vegetables into juice and smoothies releases the sugars they contain, which can damage teeth. Juices and smoothies should be consumed at mealtimes, not as a between-meal snack, to reduce the risk of tooth decay.\n\n- 80g of beans and pulses. These only count once as part of your 5 A Day, no matter how many you eat. This is because although they''re a good source of fibre, they contain fewer nutrients than other fruits and vegetables.\n\n\nDifferent types of fruit and veg\n--------------------------------\n\nFruit and vegetables don''t have to be fresh to count as a portion. Nor do they have to be eaten on their own: they also count if they''re part of a meal or dish.\n\nThese all also count towards your 5 A Day:\n\nFrozen fruit and vegetables.\n\nTinned or canned fruit and vegetables. Buy ones tinned in natural juice or water, with no added sugar or salt.\nFruit and vegetables cooked in dishes such as soups, stews or pasta.\nA 30g portion of dried fruit, such as currants, dates, sultanas and figs, counts as 1 of your 5 A Day, but should be eaten at mealtimes, not as a between-meal snack, to reduce the impact on teeth.\nFruit and vegetables in convenience foods, such as ready meals and shop-bought pasta sauces, soups and puddings.\nSome ready-made foods are high in salt, sugar and fat, so only have them occasionally or in small amounts.\n\nYou can find the salt, sugar and fat content of ready-made foods on the label.\n\n\nDrinks and 5 A Day\n------------------\n\nKeep an eye on the amount of fruit juice and smoothies you drink. The current advice is to limit consumption of fruit or vegetable juices and smoothies to a combined total of 150ml a day (1 portion). Crushing fruit into juice releases the sugars they contain, which can damage teeth. Even unsweetened fruit juice and smoothies are sugary, so limit these to a combined total of 150ml a day.\nDiluting 150ml of fruit juice with water (still or sparkling) can make it go further.\nRemember to keep fruit juice and smoothies to mealtimes to reduce the impact on teeth.\n\n\nDo potatoes count towards my 5 A Day?\n--------------------------------------\n\nNo. Potatoes are a starchy food and a great source of energy, fibre, B vitamins and potassium. \n\nIn the UK, we get a lot of our vitamin C from potatoes. Although they typically only contain around 11 to 16mg of vitamin C per 100g of potatoes, we generally eat a lot of them.\n\nWhen eaten as part of a meal, potatoes are generally used in place of other sources of starch, such as bread, pasta or rice. Because of this, they don''t count towards your 5 A Day.\n\nOther vegetables that don''t count towards your 5 A Day are yams, cassava and plantain. They''re also usually eaten as starchy foods.\n\nSweet potatoes, parsnips, swedes and turnips do count towards your 5 A Day because they''re usually eaten in addition to the starchy food part of the meal.\n\nPotatoes play an important role in your diet, even if they don''t count towards your 5 A Day. It''s best to eat them without any added salt or fat. \n\nThey''re also a good source of fibre, so leave the skins on where possible to keep in more of the fibre and vitamins.\n\nFor example, if you''re having boiled potatoes or a jacket potato, make sure you eat the skin, too.\n\n\n','\n',char(10)),'Source: https://www.nhs.uk/live-well/eat-well/5-a-day-what-counts/','16 Jul 2021','4',replace('QUESTION\n\nWhen is this article about?\n\nA. Healthy food\nB. Fire safety\n\n\nANSWER\n\nA.','\n',char(10)));
+INSERT INTO article VALUES(49,replace('Online Conversations & Website Engagement\n\n3 Jul 2021\n\n\nI was reading a post on online conversations by Manu last night, and the whole thing resonated with me. So I wanted to jot down my thoughts about online conversations and why I think it’s broken.\n\n"I’ll keep saying it till the day I die, or until someone invents something better: private conversations via email. If you care about discussing something with someone, like genuinely care, try contacting them directly, in private, via email."\n\n -- Manu Moreale\n\n\nA couple of years ago, I removed all comments from this site. It’s a WordPress site, so enabling comments is trivial. However, I found that the vast majority of the comments I was getting were along the lines of this:\n\n Some Internet Guy\n\n 21 May 2020\n\n This is a great post, I wrote something similar on my site. Check it out…\n\n https://someinternetguy.com/my-unrelated-post\n\n\nIf it wasn’t my pal Some Internet Guy it was spam comments, usually about viagra, or sometimes trolls wishing me dead. Which is always nice. 😍\n\nLukily for me Akismet caught most of the spam, but I still had to wade through Some Internet Guy and his ilk’s useless comments on a daily basis.\n\n\nI still wanted onlined conversations\n-------------------------------------\n\nProblem was, dispite all the useless comments, I still wanted the engagement from genuine readers, as that’s the main reason I write content. So I replaced the comment form with a simple button that said Reply via email, which linked to my email address.\n\n\nAt first I wasn’t sure it would work. But a couple years on, I’m happy to report that it has. I’m sure I miss many useful comments, as a lot of people are less likely to send an email than write a comment. Mainly because there’s more involved in the latter, I think.\n\nBut that’s precisely why it has worked (I think). You see, this very small barrier of having to click a button, compose an email and send it just to me means many don’t bother. Those that do aren’t looking for traffic to their site, like Some Internet Guy. They’re genuinely interested in the subject of the post, and just want to discuss it further.\n\nI’ve had email conversations last weeks, and some people who have emailed me have kinda become friends off the back of it. I don’t think that would have happened if I was still using comments.\n\nI emailed Manu after reading his post, and we had a nice little conversation. He checked out my posts and we had a short chat about some stuff on this blog that he had thoughts on. It was a great connection, as are many of the engagements I have as a result of people emailing me.\n\nAnd don’t get me started on how much time it has saved me by not having to wade through useless comments every. Single. Day.\n\nClosing thoughts\n----------------\n\n\nI’m really happy I decided to remove comments from this site. If you have comments on your site, and you’re having similar problems to me (or if you’re using the horrendous Disqus) maybe consider doing the same?\n\nI’m not saying it will definitely work for you, but it has for me, and it seems to have done the trick for Manu too.\n\nAre you all in on comments on your site? Or do you have nothing at all? Please do let me know your thoughts using the — you guessed it — email button below. 😁\n','\n',char(10)),'Source: https://kevq.uk/online-conversations-website-engagement/','17 Jul 2021','3',replace('QUESTION\n\nWhy did the author remove comments from his web site?\n','\n',char(10)));
+INSERT INTO article VALUES(50,replace('Photos don’t capture the moment\n\nChad Moore\n\n7 June 2021\n\nI took this picture today, June 07 2021 around sunrise. When I looked at the picture on my phone, I thought to myself, “this picture doesnt do this sunrise justice”. I continiued to ruminate… Maybe I need to be a better iPhone photographer… I am sure there are tutorials and courses for that… Maybe I need a better camera. A real camera. Which one? How much does it cost? What things that I have now, could I sell to offset the spend? Maybe I should talk to my friends who are photographers…\n\nAnd so on, heading straight down a rabbit hole because I thought there was something lacking in me. My skills were not up to it. My tools aren’t “right”. I started walking and sat with these feelings. If I was literally the best photographer in the world, and I had the best and most perfect camera for sunrise photos at the beach, how much better would my picture be? Could I really capture the moment perfectly?\n\nYes, my picture would be better. But no, I wouldn’t be able to perfectly capture the moment.\n\nThe camera is a marvel of technology, and photos are great artifacts of what’s around us. What we’re experiencing. There are amazingly skilled photographers who can use their art and science to create emotionally moving imagery.\n\nBut photographs can’t capture the moment. Photos are visual representations of those moments, and they help us remember them.\n\nThe camera can’t capture the heat and humidity. The sounds of the waves and the birds. The smell of the ocean. The background noise of people and dogs on the beach. They can’t capture what’s in our heads at the moment.\n\nSo, I look at this picture as a remembrance of all those things I was experiencing this morning. Not as a perfect capture of it.\n\n','\n',char(10)),'Source: https://www.chadmoore.net/photos-are-remembrances','17 Jul 2021','4',replace('QUESTION\n\nWhat things a camera cannot do?\n','\n',char(10)));
DELETE FROM sqlite_sequence;
-INSERT INTO sqlite_sequence VALUES('article',46);
+INSERT INTO sqlite_sequence VALUES('article',50);
COMMIT;