Python小程序:Pig Latin

Python编程快速上手——让繁琐工作自动化 第2版》

6.8 项目 小程序:Pig Latin

简介

Pig Latin 是一种傻乎乎的、可伪造的语言, 它会改变英语单词。如果单词以元音开头,就在单词末尾添加yay。如果单词以辅音或辅音簇(例如ch或gr)开头,那么该辅音或辅音簇会移至单词的末尾,然后加上ay

让我们编写一个Pig Latin 程序,该程序将输入如下内容:

Enter the English message to translate into Pig Latin:
My name is AL SWEIGART and I am 4,000 years old.
Ymay amenay isyay ALYAY EIGARTSWAY andyay Iyay amyay 4,000 yearsysy oldyay.

该程序的工作原理是用本章介绍的方法更改字符串。在文件编辑器中输入以下源代码,并将文件另存为pigLatin.py:

(以下是书中提供的源代码,手敲版)

# English to Pig Latin
print('Enter the English message to translate into Pig Latin:')
message = input()

VOWELS = ('a', 'e', 'i', 'o', 'u', 'y')

pigLatin= []  # A list of the words in Pig Latin.
for word in message.split():
    # Separate the non-letters at the start of this word:
    prefixNonLetters = ''
    while len(word) > 0 and not word[0].isalpha():
        prefixNonLetters += word
        word = word[1:]
    if len(word) == 0:
        pigLatin.append(prefixNonLetters)
        continue

    # Separate the non-letters at the end of this word:
    suffixNonLetters = ''
    while not word[-1].isalpha():
        suffixNonLetters += word[-1]
        word = word[:-1]

    # Remember if the word was in uppercase or title case.
    wasUpper = word.isupper()
    wasTitle = word.istitle()

    word = word.lower()  # Make the word lowercase for translation.

    # Separate the consonants at the start of this word:
    prefixConsonants = ''
    while len(word) > 0 and not word[0] in VOWELS:
        prefixConsonants += word[0]
        word = word[1:]

    # Add the Pig Latin ending to the word:
    if prefixConsonants != '':
        word += prefixConsonants + 'ay'
    else:
        word += 'yay'

    # Set the word back to uppercase or title case:
    if wasUpper:
        word = word.upper()
    if wasTitle:
        word = word.title()

    # Add the non-letters back to the start or end of the word.
    pigLatin.append(prefixNonLetters + word + suffixNonLetters)

# Join all the words back together into a single string:
print(' '.join(pigLatin))
代码添加中文注释

更新后代码:

# English to Pig Latin
print('Enter the English message to translate into Pig Latin:')
message = input()

VOWELS = ('a', 'e', 'i', 'o', 'u', 'y')

pigLatin = []  # A list of the words in Pig Latin.
for word in message.split():
    # 提取某单词开头部分的非字母字符,并将该单词赋值为提取之后的单词
    # Separate the non-letters at the start of this word:
    prefixNonLetters = ''
    while len(word) > 0 and not word[0].isalpha():
        prefixNonLetters += word
        word = word[1:]
    # 如果提取某单词开头部分的非字母字符之后,该单词长度为空(即该单词只由非字母字符组成),将该单词直接添加到pigLatin列表
    if len(word) == 0:
        pigLatin.append(prefixNonLetters)
        continue

    # 提取某单词结尾部分的非字母字符,并将该单词赋值为提取之后的单词,赋值时注意保留原字符顺序。
    # Separate the non-letters at the end of this word:
    suffixNonLetters = ''
    while not word[-1].isalpha():
        suffixNonLetters += word[-1]
        word = word[:-1]

    # 用变量标记该单词是纯大写还是标题格式,剩下的默认均为小写
    # Remember if the word was in uppercase or title case.
    wasUpper = word.isupper()
    wasTitle = word.istitle()

    # 将单词均变为小写进行操作
    word = word.lower()  # Make the word lowercase for translation.

    # 从单词开头分离所有的辅音字母
    # Separate the consonants at the start of this word:
    prefixConsonants = ''
    while len(word) > 0 and not word[0] in VOWELS:
        prefixConsonants += word[0]
        word = word[1:]

    # 判断是否含有辅音字符,把 Pig Latin 格式的后缀添加到单词中
    # Add the Pig Latin ending to the word:
    if prefixConsonants != '':
        word += prefixConsonants + 'ay'
    else:
        word += 'yay'

    # 判断纯大写和标题格式变量进行还原单词大小写状态
    # Set the word back to uppercase or title case:
    if wasUpper:
        word = word.upper()
    if wasTitle:
        word = word.title()

    # 添加修改后的单词到pigLatin列表中
    # Add the non-letters back to the start or end of the word.
    pigLatin.append(prefixNonLetters + word + suffixNonLetters)

# 将pigLatin列表用join()方法连接
# Join all the words back together into a single string:
print(' '.join(pigLatin))
代码优化

