您的位置:首页 > 编程语言 > Python开发

Python核心编程 第六章练习

2016-04-26 18:37 507 查看
笔者刚刚开始python的系统学习,所以在代码上还无法达到pythonic的水准,很多写法也都是按照C++的习惯来写的,希望能有前辈进行交流指导。

欢迎拍砖

6_2

#!/usr/bin/env python
# encoding: utf-8

import string
import keyword

alphas = string.letters + '_'
nums = string.digits
keywd = keyword.kwlist

print "Welcome to the Identifier Checker v2.0"
print "Testees must be 2 chars long"
isValid = False

myInput = raw_input('')

if len(myInput) > 1:
if myInput[0] not in alphas:
print """invalid: first symbol ust be alphabetic"""
else:
for otherChar in myInput[1:]:
if otherChar not in alphas + nums:
print """invalid: remaining symbols must be
alphanumeric"""
break
else:
isValid = True
if myInput not in keywd and isValid:
print """invalid: the input is a keyword itself"""
else:
print "okay as an identifier"


6_3

这道题目的中文版书籍翻译有误,原题是:b.Do the same thing, but for strings and in reverse alphabetical (largest-to-smallest lexicographic) order.中文版翻译为:(b) 跟 a 一样,不过要用字典序从大到小排列之.

这显然是不对的,因此笔者在此处翻译为:“跟a一样,不过要求输入的字符改变为英文字母串,按照从打到小排列(这个lexicographic的原意为词典,此处笔者理解为由英文字母组成的单词)

#!/usr/bin/env python
# encoding: utf-8

import string

def num_input():
num = string.digits + '.'
while True:
isDigit = True
try:
lst_dgit = raw_input("Please input digit: ").split()
for i in lst_dgit:
for j in i:
if j not in num:
print i
isDigit = False
break
if not isDigit:
break
if isDigit:
break
else:
print "You input is not all digits, Please do it again!"
except (EOFError, KeyboardInterrupt, IndexError):
break
lst_num = [float(i) for i in lst_dgit]
lst_num.sort(reverse = True)
print lst_num

def string_input():
alpha = string.uppercase + string.lowercase
while True:
isAlpha = True
try:
lst_alpha = raw_input("Please input string: ").split()
for i in lst_alpha:
for j in i:
if j not in alpha:
isAlpha = False
break
if not isAlpha:
break
if isAlpha:
break
else:
print "Your input is not all lexicographic."
except(EOFError, KeyboardInterrupt, IndexError):
break
lst_string = [str(i) for i in lst_alpha]
lst_string.sort()
print lst_string

CMDs = {'e': num_input, 's': string_input}

def showmenu():
pr = '''
(S)tring
(D)igit
(Q)uit

Please select: '''
while True:
while True:
try:
choice = raw_input(pr).split()[0].lower()
except(EOFError, KeyboardInterrupt, IndexError):
choice = 'q'
print '\nYou picked: [%s]' %choice
if choice not in 'sdq':
print 'Invalid option, try again'
else: break
if choice == 'q':
break
CMDs[choice]()

if __name__ == "__main__":
showmenu()


6_4

此题中,为了使得python能够使用常规的计算方式,而非采用“地板除”,引用了division模块。

#!/usr/bin/env python
# encoding: utf-8

from __future__ import division #to make the python do the real division

def Classify(value):
if value > 90:
return 'A'
if value > 80:
return 'B'
if value > 70:
return 'C'
if value > 60:
return 'D'
else:
return 'F'

if __name__ == "__main__":
lst = [90, 93, 64, 34, 69]
lst.sort()
sum_lst = sum(lst)
avg_lst = sum_lst/len(lst)
print "the average grade is %0.2f" %avg_lst
class_lst = [Classify(i) for i in lst]
print class_lst


6_5

这个部分中文版的练习题翻译比较奇怪,跟正文的水准有些差距。对照了英文原文,将个人翻译写于此处。c小题的原文为:

c.Determine if a string is palindromic (the same backward as it is forward). Extra

credit: Add code to suppress symbols and whitespace if you want to process

anything other than strict palindromes.

翻译为:判断某个字符串是否是回文序列(正序与倒序保持一致)。附加题:添加代码,使得能够抑制符号以及空格,来判断非严格的回文序列。

6_5_a

#!/usr/bin/env python
# encoding: utf-8

if __name__ == "__main__":
strInput = raw_input("Please input a string: ")
print "The forward string is: "
for i in strInput:
print i,
print '\n',
print "The backward string is: "
for i in strInput[::-1]:
print i,
print '\n'


6_5_b

#!/usr/bin/env python
# encoding: utf-8

if __name__ == "__main__":
str1 = raw_input("Please input the 1st string: ").strip()
str2 = raw_input("Please input the 2nd string: ").strip()
#compare the length of the 2 strings
isEqual = True
if len(str1) == len(str2):
for (i, j) in zip(str1, str2):
if i != j:
isEqual = False
break
if isEqual:
print "the input is the same string!"
else:
print "Not the same string!"


