python核心编程(第二版)参考答案(自制)--第六章·序列:字符串、列表和元组(Part2)

###最近自学python,使用的教材是python核心编程(第二版)。自己做了练习题的答案,不管正确与否,算是给自己的一种约束和督促吧。

--------------------------------------------------------

6-11.*转换。(a)创建一个从整型到IP地址的转换,如下格式:www.xxx.yyy.zzz。(b)更新你的程序,使之可以逆转换。

def int_to_IP(num):
    WWW=(num>>24)&0xFF
    XXX=(num>>16)&0xFF
    YYY=(num>>8)&0xFF
    ZZZ=num&0xFF
    print '%d.%d.%d.%d'%(WWW,XXX,YYY,ZZZ)
def IP_to_int(str1):
    str2=str1.split('.')
    res=0
    if len(str2)!=4:
        print 'Invalid IP!'
        return 0
    else:
        for x in str2:
            if int(x)>255 or int(x)<0:
                print 'Invalid IP!'
                return 0
            else:
                res=(res<<8)+int(x)
    print res    

int_to_IP(256)
IP_to_int('0.0.1.0')

--------------------------------------------------------

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()类似,不同的是,如果找到匹配的字符就用新的字符替换原先字符。返回修改后的字符串。

def findchr(string,char):
    if not isinstance(string, str):
        print 'Error!'
        return -1
    if len(str(char))!=1:
        print 'Error!'
        return -1
    for x in xrange(len(string)):
        if string[x]==str(char):
            print 'find!'
            return x
    print 'Not found!'
    return -1

def rfindchr(string,char):
    if not isinstance(string, str):
        print 'Error!'
        return -1
    if len(str(char))!=1:
        print 'Error!'
        return -1
    for x in range(len(string)-1,-1,-1):
        if string[x]==str(char):
            print 'find!'
            return x
    print 'Not found!'
    return -1

def subchr(string,oigchar,newchar):##just replace the first found char
    if len(str(newchar))!=1:
        print 'Error!'
        return -1
    index=findchr(string,oigchar)
    string=string[:index]+str(newchar)+string[index+1:-1]
    return string

A='ABCDEFABCDx'        
print subchr(A,'A','b')

--------------------------------------------------------

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都必须是浮点值。

def atoc(compl_string):
    if compl_string[-1] not in 'jJ':
        compl_real=float(compl_string)
        compl_imag=0.0
    else: 
        for x in xrange(len(compl_string)-1,-1,-1):
            if (compl_string[x] in '+-') and (compl_string[x-1] not in 'e'+'E'):
                if x==0:
                    compl_real=0.0
                else:
                    compl_real=float(compl_string[:x])   
                compl_imag=float(compl_string[x:len(compl_string)-1])
    return complex(compl_real,compl_imag)

print atoc('3e2-5.67e+3j')

--------------------------------------------------------

6-14.*随机数。设计一个“石头、剪子、布”游戏,有时又叫“Rochambeau”,你小时候可能玩过,下面是规则。你和你的对手,在同一时间做出特定的手势,必须是下面一种:石头、剪子、布。胜利者从下面的规则产生,这个规则本身是个悖论。

(a)布包石头。

(b)石头砸剪子。

(c)剪子剪破布。在你的计算机版本中,用户输入他/她的选项,计算机找一个随机选项,然后由你的程序来决定一个胜利者或者平手。注意,最好的算法是尽量少使用if语句。

import random
def Rochambeau(Yoursig):
    Default_Sig=['scissor','stone','cloth']
    Yoursig=str(Yoursig)
    Result=["Computer Win!","Draw!","You win!"]
    if Yoursig not in Default_Sig:
        print 'Error Input!'
        return -1
    computerSig=random.choice(Default_Sig)
    index=Default_Sig.index(Yoursig)-Default_Sig.index(computerSig)
    print "You VS Computer:",Yoursig,"VS",computerSig,"Result:",Result[(index+4)%3]

Rochambeau('stone')
--------------------------------------------------------

6-14.*随机数。转换。
(a)给出两个可识别格式的日期,比如MM/DD/YY或者DD/MM/YY格式。计算出两个日期之间的天数。
(b)给出一个人的生日,计算此人从出生到现在的天数,包括所有的闰月。
(c)还是上面的例子,计算出此人下次过生日还有多少天。

MONTHDAYS=[31,28,31,30,31,30,31,31,30,31,30,31]
def LeapYear(year):
    if not (year%400):
        return True
    elif (year%100) and (not year%4):
        return True
    else:
        return False

def days_sum(year,month,day):
    days_add=0
    for x in xrange(month-1):
        days_add+=MONTHDAYS[x]
    days_add+=day
    if LeapYear(year):
        if month>=3:
            days_add+=1
    else:
        if (month,day)==(2,29):
            print 'wrong date!'
            return 0;
    return days_add
    
