【敬初学者】Python基础学完了,该怎么知道自己学的怎么样呢?十个经典实战小项目附源码

【敬初学者】Python基础学完了,该怎么知道自己学的怎么样呢?十个经典实战小项目附源码初学者要想成功,一句话,大量的实操,大量的练,乍一看我的这个答案似乎有点敷衍,但是这确实是我接触Python以来,总结出的最有价值的经验,接下来分享我自己初学时用来练手的经典实战小项目,适合初学者敲的代码。1.街霸游戏1.1KO街霸游戏小剧场特别调查员春丽突然收到了来自中尉查理的一封邮件,邮件里详细地说明了神月家族在美国唐人街举办的街霸挑战赛,挑战的终极boss正是街霸维加。春丽在很小的时候,父亲就被维加残忍地杀害,为报父仇,春丽毅然决然地买好了飞往唐人街的机票。邪恶的维加正通过催眠术,控制着

大家好,又见面了,我是你们的朋友全栈君。

前言

初学者要想成功,一句话,大量的实操,大量的练,乍一看我的这个答案似乎有点敷衍,但是这确实是我接触Python以来,总结出的最有价值的经验,接下来分享我自己初学时用来练手的经典实战小项目,适合初学者敲的代码。
在这里插入图片描述

1.街霸游戏

1.1 KO街霸

在这里插入图片描述游戏小剧场
特别调查员春丽突然收到了来自中尉查理的一封邮件,邮件里详细地说明了神月家族在美国唐人街举办的街霸挑战赛,挑战的终极boss正是街霸维加。春丽在很小的时候,父亲就被维加残忍地杀害,为报父仇,春丽毅然决然地买好了飞往唐人街的机票。

邪恶的维加正通过催眠术,控制着在擂台上饮败的格斗家们在世界各地执行暗杀计划。

隆远在印度修行,孤身一人的春丽能在擂台上挑战成功吗?

程序完整源码

这是一个针对Python初学者的练手小程序,简单地模拟春丽与维加的格斗过程。有一定开发经验的朋友可以对程序进行扩展,比如利用多进程来模拟春丽同时与多人进行格斗。

Python

# 导入random模块,执行random模块中的choice方法来随机获取列表中的元素
import random
import time
VEGA_STRATEGIES = ["原地蹲防", "失误", "回旋攻击", "失误", "伤害修正", "回血", "超必杀"]
CHUNLI_KUNFU = ["气功拳", "旋转踢", "百裂脚", "霸山天升脚"]
def countdown(seconds=3, message=""):
""" :param seconds: 倒数的秒数 :param message: 倒计时结束后输出的提示信息 :return: """
for _ in range(seconds, 0, -1):
_, _ = print(_), time.sleep(1)
else:
print(message)
def  generate_prompts(kunfu):
""" :param kunfu: 街霸格斗选手的格斗招数,为一个列表对象,例如["气功拳", "旋转踢"] :return: 返回用户指令输入的提示信息,为一个字符串对象 """
prompts = "\n"
for index, value in enumerate(kunfu):
prompts += "<{}>{}".format(index, value)
prompts += "\n输入<>中的指令来挑战街霸:__\b\b"
return prompts
def fight():
# 定义整型变量fighter,用来保存街霸维加的血量
vega = 100
# 定义整型变量chunli,用来保存春丽的血量
chunli = 100
blood = 5
prompts = generate_prompts(CHUNLI_KUNFU)
countdown(message="Fight!")
# 执行while循环,不断重复执行下面的代码
while True:
# 春丽或boss其中一人血量为0时就退出战斗
if vega * chunli == 0:
break
# 执行input函数获得键盘的输入内容
command = input(prompts)
# 对输入的字符串类型转换为整型,读者在输入时必须输入有效的数字,否则会抛出异常
try:
command = int(command)
_ = CHUNLI_KUNFU[command]
except (ValueError, IndexError):
print("春丽,这是在战斗,请输入正确的战斗指令!")
continue
print("春丽对街霸使出了{}".format(CHUNLI_KUNFU[command]))
# 使用random模块中的choice函数,来随机选择列表里的值
vega_strategy = random.choice(VEGA_STRATEGIES)
if vega_strategy == "失误":
print("街霸维加在对战中反击失误!")
else:
print("街霸维加在对战中对你使用了{}".format(vega_strategy))
if vega_strategy in { 
"原地蹲防", "回血"}:
if vega_strategy == "回血" and vega < 100:
vega += blood
elif vega_strategy == "失误":
vega -= blood*2
elif vega_strategy == "伤害修正":
vega -= blood
elif vega_strategy == "超必杀":
chunli -= blood*2
else:
chunli -= blood
chunli = 0 if chunli  <=0 else chunli
vega = 0 if vega  <=0 else vega
print("\n-*- 春丽现在的血量:{} 维加现在的血量:{} -*-".format(chunli, vega))
time.sleep(3)
if chunli == 0:
print("春丽,你战败了!")
else:
print("维加,我今天终于把你打败,父亲泉下有知,可以瞑目了!")
if __name__ == "__main__":
fight()

