1 绪论
1.1研究背景
我国是一个拥有15亿人口的大国。其中,据2017年的统计,全国共有大学生2600万左右。如此数量众多的大学生,都会有着学习基础数理课程的需求。而在高校的数学教学中,教授最多最广泛的课程便是高等数学。
然而,与之高等数学广泛的学习率相比,它同时也有着相当高的挂科统计率。大多数学生,在学习高等数学的时候,都会感觉到一定的困难。
原因大致有三:高等数学的抽象性;大一学年的学习气氛松散;缺乏足量的实际练习。
然而,抽象性,新生学习气氛松散,缺乏足量的练习,这些都是大学高等数学教育中本身存在的问题,并非一朝一夕,或者改革课堂教学就可以改变。这时候,引入新的教学方式与学习方法,例如在线教育,增加学生们的学习质量和效率,倒不失为一个不错的选项。
在线教育,需要提供给更加优秀的教学应用,因而充分发挥其网络化优势,使得学生们可以轻松地获得优质的教育资源和环境。而要达成以上一点,首先,我们需要一个可以承载知识和信息交流的平台:高等数学学习平台。
这个平台需要具备如下基础功能:承载线上教学信息,提供简洁清晰的教学内容分类浏览,承载线上习题功能,承载线上讨论与解疑。
与此同时,大学中经常使用的数学软件为:Matlab。但这存在以下问题:昂贵的收费;大型软件,不易安装;为复杂工程而设计,不易学习。
因而,现在的大学数学教学和研究,也迫切的需要一款轻量级、开源、易于使用的数学软件。在此背景下,Sage Math应运而生。
Sage Math的预期用户就是学数学的学生、教师和研究人员,主要领域也是代数、几何、数论、微积分、数值计算等常用领域。它自身的特点使得以上人员可以很容易的学习它,并使用。
虽然Sage Math是一款免费的开源软件,也提供了很多类似中文帮助文档的支持,然而在中国,Sage Math的知名度并不高,国内也没有网站长期支持Sage Math的使用,缺乏相关的数学网站和资料。这种情况导致了大多数人仍然只能使用笨重的Matlab,并且这也不便于在课堂上使用数学软件,进行辅助教学。
因而,利用Sage Math本身为了教学和研究而被创造的特性,和它轻量级、开源免费的特点相结合,将它与高等数学网上学习平台结合到一起,将会有如下作用:
有助于高等数学的课堂学习,有助于学生提升练习效率,同时通过网络化快速便捷的进行网络计算、获取资源和传播,无需重复编写课件。
因而,本文期望对Sage Math与高等数学教学的网络化结合予以研究,旨在得到一个可以对学生的在线高等数学学习和数学计算需求有着良好帮助的在线数学学习平台。
1.2 研究内容
本文对基于Saga Math的数学学习平台的开发环境、开发方法和开发过程进行了介绍和讨论。首先,对Sage Math和所需的开发环境进行系统性的介绍,涉及Sage Math的基本概念,特点和优势等。然后对所使用的开发工具、开发框架和数据库工具进行介绍。其中包括Django的python开发框架。此后对于系统的分析与设计进行介绍,详细介绍项目的需求,详细描述系统的模块划分,并详细介绍了每个模块的具体功能和详细设计。最后对整个系统做一个简要综述。
1.3 章节安排
第一章为绪论。其主要介绍系统的研究背景和研究意义,并对全文大纲做总体的介绍。
第二章对系统做一个简要的总体介绍,并讨论本系统所使用的开发环境与开发工具,其中包括对Sage Math数学工具,Django框架和MySQL数据库的介绍。
第三章中对系统进行分析和设计。其中包括系统的需求分析和系统设计,功能划分和功能设计,并对其详细设计进行阐述。
第四章对系统的架构和功能模块进行了实现。
第五章对全文做了一个总结并对系统进行综述。
2系统及开发环境概述
2. 1系统介绍
以现在的技术来开发此系统的话,除了ASP.NET,还可以有多种选择,例如JSP、PHP、ASP等。数据库的选择可以有:MYSQL、ORACLE 、ACCESS以及 SQL Server等。但是经过综合的对比比较,本系统最后决定此采用ASP.NET+SQL Server 2008为基础进行开发。整个系统基于Web的形式,这两个开发平台都提供对Web的完全支持,并拥有强大的集成和可扩展的分析功能,能帮助用户进行快速开发、调试和数据转换,开发出新一代企业级商业应用程序。
2.2使用Sage Math的理由
2.2.1 什么是Sage Math
Sage Math是在多种情况下实现数学算法的软件。首先,它可以用作科学的袖珍计算器,并且可以处理各种数字,从整数和有理数到任意精度的实数和复数的数值逼近,还包括有限域的元素。然而,数据运算并不局限于数字:Sage是计算机代数系统;例如,它可以帮助初中学生学习如何求解线性方程式,或创建,分解或简化表达式;或在多项式或有理函数域的任意环中进行此类运算。在分析中,Sage可以操作包含平方根,指数,对数或三角函数的表达式:积分,极限计算,和的简化,级数展开,某些微分方程的解等。在线性代数中,它使用向量,矩阵和子空间进行计算。它还可以帮助说明和解决概率,统计和组合问题。
总而言之,Sage致力于在广泛的数学领域(从组论到数值分析)以及其他方面,在二维和三维可视化,动画,网络,数据库... 使用一个免费而统一的软件使得萌芽期的数学家们摆脱了在多种工具之间传输数据,和学习多种编程语言的语法的麻烦。
像大多数用于数学计算的软件一样,Sage通过发布以编程语言编写的命令来使用。为此,Sage使用通用编程语言Python,仅使用一小层语法来支持交互使用中的一些常见数学符号。对于复杂或重复的计算,可以编写程序而不是简单的单行命令。当算法成熟并且有广泛应用的需求时,可以将之提交到Sage的库中。
此外,Sage是建立在开源软件之上的,它本身就是完全开源的。它可在全球范围内免费用于私人,商业,*等用途。它的许可证是众所周知的GNU公共许可证(GPL),每个人都可以下载它,在数量不限的计算机上安装它并重新分发副本。[1]
2.2.2 Sage Math的历史
2005年,美国学者William Stein发起了Sage项目,其目标是创造用于用户自己开发的、开源的,用于数学计算的免费软件。这满足了数学家们的长期需求,很快,一个由数百名开发人员组成的国际社区围绕Sage形成了结晶,其中大多数是教师和研究人员。最初,Sage专注于数论,这是其创始人感兴趣的领域。随着捐款的涌入,它的功能逐渐扩展到数学的许多领域。结合Python的科学生态系统带来的数值功能,Sage成为当今的通用数学软件。人们可以免费使用和下载Sage,同时它是免费的软件:作者对其没有施加任何限制使用,重新分配,学习或修改都是允许的。同样,本书的材料也可以*阅读,共享和重复使用(当然要有适当的信誉)。该许可证符合学术界*发展和知识传播的精神。
Sage的发展相对较快,这得益于其重用现有*软件的策略,其中包括许多专门的数学库或系统(例如GAP,PARI / GP,Maxima,Singular)。Python在科学领域特别成熟。 在同一个计算环境中,可以将Sage的功能与科学相结合,以进行包括数值计算,数据分析,统计,可视化,机器学习,生物学,天体物理学以及用于网络,数据库,Web等的技术库等内容。
起初,Sage既是“鼠尾草”药用植物的首字母缩写,也是其简称。当Sage系统后来扩展到涵盖许多数学问题时,缩写词部分被删除了。由于Sage在更大的圈子里广为人知,同时为了避免与同名的业务管理软件产生混淆,因此将其正式名称更改为Sage Math。[2]
2.2.3 Sage Math的可视化应用
Sage Math具有广泛的可视化数学功能。它可以生成2-D以及3-D图形,甚至可以制作动画图。Wiki包含一些可以使用Sage Math绘制的图像示例。[3]
不仅Sage Math本身包含了大量的可视化工具,与此同时,Sage Math与python的紧密结合,也使得它可以运用python中与可视化和图形有关的一系列库。
例如:
示例1:
sage:plot(x * sin(1/x), x, -2, 2, plot_points=500)
图2-1 示例1
示例2:
sage:t = var(‘t‘); n = 20/19
sage:g1 = polar_plot(1+2*cos(n*t),(t,0,n*36*pi),plot_points=5000)
sage:g2 = polar_plot(1+1/3*cos(n*t),(t,0,n*36*pi),plot_points=5000)
sage:g1.show(aspect_ratio=1); g2.show(aspect_ratio=0)
图2-2 示例2
2.2.4 Sage Math与向对象编程和python的关联
除了单行命令,Sage还允许使用指令序列,即程序。Sage计算机代数系统实际上是Python编程语言的扩展,除少数例外,都可以使用 Python编程的结构。
Sage计算机代数系统本身是基于众多函数(例如exp or solve)构建的,这些函数返回结果,例如数字,表达式,解决方案列表等。[4]
Sage主要有两种输入方式,一种是单纯的Sage单行指令,类似matlab;另一种便是便是直接使用python编程,使用Sage预处理后再解释运行。Sage预先包含了许多个开源的数学处理包,这会为你的数学运算带了许多方便。
此外,Sage Math是建立在面向对象的编程语言之上的。灵活的使用此特征构建对象和方法,有助于Sage Math的使用。
2.2.5 Sage Math与数学学习平台
Sage的预期用户是学数学的学生(从高中生到研究生)、教师以及研究人员。我们的目标是在代数、几何、数论、微积分、数值计算等领域提供可用于探索和尝试的软件。Sage使得进行与数学对象有关的交互实验变得容易。[5]
Sage有三个显著的特点:轻量级,开源免费,功能强大。这使得它很适合作为大学数学的辅助学习软件。
轻量级:Sage有两种使用方式:直接使用浏览器打开网页,安装到本地。其中,对于大多数人和学生来说,直接使用浏览器打开Web应用,即可以很好的满足需求,而无需像matlab一样下载繁杂的软件并安装。在课堂上,老师可以方便和学生们一起打开Sage的网站并使用它来演示教学,而Sage使用的python语法恰好也可以作为学生们基础的编程语言来学习,并可以结合python的科学库,比如anaconda和numpy , scipy。
开源免费:Sage是纯粹的开源软件,这意味着你可以免费使用它,方便的将它传播给任何人,任意的修改它。因而,这很适合作为网络数学教学的核心,因为学生们无需付费就可以享受到全部功能,并且可以使用网站和论坛的大量的开源资源。同样,开源,就意味着在将来你可以一直免费的使用它,并且有着庞大的社区来维护它。
功能强大:事实上,Sage整合了python的大部分数学处理的库的功能,使得你可以方便的进行数学运算。并且,作为一种面向对象语言,你可以使用python语言,使用条件、循环和迭代等,构建简洁而强大的函数,方法和程序,在Sage中进行运算。
因而,Sage很适合用来搭建数学平台,助力大学的数学科目学习。
2.2.6 为何要使用Sage Math
Sage是一种轻量级的开源软件,致力实现各类数学算法,同时具备着轻量级和庞大社区的特点。因而学生们可以轻易的使用Sage,而无需花费过多精力配置环境或无力购买相关正版软件。
因而,教师们在教学中,可以轻松的结合Sage的计算功能和可视化功能,演示相关定理证明和讲解习题,无需在Sage本身中花费太多功夫。
同样,学生们既可以轻松的直接使用Sage现成的函数库和程序,进行相关的计算和观看可视化结果,或者观看证明过程,也可以学习简易的Sage使用命令和python语法,编写相关的程序,轻易的得到使用数学算法后的计算结构,也可以快速的将结果可视化,而这都是传统软件或传统教学方式所得不到的。
将Sage与互联网技术相结合,搭建在线统一的学习平台网站,为大量的大学数学学习的学生和教授的教师提供平台和服务,辅助其学习和教学,具有重大的意义。
2.3 网站核心框架:Django
Python作为一种新近崛起的编程语言,具有功能强大,简洁便捷等特点,深受程序员好评,也有许多人使用python搭建网站。
而用python搭建网站,最好的框架无疑就是Django了。
Django是一款由Python定制的免费开源Web开发框架,本质基于MVC框架,即Model(模型)+View(视图)+ Controller(控制器)设计模式,因此天然具有MVC的出色基因:开发快捷、部署方便、可重用性高、维护成本低等,又对其进行改良,使之实质成为MVT框架,实现动态的逻辑处理和静态的页面展示分离。
Django的主要目的是简便、快速地开发数据库驱动的网站,用一种业务逻辑、数据、界面显示分离的方法组织代码。其可扩展性强,更容易重构代码。
图3-2 Django的基础目录结构
2.4前端技术:Bootstrap
Bootstrap 是全球最受欢迎的开源前端组件库,用于开发响应式布局、移动设备优先的 WEB 项目。
Bootstrap4 目前是 Bootstrap 的最新版本,是一套用于HTML、CSS 和JS开发的开源工具集。利用提供的大量的可扩展的的预制组件、基于jQuery的强大的插件系统,能够快速为你的想法开发出原型或者构建整个app。
Bootstrap的响应式布局设计,可以快读的设计一个界面清新、简洁的网站,并使得它可以兼容多个具有不同分辨率的设备,即适应移动设备。
同时,Bootstrap还具有丰富的开源论坛和社区,无数工程师在其中交流,并贡献资源和案例。利用社区,可以快速学习,迅速上手,同时结合Bootstrap本身的易用性特点,这使得Bootstrap具有良好的学习曲线。
图3-3 Bootstrap整体框架图
2.5 数据库:SQlite
SQLite是一款轻量级的开源的嵌入式数据库,由D.Richard Hipp在2000年发布。
SQLite所占用的体积很小,尽管如此,在处理轻型数据的时候,它的调取速度却比Mysql等数据库快得多。因而,在轻型网站上使用SQLite数据库,可以满足数据存储调取、易部署和流畅性的需求。
2.6总结
通过查阅相关资料,结合相关需求,本系统需要满足使用方便快捷、页面清晰明了、有记录用户使用数据的功能、笔记与评论等功能,因而,作者决定采用Sage Math数学工具、Django网站框架、Bootstrap前端技术和SQlite轻量级数据库的技术组合,以满足系统的需求实现,增加页面的可阅读性和流畅性。
3数学学习平台的分析和设计
本学习平台,基于Sagemath的开源特性和高等数学网络学习工具的现实需要,选取Sagemath数学工具、Django网站框架、Bootstrap前端技术和SQLite轻量级数据库,致力于实现让学生们方便的在网站使用Sagemath数学工具和学习高等数学知识。整个系统将会以基于电脑端Web应用的形式,提供流畅、稳定和方便的访问服务,和对学生有帮助性的功能。
3.1 系统需求分析
本系统的设计目的旨在开发一个可以使学生方便快捷的在网络上使用的数学软件平台和高等数学学习平台。学生们可以通过网站学习高等数学教学内容,在学习中通过Sagemath查看相关定理论证过程和相应的计算过程;完成相应的数学练习题,并且通过Sagemath快捷得出答案,系统将比对答案是否正确并返回结构;同样的,学生们可以通过笔记、提问并收到回答的方式,解疑答惑,巩固自己所掌握的知识。此外,网站应是流畅并兼容性强的。
3.1.1用户用例分析
网站将分为几个基本功能模块:
学习区:学习信息的展示;
编程区:Sage的编程与计算;
讨论区:知识的讨论与精选文章;
习题区:习题的练习和结果反馈;
登录区:注册、登录和账号设置。
具体用例图如下:
图3-1 用例图
其中,最为核心的区域为学习区和编程区。
这两块区域的设计和实现将会决定用户主要的学习效率。
3.1.2主要用例分析
接下来,将对几个用户的主要用例活动进行详细分析,其具体如下:
(1)用例名:学习活动
行为者:学生,游客
前置条件:学生已登录,进入课程的某一章节的相应学习页面;或游客未登录,直接进入上述页面。
描述:用户在学习页面通过浏览文本信息、观看视频、阅览sagemath数学展示等,进行学习活动。
说明:用户从章节列表点击进入具体章节的学习页面,进行学习,在学习结束之后进入习题部分,或下一章,结束学习活动。
后置条件:后台记录登录用户的此次学习章节。
(2)用例名:进行练习
行为者:学生,游客
前置条件:用户完成学习活动,进入练习区域。
描述:用户阅读题目文本,在sagemath编辑器中编辑sagemath代码,运行并检查结果是否符合预期,修改代码,最后确认提交。用户得到返回的正确/错误结果,并浏览正确结果和示例sagemath代码。
说明:题目应清晰,明了;用户进行试验、得到结果、提交的过程应顺畅,方便;返回正确结果和示例代码应清晰,快捷。
后置条件:后台记录用户的这次习题练习,并记录此次练习是否在未浏览答案时一次编码通过。
3.1.3用户活动图分析
根据对学生的学习活动的具体解析,得到系统的活动图如下:
图3-2 活动图
3.2系统架构设计
3.2.1系统总体设计
整个系统模块分为登录模块、教学模块、习题模块、讨论模块四部分。系统总体设计如图3-1所示。之后将分别介绍。
图3-3 总体功能图
3.2.2登录模块设计
登录模块,即包含游客登录、游客注册和个人信息管理三个主要功能。功能如图3-2所示:
(1)游客登录
用户可以通过游客身份进入网站,也可以浏览内容,但只有登录账户之后,才可以保存和查看自己的个人信息,缓存章节进度等等。因而,用户应该可以网站显著的地方,看到登录按钮,并进行快捷的登录操作。
在登录页面,用户可以输入账号密码,通过验证,进行登录。
(2)游客注册
未注册的用户,可以在以游客模式进入主站时,点击右上角的注册按钮,进入注册页面。
用户可以填写自己的基本信息,选择用户名、账号和密码,进行注册。
注册之后,用户可以跳转登录。
(3)个人信息管理
学生点击进入后可以
用户在登陆账号之后,可以在主站方便的跳转到个人信息页面。
在个人信息页面,应该有如下功能:
修改自己的个人信息;
重设密码;
查看自己的学习进度和笔记;
查看自己收到的消息和评论;
查看自己已经写下的Sage代码和相关题目;
检查自己的学习成果和习题评分。
图3-4 登录模块设计
3.2.3教学模块设计
教学模块,即学生们在学习高等数学知识时所使用的主要模块。这个模块用来加载学习用的文本信息、图片、视频和Sagemath的演示。因而,它主要包含以下三个功能,如图3-3所示:
(1)文本展示
网站将会在学习页面的主要区域,展示用以高等数学教学用的文本信息和图片。
并且,这些信息在设计上,并非由前端直接提供,而是由数据库所导出的,因而,网站管理者应可从后台直接对其进行上传、编辑和管理。
(2)视频展示
教学页面可以将教学用的视频信息导入到教学区域,以合理、直观、方便的方式展现出来。
同理,这些视频信息,也是可以由后台管理页面直接上传和管理的。
(3)Sage运算展示
网站将可以基于Sagemath的代码,直接性的演示类似于“微分的运算”,“泰勒展开”等数学运算,先提供具体代码,再将之可视化的展示出来。这将方便高等数学的教学。
图3-5 教学模块设计
3.2.4习题模块设计
习题模块,即学生们在相应的学习之后,进行高等数学的习题练习的区域。所不同的是,本网站将使用Sagemath代码作为习题和解答的方式。学生们将会学到:如何解题,如何将自己的解法转变为输入的代码,并由Sagemath程序直接返回结果,验证正确与否。之后,系统也将提供展示可行的解法。
因而,习题模块将会有以下三个功能,如图3-4所示:
(1)习题展示
和高等数学教学内容息息相关的习题将会战士在这里,用以加深学生的理解和掌握。
(2)解答代码输入
学生们将被指导以sagemath代码的形式来展示自己的解题思路,并将算式和解法输入sagemath程序,得到结果,验证与预想答案是否正确。学生将可以根据sagemath返回结果,反复修正自己的思路和代码,直到得到预期结果,点击提交。
(3)正确答案展示
在学生们正式提交解答之后,网站将范湖正确答案与正确的解答过程,这也包括了可以得到答案的示例sagemath代码。
图3-6 习题模块设计
3.2.4讨论模块设计
管理员管理模块即管理员页面窗口,用于对所有资料查询、添加、删除,比如对教师信息的管理
讨论模块,即学生们在相应的学习章节进行课堂的讨论的地方。为了能使学生们能够正常讨论以及得到一些常见解疑答惑,讨论区需具有以下三个功能,如图3-5所示:
(1)提问
这里的提问,即学生们在章节之后提出自己的问题,也可以被直接理解为发帖。学生可以通过输入文本,发出提问。
(2)评论
评论功能,即学生们对其他人发出的提问进行评论。
此外,章节的评论区域,将会将有多人的评论的提问,放置于显著的最前方,以方便阅读者快速浏览。
(3)收到消息
学生们可以在个人信息中心查看自己收到的系统消息和提问、评论的回复。
图3-7 讨论模块设计
3.3系统详细设计
3.3.1 数据库逻辑设计
逻辑设计的任务就是把概念设计阶段的E—R图转换为DBMS支持的数据模型(如关系模型),形成数据库的逻辑模式。转化时要解决的问题就是如何将实体间的联系转化为关系模型:对于实体,将每个实体转换为一个关系,实体的属性即为关系的属性,实体的码即为关系的码。
学习平台系统的数据库主体主要有五个部分,分别为:学生,章节,课程,评论,习题。
其具体的E-R关系图如下,如图3-6所示:
图3-8 学习平台E-R关系图
3.3.2 底层数据库设计
无论是什么系统,数据库的设计都起着至关重要的作用,其设计效果对系统的稳定性和流畅性以及日后维护有着直观的效果。为了完成本系统的数据模型,在此数据库设计中,共设计了5张的数据库图表,以下分别对其进行详细的介绍。
表3.1 User(用户)
字段名 |
类型 |
说明 |
userID |
int |
用户账号 |
name |
varchar |
用户名 |
userpwd |
varchar |
密码 |
right |
nvarchar |
权限 |
createdTime |
smalldatetime |
用户创建时间 |
lastChapter |
int |
上次学习章节 |
|
varchar |
电子邮件地址 |
commentID |
int |
发表评论编号 |
表3.2 Chapter(章节)
字段名 |
类型 |
说明 |
chapterID |
int |
章节编号 |
chapterName |
smallint |
章节名 |
courseID |
int |
所属课程编号 |
chapterText |
text |
章节文本 |
chapterCode |
text |
章节sagemath代码 |
chapterLink |
text |
章节视频链接 |
表3.3 Course(课程)
字段名 |
类型 |
说明 |
courseID |
int |
课程编号 |
courseName |
varchar |
课程名 |
courseAbout |
text |
课程简介 |
coureseMaker |
text |
制作人信息 |
表3.4 Practice(习题)
字段名 |
类型 |
说明 |
practiceID |
int |
习题编号 |
practiceName |
varchar |
习题名字 |
chapterID |
int |
所属章节编号 |
practiceText |
text |
课程名字 |
practiceCode |
text |
教师ID |
表3.5 Comment(评论)
字段名 |
类型 |
说明 |
commentID |
int |
评论编号 |
userID |
int |
发表评论用户编号 |
massagerID |
int |
评论对象用户编号 |
commentText |
text |
评论文本 |
chapterID |
int |
所属章节编号 |
4 数学学习平台的实现
4.1 系统架构的实现
本系统是基于Django框架来开发的,其使用的数据库为轻型数据库Sqlite,并搭配以Bootstrap制作的前端网页。
为了合理制作系统,本系统主要基于四部分:
数据库设计与制作;
登录注册功能的开发;
教学内容的开发;
习题与评论。
以下将逐个介绍。
4.2 数据库设计与制作
4.2.1数据库设计
在制作系统之前,我们首先需要完成数据库的结构与属性的具体的设计和实现。
之前在需求分析中,设计好了数据库需要的结构和字段,接下来将使用Django自带的models数据库管理功能,将规划好的数据库,以models要求的形式设计出来。
Django将其功能主要分为几大模块,路径转发,视图层,admin管理,模块层,前端页面。其中对于复杂系统来说,必不可少的就是管理数据库内容的模块层,其核心也就是Django的models.py。
首先,我们将数据库的表定义为三层,其中,上层表可以依赖于下层表,下层不可以依赖于上层,同一层的表之间可以互相依赖。这里的依赖与指的是,上层表可以使用下层表的主键,作为其外键。
因而,我们得出了三层数据表的结构:
层级划分:
- 评论
- 章节 用户 习题
- 课程
其中所对应的引用关系为:
- 评论——用户 评论——章节(评论引用用户、章节的主键作为外键)
- 习题——章节
- 章节——课程
此外,涉及到的尤为重要的多对多的关系为:
- 用户、章节
- 用户、习题
因而,进行多对多关系的设计:
- 用户_章节 id user_id chapter_id finish_already(choose: finished, study, not_finished)
- 用户_习题 id user_id practice_id grade(choose: good, so-so, bad)
在设计中,所尤为需要的注意的外键依赖和多对多关系至此设计完成。
4.2.2数据库定义与迁移
接下来,就是在Django的models模块中进行表的定义。
Django在models.py模块,将一张数据表,即定义为一个类,表内的字段便是其类的属性,可以定义其数据类型和具体属性。
除此之外,也可以在models.py直接使用python语言设计数据库的视图。
表Course的定义代码如下所示:
class Course(models.Model):
name = models.CharField(max_length = 40, verbose_name = ‘课程名‘)
about = models.CharField(max_length = 200, verbose_name=‘课程描述‘)
maker = models.TextField(max_length = 40, verbose_name=‘课程制作者‘)
def __str__(self):
return self.name
首先定义表:Course,其次,定义其三个属性:name, about, maker, 最后,定义在管理页面的展示,将返回它的name属性作为名字。
这里需要注意的是:Django的models模块,会自动给设计的类添加id属性,并按照创建时间赋值,并将id作为其主键。因而表的定义中无需再写出id和primary key。
然后我们选取三层结构的最上层:评论(Commet)作为展示:
class Comment(models.Model):
text = models.TextField(max_length = 400, verbose_name=‘评论文本‘)
chapter = models.ForeignKey(Chapter, on_delete = models.CASCADE, verbose_name=‘评论所在章节‘)
# 发出评论的人
student = models.ForeignKey(Student, on_delete=models.CASCADE, verbose_name=‘发出评论的人‘)
这里我们使用了models.ForeignKey的方法,定义了其外键。其中,定义了
on_delete=models.CASCADE,也就是引用主键的数据被删除或修改时,引用其主键作为外键的数据也同样被删除或修改。
在进行类似的定义,完成models模块的初步设计之后,接下来我们进行数据库的迁移。
使用Django自带的python manage.py makemigrations命令,django将会自动生成迁移文件。之后,再使用python manage.py migrate命令,将会执行迁移操作,将在models.py文件中创建的表和做出的修改,迁移到数据库中去。如下图所示:
图4-1 迁移数据库
至此,使用django的models模块进行的数据库设计与迁移完成。
4.2.3 使用Django自带的admin功能进行后台管理
Django自带有admin后台管理功能,允许管理用户很方便的进行后台相关操作,其中最主要的,就是数据库的表的增删改查操作。
这里,我们使用django自带的admin功能,查看新建的数据表是否正确,并为其新增内容。
其具体的管理页面如下图所示:
图4-2 admin管理页面
使用admin后台管理功能,我们为其数据库增添了充足的数据,并确认表与属性的设计是否正确。
至此,Django的models模块制作完成。.
4.3 登录注册模块的实现
在django框架中,登录注册模块,主要涉及到:
前端页面的表单设计;
前端与后端的变量传递;
view视图层的逻辑判断;
数据库的查询和添加。
以下将根据功能进行介绍。
4.3.1用户登录
用户登录,从需求上,主要是用户在前端页面,使用表单填写数据,点击登录按钮,进入主页。
从逻辑上,前端页面的表单组件,收集用户填写数据并返回后端view视图层,view视图层进行逻辑判断,并通过django的数据库查询,判断邮箱/密码是否正确,返回结果。
(1)前端登录页面
如果用户的邮箱密码在数据库中查询到相应的数据,则登陆成功,跳转至主页。如果用户输入的信息的在数据库中未核验正确,则返回出错信息,提示用户核对后重新输入。
登录功能的前端页面设计如下图所示:
图4-3 登录页面
可以看见,前端页面的主体为表单。用户填写邮箱和密码的表单之后,点击登录,则前端页面将会返回给django视图层POST请求和相应表单数据。
其前端的表单设计如下:
<form method = ‘POST‘ class="form-horizontal" role="form">
{% csrf_token %}
<div class="form-group">
<label for="firstname" class="col-sm-2 control-label">邮箱</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="email" placeholder="请输入邮箱">
</div>
</div>
<div class="form-group">
<label for="lastname" class="col-sm-2 control-label">密码</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="password" placeholder="请输入密码">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<div class="checkbox">
<label>
<input type="checkbox" >请记住我
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">登录</button>
<button type="submit" class="btn btn-default">注册</button>
</div>
</div>
</form>
<p>{{msg}}</p>
其中,使用HTML语言的<input>组件中的属性”name”,进行前后端变量值的传递。
需要注意的是,相应错误的提示信息,是通过<p>{{msg}}</p>和后端的msg变量进行传递和错误提示。
(2)后端登录逻辑
后端的View视图层在收到前端表单发来的POST请求后,判断其为登陆操作,则从POST请求中的数据,根据表单名,取到相应的数据,赋给相应的变量。先使用email变量,判断数据库的Student表中,是否存在此条数据,如存在,则取出此条数据,进一步进行密码校验。如密码校验通过,则登陆成功。如果有一步出错,则返回相应的出错信息。
View视图层对于登录功能的相应代码如下:
def login(request):
# 收到POST请求
if request.method == ‘POST‘:
# 取出POST请求中的数据,赋值给相应变量
email = request.POST.get(‘email‘)
password = request.POST.get(‘password‘)
# 根据email,查询用户是否在数据库中
if Student.objects.filter(email = email).exists():
# 取出此条数据
student = Student.objects.get(email = email)
# 判断密码是否一致
if password == student.password:
# 使用HttpResponseRedirect方法,返回新的页面
return HttpResponseRedirect(‘index‘)
else:
# 返回出错信息:密码错误
return render(request, ‘sage/login.html‘, {‘msg‘: ‘用户密码错误‘})
else:
# 没有查询到用户信息,返回错误:用户不存在
return render(request, ‘sage/login.html‘, {‘msg‘: ‘用户不存在‘})
if request.method == ‘GET‘:
return render(request, ‘sage/login.html‘,{‘msg‘:‘‘})
这里的不足之处是:django的用户密码,会在数据库里进行哈希算法加密,但view视图层将其提取到了后端视图层,并在视图层传递。因而,此举具有一定的安全隐患。其解决方法是,使用django自带的密码核对函数,将数据带到数据库层,进行核对。但因笔者能力有限,目前尚未实现,希望以后能够将其实现。
4.3.2用户注册
相比于登陆操作,注册操作设计到了向数据库添加数据,并核对相关数据是否符合格式,用户名或邮箱是否与已有数据重复。
点击登录页面的注册按钮,用户就可以进入到注册页面。在注册页面的引到下填写表单的相应数据,提交注册。
需要核对的事项有:
填写数据是否符合数据库要求的格式;
密码在填写中将以星号展示;
两次密码输入需要一致;
用户名和邮箱不得与已有数据重复;
每一项都不能为空。其前端页面如下所示:
图4-3 注册页面
前端页面的表单代码其实与登录页面相一致,这里就不再重复。
后端view视图层的校验数据与向数据库增添注册用户的代码如下:
def signup(request):
if request.method == ‘GET‘:
return render(request, ‘sage/signup.html‘,{‘msg‘:‘‘})
if request.method == ‘POST‘:
# 根据POST请求,取出相应数据到对应变量
email = request.POST.get(‘email‘)
password = request.POST.get(‘password‘)
password2 = request.POST.get(‘password2‘)
name = request.POST.get(‘password‘)
# 判断各个数据是否为空,如果为空,则返回相应的错误信息,提示用户其为空
if len(email) == 0:
return render(request, ‘sage/signup.html‘, {‘msg‘: ‘邮箱不能为空,请检查‘})
if len(password) == 0:
return render(request, ‘sage/signup.html‘, {‘msg‘: ‘密码不能为空,请检查‘})
if len(name) == 0:
return render(request, ‘sage/signup.html‘, {‘msg‘: ‘用户名不能为空,请检查‘})
if len(password2) == 0:
return render(request, ‘sage/signup.html‘, {‘msg‘: ‘再次输入不能为空,请检查‘})
# 判断密码是否足够复杂,密码长度设置为需大于8
if len(password) <= 8:
return render(request, ‘sage/signup.html‘, {‘msg‘: ‘密码长度不够,请设置更加复杂的密码‘})
# 判断用户前后两次输入的密码是否一致
if password == password2:
# 因为使用了create方法,因而需要捕获异常(不可创建会报错),报错则使用except,返回错误信息
try:
Student.objects.create(name = name, email = email, password = password)
except :
return render(request, ‘sage/signup.html‘, {‘msg‘: ‘用户名或邮箱已存在,请更换‘})
else:
# 跳转到登录页面,引到用户登录
return HttpResponseRedirect(‘login‘)
# 如不一致,提醒其前后输入密码不一致
else:
return render(request, ‘sage/signup.html‘, {‘msg‘: ‘两次输入密码不一致‘})
在用户成功登录后,将会跳转至登录页面,引导用户登录。
4.4 教学模块的实现
4.4.1教学模块页面
教学模块,主要分为两部分。
第一部分,是高等数学的教学内容的展示,位于页面的左侧与中侧,即主要部分。这一部分将会根据课程的相应章节展示相应部分的高等数学的教学内容。学生们可以通过学习,来掌握高等数学的基本知识。
第二部分,是教学页面关于SageMath的使用方法的基础教学,位于页面的右侧。与此同时,这一SageMath教学部分将与第一部分的教学内容有所关联。例如:第一部分讲述了高等数学的微积分环节,而右侧的SageMath教学就会教授学生,如何使用SageMath快捷方便的进行微积分运算。
此外,当高等数学的教学内容需要进行相应的定理证明或者运算演示,或者相应的可视化的图像,右侧的SageMath部分也会使用SageMath功能,进行相应的证明运算、计算或者可视化展示。
(1)前端教学页面
其前端页面如下图所示:
图4-4 教学页面
在前端页面中,使用了Bootstrap的设置,将其主要分为两个部分,左侧的高等数学教学区域和右侧相对应的SageMath教学区域,其关键数据为Chapter.name和Chapter.text,和Sage.name和Sage.text。
以下是关键部分的相应代码:
<div class="container page-header">
<h1>{{ curr_chapter.name }}</h1>
</div>
<div class="container page-body">
<div class="col-md-9" role="main">
<div class="body-main">
{% for section in section_list %}
<p>{{ section }}</p>
{% endfor %}
</div>
</div>
<div class="col-md-3" role="complementary">
{% for sage in sages %}
<h3>{{sage.name}}}</h3>
<h4>以下是示例代码:</h4>
<div class="compute"><script type="text/x-sage">{{ sage.text }}
</script></div>
{% endfor %}
</div>
</div>
其中,{{ curr_chapter.name }}、{{ sage.text }}为django特有的传递变量的方法。后端使用render()方法,返回html页面和相关变量,而前端页面使用{{ 变量 }}的写法,来使用变量。
此外,如下代码:
{% for section in section_list %}
{{ section }}
{% endfor %}
则使用django自带的方法,在前端页面中使用了循环语法,遍历了section_list的QuerySet列表中的每一个元素。
而在页面的最底部,具有跳转前一篇和后一篇的功能。
<div>
<nav aria-label="...">
<ul class="pager">
<li><a href="/sage/chapter/{{ previous_chapter.id }}">上一篇:{{ previous_chapter.name }}</a></li>
<li><a href="/sage/chapter/{{ next_chapter.id }}">下一篇:{{ next_chapter.name }}</a></li>
</ul>
</nav>
这里使用了previous_chapter.id、previous_chapter.name和next_chapter.id、next_chapter.name 四个变量,并且,可以进行相应页面的跳转。这四个变量在之后的后端逻辑代码中会有介绍。
(2)后端逻辑代码
在后端中,首先,需要注意的,是网站的url导航。
这里的地址导航,我们使用django自带的地址栏传递参数的模式。在地址中,传递Chapter章节的id参数,以方便view视图层取得我们需要的Chapter.id。
其urls.py代码如下:
path(‘index‘, views.index, name=‘index‘),
path(‘login‘, views.login, name=‘login‘),
path(‘signup‘, views.signup, name=‘signup‘),
path(‘chapter/<int:chapter_id>‘, views.get_chapter, name=‘chapter‘),
例如,如需要取得id=5的章节,只需向后台传递地址localhost:8000/sage/chapter/5,即可向view视图层传递chapter.id=5的参数,并返回相应的渲染之后的html文件。
其次,在教学页面的view视图层中,根据传递的chapter.id参数,我们会根据前端页面所需的数据类型,取得相应的数据,并加以排列,修整,以适应前端的显示模式。
其具体的代码如下:
def get_chapter(request, chapter_id):
# 根据地址栏传递chapter.id参数,取得数据库相应的对象
curr_chapter = Chapter.objects.get(id = int(chapter_id))
# 因为数据库中文本信息并没有存取换行符,而前端页面显示需要换行。这里我们手动使用split()方法,进行换行
section_list = curr_chapter.words.split(‘\n‘)
# 根据传递的chapter.id,取得此章节需要的SageMath代码,用于展示
sages = Sage.objects.filter(chapter=chapter_id)
# 获取所有文章
all_chapter = Chapter.objects.all()
# 判断chaper_id是否为1或者最后一个
if curr_chapter.id == 1:
previous_id = 1
next_id = 2
elif curr_chapter.id == len(all_chapter):
previous_id = curr_chapter.id-1
next_id = curr_chapter.id
# 如果不,则取到平常状态下的前一篇和后一篇的id
else:
previous_id = curr_chapter.id - 1
next_id = curr_chapter.id + 1
# 根据id取出前一篇和后一篇章节的数据
previous_chapter = Chapter.objects.get(id = previous_id)
next_chapter = Chapter.objects.get(id = next_id)
#返回参数
return render(request, ‘sage/chapter.html‘,
{
‘curr_chapter‘: curr_chapter,
‘section_list‘: section_list,
‘sages‘:sages,
‘previous_chapter‘: previous_chapter,
‘next_chapter‘: next_chapter
}
)
这里使用了previous_id和 next_id来获取前一篇章节和后一篇章节的Chapter.id,然后从数据库里取出,传递给前端,并且作出了特殊情况下的条件判断。
4.5 SageMath模块的实现
4.5.1 SageMath网页实现原理
SageMath是一款开源的数学软件,可以配置到服务器、个人电脑和网页上。一般来讲,SageMath可以采用开源python库或官网下载的方式进行安装。
为了能更广泛的推行SageMath,SageMath开发组配置了SageCell网站,使用者可以在SageCell网站上直接使用SageMath的功能,同时,也允许其他站点,通过CDN加速的方式,连接SageCell网站,复制相关功能。
在此课题里,项目即使用了SsageCell的CDN的加速服务,进行SageMath配置,从而使用户可以在网页端直接使用SageMath的相关功能。
其具体的网页CDN和相关代码配置如下:
<script src="https://sagecell.sagemath.org/static/embedded_sagecell.js"></script>
<script>$(function () {
// 连接SageCell服务器,使用‘MyCell’作为登录
sagecell.makeSagecell({inputLocation: ‘#mycell‘,
template: sagecell.templates.minimal,
evalButtonText: ‘Activate‘});
// 配置sageCell相关的前端页面代码
sagecell.makeSagecell({inputLocation: ‘div.compute‘,
evalButtonText: ‘执行‘});
之后使用相关的“class”设置,引用其SageCell的服务,并进行相关的修改。
如下图所示,使用SageMath模块求不定积分
4.5.2 SageMath教学
系统将会主要教给用户关于SageMath的四种使用方法,其中包括:使用python代码直接进行计算;使用SageMath函数进行微积分运算;使用SageMath自定义函数功能,建立功能函数,进行调用运算;使用SageMath,进行可视化展现。以下将分别介绍:
(1) 使用python代码运算
SageMath允许直接使用python进行计算,这方便了很多还没有学会SageMath但是却会基础的python的使用者。因而,网站将会有专门的一栏,来教导用户如何使用python,在SageMath输入框输入,进行运算。
(2) 使用SageMath函数进行微积分运算
SageMath为数学运算提供了很多支持,包括解方程组、微积分、群论和绘图等。因为内容太多,系统选取了对于高等数学学习而言,最为重要的一部分:微积分,展开运用SageMath计算的详细讲解和教学,希望有益于学习高等数学的学生。
(3) 使用SageMath建立自定义函数,进行函数调用
这一种方法在Matlab里也有体现,属于数学软件常用的方法,搭建数学函数,进行函数调用。网站同样会向用户介绍其方法。
(4) 使用SageMath,进行可视化展现
SageMath有着很成熟且很强大的绘图功能,可以简便的绘制出各种二维和三维的图形。一张漂亮的数学图表,即可以为论文或作业加分。网站会教导用户,如何使用SageMath,绘制相应图表。如图所示:
图4-5 使用Sage绘制多个图形
图4-6 使用Sage绘制多等线图
与此同时,系统将已有页面和下载下来的SageMath官方文档连接到一起,让学生可以在网站内部,方便快捷的浏览和查阅SageMath官方教学文档。
4.6 系统测试
系统测试,是软件开发必不可少的一个环节,主要是综合实际使用环境和一系列的外部要求,对软件和程序的方方面面进行必不可少的测试。利用这种方式,找出相应的逻辑错误、漏洞或与需求规格不相符合地方。在发现问题之后,提出完善的方案,进行相应的修改或者重构,加以改正。
同样,对于编程开发来说,测试也是必不可少的。一方面可以验证自己的思路和逻辑是否正确,程序是否正常运行,另一方面,可以看看是否有什么意料之外的因素,影响了程序的功能发挥。
在本系统中,因为由单人完成了需求分析、建模设计、软件开发等步骤,所以系统的测试并非在软件完成之后进行,而是在每个功能模块,单独进行。换句话说,也就是在每个模块完成之后或者一部分功能完成之后,即时进行测试,记录测试结果,修改出错部分,同时也结合需求分析,进行相应的修改;当系统完成之后,再进行一次全系统的黑盒测试。
下图是使用django shell命令行进行的对数据库是否能够正常使用进行的测试。
图4-7 使用django shell测试数据库的增删改查
5 总结
在此次毕业设计的项目中,我最大的收获是单人经历了一次完整的项目,历经从选题、需求分析、设计与建模、系统架构设计、编程、重构代码、测试等诸多过程。历经过这些过程,我对软件开发有了更加全面、更加深刻的认识和体会,也对自身在软件设计和编程上的不足有了更加明了的认识。
在需求分析阶段,身为一个需求分析师,最重要的,不是去提出更多、更有创意的内容,而是保持更少:提炼最核心的需求,划分优先级,再在核心需求的基础上进行增加。这样,编程的时候也不至于一下子面对太多东西,又有前端,又有后端设计,而不知所措;可以有规划、有效率的进行编程,逐步的实现系统架构的实现和需求实现的互补。因而,需求分析、软件设计和编程开发实际上是三个互相促进的部分,同时互不可缺。
在软件设计阶段,不能放任自己的思维胡思乱想,需要理清逻辑,认识到:要从哪方面下手,软件要如何设计,如何满足需求,如何设计编程架构。从前端到数据库、后端,每一个部分都需要有机的连接起来,而非一个孤立的个体,同时每一个部分都需实现需求。这一阶段,最重要的,是需要要有清晰的思路,明确的逻辑。
在编程开发阶段,实际上也是软件开发的最重要的阶段,自己最需要做到的就是:合理。如果已经有了良好的需求分析、优良的软件设计,编程开发实际上也就是实现一个个小小的功能,搭建合理的逻辑。如果逻辑是顺畅的,合理的,即使编程者没有那么高深的技术,对于整个系统而言,这一部分功能也是合理而可用的。反过来,逻辑不合理,不顺畅,即使单一部分实现的再好,也有可能和整个系统相冲突,这时候必定需要重构,一来浪费精力,二来可能给整个系统留下隐患。优秀的程序员,不一定是技术高超的人,但一定是逻辑清晰,思维明了的人。
在重构代码上,最优,也是最有效的方法,是搭建模型。在对模型的搭建中,设计人员和开发人员将会测试软件设计的整体设计是否合格,是否满足需求分析,记录相应的优缺点,从而进行调整。有了第一次开发模型的经历,在正式的开发中也会更加得心应手。此外,模型开发,也属于需求、设计、开发三者共同的历程,有助于凝结共识,扩宽思路,加深沟通,从而不局限自己所负责的领域那一片小小天地。
在测试阶段,一定要保持着对自己的产品负责的心态,进行测试。同时,测试是否满足需求,也十分重要。如果某一部分的测试不负责,则可能对其他部分和整个系统造成影响,留下隐患,影响最终的软件成品。
以上五个部分加起来,才是一次完整的项目开发过程。这一次毕业设计,我在文欣秀导师和家人的帮助下,有幸完成此次毕业设计,受益匪浅。
参考文献
[1]Zimmermann, Paul & Casamayou, Alexandre & Cohen, Nathann & Connan, Guillaume & Dumont, Thierry & Fousse, Laurent & Maltey, Fran?ois & Meulien, Matthias & Mezzarobba, Marc & Pernet, Clément & Thiéry, Nicolas & Bray, Erik & Cremona, John & Forets, Marcelo & Ghitza, Alexandru & Thomas, Hugh. (2018). Computational Mathematics with SageMath. 10.1137/1.9781611975468,3-4.
[2]Zimmermann, Paul & Casamayou, Alexandre & Cohen, Nathann & Connan, Guillaume & Dumont, Thierry & Fousse, Laurent & Maltey, Fran?ois & Meulien, Matthias & Mezzarobba, Marc & Pernet, Clément & Thiéry, Nicolas & Bray, Erik & Cremona, John & Forets, Marcelo & Ghitza, Alexandru & Thomas, Hugh. (2018). Computational Mathematics with SageMath. 10.1137/1.9781611975468,6-7.
[3] Zimmermann, Paul & Casamayou, Alexandre & Cohen, Nathann & Connan, Guillaume & Dumont, Thierry & Fousse, Laurent & Maltey, Fran?ois & Meulien, Matthias & Mezzarobba, Marc & Pernet, Clément & Thiéry, Nicolas & Bray, Erik & Cremona, John & Forets, Marcelo & Ghitza, Alexandru & Thomas, Hugh. (2018). Computational Mathematics with SageMath. 10.1137/1.9781611975468,75-76.
[4] Zimmermann, Paul & Casamayou, Alexandre & Cohen, Nathann & Connan, Guillaume & Dumont, Thierry & Fousse, Laurent & Maltey, Fran?ois & Meulien, Matthias & Mezzarobba, Marc & Pernet, Clément & Thiéry, Nicolas & Bray, Erik & Cremona, John & Forets, Marcelo & Ghitza, Alexandru & Thomas, Hugh. (2018). Computational Mathematics with SageMath. 10.1137/1.9781611975468,54-55.
[5] SAGE Mathematical Software, Version 2.6, http://www.sagemath.org
致谢
本次项目开发实际上历经很多波澜,由于本人缺乏相关的规划,中期也一度缺乏相关思路,项目进展缓慢。在文欣秀导师的帮助和家人的鼓励之下,一点一滴的补足进度。而在项目的进行过程之中,我对软件开发有了系统性的实践,对编程有了更深的体会和了解,并且自身的学识和能力得到了提升和锻炼。
为此,感谢文欣秀老师的悉心帮助,感谢计算机系里老师们一直以来的教导,也感谢家人的陪伴和鼓励。同时也感谢信息学院计算机系所给予的毕业设计开发的机会和平台。