6_5_c

#!/usr/bin/env python
# encoding: utf-8

import string
#availElem is all the character that can be used
availElem = string.digits + string.lowercase + string.uppercase

def palindrome(strToTest):
str_lst = [i for i in strToTest if i in availElem]
print str_lst
if cmp(str_lst, str_lst[::-1]) == 0:
print "It's palindrome!"
else:
print "It's not palindrome"

if __name__ == "__main__":
strToTest = raw_input("Please input a string: ")
palindrome(strToTest)


6_5_d

#!/usr/bin/env python
# encoding: utf-8

def palindrome(strToTest):
strToTest += strToTest[::-1]
print strToTest

if __name__ == "__main__":
strToTest = raw_input("Please input a string: ")
palindrome(strToTest)


6_6

#!/usr/bin/env python
# encoding: utf-8

if __name__ == "__main__":
strToStrip = raw_input("Please input the string: ")
for iStart in range(len(strToStrip)):
if strToStrip[iStart] != ' ':
break
for iEnd in range(len(strToStrip)):
if strToStrip[-iEnd-1] != ' ':
break
strResult = strToStrip[iStart: -iEnd]
print strResult


6_10

#!/usr/bin/env python
# encoding: utf-8

import string

lowstring = string.lowercase
uppstring = string.uppercase

strTmp = raw_input("Please input a string: ")
strRe = str()
for i in strTmp:
if i in lowstring:
strRe += i.upper()
elif i in uppstring:
strRe += i.lower()
else:
strRe += i
print strRe


6_11

这个题目不大会,搜索到了一个答案,出自林中路的答案,在他的基础上做了点小修改。 链接是:http://juven.blog.51cto.com/749867/975560,看了一下人家写的答案,差距一下就出来了。还是前辈厉害!

同时,这里使用了sys.argv[1], 应该是和C++的表示意义是一样的。

#!/usr/bin/env python
# encoding: utf-8

def intToIp(num):
dotIPAdd = str()
for i in range(3, -1, -1):
dotIPAdd += str(num / (256 ** i)) + '.'
if i == 3 and int(dotIPAdd.strip('.')) > 255:
print "Invalid IP, please enter another number ..."
sys.exit(1)
num = num % (256 ** i)
return (dotIPAdd.rstrip('.'))

if __name__ == "__main__":
import sys
num = int(sys.argv[1])
print intToIp(num)


6_11

这里要注意for…else的用法,else在这里还暗含程序不是通过break实现的意思,因此可以用来检测程序是否顺利执行完毕。

#!/usr/bin/env python
# encoding: utf-8

def intToIp(num):
dotIPAdd = str()
for i in range(3, -1, -1):
dotIPAdd += str(num / (256 ** i)) + '.'
if i == 3 and int(dotIPAdd.strip('.')) > 255:
print "Invalid IP, please enter another number ..."
sys.exit(1)
num = num % (256 ** i)
return (dotIPAdd.rstrip('.'))

if __name__ == "__main__":
import sys
num = int(sys.argv[1])
print intToIp(num)


6_13

此题的解答是有问题的,我定义的这种方式是在字符串的末尾反向寻找+-号,然后将两边分为实数和复数部分,但这种查找方式如果输入的值为3+3e+4j时,就会出现问题。暂且把不成熟的答案写在这里,希望有前辈能提供修改意见。

#!/usr/bin/env python
# encoding: utf-8

import string

def atoc(str2c):
pos_plus = 0
pos_minus = 0
if '+' in str2c:
pos_plus = str2c.rfind('+')
if '-' in str2c:
pos_minus = str2c.rfind('-')
pos = max(pos_plus, pos_minus)
num_real = float(str2c[0:pos])
num_imag = float(str2c[pos+1: len(str2c)-1])
return complex(num_real, num_imag)

if __name__ == "__main__":
import sys
compS = atoc(sys.argv[1])
print compS


6_14

这道问题解的不是很巧,具体的竞技过程是电脑随机选取一个用数字表示的选择:Paper for 0, Rock for 1, Scissor for 2。用户通过输入英文字符选择自己要出的手势,然后通过字典查询到其对应手势的数值,将电脑和人的数值相减就可以得到比赛的结果。但这种方法if使用仍然较多,不知道如何才能简化。

#!/usr/bin/env python
# encoding: utf-8

def Rochambeau():
pr = '''(P)aper
(R)ock
(S)cissor
(Q)uit

Please choose one
'''
import random
#the computer choose a random choice
trick_com = random.randrange(0, 3)
dct_choice = {'p': 0, 'r': 1, 's': 2}
while True:
try:
choice = raw_input(pr).split()[0].lower()
except (EOFError, KeyboardInterrupt, IndexError):
choice = 'q'
print '\nYou picked: [%s]' %choice
if choice not in 'prsq':
print "please choose the right choice!"
continue
break
if choice == 'q':
return
result =  dct_choice[choice] - trick_com
if result == -1 or result == 2:
print "you win!"
elif result == 0:
print "It's a tie"
else:
print "You lose!"
if __name__ == "__main__":
Rochambeau()


