[Python语言程序设计]Python 课程作业

Spring-_-Bear 的 CSDN 博客导航

第 1 章 Python 基础

1.1 日期打印

将输入的年、月(1~12)、日(1~31)按照指定的日期格式打印出来。

输入样例:
Year:1989
Month(1-12):08
Day(1-31):16
输出样例:
August 16th,1989

程序源码:

year = input('Year:')
month = int(input('Month(1-12):'))
day = int(input('Day(1-31):'))

# 使用列表存储每个月份的英文、每天对应的英文后缀
months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
day_suffixes = ['st', 'nd', 'rd'] + 17 * ['th'] + ['st', 'nd', 'rd'] + 7 * ['th'] + ['st']

month_str = months[month - 1]
day_str = str(day) + day_suffixes[day - 1]

print(month_str + ' ' + day_str + ',' + year)

运行示例:

在这里插入图片描述

1.2 姓名打印

将用户输入的姓名存到一个变量中,并向该用户显示一条消息。显示的消息应非常简单,如下:

“Hello Eric, would you like to learn some Python today?”

程序源码:

name = input('Please input your name:')
print('Hello ' + name + ', would your like to learn some Python today?')

运行示例:

在这里插入图片描述

1.3 字母大小写

调整名字的大小写:将一个人名存储到一个变量中,再以小写、大写和首字母大写的方式显示这个人名。

程序源码:

name = input('Please input your name:')
print(name.lower() + ', welcome! Do you like Python?')
print(name.upper() + ', welcome! Do you like Python?')
print(name.capitalize() + ', welcome! Do you like Python')

运行示例:

在这里插入图片描述

1.4 名人名言打印

名言 1:找一句你钦佩的名人说的名言,将这个名人的姓名和他的名言打印出来。输出应类似于下面这样(包括引号):

Albert Einstein once said, “A person who never made a mistake never tried anything new.”

程序源码:

print('Albert Einstein once said, "A person who never made a mistake never tried anything new."')

运行示例:

在这里插入图片描述

名言 2:重复练习 4,但将名人的姓名存储在变量 famous_person 中,再创建要显示的消息,并将其存储在变量 message 中,然后打印这条消息。

程序源码:

famous_person = 'Albert Einstein'
message = '"A person who never made a mistake never tried anything new."'
print(famous_person + ' once said, ' + message)

运行示例:

在这里插入图片描述

1.5 字符串祛除空白

剔除人名中的空白:存储一个人名,并在其开头和末尾都包含一些空白字符。务必至少使用字符组合 “\t” 和 “\n” 各一次。打印这个人名,以显示其开头和末尾的空白。然后,分别使用剔除函数 lstrip()、 rstrip() 和 strip() 对人名进行处理,并将结果打印出来。

程序源码:

name = '\n    \tS\t  pr \t \n\n\t   ing\n  \t -_- \n\t Bea\n r\n \t   '
print('------------- origin -------------')
print(name)
print('------------- lstrip -------------')
print(name.lstrip())
print('------------- rstrip -------------')
print(name.rstrip())
print('------------- strip -------------')
print(name.strip())
print('------------ replace ------------')
print(name.replace('\n', '').replace('\r', '').replace('\t', '').replace(' ', ''))

运行示例:

在这里插入图片描述

1.6 整数逆序不重复打印

输入一个 int 型整数,按照从右向左的阅读顺序,返回一个不含重复数字的新的整数。

程序源码:

number_str = input('Please input a number:')
# 将输入的数字字符串反转后放入列表中
number_list = list(reversed(number_str))
# 遍历 number_list,将不重复元素添加到 result_number_list 中
result_number_list = []
for num in number_list:
    if num not in result_number_list:
        result_number_list.append(num)
# 拼接 result_number_list 列表的每一个元素,并打印最终结果
print(''.join(result_number_list))

运行示例:

在这里插入图片描述

1.7 字典重复数据合并

数据表记录包含表索引和数值,请对表索引相同的记录进行合并,即将相同索引的数值进行求和运算。输出按照 key 值升序进行输出。

程序源码:

counts = int(input('Please input the number of the key-value group:'))
not_repeated_map = {}
for i in range(counts):
    key, value = input().split(' ')
    key = int(key)
    value = int(value)
    if key in not_repeated_map:
        # key 相同时合并 value
        not_repeated_map[key] += value
    else:
        # key 和 value 直接存入字典中
        not_repeated_map[key] = value

print('----- after merged -----')
print(not_repeated_map)

运行示例:

在这里插入图片描述

1.8 字符串拆分

连续输入字符串,请按长度为 8 拆分每个字符串后输出到新的字符串数组;长度不是 8 整数倍的字符串请在后面补数字 0,空字符串不处理。

程序源码:

content = input('Please input a string:')
str_length = len(content)
# 字符串长度不是 8 的整数倍时补 0 凑整
if str_length % 8 != 0:
    content += '0' * (8 - str_length % 8)
while len(content) != 0:
    print(content[:8])
    content = content[8:]

运行示例:

在这里插入图片描述

1.9 字符统计

输入一个字符串,对字符中的各个英文字符,数字,空格进行统计(可反复调用)按照统计个数由多到少输出统计结果,如果统计的个数相同,则按照 ASCII 码由小到大排序输出。

程序源码:

content = input('Please input a string:')
char_count_dict = {}
for char in content:
    if char.isalnum() or char.isspace():
        # 将字符添加到字典中并更新计数
        char_count_dict[char] = char_count_dict.get(char, 0) + 1

# 对字符进行排序,首先按照计数值降序排序,然后按照 ASCII 码升序排序
sorted_chars = sorted(char_count_dict.items(), key=lambda x: (-x[1], ord(x[0])))
for char, count in sorted_chars:
    print(f"{char}: {count}")

运行示例:

在这里插入图片描述

1.10 最长数字子串

在字符串中找出连续最长的数字字符串。

输入:一个字符串

输出:字符串中最长的数字字符串和它的长度。如果有相同长度的串,则要一块儿输出

程序源码:

import re

input_string = input('Please input a string:')
# 使用正则表达式找出字符串中的所有数字串
numbers = re.findall(r'\d+', input_string)
# 找到最长的数字字符串
longest_number_string = max(numbers, key=len)
longest_number_length = len(longest_number_string)
# 找到与最长数字字符串长度相同的所有数字字符串
longest_number_strings = [num for num in numbers if len(num) == longest_number_length]
print("最长的数字字符串:", longest_number_strings)
print("最长数字字符串的长度:", longest_number_length)

运行示例:

在这里插入图片描述

1.11 最少次数字符删除

实现删除字符串中出现次数最少的字符,若多个字符出现次数一样,则都删除。输出删除这些单词后的字符串,字符串中其它字符保持原来的顺序。