1.对于大小写判断的过程不够严谨,如'iPhone'、'驼峰命名法 (Camel Case)的使用情况,如MyClassName'等。

解决方法:将书中给出的元音元组VOWELS修改为大小写的字母,删除upper和title格式的判断和还原

优化前:

Enter the English message to translate into Pig Latin:
I have an iPhone, ane it's name is MyFirstPhone.
Iyay avehay anyay iphoneyay, aneyay it'syay amenay isyay yfirstphonemay.

优化后:

Enter the English message to translate into Pig Latin:
I have an iPhone, ane it's name is MyFirstPhone.
Iyay avehay anyay iPhoneyay, aneyay it'syay amenay isyay yFirstPhoneMay.

2.在计算 suffixNonLetters时,按照源代码,在某单词最后的非字母字符在重组后会是倒序,如下方代码,'T-800!' 的 '-800!' 重组后变为了 '!008-',与书中本意不符

解决方法:由于是从word[-1]开始提取,直接用+=会导致提取后的单词结尾部分的非字母字符顺序为逆序,所以使用正常字符串连接的方法

优化前:

Enter the English message to translate into Pig Latin:
I am T-800!
Iyay amyay Tay!008-

优化后:

Enter the English message to translate into Pig Latin:
I am T-800!
Iyay amyay Tay-800!

优化后代码:

# English to Pig Latin
print('Enter the English message to translate into Pig Latin:')
message = input()

VOWELS = ('a', 'e', 'i', 'o', 'u', 'y', 'A', 'E', 'I', 'O', 'U', 'Y')

pigLatin = []  # A list of the words in Pig Latin.
for word in message.split():
    # 提取某单词开头部分的非字母字符,并将该单词赋值为提取之后的单词
    # Separate the non-letters at the start of this word:
    prefixNonLetters = ''
    while len(word) > 0 and not word[0].isalpha():
        prefixNonLetters += word
        word = word[1:]
    # 如果提取某单词开头部分的非字母字符之后,该单词长度为空(即该单词只由非字母字符组成),将该单词直接添加到pigLatin列表
    if len(word) == 0:
        pigLatin.append(prefixNonLetters)
        continue

    # 提取某单词结尾部分的非字母字符,并将该单词赋值为提取之后的单词,赋值时注意保留原字符顺序。
    # 由于是从word[-1]开始提取,直接用+=会导致提取后的单词结尾部分的非字母字符顺序为逆序,所以使用正常字符串连接的方法
    # Separate the non-letters at the end of this word:
    suffixNonLetters = ''
    while not word[-1].isalpha():
        suffixNonLetters = word[-1] + suffixNonLetters
        word = word[:-1]

    # 从单词开头分离所有的辅音字母
    # Separate the consonants at the start of this word:
    prefixConsonants = ''
    while len(word) > 0 and not word[0] in VOWELS:
        prefixConsonants += word[0]
        word = word[1:]

    # 判断是否含有辅音字符,把 Pig Latin 格式的后缀添加到单词中
    # Add the Pig Latin ending to the word:
    if prefixConsonants != '':
        word += prefixConsonants + 'ay'
    else:
        word += 'yay'

    # 添加修改后的单词到pigLatin列表中
    # Add the non-letters back to the start or end of the word.
    pigLatin.append(prefixNonLetters + word + suffixNonLetters)

# 将pigLatin列表用join()方法连接
# Join all the words back together into a single string:
print(' '.join(pigLatin))
总结

1.该项目是在书中给出的VOWELS元音元组('a', 'e', 'i', 'o', 'u', 'y')的基础上编写的,解释是:元音字母包括:a, e, i, o, u。在某些语言中,y 也可以作为元音字母。

但实际上还有部分特殊情况,像 honor 、honest这样的单词中,尽管开头的字母是 h,但在发音上,h 不发音,实际发出的元音声音是由后面的字母 o 产生的。在这种情况下,尽管字母 h 处于单词开头,但实际发出的元音声音由后面的字母提供。

该脚本按照书中给出的元音元组来即可,暂时不对发音上的特殊情况进行处理。

2.Pig Latin的核心在于改变英语单词,但该脚本对复合词没有作处理,导致复合词的某一部分未被改变,如形容词复合词:Well-known(著名的)、High-quality(高质量的)、Old-fashioned(过时的),在'old-fashioned'改变为'old-fashionedyay'的过程中,'old'并未被改变。

在网络上没有找到严格的定义是否应改变为'oldyay-ashionedfay'的格式,所以暂时不对该情况进行处理了

Enter the English message to translate into Pig Latin:
Her well-known book on high-quality craftsmanship is considered a classic in the field, although some people find its approach a bit old-fashioned.
erHay ell-knownway ookbay onyay igh-qualityhay aftsmanshipcray isyay onsideredcay ayay assicclay inyay ethay ieldfay, althoughyay omesay eoplepay indfay itsyay approachyay ayay itbay old-fashionedyay.

  • 26
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值