程序的输出界面

在这里插入图片描述

1.2 春丽VS巴洛克

在这里插入图片描述
游戏小剧场
虽然美丽的春丽打败了维加,但邪恶的影罗组织并未就此覆灭。许多年以后,春丽站在A号街区,会突然想起打败神月卡琳后的那个下午。当时,身躯高大的巴洛克已将面具摘下,道场中的其他四名影子杀手,形如雕塑,酷似木偶…春丽经过这场残酷的战斗以后,在背部留下了一道很长的月牙形伤痕。

在本节程序实战中,通过多进程的方式来模拟春丽一人对抗影罗组织的五名邪恶杀手。

参考源码

通过多进程+队列来模拟春丽1VS5的街霸游戏挑战赛:

from multiprocessing import Process, Queue
import random
class Fighter:
def __init__(self, name, blood = 100, justice = True, kungfu = None, enemies = 1):
""" :param name: 表示该fighter的姓名 :param blood: 表示该fighter的血量 :param justice: 布尔类型,表示该fighter是否代表正义的一方 :param kungfu: 表示该fighter的格斗技能 :param enemies: 表示该fighter对抗的敌人数 """
self.__name = name
self.__blood = blood
self.__justice = justice
self.__kungfu = kungfu
self.__enemies = enemies
def  attack(self):
kungfu, harm = None, 0
if self.__blood > 0:
kungfu = random.choice(list(self.__kungfu.keys()))
harm = self.__kungfu[kungfu]
return kungfu, harm
@property
def name(self):
return self.__name
@property
def blood(self):
return self.__blood
@blood.setter
def blood(self, value):
self.__blood = value
@property
def enemies(self):
return self.__enemies
@enemies.setter
def enemies(self, count):
self.__enemies = count
@property
def justice(self):
return self.__justice
def fight(fighter,  justice_attacks, injustice_attacks):
""" :param fighter: Fighter对象 :param justice_attacks: 队列类型,表示春丽的攻击 :param injustice_attacks: 队列类型,表示巴洛克等杀手的攻击 :return: """
while True:
kungfu, harm = fighter.attack()
attack = { 
"name": fighter.name, "kungfu": kungfu,
"harm": harm, "blood": fighter.blood}
if fighter.justice:
# 通过justice_attacks代表的队列,向以巴洛克为首的杀手们发起一个攻击
justice_attacks.put(attack)
if fighter.blood == 0:
break
# 从justice_attacks代表的消息队列中,接收对方的一个攻击
attack = injustice_attacks.get()
# 如果对方攻击时的blood值为0,表示对方已被击败
if attack["blood"] == 0:
# 减去敌人数
fighter.enemies -= 1
if fighter.enemies == 0:
# 敌人已全部被击败, 退出战斗!
break
else:
continue
else:
# 通过justice_attacks代表的队列,向春丽发起一个攻击
injustice_attacks.put(attack)
if fighter.blood == 0:
break
# 从justice_attacks队列中接收春丽发起的攻击
attack = justice_attacks.get()
# 如果春丽攻击时的血量为0,说明春丽已经被击败
if attack["blood"] == 0:
""" 春丽已经战败,通过justice_attacks对列向己方的杀手们进行消息转发, 同时退出战斗 """
justice_attacks.put({ 
"blood": 0})
break
kungfu, harm = fighter.attack()
""" 如果在回击的过程中反击的伤害大于对方的伤害值, 则加上已有的血量值来实现回血的功能,否则将血量减去对应的伤害值 """
fighter.blood += harm - attack["harm"]
if fighter.blood <= 0:
fighter.blood = 0
elif fighter.blood > 100:
fighter.blood = 100
if fighter.blood > 0:
print("{} 获得了胜利!!!".format(fighter.name))
if __name__ == "__main__":
# 定义chunli_kungfu来保存春丽的招式及对应的伤害值
chunli_kungfu = { 

"失误": 0,
"原地蹲防": 5,
"龙星落": 10,
"气功拳": 15,
"旋转踢": 20,
"百裂脚": 20,
"霸山天升脚": 20,
"超必杀-千翼气功掌": 25
}
# 定义baroque_kungfu来保存杀手巴洛克的招式及对应的伤害值
baroque_kungfu = { 

"失误": 0,
"伤疤之恨": 15,
"闪光漩涡": 20,
"飞翔巴塞罗那": 20,
"红色冲击": 20
}
# 定义来shadow_kungfu保存影子杀手的攻击策略及对应的伤害值
shadow_kungfu = { 

"失误": 0,
"暗器": 10,
"毒药": 15,
"炸弹": 20
}
processes = []
fighters = [
Fighter(name="春丽", kungfu=chunli_kungfu, enemies=5),
Fighter(name="巴洛克", kungfu=baroque_kungfu, justice=False),
Fighter(name="影子杀手1", kungfu=shadow_kungfu, justice=False),
Fighter(name="影子杀手2", kungfu=shadow_kungfu, justice=False),
Fighter(name="影子杀手3", kungfu=shadow_kungfu, justice=False),
Fighter(name="影子杀手4", kungfu=shadow_kungfu, justice=False)
]
justice_attacks = Queue()
injustice_attacks = Queue()
for fighter in fighters:
process = Process(target=fight, args=(fighter, justice_attacks, injustice_attacks))
processes.append(process)
[process.start() for process in processes]
[process.join() for process in processes]