程序源码:

from collections import Counter

input_string = input('Please input a string:')
# 统计字符出现的次数
counter = Counter(input_string)
# 获取最小的字符出现次数
min_frequency = min(counter.values())
# 移除出现次数最少的字符
result = ''.join(char for char in input_string if counter[char] > min_frequency)
print(result)

运行示例:

在这里插入图片描述

1.12 字符统计

输入一行字符,分别统计出包含英文字母、空格、数字和其它字符的个数。

程序源码:

input_string = input("Please input a string:")
letter = 0
digit = 0
space = 0
other = 0
index = 0

while index < len(input_string):
    ch = input_string[index]
    if ch.isalpha():
        letter += 1
    elif ch.isdigit():
        digit += 1
    elif ch.isspace():
        space += 1
    else:
        other += 1
    index += 1

print('letter = %d, space = %d, digit = %d, other = %d' % (letter, space, digit, other))

运行示例:

在这里插入图片描述

第 2 章 文件 IO

2.1 CSV 文件写入

创建一个 CSV 文件,文件名自取。采用字典读写的方法在文件中写入以下内容:

在这里插入图片描述

程序源码:

import csv

with open('out.csv', 'w', newline='') as file:
    # 写入表头
    writer = csv.DictWriter(file, fieldnames=('first_name', 'last_name', 'result'))
    writer.writeheader()
    # 写入内容
    writer.writerow({'first_name': 'John', 'last_name': 'Smith', 'result': '54'})
    writer.writerow({'first_name': 'Jane', 'last_name': 'Lewis', 'result': '63'})
    writer.writerow({'first_name': 'Chris', 'last_name': 'Davies', 'result': '72'})
file.close()

# 读取文件内容并在控制台打印
with open('out.csv', 'r') as file:
    reader = csv.DictReader(file, fieldnames=('first_name', 'last_name', 'result',))
    for row in reader:
        print(row)
file.close()

运行示例:

在这里插入图片描述

2.2 银行交易模拟类 Account

在本练习中,你将创建一个 CSV 文件反映在活期存款账户上的一系列交易事务,最后把交易列表写进一个 Excel 文件。

  1. 首先定义一个新的 Account 类来表示一种银行帐户类型。
  2. 当类被实例化时,您应该提供帐号、账户持有人名称、初期余额和账户类型(可以是 “活期”、“存款” 或 “投资” 等的字符串)。
  3. 为账户提供三种实例方法;存钱(金额),取钱(金额)和余额()。
  4. Account 类还应该保存它所涉及的事务的历史记录。
  5. 一次交易事务是存款或取款的记录,帐户中的初始金额可以视为初始存款。

提示:历史记录可以实现为一个列表,包含一个有序的序列。交易事务可以被类定义为存钱或取钱方法及其金额,每次存钱取钱的就是一次新的交易事务被放进交易历史列表。最后文件打开后形式如下图:

在这里插入图片描述

程序源码:

import csv

csv_file = 'transactions.csv'


class Account:
    def __init__(self, account_number, username, balance, account_type):
        self.account_number = account_number
        self.username = username
        self.balance = balance
        self.account_type = account_type

    # 存款方法
    def deposit(self, money):
        # 增加当前账户的余额
        new_balance = float(self.balance) + float(money)
        self.balance = str(round(new_balance, 2))
        # 保存存款记录
        with open(csv_file, 'a+', newline='') as file:
            writer = csv.writer(file)
            writer.writerow(['deposit', self.balance])
        file.close()

    # 取款方法
    def withdraw(self, money):
        # 减少当前账户的余额
        new_balance = float(self.balance) - float(money)
        self.balance = str(round(new_balance, 2))
        # 保存取款记录
        with open(csv_file, 'a+', newline='') as file:
            writer = csv.writer(file)
            writer.writerow(['withdraw', self.balance])
        file.close()

    # 查询余额
    def print_balance(self):
        print('您的账户余额为 ' + self.balance + ' 元')


if __name__ == '__main__':
    # 初始化新银行账户信息
    input_number = input('请输入您的银行卡号:')
    input_username = input('请输入卡持有人姓名:')
    input_balance = float(input('请输入账户初始余额:'))
    input_type = input('请输入账户类型[活期 | 存款 | 投资]:')
    account = Account(input_number, input_username, input_balance, input_type)

    while True:
        # 打印操作菜单
        print('----- 银行账户交易系统 -----')
        print('[1]存款')
        print('[2]取款')
        print('[3]余额')
        print('[0]退出')
        choice = input('请选择您要办理的业务:')

        if choice == '0':
            break
        elif choice == '1':
            input_money = input('请输入存款金额:')
            account.deposit(input_money)
            print('存款成功!存入 ' + input_money + ' 元,余额 ' + account.balance + ' 元')
        elif choice == '2':
            input_money = input('请输入取款金额:')
            account.withdraw(input_money)
            print('取款成功!取出 ' + input_money + ' 元,余额 ' + account.balance + ' 元')
        elif choice == '3':
            account.print_balance()
        else:
            print('您的输入有误!')
            continue

运行示例:

在这里插入图片描述

2.3 股票文件记录查询

编写程序对 stock_data.txt 实现以下操作:

  1. 程序启动后,给⽤户提供查询接⼝,允许⽤户反复查询股票⾏情信息(⽤到循环) 。
  2. 允许⽤户通过模糊查询股票名,⽐如输⼊“啤酒”,就把所有股票名称中包含 “啤酒” 的信息打印出来。
  3. 允许按股票价格、涨跌幅、换⼿率这⼏列来筛选信息,⽐如输⼊ “价格 > 50” 则把价格⼤于 50 的股票都打印,输⼊ “市盈率 < 50“,则把市盈率⼩于 50 的股票都打印,不⽤判断等于。

stock_data.txt 的文件内容如下:

