0x00 Coding
https://coding.net/u/nikochan/p/2nd_SE/git
0x01 写在前面
因为在上一个作业中,是基于python完成的Command程序。那么再不想进行更多改动的基础上完成了这次的作业。选择了Web的方式,更具有挑战性!
Python中的运用较多的web框架是Django和flask。选择Flask主要是因为比较轻量级,API易读上手快。 开始了3天从入门到心塞的自学框架造轮子的不归路...
我自己希望自己的代码能更加pythonic,本次编程遵照下划线命名法
进行编码规范。
沉迷于编程让我在周末都没写托福阅读和写作,我有罪!不可赦的那种。
这次实验主要由201421123011 庞伊凡同学负责完成flask框架/app.py
的构造、数据交互以及功能实现/function.py
。201421123012 赵娅汀同学负责完成html
的部分。
思维导图
0x02 功能实现
- 错题重做功能。
- 自动计时功能。能显示用户开始答题后的消耗时间。
- 多语言支持。
- 控制输入。通过正则表达式对 输入题目数和答案的操作进行控制。只有数字才能被成功输入
- 难度分级。
0x03 程序设计
· 程序结构
├── README.md
├── app.py
├── function.py
├── static
├── templates
│ ├── answer.html
│ ├── fault.html
│ ├── index-ct.html
│ ├── index-en.html
│ ├── index.html
│ └── test.html
· 代码细析
·/app.py
这段代码是建立/hello-world/路径,并返回index.html
@app.route('/hello-world/', methods=['GET','POST'])
#@app.route('/hello/<name>')
def hello(name=None):
return render_template('index.html', name=name)
建立
/hello-world/test/
页面。并进行html页面中POST的quiz_num
,If_int
,If_Fraction
,If_complex_Fraction
的值进行获取。并传给function.py
进行主程序的运算。同事返回主程序结果至test.html
@app.route('/hello-world/test/',methods=['GET','POST'])
def show_question():
global number
if request.method == "POST":
number = request.values.get("quiz_num")
easy = str(request.values.get("If_int"))
normal = str(request.values.get("If_Fraction"))
hard = str(request.values.get("If_complex_Fraction"))
quiz=function.main(number , easy , normal, hard)
return render_template("test.html",allists=quiz)
else:
return 'test'
建立
/hello-world/answer
的页面。获取上一个页面中POST的用户答案,传入answer[],并进行结果判断后返回allists
@app.route("/hello-world/answer", methods=['GET','POST'])
def check_result():
global number
ans=[]
number=int(number)
if request.method == "POST":
ans=[]
for i in range(number):
ans=request.form.getlist("answer")
print ans
quiz=function.check(ans)
return render_template("answer.html",allists=quiz)
else:
return "Error.This page is not have any POST data."
return render_template("answer.html")
·/function.py
以上是POST的数据分析并返回给
Mode
模式选择函数。
def main(number , If_int , If_Fraction , If_complex_Fraction ):
mode=0
global allists
print number
print If_int,If_Fraction,If_complex_Fraction
for i in range(number):
if If_complex_Fraction == '1':
mode=random.randint(1,3)
Mode(mode)
elif If_Fraction=='1':
mode=random.randint(1,2)
Mode(mode)
elif If_int=='1':
calc_int()
else:
print "You didn't post the level data."
return allists
· html页面
进行了正则表达式的匹配,拒绝输入除0-9和/外的任何字符,也不能复制粘贴。
<input type="text" name=quiz_num onkeyup="(this.v=function(){this.value=this.value.replace(/[^0-9-]+/,'');}).call(this)" onblur="this.v();" /></input>
0x04 截图展示
位于Index页面的语言选择:
做题过程展示:
难度分级:
![](
)
0x05 PSP
0x06 小结
这次的实验又有了很多可以总结的东西。这几天比较忙,所以没有在第一时间写完并提交。现在的功能也还不够全面,我仍然要继续修改。包括非法输入的判断等。flask这个框架在学习起来走了不少弯路,也作为分享,提醒自己。并分享其他正在看的人。【虽然感觉可能没啥人看,毕竟自己太不Red。
- 框架写起来相对比较容易,然而关键是传值得时候使我花费了大量时间。这次的数据是通过列表(list)嵌套字典(dict)的方式。自己刚开始没读清楚API就上手去做了,结果是用的二维列表,结果折腾了很久都没有传值成功。小伙伴@201421123012 赵娅汀 的提醒让我仔细看文档之后才发现,可允许的提交方式是
[{'correct': '0', 'ans': u'1/4', 'result': '5/4', 'show': u'1 + 1/4='}, {'correct': '0', 'ans': 0, 'result': '1/4', 'show': u'1/2 - 1/4='}]
这样的。经过修改之后才成功POST了数据。
2.结对编程的方式很好,因为两个人的相互讨论从而使解决问题实现了最快的方式。比如在一些函数的实现上,卡壳了。和小伙伴讨论一番便能得出结论。 - 传值成功了取值又是一个问题。自己写的答案在获取的时候使用的是
<input name="xxx">
,然后在request.values.get
的过程中却只能传输一个answer。我用了多种方法,在html文件添加逻辑判断并传回数组,在app.py文件进行函数调用等方式均不能成功返回并提交到镶嵌的表格中去。后来又自己浏览了API并进行Google。找到了一个新的语句request.form.getlist("answer")
这句可以将POST的值以list的方式返回,最终解决了这个大问题。 - html页面单选框想要只选用一个,那么name的值要相等,即可被html解释成同类。否则无法实现单选的效果。
4.我觉得多次反复迭代并不是一个很高效的方法,仅仅是从一个函数迭代到另一个函数,以运行下一个函数作为这个函数的终结。我感觉并不是很好,因为没有返回值的操作会让我们在迭代的过程中丢掉返回值。这个问题影响了我很长时间,后来发现之后只能进行补偿。更好的办法是全部以返回值结束该函数。以后会尽力提高。
5.正因为设置相对正确的返回值,我频繁使用全局变量来完成操作。但是我看了一些书,书上说要尽量避免在python中使用全局变量以后会尽力提高。 - 人要勇于挑战自己,通过写作业的方式去学习新的框架新的语言不失是一种很好的方式,虽然可能会花费一定的时间。不过还是很值得的~
0x07 汉堡包🍔评论小伙伴
(第一个面包):娅汀编程经验较少,我作为驾驶员的身份,她是领航者的身份。刚开始我鼓励她要多勇于尝试,努力了就一定能减少bug成功运行。
(肉):培养一个良好的习惯非常重要。我负责做function的功能实现时,她在苦恼如何实现前段html页面。我跟她说:你慢慢做,别着急。一步一个脚印,今天写一点,明天写一点。总能完成的。
(第二个面包):在实现了基础功能之后,我觉得还不够满足。又和她一起完成了拒绝输入的功能。
和娅汀一起学习真的很开心。