结对编程第二次作业——四则运算自动生成器

小巫师四则运算自动生成器

1、题目要求

我们在刚开始上课的时候介绍过一个小学四则运算自动生成程序的例子,请实现它,要求:

●能够自动生成四则运算练习题
●可以定制题目数量
●用户可以选择运算符
●用户设置最大数(如十以内、百以内等)
●用户选择是否有括号、是否有小数
●用户选择输出方式(如输出到文件、打印机等)
●最好能提供图形用户界面(根据自己能力选做,以完成上述功能为主)

2、开发环境

编程语言:python、Swift
开发环境:jupyter、Xcode
运行环境:windows 10、IOS11.3

3、成员定位

驾驶员(talosl)
能够完成全部代码工作,程序基本实现全部要求功能,并将代码上传至coding.net或者GitHub代码托管系统中(15分)
能够对导航员在本次编程工作中起到的作用给出客观评价,并完成500字以上的总结(5分)
领航员(张荣盛
能够辅助驾驶员完成全部代码工作,并且为关键函数选用合适的覆盖标准设计测试用例,并编写代码进行单元自动测试(10分)
能够根据上次作业的代码检查表对驾驶员的本次工作进行评价(5分)
能够对本次工作完成500字以上的总结(5分)

4、代码实现

算式生成部分采用jupyter notebook平台,使用python3.6实现。

import random as rd
import sys
#print("请输入难度:0为普通运算,1为复合运算,2为随机运算(普通+复合)")
df=int(sys.argv[1])
#print("是否生成小数,0为不生成,1为生成")
dec=int(sys.argv[2])
#print("10以内运算输入0,100以内运算输入1")
on=int(sys.argv[3])
if (on == 0):
    oo = 10
else:
    oo = 100
#print("请输入需要生成的题目数量")
num_file=int(sys.argv[4])
#print("请输入题目长度")
num_len=int(sys.argv[5])
def df2(num_len,oo,df,dec):
    k=True
    s='+'
    l=0
    f = open('question.txt', 'a')
    f1 = open('answer.txt', 'a')
    if(num_len%2==0):
        num_len-=1
    for i in range(num_len):
        a=rd.choice("+-*/(")
        b=rd.choice("+-*/")
        l+=1
        if(dec==1):
            if (df == 0):
                s = s[:l] + str(round(rd.uniform(1, oo),2))
                s = s[:l + 1] + b
                s = s[:l+2] + str(round(rd.uniform(1, oo), 2))
                l += 2
            elif (k):
                s = s[:l] + str(round(rd.uniform(1, oo),2))
                k = False
            else:
                if (a == "("):
                    s = s[:l] + b
                    s = s[:l + 1] + a
                    s = s[:l + 2] + str(round(rd.uniform(1, oo),2))
                    s = s[:l + 3] + b
                    s = s[:l + 4] + str(round(rd.uniform(1, oo),2))
                    s = s[:l + 5] + ")"
                    s = s[:l + 6] + b
                    l += 6
                    k = True
                else:
                    s = s[:l] + a
                    k = True
        elif(df==0):
            s = s[:l] + str(rd.randint(1, oo))
            s = s[:l+1] + b
            s = s[:l+2] + str(rd.randint(1, oo))
            l+=2
        elif(k):
            s=s[:l]+str(rd.randint(1,oo))
            k=False
        else:
            if(a=="("):
                s = s[:l] + b
                s = s[:l + 1] + a
                s = s[:l + 2]+str(rd.randint(1,oo))
                s = s[:l + 3] + b
                s = s[:l + 4] + str(rd.randint(1,oo))
                s = s[:l + 5] + ")"
                s = s[:l + 6] + b
                l+=6
                k=True
            else:
                s = s[:l] + a
                k = True
    f.write (s)
    f.write ("=")
    f.write('
')
    f.write('
')
    f1.write(str((round(eval(s),2)))) 
    f1.write('
')
for i in range(num_file):
    df2(num_len,oo,df,dec)

github地址在这里~~
用户可以选择是生成普通的算式,还是带括号的复合运算,还是两者都有。
也可以选择是否生成小数,默认选择不生成小数。
用户可以选择是生成10以内的运算还是百以内的运算。
最后再输入需要的题目数量和题目的长度。
生成的算式最后会被保存为两个文件,算式文件存为“question.txt”,答案文件存为“answer.txt”。
用户也可以选择是否发送邮件,发送邮件的话会将这两个文件发送到用户指定的邮箱中,也可以群发设置群发邮件。
发送邮件代码实现如下:

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header

mail_host = "smtp.mxhichina.com"  # 设置服务器
mail_user = "talosl@dctwr.cn"  # 用户名
mail_pass = "***************"  # 口令

sender = 'talosl@dctwr.cn'
receivers = '592157602@qq.com' # 接收邮件

message = MIMEMultipart()
message['From'] = Header("四则运算器", 'utf-8')
message['To'] = Header("测试", 'utf-8')
subject = '运算测试'
message['Subject'] = Header(subject, 'utf-8')

# 邮件正文内容
message.attach(MIMEText('算式已生成', 'plain', 'utf-8'))


att1 = MIMEText(open('question.txt', 'rb').read(), 'base64', 'utf-8')
att1["Content-Type"] = 'application/octet-stream'
att1["Content-Disposition"] = 'attachment; filename="question.txt"'
message.attach(att1)


att2 = MIMEText(open('answer.txt', 'rb').read(), 'base64', 'utf-8')
att2["Content-Type"] = 'application/octet-stream'
att2["Content-Disposition"] = 'attachment; filename="answer答案.txt"'
message.attach(att2)

try:
    smtpObj = smtplib.SMTP()
    smtpObj.connect(mail_host, 25)  
    smtpObj.login(mail_user, mail_pass)
    smtpObj.sendmail(sender, receivers, message.as_string())
    print ("邮件发送成功")
except smtplib.SMTPException:
    print ("Error: 无法发送邮件")

5、执行结果

我们在jupyter notebook运行程序“四则运算自动生成器.ipynb”
在算式生成代码区输入:“2 0 1 50 5”
生成50组长度为5,百以内不带小数的算式

两个文本的内容如下:

对目的地址发送邮件

提示邮件发送成功,进到我们的邮箱中查看邮件,可以看到有一封带两个附件的邮件已经成功发到我的邮箱中

6、UI界面

因为本次作业时间比较紧张,而且我们组全部没有学过前端界面该怎么做(/泪奔),所以以下界面只是我们的一次尝试,并没有完全真正实现题目要求的功能。前端是不可能会的了(/泪奔),会前端的小哥哥个个都是人才,说话又好听,超喜欢这样的~
本次前端开发采用Xcode9.3,Swift4.1环境,项目名称为:小巫师四则运算自动生成器(support for iPhone X)


最后执行的结果最多也是发邮件了,咳咳……

7、总结

通过本次作业可以说收获良多,虽然题目要求不难,但是通过本次作业发现了很多问题,遇到了很多坑,特别是在云服务器方面,遇到了很多原来没有遇到过的坑,最后慢慢填坑才完成了。算式生成部分最开始因为文件类型的问题也是频频出错,一百多行的代码报了80多个警告可以说是很恐怖了。这个时候领航员的作用就非常的明显,一边在旁边为我加油鼓劲,一边讨论新的思想,还不断的查找bug,然后我们一边开发,一边修复bug,不仅仅提高了代码质量。也避免了最后项目完成后发现bug最后项目重做的风险。在这次结对编程中可谓是最大的收获,感受到了团队开发力量和共同协作的默契。
老师在上课的时候说,其实开发部门和测试部门是死对头。通过本次结对编程,我觉得只要有一个良好沟通的过程,就能融洽的处理这其中的关系,双方都能在这个过程学到很多东西,结对编程不仅仅是可以推动项目的进展,双方也可以学到很多东西,更是加大了后期的一个可维护度,当代码真正出现问题的时候可以尽早发现。
最后是界面实现部分,虽然我们实现了一部分界面,但是并没有完全实现一些功能,最开始的设想是生成后会进入到做题部分,根据正确率来判断是否进阶,进阶的话会出更复杂和数更混合的算式出来计算。不过因为界面实现是现在才接触,对于按钮的功能定义和传参的部分不是特别了解,中间也是出了很多问题,导致这部分功能完全没有实现,最后也只是进行简单设置和传参,最后在服务器运算和发邮件因为端口封禁的问题也是在不断的尝试新的办法。所以本次作业可以说是不仅仅是学习的过程,更是发现问题的过程。
最后,非常感谢和我组队的小伙伴,下面附上照片

原文地址:https://www.cnblogs.com/talosl/p/8831709.html