股票代码,股票名称,当前价,涨跌额,涨跌幅,年初至今,成交量,成交额,换手率,市盈率TTM,股息率,市值
SH601778,N晶科,6.29,+1.92,+43.94%,+43.94%,259.66万,1625.52万,0.44%,22.32,-,173.95亿
SH688566,吉贝尔,52.66,+6.96,+15.23%,+122.29%,1626.58万,8.09亿,42.29%,89.34,-,98.44亿
SH688268,华特气体,88.80,+11.72,+15.20%,+102.51%,622.60万,5.13亿,22.87%,150.47,-,106.56亿
SH600734,实达集团,2.60,+0.24,+10.17%,-61.71%,1340.27万,3391.14万,2.58%,亏 损,0.00%,16.18亿
SH900957,凌云B股,0.36,+0.033,+10.09%,-35.25%,119.15万,42.10万,0.65%,44.65,0.00%,1.26亿
SZ000584,哈工智能,6.01,+0.55,+10.07%,-4.15%,2610.86万,1.53亿,4.36%,199.33,0.26%,36.86亿
SH600599,熊猫金控,6.78,+0.62,+10.06%,-35.55%,599.64万,3900.23万,3.61%,亏 损,0.00%,11.25亿
SH600520,文一科技,8.21,+0.75,+10.05%,-24.05%,552.34万,4464.69万,3.49%,亏 损,0.00%,13.01亿
SH603682,锦和商业,11.73,+1.07,+10.04%,+48.29%,2746.63万,3.15亿,29.06%,29.62,-,55.42亿
SZ300831,派瑞股份,12.27,+1.12,+10.04%,+208.29%,25.38万,311.41万,0.32%,60.59,-,39.26亿
SH900939,汇丽B,0.504,+0.046,+10.04%,-23.52%,123.86万,61.86万,1.41%,52.80,0.00%,9147.60万
SH600880,博瑞传播,4.39,+0.40,+10.03%,+10.03%,1117.75万,4816.57万,1.02%,95.87,0.50%,48.00亿
SZ000609,中迪投资,7.68,+0.70,+10.03%,+39.64%,2663.08万,2.00亿,9.12%,58.84,0.00%,22.98亿
SZ300328,宜安科技,15.80,+1.44,+10.03%,+7.19%,432.45万,6832.68万,0.95%,64.80,0.51%,72.72亿
SZ002988,豪美新材,17.33,+1.58,+10.03%,+58.41%,3.50万,60.68万,0.06%,24.42,-,40.34亿
SZ000615,京汉股份,4.61,+0.42,+10.02%,+4.06%,518.09万,2388.41万,0.69%,亏 损,0.00%,36.06亿
SZ300443,金雷股份,18.33,+1.67,+10.02%,+32.74%,987.25万,1.75亿,6.19%,18.78,1.08%,43.64亿
SH600506,香梨股份,11.42,+1.04,+10.02%,+11.96%,1039.48万,1.18亿,7.04%,亏 损,0.00%,16.87亿
SZ300505,川金诺,15.61,+1.42,+10.01%,-11.26%,493.54万,7555.40万,6.03%,26.70,0.85%,20.40亿
SZ300830,金现代,14.95,+1.36,+10.01%,+239.77%,63.66万,951.76万,0.74%,70.76,0.00%,64.30亿
SH603630,拉芳家化,17.26,+1.57,+10.01%,+27.85%,949.49万,1.60亿,4.19%,209.44,0.83%,39.13亿
SZ002655,共达电声,11.43,+1.04,+10.01%,-14.64%,1683.51万,1.88亿,4.68%,166.69,0.00%,41.15亿
SZ300460,惠伦晶体,16.59,+1.51,+10.01%,+0.97%,430.28万,6974.52万,2.56%,亏 损,0.00%,27.92亿
SH603929,亚翔集成,20.33,+1.85,+10.01%,+33.40%,1373.66万,2.76亿,6.44%,84.29,1.25%,43.38亿
SH603392,万泰生物,35.97,+3.27,+10.00%,+311.09%,6.92万,248.91万,0.16%,65.24,-,155.97亿
SZ000788,北大医药,6.82,+0.62,+10.00%,+2.40%,832.44万,5583.87万,1.40%,89.69,0.32%,40.65亿
SH601609,金田铜业,10.89,+0.99,+10.00%,+66.26%,4027.64万,4.28亿,16.64%,32.38,0.32%,158.66亿
SZ000403,双林⽣物,52.48,+4.77,+10.00%,+62.48%,171.75万,9013.54万,0.63%,88.80,0.23%,143.05亿
SZ300832,新产业,72.80,+6.62,+10.00%,+131.92%,10.73万,780.85万,0.26%,40.20,0.62%,299.64亿
SZ002985,北摩⾼科,92.58,+8.42,+10.00%,+310.92%,2422.97万,21.55亿,64.54%,60.48,1.08%,139.02亿
SH603348,⽂灿股份,18.06,+1.64,+9.99%,-25.15%,357.86万,6328.87万,4.39%,89.39,0.89%,41.83亿
SH603900,莱绅通灵,8.92,+0.81,+9.99%,-5.61%,1364.10万,1.15亿,4.01%,43.78,5.06%,30.37亿
SH603042,华脉科技,17.85,+1.62,+9.98%,+17.05%,491.44万,8705.99万,4.86%,128.50,0.31%,24.28亿
SZ300260,新莱应材,19.83,+1.80,+9.98%,+68.48%,1800.45万,3.48亿,14.16%,65.15,0.73%,40.04亿
SZ000557,⻄部创业,3.42,+0.31,+9.97%,-0.87%,2751.17万,9408.89万,1.89%,79.39,0.00%,49.88亿
SZ300716,国⽴科技,9.94,+0.90,+9.96%,-4.24%,142.25万,1413.92万,1.50%,亏 损,0.29%,15.91亿
SZ002449,国星光电,11.92,+1.08,+9.96%,-6.80%,5185.52万,6.03亿,8.53%,21.51,2.73%,73.72亿
SZ002397,梦洁股份,8.50,+0.77,+9.96%,+73.47%,810.06万,6885.51万,1.67%,110.68,2.35%,64.95亿
SZ002662,京威股份,4.09,+0.37,+9.95%,+54.92%,8588.12万,3.40亿,5.89%,亏 损,0.00%,61.35亿
SZ002297,博云新材,6.30,+0.57,+9.95%,-1.87%,2852.27万,1.74亿,6.07%,亏 损,0.00%,29.69亿
SZ300351,永贵电器,8.62,+0.78,+9.95%,-2.16%,1443.26万,1.23亿,5.89%,亏 损,0.00%,33.07亿
SH600834,申通地铁,7.63,+0.69,+9.94%,+5.68%,223.20万,1703.02万,0.47%,74.74,0.56%,36.42亿
SZ000616,海航投资,3.10,+0.28,+9.93%,+27.57%,5002.95万,1.51亿,3.50%,133.28,0.00%,44.34亿
SH600662,强⽣控股,5.54,+0.50,+9.92%,+22.03%,254.89万,1412.07万,0.24%,亏 损,0.72%,58.36亿
SZ300223,北京君正,107.20,+8.92,+9.08%,+23.01%,930.81万,9.86亿,7.34%,314.71,0.00%,216.28亿
SZ002978,安宁股份,35.46,+2.95,+9.07%,+29.09%,1181.96万,4.11亿,29.10%,25.11,-,142.31亿
SZ002084,海鸥住⼯,7.09,+0.54,+8.24%,+9.24%,1647.83万,1.16亿,3.36%,33.83,0.00%,35.60亿
SH688012,中微公司,229.00,+17.30,+8.17%,+147.84%,448.32万,10.05亿,8.72%,607.21,-,1224.83亿
SZ002049,紫光国微,74.04,+5.54,+8.09%,+45.63%,4459.03万,32.57亿,7.35%,85.03,0.10%,449.29亿
SH600329,中新药业,14.83,+1.10,+8.01%,+7.00%,1159.16万,1.68亿,2.05%,18.90,2.16%,114.61亿
SZ002204,⼤连᯿⼯,5.71,+0.41,+7.74%,+77.88%,1.73亿,9.35亿,8.97%,213.83,0.55%,110.28亿
SH688088,虹软科技,84.16,+5.96,+7.62%,+78.12%,290.59万,2.43亿,7.22%,148.96,-,341.69亿
SZ300398,⻜凯材料,21.33,+1.50,+7.56%,+42.68%,2676.82万,5.65亿,6.21%,47.18,0.00%,110.41亿
SZ300298,三诺⽣物,21.93,+1.53,+7.50%,+48.45%,832.56万,1.80亿,1.89%,46.66,1.44%,123.97亿
SH603236,移远通信,235.40,+16.09,+7.34%,+61.34%,96.10万,2.22亿,4.31%,151.64,0.22%,209.93亿
SZ002074,国轩⾼科,26.93,+1.79,+7.12%,+85.09%,3628.58万,9.54亿,3.60%,亏 损,0.00%,304.25亿
SZ000710,⻉瑞基因,51.27,+3.37,+7.04%,+40.08%,411.57万,2.09亿,2.91%,63.69,0.00%,181.81亿
SZ300624,万兴科技,95.86,+6.28,+7.01%,+51.92%,374.27万,3.54亿,7.52%,84.07,0.38%,77.91亿
SZ300002,神州泰岳,6.42,+0.41,+6.82%,+96.93%,9118.57万,5.66亿,5.59%,亏 损,0.00%,126.10亿
SH603012,创⼒集团,7.30,+0.46,+6.73%,-18.16%,2648.28万,1.92亿,4.16%,15.57,1.01%,46.47亿
SZ300144,宋城演艺,31.70,+1.98,+6.66%,+2.56%,980.92万,3.08亿,0.82%,45.22,0.66%,460.77亿
SZ300724,捷佳伟创,67.58,+4.18,+6.59%,+78.36%,223.02万,1.48亿,1.31%,57.75,0.28%,216.70亿
SZ200706,瓦轴B,2.27,+0.14,+6.57%,-21.99%,25.88万,57.83万,0.16%,亏损,0.00%,9.18亿
SH603693,江苏新能,12.10,+0.74,+6.51%,+18.86%,2377.38万,2.87亿,12.32%,19.47,1.32%,74.78亿
SZ200468,宁通信B,1.82,+0.11,+6.43%,-26.32%,53.22万,96.40万,0.53%,亏损,0.00%,3.89亿
SH600426,华鲁恒升,18.11,+1.09,+6.40%,-8.86%,1369.76万,2.46亿,0.85%,13.16,2.05%,294.59亿
SH900953,凯⻢B,0.334,+0.020,+6.37%,-30.13%,186.93万,63.29万,0.78%,236.41,0.00%,2.14亿
SH600703,三安光电,25.15,+1.50,+6.34%,+36.98%,1.08亿,26.73亿,2.65%,95.77,0.42%,1025.72亿
SZ300118,东⽅⽇升,12.75,+0.74,+6.16%,-7.94%,3686.23万,4.68亿,5.29%,13.57,1.63%,114.92亿
SZ300418,昆仑万维,22.25,+1.29,+6.15%,+32.84%,3641.22万,8.00亿,4.03%,18.07,0.12%,257.36亿
SH900929,锦旅B股,1.214,+0.070,+6.12%,-25.52%,36.05万,43.02万,0.55%,19.81,0.00%,1.61亿
SZ300496,中科创达,60.79,+3.49,+6.09%,+34.99%,1062.96万,6.40亿,3.75%,96.33,0.22%,244.69亿
SH600818,中路股份,12.36,+0.71,+6.09%,+3.69%,921.26万,1.15亿,3.87%,亏 损,0.00%,39.73亿
SZ300644,南京聚隆,35.19,+2.01,+6.06%,+18.64%,872.06万,3.12亿,21.10%,79.62,0.55%,22.53亿
SZ300729,乐歌股份,24.18,+1.38,+6.05%,+3.50%,204.82万,4889.15万,8.14%,31.62,1.31%,21.09亿
SZ300767,震安科技,108.58,+6.16,+6.01%,+79.44%,146.41万,1.57亿,3.19%,92.38,0.21%,86.86亿
SH603179,DR新泉股,19.30,+1.08,+5.93%,+35.50%,147.38万,2833.24万,0.65%,35.11,2.25%,56.76亿
SH603626,科森科技,11.27,+0.63,+5.92%,+8.47%,466.11万,5187.87万,1.01%,亏 损,0.00%,53.30亿
SZ300019,硅宝科技,9.50,+0.53,+5.91%,-6.13%,423.46万,3943.10万,1.55%,24.58,1.65%,31.40亿
SZ002756,永兴材料,16.18,+0.90,+5.89%,-7.34%,247.83万,3910.01万,1.34%,18.38,2.98%,58.21亿
SZ002498,汉缆股份,6.11,+0.34,+5.89%,+102.99%,2.01亿,12.04亿,6.05%,43.98,0.62%,202.93亿
SZ002980,华盛昌,62.41,+3.46,+5.87%,+319.14%,969.65万,5.99亿,29.09%,51.97,-,83.21亿
SZ002371,北⽅华创,176.88,+9.80,+5.87%,+101.00%,1006.35万,17.45亿,2.20%,276.58,0.04%,875.76亿
SZ300139,晓程科技,8.71,+0.48,+5.83%,+0.23%,4423.87万,3.82亿,20.11%,亏 损,0.00%,23.84亿
SZ000636,⻛华⾼科,24.51,+1.33,+5.74%,+64.61%,5605.61万,13.61亿,6.26%,71.71,0.00%,219.42亿
SZ000564,供销⼤集,4.06,+0.22,+5.73%,+69.87%,2.98亿,11.89亿,14.86%,亏 损,0.00%,244.52亿
SZ002612,朗姿股份,7.84,+0.42,+5.66%,-19.34%,540.71万,4191.22万,2.31%,1224.17,4.23%,34.69亿
SH600176,中国巨⽯,9.39,+0.50,+5.62%,-13.85%,3256.19万,3.02亿,0.93%,16.97,2.14%,328.87亿
SH603313,梦百合,24.10,+1.28,+5.61%,+14.16%,356.10万,8446.14万,1.05%,21.72,0.00%,82.23亿
SZ300279,和晶科技,5.49,+0.29,+5.58%,-8.50%,2328.20万,1.31亿,5.33%,亏 损,0.00%,24.65亿

