19、Python编程:文件、异常与递归问题的解决方案

Python编程:文件、异常与递归问题的解决方案

在Python编程中,文件操作、异常处理以及递归算法是非常重要的部分。下面将为大家介绍一系列相关问题的解决方案。

1. 文件头部与尾部显示
  • 显示文件头部 :要显示文件的前10行,可使用以下代码:
import sys
NUM_LINES = 10
if len(sys.argv) != 2:
    print("Provide the file name as a command line argument.")
    quit()
try:
    inf = open(sys.argv[1], "r")
    line = inf.readline()
    count = 0
    while count < NUM_LINES and line != "":
        line = line.rstrip()
        count = count + 1
        print(line)
        line = inf.readline()
    inf.close()
except IOError:
    print("An error occurred while accessing the file.")

操作步骤如下:
1. 检查命令行参数是否只包含一个文件名。
2. 尝试打开文件。
3. 逐行读取文件,读取并显示前10行。
4. 关闭文件。若出现异常,显示错误信息。

  • 显示文件尾部 :显示文件的最后10行,代码如下:
import sys
NUM_LINES = 10
if len(sys.argv) != 2:
    print("Provide the file name as a command line argument.")
    quit()
try:
    inf = open(sys.argv[1], "r")
    lines = []
    for line in inf:
        lines.append(line)
        if len(lines) > NUM_LINES:
            lines.pop(0)
    inf.close()
except:
    print("An error occurred while processing the file.")
    quit()
for line in lines:
    print(line, end="")

操作步骤:
1. 检查命令行参数。
2. 打开文件,逐行读取,始终保存最近的10行。
3. 关闭文件。若出现异常,显示错误信息并退出。
4. 显示最后10行。

2. 文件拼接

要将一个或多个文件拼接并显示结果,代码如下:

import sys
if len(sys.argv) == 1:
    print("You must provide at least one file name.")
    quit()
for i in range(1, len(sys.argv)):
    fname = sys.argv[i]
    try:
        inf = open(fname, "r")
        for line in inf:
            print(line, end="")
        inf.close()
    except:
        print("Couldn’t open/display", fname)

操作步骤:
1. 检查是否提供了至少一个文件名。
2. 遍历所有文件名,依次打开文件。
3. 显示文件内容,关闭文件。若出现异常,显示错误信息,但继续处理后续文件。

3. 数字求和

计算用户输入数字的总和,忽略非数字输入,代码如下:

line = input("Enter a number: ")
total = 0
while line != "":
    try:
        num = float(line)
        total = total + num
        print("The total is now", total)
    except ValueError:
        print("That wasn’t a number.")
    line = input("Enter a number: ")
print("The grand total is", total)

操作步骤:
1. 读取用户输入的第一行。
2. 若输入不为空,尝试将其转换为数字并累加到总和中。
3. 若转换失败,显示错误信息。
4. 继续读取下一个输入,直到用户输入空行。
5. 显示最终总和。

4. 移除Python文件中的注释

移除Python文件中的所有注释(忽略注释字符在字符串中的情况),代码如下:

try:
    in_name = input("Enter the name of a Python file: ")
    inf = open(in_name, "r")
except:
    print("A problem was encountered with the input file.")
    print("Quitting...")
    quit()
try:
    out_name = input("Enter the output file name: ")
    outf = open(out_name, "w")
except:
    inf.close()
    print("A problem was encountered with the output file.")
    print("Quitting...")
    quit()
try:
    for line in inf:
        pos = line.find("#")
        if pos > -1:
            line = line[0 : pos]
            line = line + "\n"
        outf.write(line)
    inf.close()
    outf.close()
except:
    print("A problem was encountered while processing the file.")
    print("Quitting...")

操作步骤:
1. 读取输入文件名并打开输入文件。若打开失败,显示错误信息并退出。
2. 读取输出文件名并打开输出文件。若打开失败,关闭输入文件,显示错误信息并退出。
3. 逐行读取输入文件,查找注释字符,若存在则移除注释。
4. 将修改后的行写入输出文件。
5. 关闭输入和输出文件。若出现异常,显示错误信息并退出。

5. 生成随机密码

生成由两个随机单词拼接而成的密码,密码长度在8到10个字母之间,每个单词至少3个字母,代码如下:

from random import randrange
WORD_FILE = "../Data/words.txt"
words = []
inf = open(WORD_FILE, "r")
for line in inf:
    line = line.rstrip()
    if len(line) >= 3 and len(line) <= 7:
        words.append(line)
inf.close()
first = words[randrange(0, len(words))]
first = first.capitalize()
password = first
while len(password) < 8 or len(password) > 10:
    second = words[randrange(0, len(words))]
    second = second.capitalize()
    password = first + second
print("The random password is:", password)

操作步骤:
1. 从文件中读取所有长度在3到7个字母之间的单词。
2. 随机选择第一个单词并首字母大写。
3. 不断随机选择第二个单词,直到拼接后的密码长度在8到10个字母之间。
4. 显示随机密码。

6. 字母使用比例分析

确定并显示每个字母在单词中出现的比例,找出使用比例最小的字母,代码如下:

WORD_FILE = "../Data/words.txt"
counts = {}
for ch in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":
    counts[ch] = 0
num_words = 0
inf = open(WORD_FILE, "r")
for word in inf:
    word = word.upper().rstrip()
    unique = []
    for ch in word:
        if ch not in unique and ch >= "A" and ch <= "Z":
            unique.append(ch)
    for ch in unique:
        counts[ch] = counts[ch] + 1
    num_words = num_words + 1
inf.close()
smallest_count = min(counts.values())
for ch in sorted(counts):
    if counts[ch] == smallest_count:
        smallest_letter = ch
    percentage = counts[ch] / num_words * 100
    print(ch, "occurs in %.2f percent of words" % percentage)
print()
print("The letter that is easiest to avoid is", smallest_letter)

操作步骤:
1. 初始化一个字典,用于记录每个字母出现的次数。
2. 打开文件,逐行读取单词。
3. 提取单词中的唯一字母,更新字典中的计数。
4. 统计处理的单词总数。
5. 关闭文件。
6. 找出出现次数最少的字母。
7. 显示每个字母的使用比例和最容易避免的字母。

7. 最受欢迎的名字

显示1900年到2012年至少有一年最受欢迎的女孩和男孩名字,代码如下:

FIRST_YEAR = 1900
LAST_YEAR = 2012
def LoadAndAdd(fname, names):
    inf = open(fname, "r")
    line = inf.readline()
    inf.close()
    parts = line.split()
    name = parts[0]
    if name not in names:
        names.append(name)

def main():
    girls = []
    boys = []
    for year in range(FIRST_YEAR, LAST_YEAR + 1):
        girl_fname = "../Data/BabyNames/" + str(year) + "_GirlsNames.txt"
        boy_fname = "../Data/BabyNames/" + str(year) + "_BoysNames.txt"
        LoadAndAdd(girl_fname, girls)
        LoadAndAdd(boy_fname, boys)
    print("Girls’ names that reached #1:")
    for name in girls:
        print(" ", name)
    print()
    print("Boys’ names that reached #1: ")
    for name in boys:
        print(" ", name)
main()

操作步骤:
1. 定义 LoadAndAdd 函数,用于从文件中读取第一个名字并添加到列表中(若不存在)。
2. 在 main 函数中,创建女孩和男孩名字的列表。
3. 遍历1900年到2012年,读取每年的女孩和男孩名字文件。
4. 调用 LoadAndAdd 函数处理每个文件。
5. 显示至少有一年最受欢迎的女孩和男孩名字。

8. 拼写检查

找出文件中所有拼写错误的单词,代码如下:

from only_words import onlyTheWords
import sys
WORDS_FILE = "../Data/words.txt"
if len(sys.argv) != 2:
    print("One command line argument must be provided.")
    print("Quitting...")
    quit()
try:
    inf = open(sys.argv[1], "r")
except:
    print("Failed to open ’%s’ for reading. Quitting..." % sys.argv[1])
    quit()
valid = {}
words_file = open(WORDS_FILE, "r")
for word in words_file:
    word = word.lower().rstrip()
    valid[word] = 0
words_file.close()
misspelled = []
for line in inf:
    words = onlyTheWords(line)
    for word in words:
        if word.lower() not in valid and word not in misspelled:
            misspelled.append(word)
inf.close()
if len(misspelled) == 0:
    print("No words were misspelled.")
else:
    print("The following words are misspelled:")
    for word in misspelled:
        print(" ", word)