def day2day(str1,str2):
    print "Please input two dates like: MM/DD/YY!"
    
    #"dates format must be: MM/DD/YY!"
    [month1,day1,year1]=str1.split("/")
    [month2,day2,year2]=str2.split("/")
    month1=int(month1);month2=int(month2);
    day1=int(day1);day2=int(day2);
    year1=int(year1);year2=int(year2);
    if year2<year1:
        print "year2 must later than year1"
        return -1
    sum_days=0

    for x in xrange(year1,year2):
        if LeapYear(x):
            sum_days+=366
        else:
            sum_days+=365

    sum_days=sum_days-days_sum(year1,month1,day1)
    sum_days=sum_days+days_sum(year2,month2,day2)
    print str1+'~'+str2+":",sum_days,"days"
    return sum_days

def now_to_nextbirthday(birth,now):
    print 'Please input your birthday,now date'
    [month1,day1,year1]=birth.split("/")
    [month2,day2,year2]=now.split("/")
    month1=int(month1);month2=int(month2);
    day1=int(day1);day2=int(day2);
    year1=int(year1);year2=int(year2);
    if [month1,day1]>=[month2,day2]:
        year3=year2
    elif (month1,day1)==(2,29):
        for x in xrange(4):
            year3=year2+1+x
            if LeapYear(year3):break
    else:
        year3=year2+1
    birth=str(month1)+'/'+str(day1)+'/'+str(year3)
    nextdays=day2day(now,birth)
    return nextdays

day2day('2/25/1991','2/26/2012')        
now_to_nextbirthday('2/29/1991','3/1/2012')
--------------------------------------------------------
6-16.*矩阵。处理矩阵M和N的加和乘操作。

def matrix_in(str_matrix):
    print 'please input the matrix as a11,a12;a21,a22'
    #the end of string cannot be ';'
    matrix=str_matrix.split(';')
    m=len(matrix)
    for x in xrange(m):
        matrix[x]=matrix[x].split(',')
        for i in xrange(len(matrix[x])):
            matrix[x][i]=int(matrix[x][i])
    print 'input:',matrix
    return matrix
def matrix_add(matrix1,matrix2):    
    m1=len(matrix1);m2=len(matrix2);
    n1=len(matrix1[0]);n2=len(matrix2[0]);
    if (m1!=m2) or (n1!=n2):
        print "Cannot add the two matrix!"
        return -1
    #matrix=[[0]*n1]*m1,this method will be wrong
    matrix=[]
    for x in xrange(m1):
        matrix_row=[0]*n1        
        for i in xrange(n1):
            matrix_row[i]=matrix1[x][i]+matrix2[x][i]
        matrix.append(matrix_row)
    print '*'*20+'\nmulti result:',matrix
    return matrix
def matrix_multi(matrix1,matrix2):  
    m1=len(matrix1);m2=len(matrix2);
    n1=len(matrix1[0]);n2=len(matrix2[0]);
    if (n1!=m2):
        print "Cannot multi the two matrix!"
        return -1
    matrix=[]
    for i in xrange(m1):
        matrix_row=[0]*n2
        for j in xrange(n2):
            for x in xrange(m2):
                matrix_row[j]+=(matrix1[i][x]*matrix2[x][j])
        matrix.append(matrix_row)

    print '*'*20+'\nmulti result:',matrix
    return matrix

a=matrix_in('00,01,02;10,11,12;20,21,22')
b=matrix_in('1,1;2,0')
c=matrix_in('0,2,3;1,1,2')
matrix_add(a,a)
matrix_multi(b,c)
--------------------------------------------------------
6-17:*方法。实现一个叫myPop()的函数,功能类似于列表的pop()方法,用一个列表作为输入,移除列表的最新一个元素,并返回它。

def myPop(lis):
    x=lis[-1]
    del(lis[-1])
    return x
    
lis=[1,2,3,4]
print myPop(lis)
print lis

--------------------------------------------------------

6-18.*zip()内建函数。在6.13.2节里面关于zip()函数的例子中,zip(fn,ln)返回的是什么可迭代对象供for循环?

fn = ['ian', 'stuart', 'david']
ln = ['bairnson', 'elliott', 'paton']
print zip(fn, ln)
>>>[('ian', 'bairnson'), ('stuart', 'elliott'), ('david', 'paton')]
答:zip()内建函数返回一个由元组作为元素的列表,第i个元组包含每个输入参数(列表或可迭代对象)的第i个元素。列表长度等于输入参数当中最短的长度。

--------------------------------------------------------

6-19*多列输出。有任意项的序列或者其他容器,把它们等距离分列显示。由调用者提供数据和输出格式。例如,如果你传入100个项并定义3列输出,按照需要的模式显示这些数据。这种情况下,应该是两列显示33个项,最后一列显示34个。你可以让用户来选者水平排序或者垂直排序。

def display_list(lis_data,column_N,hori_vert=True):
    if hori_vert:
        for x in xrange(len(lis_data)):
            print lis_data[x],'\t',
            if not((x+1)%column_N):
                print ''
    else:
        row_N=len(lis_data)/column_N
        if (len(lis_data)%column_N)>0:
            row_N+=1

        for i in xrange(row_N):
            for x in xrange(0,len(lis_data),row_N):
                if i+x>=len(lis_data):
                    break
                print lis_data[i+x],'\t',
            print ''
a=range(50)
display_list(a,5,False)
注: 100项数据两列显示33个项,最后一列显示34个的设计是比较奇怪,没有道理的。应该按照常理设计。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值