程序源码:

def read_file():
    with open('stock_data.txt', 'r', encoding='utf-8') as file:
        '''
                --------------- 股票标题信息 ---------------
                0. 股票代码 1. 股票名称   2. 当前价  3. 涨跌额
                4. 涨跌幅   5. 年初至今   6. 成交量  7. 成交额
                8. 换手率   9. 市盈率TTM 10. 股息率 11. 市值
        '''
        title = file.readline().strip('\n').split(',')
        rows = []
        for line in file:
            rows.append(line.strip('\n').split(','))
        file.close()
        return title, rows


def search(key, sign, val, title, rows):
    try:
        # 获取 key 在 title 中的列下标
        target_index = title.index(key)
        # [2]当前价 [4]涨跌幅 [8]换手率
        if target_index not in [2, 4, 8]:
            print('当前价 涨跌幅 换手率,请重新输入!')
            return
    except ValueError:
        print('筛选条件不存在,请重新输入!')
        return

    # 处理 “允许按股票价格、涨跌幅、换⼿率这⼏列来筛选信息”
    for row in rows:
        column_value = row[target_index]
        # 去除 column_value 后的 %
        column_value = column_value.replace('%', '')

        # 比较 > 或 <
        if sign == '>':
            if float(column_value) > float(val):
                print(row)
        else:
            if float(column_value) < float(val):
                print(row)