操作步骤:
1. 检查命令行参数是否只包含一个文件名。
2. 尝试打开要检查的文件。若打开失败,显示错误信息并退出。
3. 从字典文件中读取所有有效单词,存储在字典中。
4. 逐行读取要检查的文件,去除标点符号,检查每个单词是否拼写错误。
5. 将拼写错误的单词添加到列表中。
6. 关闭文件。
7. 若没有拼写错误的单词,显示相应信息;否则,显示所有拼写错误的单词。

9. 文件内容脱敏

对文本文件进行脱敏处理,移除所有敏感词,将脱敏后的文本写入新文件,代码如下:

inf_name = input("Enter the name of the text file to redact: ")
inf = open(inf_name, "r")
sen_name = input("Enter the name of the sensitive words file: ")
sen = open(sen_name, "r")
words = []
line = sen.readline()
while line != "":
    line = line.rstrip()
    words.append(line)
    line = sen.readline()
sen.close()
outf_name = input("Enter the name for the new redacted file: ")
outf = open(outf_name, "w")
line = inf.readline()
while line != "":
    for word in words:
        line = line.replace(word, "*" * len(word))
    outf.write(line)
    line = inf.readline()
inf.close()
outf.close()

操作步骤:
1. 读取要脱敏的文本文件名并打开文件。
2. 读取敏感词文件名并打开文件,将所有敏感词存储在列表中。
3. 关闭敏感词文件。
4. 读取输出文件名并打开输出文件。
5. 逐行读取要脱敏的文件,将所有敏感词替换为相应数量的星号。
6. 将修改后的行写入输出文件。
7. 关闭输入和输出文件。

10. 查找缺少注释的函数

查找Python文件中没有紧跟注释的函数名,代码如下:

from sys import argv
if len(argv) == 1:
    print("At least one filename must be provided as a command line argument.")
    print("Quitting...")
    quit()
for fname in argv[1 : len(argv)]:
    try:
        inf = open(fname, "r")
        prev = " "
        lnum = 1
        for line in inf:
            if line.startswith("def ") and prev[0] != "#":
                bracket_pos = line.index("(")
                name = line[4 : bracket_pos]
                print("%s line %d: %s" % (fname, lnum, name))
            prev = line
            lnum = lnum + 1
        inf.close()
    except:
        print("A problem was encountered with file ’%s’." % fname)
        print("Moving on to the next file...")

操作步骤:
1. 检查是否提供了至少一个文件名。
2. 遍历所有文件名,尝试打开文件。
3. 逐行读取文件,记录上一行内容和行号。
4. 若当前行是函数定义且上一行不是注释,提取函数名并显示相关信息。
5. 保存当前行并更新行号。
6. 关闭文件。若出现异常,显示错误信息并继续处理下一个文件。

下面是一个简单的流程图,展示了显示文件头部的流程:

graph TD;
    A[开始] --> B[检查命令行参数];
    B -- 参数错误 --> C[显示错误信息并退出];
    B -- 参数正确 --> D[尝试打开文件];
    D -- 打开失败 --> C;
    D -- 打开成功 --> E[逐行读取文件];
    E -- 读取行数小于10且未到文件末尾 --> F[显示当前行];
    F --> E;
    E -- 读取行数达到10或到文件末尾 --> G[关闭文件];
    G --> H[结束];

以上就是这些Python编程问题的详细解决方案,希望对大家有所帮助。在实际应用中,可以根据具体需求对代码进行调整和优化。

Python编程:文件、异常与递归问题的解决方案

11. 递归求和

计算用户输入数字的总和,用户输入空行表示结束输入,代码如下:

def readAndTotal():
    line = input("Enter a number (blank to quit): ")
    if line == "":
        return 0
    else:
        return float(line) + readAndTotal()

def main():
    total = readAndTotal()
    print("The total of all those values is", total)

main()

操作步骤:
1. 定义 readAndTotal 函数,在函数内部读取用户输入。
2. 若用户输入为空行,返回 0 作为基本情况。
3. 若输入不为空行,将输入转换为数字并与递归调用 readAndTotal 函数的结果相加。
4. 在 main 函数中调用 readAndTotal 函数得到总和并显示。

12. 递归判断回文串

判断用户输入的字符串是否为回文串,代码如下:

def isPalindrome(s):
    if len(s) <= 1:
        return True
    return s[0] == s[len(s) - 1] and isPalindrome(s[1 : len(s) - 1])