2.猜谜游戏

在这里插入图片描述

2.1简单的猜数字游戏

项目要求

实现一个简单的猜数字游戏:程序启动时获取一个随机值,根据用户的输入提示大了还是小了,如果用户输入的整数与随机值相等,则退出循环。

通过random模块randint方法获取一个随机值,通过input函数获取用户的输入。

代码示例:

# 导入random模块
import random
# 获取从1到100000之间的随机数
random_number = random.randint(1, 1000000)
# 执行input方法获取用户的输入,input的返回值为字符串类型,通过int()将其转换为整型
guess_number = int(input("Please enter the number:____\b\b\b\b"))

参考源码

import time
import random
def get_random_number(start=0, end=10**3):
return random.randint(start, end)
def countdown(seconds=3, message=""):
""" :param seconds: 倒数的秒数 :param message: 倒计时结束后输出的提示信息 :return: """
for _ in range(seconds, 0, -1):
_, _ = print(_), time.sleep(1)
else:
print(message)
def serve_forever():
random_number = get_random_number()
countdown(message="猜数字游戏开始,Go!!!")
while True:
try:
guess_number = int(input("请输入你猜的数字:"+"_"*4+"\b"*4))
except ValueError:
print("请输入合法的数字!")
continue
if guess_number != random_number:
_ = print("你输入的数字大了") if guess_number > random_number else print("你输入的数字小了")
continue
print("恭喜你猜对了!!!")
if input("按键盘任意键继续玩猜数字游戏或输入quit退出游戏:____\b\b\b\b").lower() == "quit":
break
else:
random_number = get_random_number()
print("游戏已被终止,再见!!!")
if __name__ == "__main__":
serve_forever()

程序的输出界面

在这里插入图片描述
在这里插入图片描述

2.2 进阶的猜姓名游戏

项目要求

定义一个人名集合,例如 {“王祖贤”, “李嘉欣”, “李嘉诚”, “刘德华”, “叶倩文”,“叶倩倩”, “王李丹妮”}。如果用户的输入前缀匹配第一个字,则提示”不错,有点接近了”,前缀匹配前面两个字,则提示”厉害,比较接近了”,完全匹配则提示”哇塞,你是个猜姓名天才,请收下我的膝盖”。

构造该Trie结构的算法逻辑很简单,以第一次构造为例:

将姓名中的第一个字作为键插入到指针指向的空字典中,键值为一个空字典,然后将指针指向键值所对应的空字典,接着将姓名中的第二个字作为键插入到指针指向的空字典中,键值为一个空字典,同样需要将指针指向键值所对应的空字典,不断重复这样的过程,直到遍历完姓名中的所有字符。

简化的代码实例:

name = "王八蛋"
trie = { 
}
trie[name[0]] =  { 
}
trie[name[0]][name[1]] =  { 
}
trie[name[0]][name[1]][name[2]] =  { 
}

这样在查找用户的输入是否包含某姓名的前缀时,只需要遍历用户输入的字符,然后在构造好的Trie结构中进行查找。

参考源码