def main():
    title, rows = read_file()
    while True:
        keyword = input('股票查询接口:').strip()
        print(title)

        if '>' in keyword:
            # example: 当前价>20.20 key=当前价 val=20.20
            index = keyword.index('>')
            key = keyword[0:index]
            val = keyword[index + 1:]
            search(key, '>', val, title, rows)
        elif '<' in keyword:
            index = keyword.index('<')
            key = keyword[0:index]
            val = keyword[index + 1:]
            search(key, '<', val, title, rows)
        # 根据【股票名称】模糊查询
        else:
            for row in rows:
                if keyword in row[1]:
                    print(row)


main()

运行示例:

在这里插入图片描述

2.4 保存用户注册信息

编写程序实现将用户信息保存到 register.txt 中,而后进行登录,使用文件中的用户信息来验证用户名密码正确性。
程序源码:

print('----- 用户注册 -----')
username = input('账户:').strip()
password = input('密码:').strip()
with open('register.txt', 'w', encoding='utf8') as file:
    file.write('%s:%s' % (username, password))
file.close()

file = open('register.txt', 'r', encoding='utf8')
name, pwd = file.readline().split(':')
while True:
    print('----- 用户登录 -----')
    username = input('账户:').strip()
    password = input('密码:').strip()
    if name == username and pwd == password:
        print('登录成功!')
        break
    else:
        print('用户名不存在或密码错误')
file.close()

运行示例:

在这里插入图片描述

2.5 用户登录模拟

编写一个程序,当用户输入正确的用户名后,提示用户输入他最喜欢的数字,而后使用 json.dump() 将这个数字存储到文件中。最后从该文件中读取出刚刚存储的数字,并打印消息 “I know your favorite number! It’s _____.”。

程序源码:

import json

username = input('请输入您的用户名:').strip()
if 'Spring-_-Bear' == username:
    # 保存用户最喜欢的数字
    number = input('请输入您最喜欢的数字:')
    with open('user_number.json', 'w', encoding='utf8') as file:
        json.dump(number, file)
    file.close()

    # 读取用户最喜欢的数字
    with open('user_number.json', 'r', encoding='utf8') as file:
        number = json.load(file)
    file.close()
    print("I know your favorite number! It's %s." % number)

运行示例:

在这里插入图片描述

2.6 记住喜欢的数字

将练习 2.5 中的程序合二为一。如果存储了用户喜欢的数字,就向用户显示它,否则提示用户输入他喜欢的数字并将其存储到文件中。运行这个程序两次,看看它是否像预期的那样工作。

程序源码:

import json

try:
    with open('user_number.json', 'r', encoding='utf8') as file:
        number = json.load(file)
    file.close()
except FileNotFoundError:
    number = input('Please input your favorite number:')
    with open('user_number.json', 'w', encoding='utf8') as file:
        json.dump(number, file)
    file.close()
else:
    print("I know your favorite number! It's %s." % number)

运行示例:

在这里插入图片描述

2.7 验证用户

最后一个 remember_me 版本。假设用户要么已输入其用户名,要么是首次运行该程序。我们应修改这个程序,以应对这样的情形:当前和最后一次运行该程序的用户并非同一个人。为此,在 greet_user() 中打印欢迎用户回来的消息前,先询问他用户名是否是对的。如果不对,就调用 get_new_username() 让用户输入正确的用户名。

程序源码:

import json


def get_stored_username():
    try:
        with open('user.json', 'r', encoding='utf8') as file:
            username = json.load(file)
    except IOError:
        return None
    else:
        return username


def get_new_username():
    username = input('Please input your username:')
    with open('user.json', 'w', encoding='utf8') as file:
        json.dump(username, file)
    return username


def greet_user():
    username = get_stored_username()
    if username:
        choice = input('Is the username `%s` right? (y/n):' % username)
        if 'y' == choice:
            print('Welcome back, %s!' % username)
            exit(0)

    # 用户名不存在或不正确,获取新用户名
    username = get_new_username()
    print('We will remember you, %s!' % username)


greet_user()

运行示例:

在这里插入图片描述

第 3 章 函数

3.1 文件内容批量替换

编写函数 file_content_replace(),用户传入修改的文件名,与要修改的内容,执行函数,完成修改操作。

程序源码:

import os


def file_content_replace(filename, old_content, new_content):
    if os.path.exists(filename):
        new_filename = 'new.' + filename
        new_file = open(new_filename, 'a', encoding='utf8')

        # 读取原文件,将每行内容的 old_content 替换为 new_content
        with open(filename, 'r', encoding='utf8') as file:
            while True:
                line = file.readline()
                if not line:
                    break
                if old_content in line:
                    line = line.replace(old_content, new_content)
                    print('After replace: ' + line)
                new_file.write(line)
        new_file.close()

        # 移除原文件,并将新文件重命名为原文件
        os.remove(filename)
        os.rename(new_filename, filename)
    else:
        print('File not found exception!')


file_content_replace('register.txt', 'bear', 'Spring-_-Bear')

运行示例:

在这里插入图片描述

