面向未来验证我的应用程序代码的可读性(Django,初学者)
Future-proofing my application code for readability (Django, Beginner)
我的网站的目标是有一个页面,我们称之为"Random Question!"
每次用户进入页面,随机生成一组数字,他们必须正确回答问题:数字a + 数字b。
如果他们是正确的,他们会转到一个显示 "Correct" 的页面,然后他们将被重定向回同一页面,再次使用一组不同的数字。
现在,问题是,在第一页 "Random Question!",我想添加另一个问题。
Views.py:
def form_handle(request):
if request.method == 'POST':
form = MyForm(request.POST) # if post method then form will be validated
if form.is_valid():
cd = form.cleaned_data
num1 = cd.get('num1')
a = request.session.get('a', 0)
b = request.session.get('b', 0)
if float(num1) == float(a + b):
# give HttpResponse only or render page you need to load on success
return render(request, 'sectipn1part1success', {})
else:
# if sum not equal... then redirect to custom url/page
return HttpResponseRedirect('rr/') # mention redirect url in argument
else:
a = random.randrange(5,10);
b = random.randrange(10,20);
request.session['a'] = a
request.session['b'] = b
question1 = ('What is ' + str(a) + ' + ' + str(b) + ' ?')
form = MyForm() # blank form object just to pass context if not post method
context = {
'form': form,
'a': a,
'b': b,
'question1': question1
}
return render(request, "section1part1.html", context)
如您所见,现在它只做一种简单的问题,仅加法(问题 1)。
我想补充一个问题,比如问题2,可以是"What is a / 2"。
可以使用 Java SWITCH 语句之类的东西来实现上面的内容(我不确定 Django 是否有它,尽管没有它应该可以做到)。将生成对应于另一个问题的随机数。然后我必须在 if request.method == 'POST' 之后使用另一个 IF 语句来计算正确答案,因为每个新问题的计算方式都会不同。
现在,以上在短期内将是一个很好的策略。
从长远来看,我不确定它是否理想。有没有更好的方法来做这种事情,或者我的方法可以吗?
我正在考虑其他方法,包括:
- 例如,使用视图调度程序类型的函数,它会调用另一个视图而不是一个视图上的所有内容,但我不确定这是否可能
** 是否有任何我应该注意的性能注意事项? **
更新 #1
好的,我已经开始实施上面的建议了。这是发生了什么:
Django 视图被调用 --> 另一个视图函数被随机调用并进行处理和 returns 上下文对象
else: #add another 'if' randomiser to selection question function randomly
context = question1(request)
context = question2(request)
return render(request, "section1part1.html", context)
这是好的做法/风格吗?我应该继续这样做吗?
form_handle
应该只负责处理表格。所有创建问题和答案的工作都应该由其他东西来完成。一旦你这样做了,就很容易切换出问题类型,或者生成无限循环的问题,或者创建一个问题列表来循环,或者...
这是一个 Question
class 的例子。您可以轻松地创建 return 一个 (question, answer)
元组或任何其他种类的 question/answer 生成器的函数。
class Question(object):
def answer(self):
raise NotImplementedError
def question(self):
raise NotImplementedError
class AdditionQuestion(Question):
def __init__(self):
a_range = (5, 10)
b_range = (10, 20)
self.a = random.randrange(*a_range)
self.b = random.randrange(*b_range)
def answer(self):
return self.a + self.b
def question(self):
return 'What is {} + {}?'.format(self.a, self.b)
class MultiplicationQuestion(Question):
def __init__(self):
a_range = (100, 200)
b_range = (10, 20)
self.a = random.randrange(*a_range)
self.b = random.randrange(*b_range)
def answer(self):
return self.a * self.b
def question(self):
return 'What is {} * {}?'.format(self.a, self.b)
那么,您的代码仅依赖于具有 object.question()
和 object.answer()
的对象。如果您想要非数字答案,或者足够接近的答案(例如:3.3333 足够接近 3.333333),您可以将 if float(num1) == float(answer):
更改为 if compare_answers(num1, answer):
,然后编写一个 compare_answers
函数。
def form_handle(request):
if request.method == 'POST':
form = MyForm(request.POST) # if post method then form will be validated
if form.is_valid():
cd = form.cleaned_data
num1 = cd.get('num1')
answer = request.session.get('answer', 0)
if float(num1) == float(answer):
# give HttpResponse only or render page you need to load on success
return render(request, 'sectipn1part1success', {})
else:
# if sum not equal... then redirect to custom url/page
return HttpResponseRedirect('rr/') # mention redirect url in argument
else:
question = AdditionQuestion()
answer = question.answer()
request.session['answer'] = answer
form = MyForm() # blank form object just to pass context if not post method
context = {
'form': form,
'answer': answer,
'question': question.question()
}
return render(request, "section1part1.html", context)
如果您想要一个随机问题类型的生成器,也可以将其制作成自己的 function/object。将它与 form_handle
分开,以便于更改:
def random_question():
class_ = random.choice([MultiplicationQuestion, AdditionQuestion])
return class_()
然后将此处的行更改为:
else:
question = AdditionQuestion()
至:
else:
question = random_question()
我的网站的目标是有一个页面,我们称之为"Random Question!"
每次用户进入页面,随机生成一组数字,他们必须正确回答问题:数字a + 数字b。
如果他们是正确的,他们会转到一个显示 "Correct" 的页面,然后他们将被重定向回同一页面,再次使用一组不同的数字。
现在,问题是,在第一页 "Random Question!",我想添加另一个问题。
Views.py:
def form_handle(request):
if request.method == 'POST':
form = MyForm(request.POST) # if post method then form will be validated
if form.is_valid():
cd = form.cleaned_data
num1 = cd.get('num1')
a = request.session.get('a', 0)
b = request.session.get('b', 0)
if float(num1) == float(a + b):
# give HttpResponse only or render page you need to load on success
return render(request, 'sectipn1part1success', {})
else:
# if sum not equal... then redirect to custom url/page
return HttpResponseRedirect('rr/') # mention redirect url in argument
else:
a = random.randrange(5,10);
b = random.randrange(10,20);
request.session['a'] = a
request.session['b'] = b
question1 = ('What is ' + str(a) + ' + ' + str(b) + ' ?')
form = MyForm() # blank form object just to pass context if not post method
context = {
'form': form,
'a': a,
'b': b,
'question1': question1
}
return render(request, "section1part1.html", context)
如您所见,现在它只做一种简单的问题,仅加法(问题 1)。
我想补充一个问题,比如问题2,可以是"What is a / 2"。
可以使用 Java SWITCH 语句之类的东西来实现上面的内容(我不确定 Django 是否有它,尽管没有它应该可以做到)。将生成对应于另一个问题的随机数。然后我必须在 if request.method == 'POST' 之后使用另一个 IF 语句来计算正确答案,因为每个新问题的计算方式都会不同。
现在,以上在短期内将是一个很好的策略。
从长远来看,我不确定它是否理想。有没有更好的方法来做这种事情,或者我的方法可以吗?
我正在考虑其他方法,包括:
- 例如,使用视图调度程序类型的函数,它会调用另一个视图而不是一个视图上的所有内容,但我不确定这是否可能
** 是否有任何我应该注意的性能注意事项? **
更新 #1
好的,我已经开始实施上面的建议了。这是发生了什么:
Django 视图被调用 --> 另一个视图函数被随机调用并进行处理和 returns 上下文对象
else: #add another 'if' randomiser to selection question function randomly
context = question1(request)
context = question2(request)
return render(request, "section1part1.html", context)
这是好的做法/风格吗?我应该继续这样做吗?
form_handle
应该只负责处理表格。所有创建问题和答案的工作都应该由其他东西来完成。一旦你这样做了,就很容易切换出问题类型,或者生成无限循环的问题,或者创建一个问题列表来循环,或者...
这是一个 Question
class 的例子。您可以轻松地创建 return 一个 (question, answer)
元组或任何其他种类的 question/answer 生成器的函数。
class Question(object):
def answer(self):
raise NotImplementedError
def question(self):
raise NotImplementedError
class AdditionQuestion(Question):
def __init__(self):
a_range = (5, 10)
b_range = (10, 20)
self.a = random.randrange(*a_range)
self.b = random.randrange(*b_range)
def answer(self):
return self.a + self.b
def question(self):
return 'What is {} + {}?'.format(self.a, self.b)
class MultiplicationQuestion(Question):
def __init__(self):
a_range = (100, 200)
b_range = (10, 20)
self.a = random.randrange(*a_range)
self.b = random.randrange(*b_range)
def answer(self):
return self.a * self.b
def question(self):
return 'What is {} * {}?'.format(self.a, self.b)
那么,您的代码仅依赖于具有 object.question()
和 object.answer()
的对象。如果您想要非数字答案,或者足够接近的答案(例如:3.3333 足够接近 3.333333),您可以将 if float(num1) == float(answer):
更改为 if compare_answers(num1, answer):
,然后编写一个 compare_answers
函数。
def form_handle(request):
if request.method == 'POST':
form = MyForm(request.POST) # if post method then form will be validated
if form.is_valid():
cd = form.cleaned_data
num1 = cd.get('num1')
answer = request.session.get('answer', 0)
if float(num1) == float(answer):
# give HttpResponse only or render page you need to load on success
return render(request, 'sectipn1part1success', {})
else:
# if sum not equal... then redirect to custom url/page
return HttpResponseRedirect('rr/') # mention redirect url in argument
else:
question = AdditionQuestion()
answer = question.answer()
request.session['answer'] = answer
form = MyForm() # blank form object just to pass context if not post method
context = {
'form': form,
'answer': answer,
'question': question.question()
}
return render(request, "section1part1.html", context)
如果您想要一个随机问题类型的生成器,也可以将其制作成自己的 function/object。将它与 form_handle
分开,以便于更改:
def random_question():
class_ = random.choice([MultiplicationQuestion, AdditionQuestion])
return class_()
然后将此处的行更改为:
else:
question = AdditionQuestion()
至:
else:
question = random_question()