6_15

这道题目中,同样参考了林中路前辈的答案。链接再次挂出http://juven.blog.51cto.com/749867/975560

这个题目中,注意datetime模块的使用,在该模块中我试图使用datetime.date(),直接通过参数传递一个元组类型的变量,被提示只能分开传递,很是郁闷。

另外,这注意now变量,我的原意是希望通过datetime.datetime.now()直接赋值给D3,然后将D3直接与其他变量进行加减,结果报错。后来只好用了这个傻办法,将datetime的信息截取为date了。必须承认这道题目我的解法一点都不优雅。羞愧捂脸

#!/usr/bin/env python
# encoding: utf-8

def convert2Date(strDate):
lstDate = strDate.split('/')
tupDate = (int(lstDate[-1]), int(lstDate[0]), int(lstDate[1]))
return tupDate

if __name__ == "__main__":
import datetime
strDate1 = raw_input("Enter the date: ")
strDate2 = raw_input("Enter another date: ")
tupDate1 = convert2Date(strDate1)
tupDate2 = convert2Date(strDate2)
D1 = datetime.date(tupDate1[0], tupDate1[1], tupDate1[2])
D2 = datetime.date(tupDate2[0], tupDate2[1], tupDate2[2])
print (D2-D1).days
now = datetime.datetime.now()
D3 = datetime.date(now.year, now.month, now.day)
#b
print (D3-D1).days
#c
D4 = datetime.date(D3.year, D1.month, D1.day)
deltaDays = (D4-D3).days
if deltaDays > 0:
print deltaDays
else:
print (datetime.date(D3.year+1, D1.month, D1.day)
- D3).days


6_16

这道题目的安排有点奇怪,不知道原意是否是让我们自己写一个函数,我偷了懒,查阅网络之后,发现其实第5章中提到了numpy的module很适合在此处使用,暂且把numpy当做我使用的第一个轮子吧!

#!/usr/bin/env python
# encoding: utf-8

import numpy as np
M = np.array([[2, 3], [1, 5]])
N = np.array([[1, 4], [4, 6]])
print M + N
print np.dot(M, N)


6_17

#!/usr/bin/env python
# encoding: utf-8

def myPop(lst):
sizeoflst = len(lst)
lstElement = lst[sizeoflst-1]
del lst[sizeoflst-1]
return lstElement

if __name__ == "__main__":
lst = [3, 6, 7, 0 ,3]
print lst
print myPop(lst)
print lst
print myPop(lst)
print lst


6_19

这一部分真是写的又臭又长,为了使用一下迭代的思想,把自己给坑进去了。注意阅读代码的话,会发现有两个参数numOfRow, leftRow刚刚开始的时候是同一个值。这里我是希望用leftRow来表示还剩下的行数,然后用numOfRow用来做序号的步长。安排的不大合理,但是我暂时想不出合适的办法。

另外,这道题目我把用户输入的数组的环节给略去了,因为实在要输起来意义不大,用个raw_input().split()就可以获取到了。所以这里直接默认了一个0-99的数组,方便测试使用。

#!/usr/bin/env python
# encoding: utf-8

def Arrange(strHV, numOfRow, leftRow, lst, iStart):
if leftRow == 0:
return
numOfLine = (len(lst)-iStart)/numOfRow
leftRow -= 1
if strHV == "h":
for i in range(iStart, iStart + numOfLine):
print lst[i],
iStart += numOfLine
else:
for i in range(iStart, 100, numOfRow):
print lst[i],
iStart += 1
print ''
Arrange(strHV, numOfRow,leftRow, lst, iStart)

def main():
pr = '''(H)orizontal
(V)ertical
(Q)uit

Choice one please: '''
while True:
try:
choice = raw_input(pr).split()[0].lower()
except(EOFError, KeyboardInterrupt, IndexError):
choice = 'q'
print '\nYou picked: [%s]' %choice
if choice not in 'hvq':
print "Please choose the right choice!"
continue
break
if choice == 'q':
return
numOfRow = int(raw_input("Please input the number of the row: "))
lst = range(100)
Arrange(choice, numOfRow,numOfRow, lst, 0)

if __name__ == "__main__":
main()


后记

这段时间一方面在忙着找实习,白天要做老师的课题项目,晚上见缝插针的,终于把这章的习题完成了,接下来我将继续完成下面几章的内容。

之所以开通这个博客倒不是希望阅读量多大,只是作为一个自己记录学习的地方,算是作为一个非科班的程序员的成长之路吧。

最后,真诚的希望未来能向各位前辈多多讨教。以上!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息