def main():
    line = input("Enter a string: ")
    if isPalindrome(line):
        print("That was a palindrome!")
    else:
        print("That is not a palindrome.")

main()

操作步骤:
1. 定义 isPalindrome 函数,若字符串长度小于等于 1,返回 True 作为基本情况。
2. 若字符串长度大于 1,检查首尾字符是否相等,若相等则递归调用 isPalindrome 函数检查去掉首尾字符后的子串。
3. 在 main 函数中读取用户输入的字符串,调用 isPalindrome 函数进行判断并显示结果。

13. 计算字符串编辑距离

计算两个字符串之间的编辑距离,编辑距离是将一个字符串转换为另一个字符串所需的最少插入、删除和替换操作次数,代码如下:

def editDistance(s, t):
    if len(s) == 0:
        return len(t)
    elif len(t) == 0:
        return len(s)
    else:
        cost = 0
        if s[len(s) - 1] != t[len(t) - 1]:
            cost = 1
        d1 = editDistance(s[0 : len(s) - 1], t) + 1
        d2 = editDistance(s, t[0 : len(t) - 1]) + 1
        d3 = editDistance(s[0 : len(s) - 1] , t[0 : len(t) - 1]) + cost
        return min(d1, d2, d3)

def main():
    s1 = input("Enter a string: ")
    s2 = input("Enter another string: ")
    print("The edit distance between %s and %s is %d." % (s1, s2, editDistance(s1, s2)))

main()

操作步骤:
1. 定义 editDistance 函数,若其中一个字符串为空,编辑距离为另一个字符串的长度。
2. 若两个字符串都不为空,检查最后一个字符是否相等,若不相等则 cost 设为 1。
3. 递归计算三种可能的编辑距离(删除、插入、替换)。
4. 返回三种距离中的最小值。
5. 在 main 函数中读取用户输入的两个字符串,调用 editDistance 函数计算编辑距离并显示结果。

14. 查找元素最长序列

找出以用户输入元素开头的最长元素序列,序列中每个元素的首字母与前一个元素的尾字母相同,代码如下:

ELEMENTS_FNAME = "../Data/Elements.csv"

def longestSequence(start, words):
    if start == "":
        return []
    best = []
    last_letter = start[len(start) - 1].lower()
    for i in range(0, len(words)):
        first_letter = words[i][0].lower()
        if first_letter == last_letter:
            candidate = longestSequence(words[i], words[0 : i] + words[i + 1 : len(words)])
            if len(candidate) > len(best):
                best = candidate
    return [start] + best

def loadNames():
    names = []
    inf = open(ELEMENTS_FNAME, "r")
    for line in inf:
        line = line.rstrip()
        parts = line.split(",")
        names.append(parts[2])
    inf.close()
    return names

def main():
    names = loadNames()
    start = input("Enter the name of an element: ")
    start = start.capitalize()
    if start in names:
        names.remove(start)
        sequence = longestSequence(start, names)
        print("A longest sequence that starts with", start, "is:")
        for element in sequence:
            print(" ", element)
    else:
        print("Sorry, that wasn’t a valid element name.")

main()

操作步骤:
1. 定义 loadNames 函数,从文件中读取所有元素名称并存储在列表中。
2. 定义 longestSequence 函数,若起始元素为空,返回空列表作为基本情况。
3. 遍历所有元素,若元素首字母与起始元素尾字母相同,递归调用 longestSequence 函数查找以该元素开头的最长序列。
4. 选择最长的候选序列并返回,将起始元素添加到序列开头。
5. 在 main 函数中调用 loadNames 函数加载元素名称,读取用户输入的起始元素。
6. 若输入元素有效,从列表中移除该元素,调用 longestSequence 函数查找最长序列并显示。
7. 若输入元素无效,显示错误信息。

15. 递归扁平化列表

使用递归将可能包含嵌套列表的列表扁平化,代码如下:

def flatten(data):
    if data == []:
        return []
    if type(data[0]) == list:
        return flatten(data[0]) + flatten(data[1:])
    else:
        return [data[0]] + flatten(data[1:])

def main():
    print(flatten([1, [2, 3], [4, [5, [6, 7]]], [[[8], 9], [10]]]))
    print(flatten([1, [2, [3, [4, [5, [6, [7, [8, [9, [10]]]]]]]]]]))
    print(flatten([[[[[[[[[[1], 2], 3], 4], 5], 6], 7], 8], 9], 10]))
    print(flatten([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]))
    print(flatten([]))

