我这个小白学习Python课后习题的不同答案讨论(准备长期更新)
这是关于我学习小甲鱼(小污龟)老版《零基础入门学习Python》的课后题不同答案(异曲同工?小补充?)前面就有一些,但是本小白没有点懒,从17课开始吧
https://fishc.com.cn/thread-41663-1-1.html (出处: 鱼C论坛)]17课
========================================
关于欧几里德最大公约数,相当于补充了(x,y)大小顺序
def gcd(x,y):
if x>y:
while x%y!=0:
a=x%y
x=y
y=a
return y
else:
c=x
x=y
y=c
while x%y!=0:
a=x%y
x=y
y=a
return y
=============================================
关于10进制转2进制,我还跑去更新了下百度词条,不知道能不能成功哈哈!
这里相当于增加了0和负数的输入性
def bilibili(b):
t=[]
i=''
e=''
while b<0:
b=-b
i='-'
while b//2!=0:
a=b%2
t.append(a)
b=b//2
if b!=0:
t.append(1)
else:
t.append(0)
while t:
e+=str(t.pop())
return (i+"0b"+e)
#b要为整数,效果同内置函数bin()
========================================
有什么优化或者建议欢迎补充 第18课https://fishc.com.cn/thread-42532-1-1.html (出处: 鱼C论坛)]第018讲:函数:灵活即强大 | 课后测试题及答案 https://fishc.com.cn/thread-42532-1-1.html (出处: 鱼C论坛)
=======================
动动手0
开始我也是和小污龟一样想法,甚至还用了if语句来判断末尾是否等于5,后来想想好像这个题本意不是这个意思,然后就
def su3m(*team,base=3):
reversed(team)
return sum(team)*base
==========================
动动手1,开始还以为是小污龟偷懒搞一样的题,然后实力提高的我简单构想了下更复杂的位数组合,但是没有打代码,
看了小污龟的那个放在末端的print()缩进真的牛啤,第一次知道可以这样玩缩进达到输出顺序改变,
还有就是那个//加while循环感觉很好,比我构想的切片循环取数要简洁得多
小污龟这个牛啤,我就不发我的弟弟代码了
===========================
动手2,算是偷懒了吧直接用了count,感觉没有领悟小污龟的用意
def findstr():
t=input("请输入目标字符串:")
t1=input("请输入子字符串(两个字符):")
t2=t.count(t1)
print('子字符串在目标字符串中共出现',t2,'次')
return
哈哈{:5_109:} 我把百度百科那个词条更新了
原版
==================
我增补后的bilibili版
本帖最后由 icewin 于 2019-11-7 21:19 编辑
19课第019讲:函数:我的地盘听我的 | 课后测试题及答案
https://fishc.com.cn/thread-42573-1-1.html
(出处: 鱼C论坛)
=======================
看到第4题感觉不对劲,想了下如果都是def fun1()会怎么样,然后试了下,结果是相当于从新把 fun1()写了一次,旧的删了
然后看这个题,中了小甲鱼圈套,return这个返回值,还是很重要的知识点!!!
=======================
动动手0我的版本如下
def whl():
t2=list(t)
t2.reverse()
i=0
a=(len(t)//2)
for x in range(a):
if t==t2:
i+=1
if i==a:
print('是文回联')
else:
print('不是文回联!')
t=input('请输入一句话:')
whl()
感觉小甲鱼的方法1基础逻辑性很好,但是逻辑太多不容易看懂
方法2和我的基本一样,但我让计算量少了一半,和方法1里面那个//2一样
不过还是小甲鱼规范与一些用的return返回数据
===========================================
动手1我的就很弟弟级别了
def count1(a):
c=("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
d='1234567890'
e=" "
C=0
D=0
E=0
F=0
for x in a:
if x in c:
C+=1
elif x in d:
D+=1
elif x in e:
E+=1
else:
F+=1
print("个字符串共有英文字母",C,"个,","数字",D,"个,","空格",E,'个','其他字符',F,"个。")
def count(a1,a2):
A1=print("第1",end=''),count1(a1)
A2=print("第2",end=''),count1(a2)
return A1,A2
count('I love fishc.com.','I love you ,you love me.')
小甲鱼用的收集参数(我看了其他地方资料这个也叫不定长参数),这个就很nice,另外那个%d格式化整数的用法很惊艳
还有就是字符串那节历史遗留问题,太多内置函数,我使用经常出现语法错误,都不敢用了。 第20 课https://fishc.com.cn/thread-42685-1-1.html (出处: 鱼C论坛)]第020讲:函数:内嵌函数和闭包 | 课后测试题及答案 https://fishc.com.cn/thread-42685-1-1.html (出处: 鱼C论坛)
我都快要被劝退了!!!!!!!
这里没讲域什么的,我是真难理解,查了乱七八糟的零零散散的资料,总结是先不去理解反正课后题关系不大,学过的暂时基本够用
放出我半成品的动动手答案,这里我很费解为什么input()不能用,我打算先将这些问题放一下,当然有高手愿意不辞劳苦指出我的问题,我是非常感激的
t=input('输入telegram')
def zifu():#先试图把字符搞出来变成一个独立列表,然后想办法取出来搞count
w=[]
for m in t: #按理说局部变量里面不能给全局变量赋值,但使用这个for好像没什么影响
if m not in w:
w.append(m)
for i in w:
a=t.count(i)
c=print(i,a)
print('字符和次数:',zifu())
#失败了,转义字符等问题没解决,想过用'''或r,但是少了input就少了灵魂,看了答案很失望,还是用的暴力
=======================
def mima():
t=input("密码")
t=t.replace('\n',"")
i=2
key=[]
for x in t:
i+=1
if x.islower()==True:
x1=t[(i-3):i]
x2=t[(i+1):(i+4)]
if 3<i< (len(t)-4):
x3=t
x4=t
if (x1.isupper()==True)and(x2.isupper()==True)and(x3.isupper()==False)and(x4.isupper()==False):
key.append(x)
else:
if i==3:
x4=t
if(x1.isupper()==True) and (x2.isupper()==True)and(x4.isupper()==False):
key.append(x)
if i==len(t)-4:
if(x1.isupper()==True) and (x2.isupper()==True)and(x3.isupper()==False):
key.append(x)
return key
print(mima())
#呕心沥血找的是单个字母,前功尽弃,后来发现是对的,只是不能用input
==============
我就做了个不限单小写字母的,但是有个末尾bug和其他bug,原因不清楚,先放着,以后懂的语法多了应该就ok
def mima():
t=input("密码")
t=t.replace("\n","")
i=2
key=[]
p=[]
for x in t:
i+=1
if x.islower():
p.append(x)
continue
x1=t[(i-3-len(p)):(i-len(p))]
x2=t
if 3<(i-len(p)) and i< (len(t)-3):
x3=t
x4=t
if (x1.isupper())and (x2.isupper())and(x3.isupper()==False)and(x4.isupper()==False):
key.extend(p)
else:
if (i-len(p))==3:
x4=t
if(x1.isupper()) and (x2.isupper())and(x4.isupper()==False):
key.extend(p)
if i==len(t)-3:
x3=t
x2=t[-3:]
if (x1.isupper()) and (x2.isupper()) and (x3.isupper()==False) :
key.extend(p)
p=[]
return key
print(mima())
#虽然不知道为什么我这个无法搞出 if i==len(t)-3:这个里面的测试,虽然我第一次做得是符合题意的,虽然有点问题,这个不符合题意,但这个bug很纠结
==================
ps:这节课可能教学顺序有点问题,让人很难理解和运用,但是可以先不去理解,先放着,半懂就可以,后面我查了资料,等课程学到后面,前面问题会解决,希望别被劝退,我差点就被劝退了,哈哈 21课没多少想说的,挺简单,就是第3题感觉range(1,100)应该改成range(3,101)这样比较好,毕竟100以内也包括100嘛
第4题没给题目 答案,自由发挥如果是第3题那样可以这样玩
[ i for i in range(1, 100) if not(i%3)]
list(filter(lambda x:not (x%3),range(1,101)))
我找了一个复杂的这就尴尬了,2个参数首先iterable就不好搞了嵌套循环想不出办法,想了个办法是曲线救国
filter是筛选器,这里面临2个参数要筛选,写下来发现比列表推导式展开还复杂,就放弃了,尝试了许多想法,Error使我强大{:5_104:}
24课,我写的都是伪递归,没能把握递归精髓>>>
大繁化简(复杂问题简单化,公式化,这是最骚的(最难办到),也是第一步思考的逻辑,天才逻辑)-->归途应变(巧妙安插返回值的顺序或方案精简代码)
举个例子:发一下我的弟弟代码,用了递归却显得代码很臃肿
def bin6(n,t=[]):
t.append(str(n%2))
if n==1:
print("0b",end="")
while t:
print(t.pop(),end="")
else:
return bin6(n//2,t)
n=int(input("输入整数"))
bin6(n)
如果思考是是return bin6(n//2)+str(n%2) 这种逻辑排布,将省去很多繁琐的代码结构。 本帖最后由 icewin 于 2019-11-18 23:39 编辑
25课
第5题我直接用的元组从新输入,看到答案那个split(',')我才想起来字符bif牛啤
动手题print('''
|---欢迎进入通讯录程序---|
''')
t=print('''
|---1:查询联系人资料 ---|
|---2:插入新的联系人 ---|
|---3:删除已有联系人 ---|
|---4:退出通讯录程序 ---|
''')
dict1={}
while 1:
g=print(' ')
a=int(input("请输入相关的指令代码:"))
if a==4:
print('|---感谢使用通讯程序---|')
break
else:
b=input("请输入联系人姓名:")
if a ==1:
if b in dict1:
print(b+' : '+dict1)
else:
print('没有这个人呐,兄弟')
elif a==2:
if bin dict1:
print('您输入的姓名在通讯录中已存在-->>'+b+dict1)
d=input('是否修用户资料(YES/NO):')
if d=='YES':
del dict1
else:
continue
c=input('请输入用户联系电话:')
dict1=c
elif a==3:
if b in dict1:
del dict1
else:
print('冒得这个人')
continue
else:
print("请按提示输入"+t)
大体上和小甲鱼差不多,小甲鱼input用得比较6少了几行 本帖最后由 icewin 于 2019-11-19 23:52 编辑
26课动手题def niupi():
a='''
|---新建用户:N/n---|
|---登录帐号:E/e---|
|---退出程序:Q/q---|
'''
c={}
g=['n','e','q','Q','N','E']
while 1:
print(a)
b=input("|---请输入指令代码:")
if b not in g:
continue
if b=='N' or b=='n':
d=input("请输入用户名:")
while (d in c)or(d==''):
d=input('此用户名已经被使用,请重新输入:')
e=input('请输入密码:')
while e=='':
print('密码不能为空')
e=input("请输入密码:")
c=e
print('注册成功赶紧试试登录吧小污龟差差oo')
continue
if b=='E' or b=='e':
d=input("请输入用户名:")
while d not in c:
d=input('此用户不存在请重新输入:\n(返回上层按Q )')
if d=="Q":
break
if d=="Q":
continue
e=input("请输入密码:")
while c.get(d)!=e:
e=input('密码不对(返回上一级q)')
if e=='q':
break
if c.get(d)==e:
print('欢迎进入小污龟系统,请点右上关掉这个程序')
break
if b=='Q' or b=='q':
break
niupi()
小污龟的14行密码设置可以为空,开始我担心.get()会直接让等号失效,后来测试发现密码帐号可以为空,因为input输入的是‘’而不是None,我多虑了,另外小甲鱼密码输错应该会弹到第一个循环,我的是多次输入,按Q返回上层。不知道分多个函数好还是用一个函数封装好。 29课圆满完成,先发课堂练习,因为封装比较丑,算个半成品def split1(i):
b='f:\\boy_'+str(i)+'.txt'
g='f:\\girl_'+str(i)+'.txt'
global boy ,girl #虽然解决繁琐的问题,但是小甲鱼说过global是隐患,所以我又觉得不妥
boy=open(b,'a+')
girl=open(g,'a+') #有没有办法弄成nonlocal 或lambda,我测试了
#报错说是function没有write属性,所以
def save1():
f=open('f:\\record.txt')
i=1
split1(i)
for a1 in f:
if '========'in a1:
boy.close()
girl.close()
i+=1
split1(i)
continue
if "小甲鱼:"in a1:
boy.write(a1)
if "小客服:"in a1:
girl.write(a1)
boy.close()
girl.close()
f.close()
save1()
比小甲鱼看起来要简单粗暴一点点,当然不够优雅
动手题0
def savetxt1():
name =input('请输入文件名')
file_write=input('请输入内容【单独输入‘:w’保存退出】:\n')
name1='f:\\'+name+'.txt'
f=open(name1,'a+')
while file_write !=':w':
f.write(file_write+'\n')
file_write=input()
f.close()
savetxt1()
基本是一样的,只是我用的while 判断,小甲鱼用了if else,从行数来说我略胜一筹。
动手题1
我一直思考怎么同步行数比较用了字典,感觉很牛批,看到小甲鱼直接用.readline()的指针,就感觉小污龟就是小污龟,666,虽然这把被小污龟ko了,但字典同步打开了新思路
def different():
name1='f:\\'+input('请输入第一个文件名:')+'.txt'
name2='f:\\'+input('请输入另一个文件名:')+'.txt'
f1=open(name1,'r')
f2=open(name2,'r')
i=0
line1=0
d1={}
list1=[]
for fx1 in f1:
line1+=1
d1=fx1
line1=0
for fx2 in f2:
line1+=1
x1=d1
if x1 != fx2:
i+=1
list1.append(line1)
print('两个文件共有【',i,'】处不同')
for x in list1:
print('第',x,'行不一样')
f1.close
f2.close
different()
动手题2,由于指针理解不够,不怎么会.readline()我写的就是个弟弟,就不发了
动手题3行数来看差不多,但逻辑完全不一样
def lineP():
file=input('请输入要打开的文件(c:\\text.txt):')
file1=open(file,'r')
line=input('请输入需要显示该文件行数【格式如13:21或:21或21:】:')
linelist=line.split(':')
i=0
i1=linelist
i2=linelist
if i1=='' and i2!='':
print('文件',file,'从开始到第',i2,'行内容如下:')
i1=0
elif i2==''and i1!='':
print('文件',file,'从第',i1,'行到末尾内容如下:')
i2=len(file1.read()) #取一个大于等于总行数的数想出来的办法
file1.seek(0)
elif i1=='' and i2=='':
print('文件',file,'全文内容如下:')
i1=0
i2=len(file1.read())
file1.seek(0)
else:
print('文件',file,'从第',i1,'行到第',i2,'行内容如下:')
i1=int(i1)
i2=int(i2)
for x in file1:
i+=1
if i>=i1 and i<=i2:
print(x)
file1.close()
lineP()
第四题,感觉差不多,似乎我的更容易理解
def x():
name1=input('请输入文件名:')
name='f:\\'+name1
old=input('请输入需要替换的单词或字符:')
new=input('请输入新的单词或字符:')
file=open(name,'r+')
f=file.read()
i=f.count(old)
print('文件',name1,'中共有',i,'个【',old,'】')
print('您确定把所有的【',old,'】替换成【',new,'】吗?')
t=input('\n【YES/NO】:')
if t=='yes'or t=='YES':
f1=f.replace(old,new)
file.close()
file1=open(name,'w')
file1.write(f1)
file1.close()
x()
本帖最后由 icewin 于 2019-11-23 00:11 编辑
{:10_277:}被吞贴了?写半天,被吞了,算了就不发了。 30课第2题
def shou():
import os
f=input('请输入带查找的初始目录:')
f1=input('请输入需要查找的目标文件:')
t=list(os.walk(f))
for (a,b,c) in t:
if f1 in c :
print(a+f1)
shou()
看起来比课后答案要舒服一点点
第3题
def dianying():
import os
r=open('f:\\测试文件夹\\vedioList.txt','w+')
r1=[]
f='f:\\课堂练习'
os.chdir(f)
t=list(os.walk(f))
for (a,b,c)in t:
for x in c:
if '.'in x:
f1=x.split('.')
if (f1[-1])in('mp4','avi','rmvb','mkv'):
r1.append(a+x+'\n')
r.writelines(r1)
r.close()
dianying()
第4题行数其实差不多
def gjz():
import os
p=input('请将该脚本放于待查找的文件夹内,请输入关键字:')
print('请问是否需要打印关键字【',p,'】在文件中的具体位置',end='')
p1=input('(YES/NO):')
if p1== 'YES':
f='f:\\课堂练习'
f1=os.walk(f)
for (a,b,c)in f1: #确定是否存在txt文件
for x in c:
if '.'in x:
t=x.split('.')
if t[-1]=='txt':
ax=a+'\\'+x
weizi(ax,p)
def weizi(ax,p): #打印文件位置,关键字位置
f2=open(ax,'r')
i=0 #行数
o=0
for x1 in f2:
i+=1
if p in x1 :
if o==0: #设法只打印一次排头
print('='*75)
print("在文件【%s】中找到关键字【%s】"%(ax,p))
o+=1
r=0
q=0
s=[]
while q!=-1:
q=x1.find(p,r)
r=q+3
if q!=-1:
s.append(q)
print('关键字出现在第',i,'行,第',s,'个位置')
f2.close()
gjz()
31课开始的时候我以为没有换行符,想复杂了,搞半天跑起来不正常,后来分步测试,发现是我想多了,扫了眼答案根本吗记,自己从新写,写完发现和答案基本一样。。。。难受
import os
import pickle
os.chdir("f:\\课堂练习")
def split1(i,b1,g1):
b='boy_'+str(i)+'.txt'
g='girl_'+str(i)+'.txt'
global boy ,girl
boy=open(b,'wb')
girl=open(g,'wb')
pickle.dump(b1,boy)
pickle.dump(g1,girl)
boy.close()
girl.close()
def save1():
f=open('f:\\课堂练习\\record.txt')
i=1
b1=[]
g1=[]
for a1 in f:
if '========'in a1:
split1(i,b1,g1)
b1=[]
g1=[]
i+=1
continue
if "小甲鱼:"in a1:
b1.append(a1)
if "小客服:"in a1:
g1.append(a1)
split1(i,b1,g1)
f.close()
save1()
35课最后一题,看到有人说二进制不报错,果断试试,感觉不错,我的代码如下
import easygui as gui
import os
list1=['.txt','.py']
dict1={'.txt':0,'.py':0} #文件类型,和个数
dict2={'.txt':0,'.py':0} #文件类型和行数
def file1(path1): #判断文件是否为路径,更新字典
a=os.listdir(path1)
for i in range(len(a)):
c=path1+'\\'+a
b=os.path.isdir(c)
if b: #准备写递归@_@,用walk不知道多好,非要要求用递归
file1(c) #调整了下框架,感觉好像递归行数要简洁一点
else:
d=os.path.splitext(c)
if d in dict1:
dict1+=1
f=open(c,'rb') #只读搞不了,二进制读取可以解读
dict2=dict2+len(f.readlines())
f.close()
path1=gui.diropenbox(msg='请选择您的代码库',title='浏览文件夹',default='f:\\课堂练习')
file1(path1)
ia=sum(dict2.values())
ib='%4.2f '%(ia/10e2)+'%'
ic=10e4-ia
msg1='您目前共累计编写了%s行代码,完度%s\n离10万行代码还差%s行,请继续努力'%(ia,ib,ic)
text0='【%s】源文件%s个,源代码%s行\n'
text1=''
for t in list1:
text2=text0 %(t,dict1,dict2)
text1+=text2
gui.textbox(msg=msg1,title='统计结果',text=text1)
本帖最后由 icewin 于 2019-12-12 19:42 编辑
37课最后一题,我间接用了数学概率方法,但是这个表达似乎不怎么样帅气,现在实力有限
import random
class Xy:
def __init__(self):
x=random.randint(0,10)
y=random.randint(0,10)
self.xy=(x,y)
g=random.randint(0,5)
f=random.randint(0,2)
s=random.choice([-1,1])
self.g=g
self.f=f
self.s=s
gy=[(0,0),(0,1),(0,2),(1,1),(1,0),(2,0)]
fy=[(0,0),(0,1),(1,0)]
wg=[(Xy().xy)]
fish=[]
gh=100
for f1 in range(10):
fish.append(Xy().xy)
print(wg,fish)
def guihp():#每回合后的hp
global gh
if gh>0:
gh-=1 #一次吃多条
for tt in fish:
if tt==wg:
fish.remove(tt)
gh+=20
if gh>100: #不加hp上限还能吃鱼,加了就更难了
gh=100
n=0
def huifan(n):#边界回返,如果不回返改成停下来也可以,似乎更像甲鱼的行为
if n<0:
n=-n
if 10<n:
n=20-n
return n
def gyidong():#乌龟一次移动
wgy=gy
a=wg+wgy*Xy().s#Xy().s是选择方向
b=wg+wgy*Xy().s
a=huifan(a)
b=huifan(b)
wg=(a,b)
def fyidong():#鱼一次移动
for fn in range(len(fish)):
wfy=fy
(af,bf)=fish
af=af+wfy*Xy().s
bf=bf+wfy*Xy().s
af=huifan(af)
bf=huifan(bf)
fish=(af,bf)
while gh:
guihp()
gyidong()
fyidong()
print(wg,fish,gh)
if len(fish)==0:
print('鱼全部死光光,乌龟胜利')
break
if gh==0:
print('这乌龟连个鱼都吃不完')
关于构造函数总结,可能有不对的地方
class MyClass:
name = 'FishC'
def myFun(self):
print("Hello FishC!")
def __init__(self):
self.r='kkkk'
self.c='llll'
print('666')
print(MyClass.name)#MyClass不带()只提取属性,构造函数不运行,带括号自动运行。
print('0==='*20)
MyClass().myFun() #构造函数先自动运行,函数再运行,和类里面顺序无关。
print('1==='*20)
print(MyClass().r,MyClass().c)#这里类构造函数先运行2次,(这个并排优先级很奇怪),再提取里面方法
print('2==='*20)
MyClass().r #构造函数运行一次,没有打印‘方法’
print('3==='*20)
x=MyClass() #构造函数运行一次,下面用‘方法’,不再运行,直接提取‘方法’
print('4==='*20)
print(x.r,x.c)#这样写很奇怪,可能就像餐余垃圾,是死的,如果每次想取随机数还是和类一起写,例如上面1-2
#如果说类是一个函数,那么类里面的构造函数就是这个类函数会自动执行的运算,调取构造函数里面‘方法’只不过是
#把运算完后的对应数据取出来,简单来说和一般函数没太大区别,但是因为类的存在使代码行数少了一些def 函数的命名操作
关于range猜测
def range1(x):
#姑且先把x想象成一个列表或元组,因为不了解更底层逻辑也只能先这样
range1=[]
if len(x)==1:
a=0
b=x
c=1
elif len(x)==2:
a=x
b=x
c=1
elif len(x)==3:
a=x
b=x
c=x
while 1:
try:
range1.append(a)
a+=c
if b<=a:
break
except:
pass#不知道底层逻辑报错原因条件还写不出来
return range1
#突然感觉橙色的字体逻辑来说相对贴近底层逻辑
页:
[1]