import time
def countdown(seconds=3, message=""):
""" :param seconds: 倒数的秒数 :param message: 倒计时结束后输出的提示信息 :return: """
for _ in range(seconds, 0, -1):
_, _ = print(_), time.sleep(1)
else:
print(message)
def build_lookup_table(data):
""" :param data: a set of names, e.g: {"王祖贤", "李嘉欣"} :return: lookup table e.g:{'王': {'祖': {'贤': {}}}, '李': {'嘉': {'欣': {}}}} """
lookup_table = { 
}
for name in data:
lookup_table_ = lookup_table
for char in name:
if char not in lookup_table_:
lookup_table_[char] = { 
}
lookup_table_ = lookup_table_[char]
return lookup_table
def guess_name():
stars = { 
"王祖贤", "李嘉欣", "李嘉诚", "刘德华", "叶倩文", "叶倩倩", "王李丹妮"}
# 构造一个查找表
lookup_table = build_lookup_table(stars)
countdown(3, "猜姓名游戏开始,Go!!!")
messages = { 
0: "不要瞎猜好吗?",  1: "不错,有点接近了",  2: "厉害,比较接近了",
66: "哇塞,你是个猜姓名天才,请收下我的膝盖"}
end = 2
while True:
name = input("请输入你要猜的姓名:____\b\b\b\b")
if name in stars:
print(messages[66])
if input("按键盘任意键继续玩猜数字游戏或输入quit退出游戏:____\b\b\b\b").lower() == "quit":
break
else:
lookup_table_ = lookup_table
index = 0
for word in name:
if word in lookup_table_:
lookup_table_ = lookup_table_[word]
index = index+1 if index < end else index
else:
break
print(messages[index])
if __name__ == "__main__":
guess_name()

程序的输出界面

在这里插入图片描述

在这里插入图片描述

2.3基于英文分词的猜单词游戏

项目要求

① 对某一篇英文文章进行分词,以获取一个英语词典
② 如果用户输入的单词在词典中,则提示”你是个猜单词天才,请收下我的膝盖”
③ 如果用户的输入前缀匹配第一个字母,则提示”不错,有点接近了”,前缀匹配前面两个字母,则提示”厉害,比较接近了”

算法逻辑如下:

① 定义一个布尔类型的标记变量,初始情况下为True,表示已完成单词的拆分
② 遍历英文字符串,如果当前字符为分隔符且尚未切分,则开始分词:将起始位置的索引与分隔符位置之前的所有字符进行拆分

③ 如果当前字符不是分隔符且已拆分,则将标记变量更新为False, 同时更新拆分的起始位置

在这里插入图片描述

参考源码

import time
def cut(content, language=0):
""" :param content: 待分词的英文字符串,例如:"when a great dream shows up" :param language: 0表示对英文进行分词 :return: 返回分词后的词典,是一个集合类型, 例如:{"an", "and"} """
dictionary = set()
length = len(content)
# 定义英文中的分隔符
stop_words = { 
";", " ", "\n", ".", "!"}
if language == 0:
begin = 0
# 标记变量,初始情况下表示已拆分
is_cutted = True
for index in range(length):
# 如果当前字符为分隔符
if content[index] in stop_words:
# 且未拆分
if not is_cutted:
dictionary.add(content[begin:index])
is_cutted = True
continue
elif is_cutted:
begin = index
is_cutted =  False
return dictionary
def build_trie(dictionary):
""" :param dictionary:英文词典集合 :return: 单词查找树,系字典对象 """
trie = { 
"root": { 
}}
for word in dictionary:
next = trie["root"]
for char in word:
if char not in next:
next[char] = { 
}
next = next[char]
else:
next[0]=0
return trie
def countdown(seconds=3, message=""):
""" :param seconds: 倒数的秒数 :param message: 倒计时结束后输出的提示信息 :return: """
for _ in range(seconds, 0, -1):
_, _ = print(_), time.sleep(1)
else:
print(message)
def guess_words():
content = "when a great dream shows up, grab it!"
dictionary = cut(content)
lookup_table = build_trie(dictionary)
countdown(3, "猜单词游戏开始,Go!!!")
messages = { 
0: "不要瞎猜好吗?", 1: "不错,有点接近了", 2: "厉害,比较接近了",
66: "哇塞,你是个猜单词天才,请收下我的膝盖"}
end = 2
while True:
word = input("请输入你要猜的单词:____\b\b\b\b")
if word in dictionary:
print(messages[66])
if input("按键盘任意键继续玩猜单词游戏或输入quit退出游戏:____\b\b\b\b").lower() == "quit":
break
else:
lookup_table_ = lookup_table["root"]
index = 0
for ch in word:
if ch in lookup_table_:
lookup_table_ = lookup_table_[ch]
index = index+1 if index < end else index
else:
break
print(messages[index])
if __name__ == "__main__":
guess_words()