main()

操作步骤:
1. 定义 flatten 函数,若列表为空,返回空列表作为基本情况。
2. 若列表第一个元素是列表,递归调用 flatten 函数将第一个元素和剩余元素分别扁平化并合并。
3. 若列表第一个元素不是列表,将第一个元素添加到递归调用 flatten 函数处理剩余元素的结果前面。
4. 在 main 函数中调用 flatten 函数对不同的嵌套列表进行测试并打印结果。

16. 递归游程编码

对字符串或列表进行游程编码,代码如下:

def encode(data):
    if len(data) == 0:
        return []
    index = 1
    while index < len(data) and data[index] == data[index - 1]:
        index = index + 1
    current = [data[0], index]
    return current + encode(data[index : len(data)])

def main():
    s = input("Enter some characters: ")
    print("When those characters are run-length encoded, the result is:", encode(s))

main()

操作步骤:
1. 定义 encode 函数,若输入为空,返回空列表作为基本情况。
2. 找到第一个与第一个元素不同的元素的索引。
3. 将第一个元素和其连续出现的次数作为当前编码项。
4. 递归调用 encode 函数处理剩余元素并将结果与当前编码项合并。
5. 在 main 函数中读取用户输入的字符串,调用 encode 函数进行游程编码并显示结果。

下面是一个简单的流程图,展示了递归判断回文串的流程:

graph TD;
    A[开始] --> B[输入字符串];
    B --> C[判断字符串长度是否小于等于1];
    C -- 是 --> D[返回True];
    C -- 否 --> E[检查首尾字符是否相等];
    E -- 否 --> F[返回False];
    E -- 是 --> G[递归调用判断子串];
    G --> C;
    D --> H[结束];
    F --> H;

为了更清晰地对比这些不同的功能,下面给出一个简单的表格:
| 功能 | 关键函数 | 主要操作 |
| ---- | ---- | ---- |
| 递归求和 | readAndTotal | 递归读取用户输入并累加 |
| 递归判断回文串 | isPalindrome | 递归检查字符串首尾字符并处理子串 |
| 计算字符串编辑距离 | editDistance | 递归计算三种编辑操作的最小距离 |
| 查找元素最长序列 | longestSequence | 递归查找以元素开头的最长序列 |
| 递归扁平化列表 | flatten | 递归处理嵌套列表 |
| 递归游程编码 | encode | 递归处理字符串或列表进行编码 |

通过以上这些解决方案,我们可以看到递归在解决复杂问题时的强大能力。同时,文件操作和异常处理也为我们处理数据和应对各种情况提供了有效的手段。在实际编程中,我们可以根据具体需求灵活运用这些方法,提高代码的效率和健壮性。希望这些内容能帮助大家更好地掌握 Python 编程中的文件、异常和递归相关知识。

【电能质量扰动】基于ML和DWT的电能质量扰动分类方法研究(Matlab实现)内容概要:本文研究了一种基于机器学习(ML)和离散小波变换(DWT)的电能质量扰动分类方法,并提供了Matlab实现方案。首先利用DWT对电能质量信号进行多尺度分解,提取信号的时频域特征,有效捕捉电压暂降、暂升、中断、谐波、闪变等常见扰动的关键信息;随后结合机器学习分类器(如SVM、BP神经网络等)对提取的特征进行训练分类,实现对不同类型扰动的自动识别准确区分。该方法充分发挥DWT在信号去噪特征提取方面的优势,结合ML强大的模式识别能力,提升了分类精度鲁棒性,具有较强的实用价值。; 适合人群:电气工程、自动化、电力系统及其自动化等相关专业的研究生、科研人员及从事电能质量监测分析的工程技术人员;具备一定的信号处理基础和Matlab编程能力者更佳。; 使用场景及目标:①应用于智能电网中的电能质量在线监测系统,实现扰动类型的自动识别;②作为高校或科研机构在信号处理、模式识别、电力系统分析等课程的教学案例或科研实验平台;③目标是提高电能质量扰动分类的准确性效率,为后续的电能治理设备保护提供决策依据。; 阅读建议:建议读者结合Matlab代码深入理解DWT的实现过程特征提取步骤,重点关注小波基选择、分解层数设定及特征向量构造对分类性能的影响,并尝试对比不同机器学习模型的分类效果,以全面掌握该方法的核心技术要点。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值