3.2 统计字符个数函数

编写函数,计算传入字符串中数字、字母、空格以及其他字符的个数。

程序源码:

def character_count(content):
    digit = 0
    alpha = 0
    space = 0
    other = 0

    for ch in content:
        if ch.isdigit():
            digit += 1
        elif ch.isalpha():
            alpha += 1
        elif ch.isspace():
            space += 1
        else:
            other += 1
    return digit, alpha, space, other


print('digit: %s, alpha: %s, space: %s, other: %s' % (character_count(input('Please input a string:'))))

运行示例:

在这里插入图片描述

3.3 判断对象长度

编写函数,判断用户传入的对象(字符串、列表、元组)长度是否大于 5。

程序源码:

def object_length(obj):
    if len(obj) > 5:
        print('对象长度大于 5')
    else:
        print('对象长度不大于 5')


object_length('WuhanUniversityOfTechnology')
object_length([23, 35, 57, 85])
object_length({'小灰灰', '喜羊羊', '美羊羊', '红太狼', '灰太狼'})

运行示例:

在这里插入图片描述

3.4 保留列表前两位元素值

编写函数,检查传入列表的长度,如果大于 2,那么仅保留前两个长度的内容,并将新内容返回给调用者。

程序源码:

def first_two_elements(arr):
    return arr[:2] if len(arr) > 2 else arr


def main():
    arr = [23, 46, 32, 75]
    print('Before: ', arr)
    print('After:  ', first_two_elements(arr))


main()

运行示例:

在这里插入图片描述

3.5 奇数位元素

编写函数,检查获取传入列表或元组对象的所有奇数位索引对应的元素,并将其作为新列表返回给调用者。

程序源码:

def odd_elements(arr):
    return arr[::2]


array = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print('Before: ', array)
print('After: ', odd_elements(array))

运行示例:

在这里插入图片描述

3.6 字典保留 value 值前两位

编写函数,检查字典的每一个 value 的长度,如果大于 2,那么仅保留前两个长度的内容,并将新内容返回给调用者。字典中的 value 只能是字符串或列表:dic = {“k1”: “v1v1”, “k2”: [11,22,33,44]}。

程序源码:

def dictionary_value_process(dictionary):
    result = {}

    for key, val in dictionary.items():
        # 保留字典 value 的前两位值
        result[key] = val[:2] if len(val) > 2 else val

    return result


data = {'name': 'Spring-_-Bear', 'sex': ['male', 'female']}
print('Before: ', data)
print('After: ', dictionary_value_process(data))

运行示例:

在这里插入图片描述

第 4 章 类

4.1 公司股票模拟类 Stock

设计一个名为 Stock 的类来表示一个公司的股票,它包括∶

  1. 一个名为 symbol 的私有字符串数据域表示股票的符号。
  2. 一个名为 name 的私有字符串数据域表示股票的名字。
  3. 一个名为 previousClosingPrice 的私有浮点数据域存储前一天的股票价。
  4. 一个名为 currentPrice 的私有浮点数据域存储当前的股票价。
  5. 一个构造方法创建一支具有特定的符号、名字、之前价和当前价的股票。
  6. 一个返回股票名字的 get 方法。
  7. 一个返回股票符号的 get 方法。
  8. 获取/设置股票之前价的 get 和 set 方法。
  9. 获取/设置股票当前价的 get 和 set 方法。
  10. 一个名为 getChangePercent() 的方法返回从 previousClosingPrice 到 curentPrice 所改变的百分比。

实现这个类。编写一个测试程序,创建一个 Stock 对象,它的符号是 INTC,它的名字是 Intel Corporation,前一天的结束价是 20.5,新的当前价是 20.35,并且显示价格改变的百分比。

程序源码:

class Stock:
    def __init__(self):
        self.symbol = ''
        self.name = ''
        self.previous_closing_price = 0
        self.current_price = 0

    def stock(self, stock_info_list):
        self.symbol = stock_info_list[0]
        self.name = stock_info_list[1]
        self.previous_closing_price = stock_info_list[2]
        self.current_price = stock_info_list[3]

    def get_name(self):
        return self.name

    def get_symbol(self):
        return self.symbol

    def set_previous(self, price):
        self.previous_closing_price = price

    def get_previous(self):
        return self.previous_closing_price

    def set_current(self, price):
        self.current_price = price

    def get_current(self):
        return self.current_price

    def get_change_percent(self):
        return (self.current_price - self.previous_closing_price) / self.current_price


intel = Stock()
intel.stock(['INTC', 'Intel Corporation', 20.5, 20.35])

print('Stock symbol: %s' % intel.get_symbol())
print('Stock name: %s' % intel.get_name())
print('Current price: %s' % intel.get_current())
print('Previous closing price: %s' % intel.get_previous())
print('Change percent: %.2f%%' % (intel.get_change_percent() * 100))

运行示例:

在这里插入图片描述

4.2 账户模拟类 Account

设计一个名为 Account 的类,它包括:

  1. 账户的一个名为 id 的私有 int 数据域。
  2. 账户的一个名为 balance 的私有浮点数据域。
  3. 一个名为 annuallnterestRate 的私有浮点数据域存储当前年利率。
  4. 一个构造方法创建具有特定 id(默认值 0)、初始额(默认值 100)以及年利率(默认值 0)。
  5. id、balance 和 annuallnterestRate 的访问器和修改器。
  6. 一个名为 getMonthlyInterestRate() 的方法返回月利率。
  7. 一个名为 getMonthlyInterest() 的方法返回月利息。
  8. 一个名为 withdraw 的方法从账户取出特指定数额。
  9. 一个名为 deposit 的方法向账户存入指定数额。

绘制这个类的 UML类图,然后实现这个类。编写测试程序创建一个 Account 对象,这个账户的 id 是122,账户额是 20000 美元,年利率是 4.5%。使用 withdraw 方法取 2500 美元,使用 deposit 方法存 3000 美元,并打印 id、金额、月利率和月利息。

提示:

  • 方法 getMonthlyInterest() 返回每月利息额,而不是返回利率。月利息额 = 余额 * 月利息率,也即 balance * monthlyInterestRate。
  • 月利息率等于年利息率的十二分之一:monthlyInterestRate = annuallnterestRate / 12。
  • annuallnterestRate 是一个百分数(如 4.5%),你需要将它除以 100。

UML 类图:

在这里插入图片描述

程序源码:

class Account:
    def __init__(self):
        self.id = 0
        self.balance = 100.0
        self.annualInterestRate = 0.0

    def account(self, id, balance, rate):
        self.id = id
        self.balance = balance
        self.annualInterestRate = rate

    def get_id(self):
        return self.id

    def set_id(self, id):
        self.id = id

    def get_balance(self):
        return self.balance

    def set_balance(self, balance):
        self.balance = balance

    def get_rate(self):
        return self.annualInterestRate

    def set_rate(self, rate):
        self.annualInterestRate = rate

    def get_monthly_interest_rate(self):
        return self.annualInterestRate * 100 / 12

    def get_monthly_interest(self):
        return self.balance * self.annualInterestRate / 12

    def withdraw(self, money):
        if money <= self.balance:
            self.balance -= money
        else:
            print('取款失败,余额不足!')

    def deposit(self, money):
        self.balance += money


zhangsan = Account()
zhangsan.account(122, 20000, 0.045)

print('取款前: ', zhangsan.__dict__)
zhangsan.withdraw(2500)
print('取款后: ', zhangsan.__dict__)

print('存款前: ', zhangsan.__dict__)
zhangsan.deposit(3000)
print('存款后: ', zhangsan.__dict__)

print('月利率:%.2f%%' % zhangsan.get_monthly_interest_rate())
print('月利息:%.2f' % zhangsan.get_monthly_interest())

运行示例:

在这里插入图片描述

4.3 风扇模拟类 Fan

设计一个名为 Fan 的类表示一个风扇。这个类包括∶

  1. 三个名为 SLOW、MEDIUM 和 FAST 的常量,它们的值分别是 1、2 和 3 以表示风扇速度。
  2. 一个名为 speed 的私有整型数据域表明风扇的速度。
  3. 一个名为 on 的私有布尔数据域表明风扇是否是打开状态(默认值是 False)。
  4. 一个名为 radius 的私有浮点数据域表明风扇的半径。
  5. 一个名为 color 的私有字符串数据域表明风扇的颜色。
  6. 四个数据域的访问方法和修改方法。
  7. 一个构造方法创建一个具有特定速度(默认值为 SLOW)、半径(默认值为 5)、颜色(默认值为 blue)以及是否打开(默认值为 False)。

编写测试程序创建两个 Fan 对象。对第一个对象,赋值最大速度、半径为 10、颜色为 yellow,打开它。对第二个对象,赋值中速、半径为 5、颜色为 blue,关闭它。显示每个对象的 speed、radius、color 和 on 属性。

程序源码:

class Fan:
    SLOW = 1
    MEDIUM = 2
    FAST = 3

    def __init__(self):
        self.speed = self.SLOW
        self.on = False
        self.radius = 5.0
        self.color = 'blue'

    def fan(self, speed, on, radius, color):
        self.speed = speed
        self.on = on
        self.radius = radius
        self.color = color

    def set_speed(self, speed):
        self.speed = speed

    def get_speed(self):
        return self.speed

    def set_on(self, on):
        self.on = on

    def get_on(self):
        return self.on

    def set_radius(self, radius):
        self.radius = radius

    def get_radius(self):
        return self.radius

    def set_color(self, color):
        self.color = color

    def get_color(self):
        return self.color


fan1 = Fan()
fan1.fan(Fan.FAST, True, 10.0, 'yellow')
fan2 = Fan()
fan2.fan(Fan.MEDIUM, False, 5.0, 'blue')
print('fan1: ', fan1.__dict__)
print('fan2: ', fan2.__dict__)

运行示例:

在这里插入图片描述

第 5 章 高级特性

5.1 信用卡号码格式处理

处理信用卡号码。创建一个允许使用连字符的正则表达式,但是仅能用于正确的位置。例如,15 位的信用卡号码使用 4-6-5 的模式,表明 4 个数字 - 连字符 - 6 个数字 - 连字符 - 5 个数字;16 位的信用卡号码使用 4-4-4-4 的模式。记住,要对整个字符串进行合适的分组。

程序源码:

import re

print(re.match('\d{4}-\d{6}-\d{5}', '1111-222222-33333').group())
print(re.match('\d{4}-\d{4}-\d{4}-\d{4}', '4444-5555-6666-7777').group())

运行示例:

在这里插入图片描述

5.2 数据格式生成处理器

5.2.1 生成指定格式数据

设计一个数据生成代码,随机生成如下格式的数据:

Sun Sep 3 06:07:27 2000::xonrbn@jsbjxxwq.com::967932447-6-8
Wed Oct 13 17:04:24 1971::grumz@sgzdtkvrcw.edu::56192664-5-10
Fri Feb 24 10:08:07 1984::qgquf@hhztcrrfb.com::446436487-5-9
Tue Jan 21 13:08:54 1997::xezg@mnrehinw.com::853823334-4-8
Tue Feb  6 11:47:03 1973::qqnjdk@zwzyik.edu::97818423-6-6
Sun Jan 30 14:03:51 1977::taqd@cppwbqq.edu::223452231-4-7

生成拥有三个字段的字符串,由一对冒号或者一对双冒号分隔。第一个字段是随机(32 位)整数,该整数将被转换为一个日期,下一个字段是一个随机生成的电子邮件地址,最后一个字段是一个由单横线(-)分隔的整数集,再加开头的星期和月份构成的数据集。最后将数据写入 data.txt 文件中。

程序源码:

from random import randrange, choice
from string import ascii_lowercase as lc
from time import ctime

with open('data.txt', 'a', encoding='utf8') as file:
    for i in range(5, 10):
        # 32 位随机整数
        random_integer = randrange(2 ** 32)
        # 将 32 位整数转换为日期时间:Mon Sep 27 10:29:41 2004
        datetime_str = ctime(random_integer)
        # 邮箱地址:name@group.domain_suffix
        name = ''.join(choice(lc) for j in range(randrange(5, 10)))
        group = ''.join(choice(lc) for k in range(randrange(5, 10)))
        email_address = name + '@' + group + '.' + choice(('com', 'edu', 'cn', 'net', 'org', 'gov',))

        # 数据写入文件并打印
        line = '%s::%s::%d-%d-%d' % (datetime_str, email_address, random_integer, randrange(5, 10), randrange(5, 10))
        file.write(line + '\n')
        print(line)

file.close()

运行示例:

在这里插入图片描述

5.2.2 判断一周中每一天的次数

基于 5.2.1 生成的文件数据,判断在 data.txt 中一周的每一天出现的次数。

程序源码:

import re

week = {'Mon': 0, 'Tue': 0, 'Wed': 0, 'Thu': 0, 'Fri': 0, 'Sat': 0, 'Sun': 0}
with open('data.txt', 'r', encoding='utf8') as file:
    for line in file:
        day_of_week = re.findall('^\w{3}\s', line.strip())[0].strip()
        week[day_of_week] += 1
file.close()

print(week)

运行示例:

在这里插入图片描述

5.2.3 确保无数据损坏