程序的输出界面
在这里插入图片描述
在这里插入图片描述

3.简洁的小项目

(偷懒上线)

3.1 抓取知乎图片,只用30行代码

from selenium import webdriver
import time
import urllib.request
driver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://www.zhihu.com/question/29134042")
i = 0
while i < 10:
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
time.sleep(2)
try:
driver.find_element_by_css_selector('button.QuestionMainAction').click()
print("page" + str(i))
time.sleep(1)
except:
break
result_raw = driver.page_source
content_list = re.findall("img src=\"(.+?)\" ", str(result_raw))
n = 0
while n < len(content_list):
i = time.time()
local = (r"%s.jpg" % (i))
urllib.request.urlretrieve(content_list[n], local)
print("编号:" + str(i))
n = n + 1

3.2 两个聊天机器人互相聊天

from time import sleep
import requests
s = input("请主人输入话题:")
while True:
resp = requests.post("http://www.tuling123.com/openapi/api",data={ 
"key":"4fede3c4384846b9a7d0456a5e1e2943", "info": s, })
resp = resp.json()
sleep(1)
print('小鱼:', resp['text'])
s = resp['text']
resp = requests.get("http://api.qingyunke.com/api.php", { 
'key': 'free', 'appid':0, 'msg': s})
resp.encoding = 'utf8'
resp = resp.json()
sleep(1)
print('菲菲:', resp['content'])
#网上还有一个据说智商比较高的小i机器人,用爬虫的功能来实现一下:
import urllib.request
import re
while True:
x = input("主人:")
x = urllib.parse.quote(x)
link = urllib.request.urlopen(
"http://nlp.xiaoi.com/robot/webrobot?&callback=__webrobot_processMsg&data=%7B%22sessionId%22%3A%22ff725c236e5245a3ac825b2dd88a7501%22%2C%22robotId%22%3A%22webbot%22%2C%22userId%22%3A%227cd29df3450745fbbdcf1a462e6c58e6%22%2C%22body%22%3A%7B%22content%22%3A%22" + x + "%22%7D%2C%22type%22%3A%22txt%22%7D")
html_doc = link.read().decode()
reply_list = re.findall(r'\"content\":\"(.+?)\\r\\n\"', html_doc)
print("小i:" + reply_list[-1])

在这里插入图片描述

3.3 自动写检讨书

import random
import xlrd
ExcelFile = xlrd.open_workbook(r'test.xlsx')
sheet = ExcelFile.sheet_by_name('Sheet1')
i = []
x = input("请输入具体事件:")
y = int(input("老师要求的字数:"))
while len(str(i)) < y * 1.2:
s = random.randint(1, 60)
rows = sheet.row_values(s)
i.append(*rows)
print(" "*8+"检讨书"+"\n"+"老师:")
print("我不应该" + str(x)+",", *i)
print("再次请老师原谅!")
''' 以下是样稿: 请输入具体事件:抽烟 老师要求的字数:200 检讨书 老师: 我不应该抽烟, 学校一开学就三令五申,一再强调校规校纪,提醒学生不要违反校规,可我却没有把学校和老师的话放在心上,没有重视老师说的话,没有重视学校颁布的重要事项,当成了耳旁风,这些都是不应该的。同时也真诚地希望老师能继续关心和支持我,并却对我的问题酌情处理。 无论在学习还是在别的方面我都会用校规来严格要求自己,我会把握这次机会。 但事实证明,仅仅是热情投入、刻苦努力、钻研学业是不够的,还要有清醒的政治头脑、大局意识和纪律观念,否则就会在学习上迷失方向,使国家和学校受损失。 再次请老师原谅! '''

3.4 屏幕录相机,抓屏软件

from time import sleep
from PIL import ImageGrab
m = int(input("请输入想抓屏几分钟:"))
m = m * 60
n = 1
while n < m:
sleep(0.02)
im = ImageGrab.grab()
local = (r"%s.jpg" % (n))
im.save(local, 'jpeg')
n = n + 1

在这里插入图片描述

3.5 制作Gif动图

 from PIL import Image
im = Image.open("1.jpg")
images = []
images.append(Image.open('2.jpg'))
images.append(Image.open('3.jpg'))
im.save('gif.gif', save_all=True, append_images=images, loop=1, duration=1, comment=b"aa

在这里插入图片描述

分享到这结束了,感谢观看哦,最后说一句,要想成功就要多去练多去敲,重中之重。

更多Python精彩内容与资源分享可以看我主页简介。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/142177.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号