python中四则运算符号_Python-四则运算-蔡晓晴,杜婷萱
一、需求
1.使用-n 参数控制生成题目的个数
2.使用-r 参数控制题目中数值(自然数、真分数和真分数分母)的范围
3.生成的题目中计算过程不能产生负数
4. 生成的题目中如果存在形如e1 ÷ e2的子表达式,那么其结果应是真分数。
5. 每道题目中出现的运算符个数不超过3个。
6. 程序一次运行生成的题目不能重复,即任何两道题目不能通过有限次交换+和×左右的算术表达式变换为同一道题目。
7.生成的题目存入执行程序的当前目录下的Exercises.txt文件
8.在生成题目的同时,计算出所有题目的答案,并存入执行程序的当前目录下的Answers.txt文件
9. 程序应能支持一万道题目的生成。
10. 程序支持对给定的题目文件和答案文件,判定答案中的对错并进行数量统计,输入参数如下:
Myapp.exe -e .txt -a .txt
统计结果输出到文件Grade.txt,格式如下:
Correct: 5 (1, 3, 5, 7, 9)
Wrong: 5 (2, 4, 6, 8, 10)
二、PSP2.1表格
PSP:
PSP2.1Personal Software Process Stages预估耗时(分钟)实际耗时(分钟)
Planning
计划
20
30
· Estimate
· 估计这个任务需要多少时间
20
30
Development
开发
1230
1665
· Analysis
· 需求分析 (包括学习新技术)
120
300
· Design Spec
· 生成设计文档
60
60
· Design Review
· 设计复审 (和同事审核设计文档)
30
50
· Coding Standard
· 代码规范 (为目前的开发制定合适的规范)
10
5
· Design
· 具体设计
30
40
· Coding
· 具体编码
900
1100
· Code Review
· 代码复审
40
30
· Test
· 测试(自我测试,修改代码,提交修改)
40
80
Reporting
报告
50
70
· Test Report
· 测试报告
10
10
· Size Measurement
· 计算工作量
10
20
· Postmortem & Process Improvement Plan
· 事后总结, 并提出过程改进计划
30
40
合计
1300
1765
三、设计实现过程:
1.功能1~9的实现步骤
· 一开始题目运行采用递归的方法,后来调用的函数过多,递归函数太复杂,于是改成for生成题目
· 查重用了字典的方法
· 随机括号的生成费时良久,考虑到随机的各种情况,左括号和右括号的定位问题,存储结构等等问题。
· 在寻找计算的简便方法的时候,我们找到一个函数eval(string)可以直接识别并计算一整条string。
· 减号的判断,由于计算的方法不是根据括号从内到外计算的,要一个个计算却会使得函数过于复杂,向同学取经后,我们还是采用了负数舍去的方法。
2.功能10的实现过程:
· 用正则表达式检查输入的文本格式是否正确
· 根据空格split分别存储真分数等各个数值
· 调用两个函数进行,分数与真分数互相转换
效能分析:
CPU运行时间:
10000道题的生成时间:
100道题的时间:
功能10:
可以看出来到了大量题目的时候,由于查重,时间复杂度成指数级上升。
代码说明:
功能1~9:
1. #随机生成一道题目中的符号和数字
defrandom_list(self):
char_list = ["+", "-", u"×", u"÷"]
num_list =[]
char_choice =[]
cc = ""loop_times = random.randint(2,4)
for i inrange(loop_times):
static = random.randint(1, self.num_range)
if self.num_range > 1:
float_n =produce_random.choose_num(self)
choice =random.choice([static, float_n])
else:
choice =static
cc +=str(choice)
num_list.append(choice)
if i < (loop_times - 1):
cha =random.choice(char_list)
char_choice.append(cha)
cc +=cha
jo = str(num_list+char_choice)
if jo indic_t.keys():
self.random_list()
else:
dic_t[jo] =0
return char_choice, num_list
2. #随机生成分数
defchoose_num(self):while(1):
a= random.randint(1, self.num_range**2)
b= random.randint(2, self.num_range)if Decimal(a/b)
3. #根据符号随机加括号
defplus_(self,char_choice, num_list):
numble= len(num_list) +len(char_choice)
ccc= [""] *numbleif len(char_choice) == 1:pass
else:"""括号对数"""n_kuo= random.randint(0, len(char_choice) - 1)if n_kuo !=0:
p_kuo_l=[]"""设置list1初值"""list1=[]for i inrange(0, len(char_choice)):
z= 2 *i"""改为append"""list1.append(z)
p_kuo_l= random.sample(list1, 1) #按照char的数量来存,2个就是[0,2],3个[0,2,4]
ccc.insert(p_kuo_l[0], '(') #插入1st左边的括号
if len(char_choice) == 2:
ccc.insert(p_kuo_l[i-1] + 4, ')')if len(char_choice) == 3:"""第一个右括号"""
if p_kuo_l[0] ==0:
list1= [4]if p_kuo_l[0] == 2:
list1= [p_kuo_l[0] + int(random.sample([4, 6], 1)[0])]if p_kuo_l[0] == 4:
list1= [8]
p_kuo_r=list1[:]
ccc.insert(p_kuo_r[0],')')
x= p_kuo_l +p_kuo_rif n_kuo == 2: #加第二个右括号
if x[0] == 2:if x[1]==x[0]+4:
y= random.sample([0, x[0]], 1)
ccc.insert(y[0],'(')if y[0] ==0:
ccc.insert(x[1]+1, ')')else:
ccc.insert(x[0]+ 8, ')')else:
y= random.sample([x[0], x[0] + 3], 1)
ccc.insert(y[0],'(')if y[0] == 2:
ccc.insert(x[0]+ 5, ')')else:
ccc.insert(x[0]+ 7, ')')if x[0] ==0:
y=x[0]
ccc.insert(y,'(')
ccc.insert(x[0]+ 8, ')')if x[0] == 4:
y= x[0]-2ccc.insert(y,'(')
ccc.insert(x[0]+7, ')')
num=0
cha=0
list_all= [] #装数字+字符
j =0
flag=True#标记乘号的个数
multi_n =[]#标记除号的个数
divide_n =[]for i inrange(0, len(num_list)):if j == (len(num_list) - 1):
j-= 1flag=False
list_all.append(num_list[i])if i == j and flag ==True:
list_all.append(char_choice[j])
j+= 1j=0for i inrange(0, len(ccc)):if ccc[i] != '':continue
if list_all[j]=='×':
multi_n.append(i)if list_all[j]=='÷':
divide_n.append(i)
ccc[i]=list_all[j]
j+= 1
return ccc, multi_n, divide_n
4. #符号转换,把list改为str来计算,分数周围有自己的括号(计算的时候将分数看成除法来计算)
defjoin_c(self, ccc, multi_n, divide_n):
list1=ccc[:]
ll=[]for i inmulti_n:
list1[i]= '*'
for j individe_n:
list1[j]= '/'
for i inlist1:if type(i) ==Fraction:if i.denominator == 1:
ll.append(str(i))else:
ll.append('('+str(i)+')')elif type(i) ==int:
ll.append(str(i))else:
ll.append(i)
final= ''.join(ll)return final
5. #计算
defcalculate(final):
result=eval(final)return result
6. #查找小数循环,小数转分数
def ff_c(self, demical): #参数为小数
for i in range(1, 16):
cpart=demical[:i]if len(cpart) < 4:if (cpart * i * 4) == demical[:4 * i]: #4次重复
return cpart #循环体
return 0 #找不到循环体,返回0
#小数转分数
def demical_to_fraction(self, digi, back_num=0):
digi=str(digi)if len(digi) <= 15: #有限小数
returnFraction(digi)
real_num, dot_area= digi.split('.')
float_num=float(digi)for i inrange(len(digi)):
cycle_start=dot_area[i:]
result=self.ff_c(cycle_start)
length= len(str(result)) #循环体的长度
if result: #存在循环体
if i != 0: #不是小数点后第一位
new_number = float_num * (10 ** i) #移位数
self.demical_to_fraction(new_number, i) #递归
break
else: #小数点后的第一位
fraction = Fraction(int(result), int('9' * length)) #小数转分数
final_num = int(real_num) +fractionreturn final_num / (10 ** back_num) #回退移的位数
return False
7. #最后转为真分数输出
defchange_l(self,li):
hh=[]for i inli:if type(i) ==Fraction:
hh.append(change_ff(i))
hh.append(' ')continue
else:
hh.append(str(i))
hh.append(' ')return hh
8. # 写入文件
defwrite(self, f_line):
self.glocount+= 1count= int((self.glocount + 1) / 2)
tihao= str(count) + '.'file= open('Exercise.txt', 'a')
f_line= tihao + f_line + '='file.write(f_line+ '\n')
file.close()defwrite_a(self, f_line):
self.glocount+= 1tihao= str(int(self.glocount / 2)) + '.'file= open('Answers.txt', 'a')
f_line= tihao +f_line
file.write(f_line+ '\n')
file.close()
功能10:
1. # 支持读取给定的文件
defread_f(name):
with open(name) as Re:
file=Re.readlines()return file
2. #检查文件名是否符合格式
defcheck_file(file_name):if re.match(r"[a-zA-Z0-9]*\..", file_name):returnTrueprint("The file name is not right.")return False
3. #转换分数AND真分数
defchange_re_fra(expre):if re.search("[1-9]\'[1-9]/[1-9]", expre):
l1= expre.split("\'")
l2= l1[1].split("/")
num_1=eval(l1[0])
num_2=eval(l2[0])
num_3= eval(l2[1])
middle_p= num_3*num_1
num_2+=middle_preturnstr(Fraction(num_2,num_3))if expre == '×':
expre= '*'
if expre == '÷':
expre= '/'
returnexpredefchange_ff(fra):
d=fra.denominator
n=fra.numerator
midde= n //dif midde ==0:returnstr(n)
cha= n - d *middeif cha ==0:returnstr(midde)return str(midde)+'\''+str(Fraction(cha,d))
4. #比对提交的和user答案一致性
defbidui(ans,user):
corr,wrong=[],[]
a_line=read_f(ans)
user_line=read_f(user)for i inrange(0,len(a_line)):if a_line[i] ==user_line[i]:
corr.append(str(i))
corr.append(',')else:
wrong.append(str(i))
wrong.append(',')
u1= ''.join(corr)
u2= ''.join(wrong)
co= 'Correct:'+str(len(corr)//2)+'('+u1+')'w= 'Wrong:'+str(len(wrong)//2)+'('+u2+')'write_Grade(co,w,'Grade.txt')
defcompare(file_list):
file=read_f(file_list[0])
gloc=0for i infile:
i=i.rstrip()
lii= i.split('.')
c= lii[1].split(' ')
strr= ''
for j inc:if j != '=':
str=change_re_fra(j)
strr+=str
result=calculate(strr)
f_result=demical_to_fraction(result)
ff_result=change_ff(f_result)
write1(ff_result,'answer2.txt',gloc)
gloc+= 1bidui('answer2.txt',file_list[1])
5. #写入文件
defwrite1(result, name,glocount):
glocount+= 1count=glocount
tihao= str(count) + '.'file= open(name, 'a')
f_line= tihao +result
file.write(f_line+ '\n')
file.close()defwrite_Grade(c,w,name):
file= open(name, 'a')
file.write(c+'\n'+w)
file.close()
main函数:
if __name__ == '__main__':
file= open('Exercise.txt', 'r+')
file.truncate()
file.close()
file= open('Answers.txt', 'r+')
file.truncate()
file.close()
sys.setrecursionlimit(10000)
dic_t={}if len(sys.argv)>2:
num_range, ti_num=menu()if num_range > 0 and ti_num >0:
instance=produce_random(num_range, ti_num)
instance.running()else:print("输入命令不足")
defmenu():
flag=0
compare_arg=0
file_rrlist=[]for i inrange(len(sys.argv)):if sys.argv[i]=='-e':if check_file(sys.argv[i+1]):
file_rrlist.append(sys.argv[i+1])
compare_arg+= 1
continue
elif sys.argv[i]=='-a':if check_file(sys.argv[i+1]) and compare_arg==1:
file_rrlist.append(sys.argv[i+1])
compare(file_rrlist)
flag= -1
elif sys.argv[i]=='-n' and compare_arg==0:
ti_num= input("请输入题目数量:")
ti_num=int(ti_num)if ti_num<=0:print("数量过少,请重试")breakflag+= 1
elif sys.argv[i]=='-r' and compare_arg==0:
num_range= input("请输入数值范围:")
num_range=int(num_range)if num_range<=1:print("数值范围不存在")continue
else:breakflag+=1
if flag == 1:returnnum_range, ti_numelif flag==-1:return -1,-1
else:print("输入不正确")return 0, 0
defrunning(self):#利用for循环输出多道题
for i inrange(self.num):whileTrue:
char_choice, num_list=self.random_list()
k, multi_n, divide_n=self.plus_(char_choice, num_list)
new_title=self.join_c(k, multi_n, divide_n)
z=calculate(new_title)if z <0:continuefinal_result=demical_to_fraction(z)if type(final_result) == float or final_result==False:continue
if final_result.denominator >self.num_range:continue
else:breaknn_tt=self.change_l(k)
final_result=change_ff(final_result)
nn_tt= ''.join(nn_tt)print(nn_tt)
self.write(nn_tt)
self.write_a(str(final_result))
测试结果分析:
生成题目:
10000道题,范围为1000:
测试文件查错:
总结:
我们采取的分工合作是蔡同学先负责写随机数、menu等等,杜同学写加括号、功能10的实现,之后由于加括号出现了很多bug,两人都在这个函数上掉了大把的头发,前期代码在后期测试时很多地方的需要上有较多的调整,对于有些功能比如查重用了比较暴力的删除法,增加了不少运行时间。
——蔡晓晴:我觉得这次结对编程还是获益良多的,例如我们开始没找到合适的方法来沟通、设计,到后面逐步完善我们的设计方案,修改bug。我觉得这其中彼此的思想碰撞有很大的作用,也谢谢同伴的帮助!(^-^)V
——杜婷萱: 一开始我们采取两个人一边写一边看的形式让我略感压力的同时,双人互挑bug的讨论比一个人的思路更广阔,纸上谈兵也能发现很多的问题,我学习到思路理清楚很重要,如果仅仅只是有个想法而不做深入思考就写代码就会写的很乱,不仅浪费时间,还会难以让同伴理解。而且双方的沟通很重要,两人最好尽量同步,现实代码总比理想的冗余了许多,结对其实更考验写代码的速度和质量。作为一个messy coder蔡同学帮助了我非常多,感谢ヽ( ̄▽ ̄)و
python中四则运算符号_Python-四则运算-蔡晓晴,杜婷萱相关推荐
- python中并集符号_python中列表之间求差集、交集、并集
求两个列表的交集.并集.差集 def diff(listA, listB): # 求交集的两种方式 retA = [i for i in listA if i in listB] retB = lis ...
- python中续行符号_Python 的续行标志是( )_大学英语(2)答案_学小易找答案
[其它]编写C程序,设计学生类型,使用结构体数组实现任务二中的所有功能,即能输入任意多个人的多门课的考试成绩;能计算每个人的总成绩和平均成绩;能输出总分第一名和最后一名的分值;能查询个人成绩信息(包括 ...
- python中的@符号的作用
python中的@符号的作用_weixin_34014555的博客-CSDN博客 Python中的" @"(@)符号有什么作用?_p15097962069的博客-CSDN博客
- python中特殊符号怎么输入_python中怎么输入引号
Python中的引号可分为单引号.双引号和三引号. 在Python中我们都知道单引号和双引号都可以用来表示一个字符串,比如str1 = 'python' str2 = "python&quo ...
- python特殊含义符号_python 正则表达式中的特殊符号介绍
python 2.7.3 正则表达式:正则表达式就是根据自己的需要定义字符串而已, 定义方法: s = r'\d{3,4}' 为了与字符串赋值做区分,定义时需要加个 r . 用途 : 定义好以后可以从 ...
- python中的乘方_python乘方运算
广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! 算数运算符是完成基本的算术运算使用的符号,用来处理四则运算运算符描述实例+加10 ...
- python中的乘方_python中的乘方
广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! 一,算术运算python中的乘方运算符号为 **,比较特殊. 作为运算符,%表示 ...
- python中幂运算_python里幂运算
广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! "**"运算这个"**"比较简单,就是标 ...
- python中幂运算_python的幂运算
广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! "**"运算这个"**"比较简单,就是标 ...
最新文章
- [扫盲] Salesforce.com: 业界云计算(Cloud Computing)的主要倡导者之一
- NOIP2011 提高组 Day1
- scanf family API 高级用法
- CVPR 2020 HAN:《Hypergraph Attention Networks for Multimodal Learning》论文笔记
- HarmonyOS之AI能力·助手类意图识别
- GLTF格式——关系描述
- kerberos的系统搭建
- 本地环境测试二级域名
- Docker修改MySQL默认端口
- linux安装vsftpd并配置文件,Linux 系统下 vsftpd 的安装与配置
- 吾爱破解“凉”了之后,还能去哪儿下载软件?
- python 文件夹_使用python进行文件夹对比
- 7-24 约分最简分式 (15 分)
- Jquery获取单选框与复选框选中的值
- 科技金融企业助力乡村振兴,能有多大新意?
- Particle for alexa smart home skill (3)
- Flutter Win桌面应用环境配置
- 迅播Gvod清理缓存与改变缓存文件夹位置的方法
- Opera 使用迅雷下载
- c# winform中获取当前日期和时间