通过确认整数字段中的第一个整数匹配在每个输出行起始部分的时间戳,确保在 data.txt 中没有数据损坏。

程序源码:

import re

with open('data.txt', 'r', encoding='utf8') as file:
    for line in file:
        date_str = re.findall('^\w{3}\s\w{3}\s\s?\d{1,2}\s\d{2}:\d{2}:\d{2}', line.strip())[0]
        print(date_str)

运行示例:

在这里插入图片描述

5.2.4 提取每行中完整的时间戳

程序源码:

import re

with open('data.txt', 'r', encoding='utf8') as file:
    for line in file:
        date_str = re.findall('^\w{3}\s\w{3}\s\s?\d{1,2}\s\d{2}:\d{2}:\d{2}', line.strip())[0]
        print(date_str)
file.close()

运行示例:

在这里插入图片描述

5.2.5 提取每行中完整的电子邮件地址

程序源码:

import re

with open('data.txt', 'r', encoding='utf8') as file:
    for line in file:
        email = re.findall('\w+@\w+\.\w{3}', line.strip())[0]
        print(email)
file.close()

运行示例:

在这里插入图片描述

5.2.6 提取时间戳中的月份

程序源码:

import re

with open('data.txt', 'r', encoding='utf8') as file:
    for line in file:
        month = re.findall('^\w{3}\s(\w{3})', line.strip())[0]
        print(month)
file.close()

运行示例:

在这里插入图片描述

5.2.7 提取登录名和域名

仅仅从电子邮件地址中提取登录名和域名(包括主域名和高级域名一起提取)。

程序源码:

import re

with open('data.txt', 'r', encoding='utf8') as file:
    for line in file:
        domain = re.findall('(\w+)@\w+\.(\w{3})+', line.strip())[0]
        print(domain)
file.close()

运行示例:

在这里插入图片描述

5.3 随机矩阵归一化

随机产生一个整数矩阵,将矩阵归一化到 0~1,即最小的变成 0,最大的变成 1,最小与最大之间的等比缩放。

程序源码:

import numpy as np

# 设置随机种子以确保结果可复现
np.random.seed(42)
# 生成一个 5x5 的整数矩阵,范围在 0~99 之间
matrix = np.random.randint(0, 100, size=(5, 5))
# 将矩阵归一化到 0~1,即最小的变成 0,最大的变成 1,最小与最大之间的等比缩放
min_val = np.min(matrix)
max_val = np.max(matrix)
normalized_matrix = (matrix - min_val) / (max_val - min_val)

print('-------------------------- matrix --------------------------')
print(matrix)
print('\n-------------------- normalized_matrix --------------------')
print(normalized_matrix)

运行示例:

在这里插入图片描述

5.4 数组元素间插入新值

给定数组 [1, 2, 3, 4, 5],如何得到在这个数组的每个元素之间插入 3 个 0 后的新数组。

程序源码:

import numpy as np

arr = np.array([1, 2, 3, 4, 5])
# 计算插入 3 个 0 后的新数组长度
new_length = len(arr) + (len(arr) - 1) * 3
# 创建一个全 0 的新数组
new_arr = np.zeros(new_length, dtype=arr.dtype)
# 将原数组元素和 0 交替插入到新数组中
new_arr[::4] = arr

print(new_arr)

运行示例:

在这里插入图片描述

5.5 边界矩阵

创建一个 10*10 的 ndarray 对象,且矩阵边界全为 1,里面全为 0。

程序源码:

import numpy as np

border_arr = np.zeros((10, 10), dtype=int)
# 将矩阵边界值赋值为 1
border_arr[0, :] = 1
border_arr[:, 9] = 1
border_arr[:, 0] = 1
border_arr[9, :] = 1

print(border_arr)

运行示例:

在这里插入图片描述

5.6 交换矩阵两行元素

给定一个二维矩阵,请交换任意两行元素。

程序源码:

import numpy as np

arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9], [9, 8, 7], [6, 5, 4], [3, 2, 1]])
print('-------------- array --------------')
print(arr)
# 交换第二行和第三行
arr[[1, 2], :] = arr[[2, 1], :]
print('---------- exchange array ----------')
print(arr)

运行示例:

在这里插入图片描述

第 6 章 网络编程

编写 CS 架构的软件,实现客户端可以下载服务端的文件,如图片、视频、文本等。

程序源码:

server.py:监听端口,等待来自客户端的请求,建立连接后传递文件数据给客户端。

import socket
import os


def send_file(connection, filename):
    # 检测文件是否存在
    if not os.path.exists(filename):
        connection.send(b'File not found')
        return

    # 发送文件大小给客户端
    file_size = os.path.getsize(filename)
    connection.send(str(file_size).encode())

    # 发送文件内容给客户端
    with open(filename, 'rb') as file:
        while True:
            data = file.read(1024)
            if not data:
                break
            connection.send(data)

    print(f"File '{filename}' sent successfully")


def start_server():
    # 创建服务器套接字
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 绑定服务器地址和端口
    server_socket.bind(('localhost', 8888))
    # 监听连接请求
    server_socket.listen(1)
    print('Server is running and listening for connections...')

    while True:
        # 接收客户端连接
        connection, client_address = server_socket.accept()
        print('Accepted connection form:', client_address)

        # 接收客户端请求的文件名
        filename = connection.recv(1024).decode()
        print('Requested file:', filename)

        # 发送文件给客户端
        send_file(connection, filename)

        # 关闭连接
        connection.close()


if __name__ == '__main__':
    start_server()

client.py:向服务器发送需要的文件名,而后接收来自服务器的文件数据并保存到本地。

import socket
import os
import uuid


def receive_file(client_socket, filename):
    # 接收文件大小
    file_size = int(client_socket.recv(1024).decode())
    if file_size == -1:
        print("File not found or it's a empty file")
        return

    # 接收文件内容
    save_file_name = str(uuid.uuid4()) + '.' + os.path.basename(filename).split('.')[1]
    with open(save_file_name, 'wb') as file:
        total_received = 0
        while total_received < file_size:
            data = client_socket.recv(1024)
            file.write(data)
            total_received += len(data)

            # 计算并显示进度
            progress = min((total_received / file_size * 100), 100)
            print(f"Downloading: {progress}%")

    print(f"File '{filename}' received successfully")


def start_client():
    # 创建客户端套接字
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 连接服务器
    client_socket.connect(('localhost', 8888))

    # 发送文件名给服务器
    filename = input('Input the filename you want:')
    client_socket.send(filename.encode())

    # 接收文件
    receive_file(client_socket, filename)

    # 关闭连接
    client_socket.close()


if __name__ == '__main__':
    start_client()

运行示例:

server.py

在这里插入图片描述

client.py

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

春天熊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值