6-2. 字符串标识符.修改例 6-1 的 idcheck.py 脚本,使之可以检测长度为一的标识符,并且可以识别 Python 关键字,对后一个要求,你可以使用 keyword 模块(特别是 keyword.kelist)来帮你.
import string
import keyword
alphas=string.letters+'_'
num=string.digits
aplpnums=alphas+num
print 'Testees must be at least 1 char long.'
myinput=raw_input('Identifier to test? ')
if len(myinput)>=1:
if myinput[0] not in alphas:
print 'invalid: first symbol must be alphabetic'
else:
for otherchar in myinput [1:]:
if otherchar not in aplpnums:
print 'invalid: remaining symbols must be alphanumeric'
break
else:
if myinput in keyword.kwlist:
print 'invalid: symbol is reserved as keyword'
else:
print 'okay as an identifier'
6-3
排序
(a) 输入一串数字,从大到小排列之.
(b) 跟 a 一样,不过要用字典序从大到小排列之
(a)
numstr=raw_input('input some numbers: ')
numlist=list(numstr)
n=len(numlist)
for i in range(0,n):
for j in range(0,n-i-1):
if int(numlist[j])<int(numlist[j+1]):
temp=numlist[j]
numlist[j]=numlist[j+1]
numlist[j+1]=temp
numlist.sort()
numlist.reverse()
print numlist
(b)
numstr=raw_input('input some numbers: ')
numlist=list(numstr)
numlist.sort()
numlist.reverse()
print numlist
6-4 算术. 更新上一章里面你的得分测试练习方案,把测试得分放到一个列表中去.你的代码应该可以计算出一个平均分,见练习 2-9 和练习 5-3.
score=[65,76,87,98]
print (sum(score)/len(score))
6-5 字符串
(a)更新你在练习 2-7 里面的方案,使之可以每次向前向后都显示一个字符串的一个字符.
(b)通过扫描来判断两个字符串是否匹配(不能使用比较操作符或者 cmp()内建函数)。附加题:在你的方案里加入大小写区分.
(c)判断一个字符串是否重现(后面跟前面的一致).附加题:在处理除了严格的回文之外,加入对例如控制符号和空格的支持。
(d)接受一个字符,在其后面加一个反向的拷贝,构成一个回文字符串.
(a)
s=raw_input('Enter a string:')
i=0
while i<len(s):
print s[0:i+1],
i+=1
print
j=0
rs=''
while j<len(s):
rs+=s[-1-j]
print rs,
j+=1
(b)
str1=raw_input('Enter 1st string:')
str2=raw_input('Enter 2nd string:')
newstr1=str1.lower()
newstr2=str2.lower()
if len(str1) != len(str2):
print "not equal"
else:
for i in range(len(str1)):
if newstr1[i] != newstr2[i]:
print "not equal"
break
else:
print "equal"
(C)
str=raw_input('Enter 1st string:')
l=len(str)
if l % 2 == 0:
for i in range(l/2):
if str[i]!=str[l-1-i]:
print "not repeat"
break
else:
print "repeat"
elif l % 2 != 0:
for i in range(l/2):
if str[i]!=str[l-i-1]:
print "not repeat"
break
else:
print "repeat"
(d)
str1=raw_input('Enter 1st string:')
str2=str1 + str1[::-1]
print str2
6-6 字符串.创建一个 string.strip()的替代函数:接受一个字符串,去掉它前面和后面的空格(如果使用 string.*strip()函数那本练习就没有意义了)
str=raw_input('Enter a string:')
i=0
j=len(str)-1
while 1:
if str[i]==' ':
i+=1
else:
break
while 1:
if str[j]==' ':
j-=1
else:
break
print str[i:j+1]
6-7 调试.看一下在例 6.5 中给出的代码(buggy.py)
(a)研究这段代码并描述这段代码想做什么.在所有的(#)处都要填写你的注释.
(b)这个程序有一个很大的问题,比如输入 6,12,20,30,等它会死掉,实际上它不能处理任何的偶数,找出原因.
(c)修正(b)中提出的问题.
#功能:删除列表中能被输入的数整除的元素
num_str=raw_input('Enter a number: ')
num_num=int(num_str)
fac_list=range(1,num_num+1)
print "before:",fac_list
i=0
while i<len(fac_list):
if num_num%fac_list[i]==0:
del fac_list[i]
else:
i=i+1
print "after:",fac_list
6-8 列表。给出一个整型值,返回代表该值得英文,比如输入89会返回“eight-nine”。附加题:能够返回符合英文语法规律的新式,比如输入89会返回“eighty-nine”。本练习中的值假定在0~1000。
single=['','one','two','three','four','five','six','seven','eight','nine']
double1=['ten','eleven','tweleve','thirting','fourting','fifting','sixting','seventing','eighting','nineting']
double2=['','','twenty','thirty','fourty','fifty','sixty','seventy','eighty','ninety']
numstr=raw_input('Enter a number 0--1000: ')
numlen=len(numstr)
num=int(numstr)
if numlen==1:
if int(numstr[0])>0:
print single[num]
else:
print 'zero'
elif numlen==2:
if numstr[0]=='1':
print double1[num-10]
else:
print double2[int(numstr[0])]+'-'+single[int(numstr[1])]
elif numlen==3:
if numstr[1]=='1':
tmp=double1[int(numstr[2])]
else:
tmp=double2[int(numstr[1])]+'-'+single[int(numstr[2])]
print single[int(numstr[0])]+' hundred '+tmp
else:
print 'one thousand'
6-9 转换。为练习5-13写一个姊妹函数,接受分钟数,返回小时数和分钟数。总时间不变,并且要求小时尽可能大。
min=int(raw_input('please input a number as minutes: '))
def totaltime(min):
if min<60:
print '0 hours %d minutes' %(min)
elif min>=60:
print '%d hours %d minutes' %(min/60,min%60)
totaltime(min)
6-10 字符串。写一个函数,返回一个跟输入字符串相似的字符串,要求字符串的大小写反转,比如,输入“Mr.Ed”,应该返回“mR.eD”作为输出。
ostr=raw_input('please input a string: ')
def changecase(str):
dstr=str.swapcase()
print dstr
changecase(ostr)
6-11 转换。
(a)创建一个从整型到IP地址的转换,如下格式: www.xxx.yyy.zzz。
(b)更新你的程序,使之可以逆转换。
a)ip=int(raw_input('please input a number as IP: '))
print 'IP'+'='+str(int(int(ip)/16777216) & 255)+'.'\
+str(int(int(ip)/65536) & 255)+'.'+str(int(int(ip)/256) & 255)+'.'+str((int(ip) & 255))
b)ip=raw_input('please input a IP like xxx.xxx.xxx.xxx : ')
print 'IP'+'='+str(int(ip.split('.')[0])*16777216+int(ip.split('.')[1])*65536+\
int(ip.split('.')[2])*256+int(ip.split('.')[3]))
6-12 字符串。
(a)创建一个名字为findchr()的函数,函数声明如下。
def findchr(string, char)
findchr()要在字符串string中查找字符char,找到就返回该值得索引,否则返回-1。不能用string.*find()或者string.*index()函数和方法。
(b)创建另一个叫rfindchr()的函数,查找字符char最后一次出现的位置。它跟findchr()工作类似,不过它是从字符串的最后开始向前查找的。
(c)创建第三个函数,名字叫subchr(),声明如下。
def subchr(string, origchar, newchar)
subchr()跟findchr()类似,不同的是,如果找到匹配的字符就用新的字符替换原先字符。返回修改后的字符串。
a)
def findchr(string, char):
strlen=len(string)
if char in string:
for i in range(strlen):
if char==string[i]:
print i
else:
print -1
b)
def rfindchr(string, char):
strlen=len(string)
if char in string:
for i in range(strlen):
if char==string[-1-i]:
print strlen-i-1
break
else:
print -1
c)
def subchr(string, origchar, newchar):
while(1):
if findchr(string,origchar)==-1:
break
else:
p=findchr(string,origchar)
string=string[:p]+newchar+string[p+1:]
print string
6-13 字符串.string模块包含三个函数,atoi(),atol()和atof(),他们分别负责把字符串转换成整型、长整型和浮点型数字。从Python 1.5起,Python的内建函数int()、long()、float()也可以做同样的事了,本文来,complex()函数可以把字符串转换成复数(然而1.5之前,这些转换函数只能工作于数字之上)
string模块中并没有实现一个atoc()函数,那么你来实现一个atoc(),接受单个字符串做参数输入,一个表示复数的字符串,例如'-1.23e+4-5.67j',返回相应的复数对象。你不能用eval()函数,但可以使用complex()函数,而且你只能在如下的限制之下使用:complex():complex(real, imag)的real和imag都必须是浮点值。
str=raw_input('input a string as comlex number:')
def atoc(str):
strlen=len(str)
for i in range(strlen):
if '+'==str[-1-i] or '-'==str[-1-i]:
op1=str[:-1-i]
op2=str[-1-i:-1]
break
else:
continue
print complex(float(op1),float(op2))
atoc(str)
6-14 随机数。设计一个“石头、剪子、布”游戏,有时又叫“Rochambeau”,你小时候可能玩过,下面是规则。你和你的对手,在同一时间做出特定的手势,必须是下面一种:石头、剪子、布。胜利者从下面的规则产生,这个规则本身是个悖论。(a)布包石头。(b)石头砸剪子。(c)剪子剪破布。在你的计算机版本中,用户输入他/她的选项,计算机找一个随机选项,然后由你的程序来决定一个胜利者或者平手。注意,最好的算法是尽量少使用if语句。
import random
print '0 siccsor'
print '1 stone'
print '2 fabric'
print '3 quit'
list = ['siccsor','stone','fabric']
while True:
i = input("pls input operation number: ")
if (3 == i):
break
elif (i<0 or i>3):
print 'Error input operation, try agin. 3 operation is quit\n'
continue
c = random.randint(0,2)
if (i == c):
print 'your is %s, computer is %s ' % (list[i],list[c])
print 'it is draw'
elif (i-c) == 2 or (i-c) == -1:
print 'your is %s, computer is %s ' % (list[i],list[c])
print 'computer win'
else:
print 'your is %s, computer is %s ' % (list[i],list[c])
print 'you win'
6-15 转换。
(a)给出两个可识别格式的日期,比如MM/DD/YY或者DD/MM/YY格式。计算出两个日期之间的天数。
(b)给出一个人的生日,计算此人从出生到现在的天数,包括所有的闰月。
(c)还是上面的例子,计算出此人下次过生日还有多少天。
import time
def isLeapYear(year):
if (year%4==0 and year%100!=0) or (year%400==0):
return True
def IntervalDays(str1,str2):
month1 = [0,31,28,31,30,31,30,31,31,30,31,30,31]
month2 = [0,31,29,31,30,31,30,31,31,30,31,30,31]
#假定输入的日期都是正确的且后一个日期比前一个日期大
bdate = str1.split('/')
bdate[0],bdate[1],bdate[2]=int(bdate[0]),int(bdate[1]),int(bdate[2])
edate = str2.split('/')
edate[0],edate[1],edate[2]=int(edate[0]),int(edate[1]),int(edate[2])
if bdate==edate:
print '0 days'
elif bdate[1]==edate[1] and bdate[2]==edate[2]:
print '%d days' %abs(bdate[0]-edate[0])
elif bdate[1]!=edate[1] and bdate[2]==edate[2]:
bdays=0
edays=0
if isLeapYear(bdate[2]):
for i in range(1,bdate[1]):
bdays+=month2[i]
bdays=bdays+bdate[0]
for i in range(1,edate[1]):
edays+=month2[i]
edays=edays+edate[0]
print '%d days' %abs(edays-bdays)
else:
for i in range(1,bdate[1]):
bdays+=month1[i]
bdays=bdays+bdate[0]
for i in range(1,edate[1]):
edays+=month1[i]
edays=edays+edate[0]
print '%d days' %abs(edays-bdays)
elif bdate[2]!=edate[2]:
days=0
for i in range(bdate[2]+1,edate[2]):
if isLeapYear(i):
days+=366
else:
days+=365
if isLeapYear(bdate[2]):
for i in range(bdate[1]+1,13):
days+=month2[i]
days+=(month2[bdate[1]]-bdate[0])
else:
for i in range(bdate[1]+1,13):
days+=month1[i]
days+=(month1[bdate[1]]-bdate[0])
if isLeapYear(edate[2]):
for i in range(1,edate[1]):
days+=month2[i]
days+=edate[0]
print '%d days' %(days)
else:
for i in range(1,edate[1]):
days+=month1[i]
days+=edate[0]
print '%d days' %(days)
if __name__=='__main__':
#(a)
date1=raw_input("input a start date as DD/MM/YYYY: ")
date2=raw_input("input a end date as DD/MM/YYYY: ")
IntervalDays(date1,date2)
#(b)
birth=raw_input("input a birth date as DD/MM/YYYY: ")
today=str(time.strftime("%d/%m/%Y"))
print 'today is %s ' %today
IntervalDays(birth,today)
#(c)
birth=raw_input("input a birth date as DD/MM/YYYY: ")
today=str(time.strftime("%d/%m/%Y"))
print 'today is %s ' %today
if today.split('/')[1]<birth.split('/')[1]:
nbirth=str(birth.split('/')[0]+'/'+birth.split('/')[1]+'/'+today.split('/')[2])
IntervalDays(today,nbirth)
elif today.split('/')[1]==birth.split('/')[1]:
if today.split('/')[0]<birth.split('/')[0]:
print '%d days' %(int(birth.split('/')[0])-int(today.split('/')[0]))
else:
year=int(today.split('/')[2])+1
nbirth=str(birth.split('/')[0]+'/'+birth.split('/')[1]+'/'+str(year))
IntervalDays(today,nbirth)
6-16 矩阵。处理矩阵M和N的加和乘操作。
a)两个矩阵的维数相等才能相加
a = ([1,2,3],[4,5,6],[7,8,9])
b = ([9,8,7],[6,5,4],[3,2,1])
c = ([0,0,0],[0,0,0],[0,0,0])
for i in range(0,len(a)):
for j in range(0,len(b)):
c[i][j] = a[i][j]+b[i][j]
print c
b)矩阵1的列数与矩阵2的行数相等两个矩阵才能相乘
a = ([1,2,3,4],[5,6,5,8],[9,10,11,12])
b = ([1,1,1],[1,1,1],[1,1,1],[1,1,1])
c = ([0,0,0],[0,0,0],[0,0,0])
for m in range(0,len(c)):
for i in range(0,len(a)):
for j in range(0,len(b)):
c[m][i] += a[i][j]*b[j][i]
print c
6-17 方法。实现一个叫myPop()的函数,功能类似于列表的pop()方法,用一个列表作为输入,移除列表的最新一个元素,并返回它。
l=[1,2,3,4,5]
def mypop(list):
tmp=list[-1]
del list[-1]
return tmp
print mypop(l)
print l
6-18 zip()内建函数。在6.13.2节里面关于zip()函数的例子中,zip(fn,ln)返回的是什么?
返回一个列表,列表中的每个元素是一个元组
6-19 多列输出。有任意项的序列或者其他容器,把它们等距离分列显示。由调用者提供数据和输出格式。例如,如果你传入100个项并定义3列输出,按照需要的模式显示这些数据。这种情况下,应该是两列显示33个项,最后一列显示34个。你可以让用户来选者水平排序或者垂直排序。
import random
list = []
nums = input("pls input a number for iterms: ")
clns = input("pls input a number for columns: ")
for i in range(0,nums):
list.append(i+1)
print list
print '0 horizontal sort'
print '1 vertical sort'
print '2 quit'
while True:
print
i = input("pls input operation number: ")
if (2 == i):
break
elif (i<0 or i>2):
print 'Error input operation, try agin. 3 operation is quit\n'
continue
if (0 == i):
n = 0
for m in range(0,nums):
print "%4d" %list[m],
n += 1
if n % clns == 0:
print
elif (1 == i):
n = 0
for i in range(0,nums/clns+1):
if i == nums/clns:
for j in range(0,nums%clns):
print 4*clns*' '+str(list[i*clns+j])
else:
for j in range(0,clns):
print "%4s" %str(list[i+j*(nums/clns)]),
print
n += 1
if n % clns == 0:
continue