1 背景概述
1.1 开发背景
随着网络技术逐渐渗入社会生活各个层面,各大编程语言随即发展,Python也不负众望,已经在云计算、云服务、人工智能、web、科学计算、大数据等领域站稳了脚跟,在未来十年的时间里可以Python会越来越火!Python语言是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。
Python是一种面向对象、解释型、动态类型计算机程序设计语言,是一种面向对象的动态类型语言。它具有如下特点:简单、易学、优雅、可移植、丰富的Python标准库等。根据此特点,我们可以利用Python语言编写游戏、网站爬虫以及基于python的网站开发。
随着网络的迅速发展,万维网成为大量信息的载体,如何有效地提取并利用这些信息成为一个巨大的挑战。搜索引擎(Search Engine),例如传统的通用搜索引擎如AltaVista,Yahoo!和Google等,作为一个辅助人们检索信息的工具成为用户访问万维网的入口和指南。但是,这些通用性搜索引擎也存在着一定的局限性,为了解决上述问题,定向抓取相关网页资源的聚焦爬虫应运而生。
1.2 研究意义
随着人工智能的发展,Python技术的流行,Python也为人们的工作与生活上带来了很多的便捷。从自身特性看Python发展,Python自身强大的优势决定其不可限量的发展前景。Python作为一种通用语言,几乎可以用在任何领域和场合,角色几乎是无限的。Python具有简单、易学、免费、开源、可移植、可扩展、可嵌入、面向对象等优点,它的面向对象甚至比java和C#.net更彻底。它是一种很灵活的语言,能帮你轻松完成编程工作。强大的类库支持,使编写文件处理、正则表达式,网络连接等程序变得相当容易。能运行在多种计算机平台和操作系统中,如各位unix,windows,MacOS,OS/2等等,并可作为一种原型开发语言,加快大型程序的开发速度。从企业应用来看Python发展Python被广泛的用在Web开发、运维自动化、测试自动化、数据挖掘等多个行业和领域。
随着科技的迅猛发展、社会的不断进步,人们的生活节奏越来越快,在快时代中,我们应该学会利用编程语言来便利自己、享受生活、享受当下。本次课设实验主要利用了python语言简单易学、有丰富的Python标准库这两个特点进行编写了猜数游戏以及爬取河南省各城市的天气预报,通过这两个实验,进一步了解了Python语言标准库的使用。
2 可行性分析
2.1 技术可行性
技术上的可行性分析主要是分析技术条件能否顺利完成开发工作,硬、软件能否满足开发者的需要等。在软件方面,本系统采用的是pycharm进行开发,而数据库系统采用的是Mysql。通过分析,在软、硬件方面现有工具与环境完全可以实现系统的开发,如下表2.1所示,因此具有技术上的可行性。
表2.1 技术分析表
关键技术项 | 要求 | 现有水平 | 对照分析 |
Python | 精通 | 了解 | 可以满足要求 |
Mysql | 精通 | 了解 | 可以满足要求 |
2.2 社会可行性
2.2.1 法律可行性
该产品没有侵权或者抄袭等违法情况,也没有被申请过专利,故可行。
2.2.2 政策可行性
无国家政策限制,也无地方政府(或其它机构)的限制。
2.3 使用可行性
该产品对于用户没有要求,适用于普通大众,适用于任何网络设备,易于普及,并且用户容易上手操作,使用方法非常方便。而且对于服务端操作人员而言,维护十分简单。总体而言,功能十分适合现阶段大众的需要。
对于服务端的操作人员,在tkinter版猜数游戏中,仅仅涉及到简单的登录注册、输入猜数范围等操作;而在爬取河南各城市天气预报中,只需用户输入简单的执行语句即可爬取相关内容,因此仅仅需要操作人员熟悉简单的电脑操作即可。
该产品操作简单快捷,功能大部分齐全,可以满足用户的基本需求,而且通俗易学。综上所述,这两个程序具有使用可行性。
3 需求分析
3.1 项目功能分析
tkinter版猜数游戏是一个简易的娱乐小游戏,该系统利用tkinter标准库来编写GUI版本的猜数游戏。其内容包括:每次猜数之前要启动游戏并设置猜数范围和最大猜测次数等参数,退出游戏时要显示战绩,即共玩了几次、猜对了几次,因此要为用户提供一个方便简易的使用界面。系统的主要功能包括:新用户注册功能,用户登录功能,输入猜数的范围,输入最大猜测次数,显示已玩次数及猜对次数。
爬取河南各城市天气预报是使用scrapy框架来实现的,其实验内容为:安装python拓展库scrapy,然后编写爬虫项目,从网站http://www.weather.com.cn/henan/index.shtml爬取河南各城市的天气预报,并把爬取到的天气数据写入本地文本weather.txt中。系统的主要功能包括爬取河南各城市的天气预报数据,其数据包括:城市名、时间、天气状况、最高温度、最低温度以及风力。
3.2 功能需求描述
3.2.1 tkinter版猜数游戏功能描述
tkinter版猜数游戏的主要目的是丰富用户的课余生活,且要为用户提供一个简单且美观的使用界面。该游戏主要实现以下功能:
①注册功能:用户在登录页面上单击“注册”按钮,可以进入用户注册页面,用户需要填写用户名、密码、进行注册,注册成功后,该用户的账号及密码会添加到user表中进行存储,而后自动关闭注册页面,并返回到系统登录页面等待用户登录。
②登录功能:用户在登录页面上必须输入合法且正确的用户名和密码之后才能进入系统,若输入信息非法,则自动跳转到密码错误页面。
③设置游戏规则功能:用户在成功登陆后,会进入到游戏规则设置页面,此处需用户填入猜数字的范围以及猜数字的次数,设置完成后,点击“开始游戏”按钮,方可进入游戏。
④显示猜数对错功能:用户成功进入游戏后,开始猜数,若猜的数大了,则弹出提示框“你猜大了”;若猜的数小了,则弹出提示框“你猜小了”;根据提示框继续猜数,直至机会用完为止。若在机会没用完之前猜对了,则弹出成功提示框“恭喜你猜对了”,若机会用完之后还没猜出,则弹出失败提示框“你猜错了,并且机会已经用完了!”。
⑤显示战绩功能:用户结束游戏后,将显示此次游戏一共玩了几次,成功了几次。
3.2.2 爬取河南省天气预报功能描述
爬取河南省天气预报,主要利用了python语言中的scrapy库,该爬虫主要实现以下功能:
根据对应超链接爬取河南省各城市的七天天气预报,其天气预报的数据包括:城市名、时间、天气状况、最高温度、最低温度以及风力,并把爬取到的数据保存在本地的weather.txt中。
4 概要设计
4.1 任务概述
本实验设计的目标是:
1、安 装 Python 扩 展 库 scrapy , 然 后 编 写 爬 虫 项 目 , 从 网 站http://www.weather.com.cn/shandong/index.shtml 爬取河南各城市的天气预报数据,并把爬取到的天气数据写入本地文本 weather.txt。
2、使用 Python 标准库 tkinter 编写 GUI 版本的猜数游戏。每次猜数之前要启动游戏并设置猜数范围和最大猜测次数等参数,退出游戏时显示战绩(共玩几次,猜对几次)信息。
4.2 功能模块
4.2.1 使用scrapy框架爬取河南各城市天气预报
1、scrapy框架结构图如下图4-1所示:
图4-1 scrapy架构图
2、scrapy框架各文件功能分析图如下图4-2所示:
3、爬取河南各城市天气预报功能整体实现模块图如下图4-3所示:
4.2.2 tkinter版猜数游戏
猜数游戏功能整体实现模块图如下图4-4所示:
图4-4 功能整体实现模块图
4.3 处理流程设计
4.3.1爬虫系统操作流程
首先利用命令“scrapy+startproject+项目名称“ 创建项目,然后再利用命令“scrapy+genspider+文件名称”域名创建爬虫文件,再然后在在parse方法中做数据的提取。先提取出河南各个城市的URL,再模拟请求响应过程,创建parse1方法对各个城市的七天的天气状况信息进行提取,最后将得到的数据通过Item pipeline(管道文件)保存在weather.txt文件中,爬虫系统流程图如图4-5所示:
图4-5 爬虫系统流程图
4.3.2猜数小游戏系统操作流程
首先创建一个登陆界面,如果没有账号,进如注册界面先进行注册,并将注册好的信息保存到数据库中保存,随后返回登陆界面进行登录,登陆成功后会进入到游戏规则说明界面,说明游戏规则,然后根据要求设置猜数最大值、最小值、和最大猜数次数,设置完成后进入游戏界面,在游戏次数之内,如果猜对了,进入成功界面,失败则进入失败界面,而在成功和失败界面都有两个按钮,可以选择退出或者再玩一次,如果退出,则会重新显示用户玩多少次,猜对了多少次,然后确认退出,退出系统。猜数游戏系统流程图如下图4-6所示:
图4-6 猜数游戏系统流程图
4.4 数据库设计
4.4.1 概念结构设计
概念设计阶段主要是将需求分析阶段得到的用户需求抽象为信息结构(概念模型)的过程,它是整个数据库设计的关键。本系统的主要任务及目标如下:
- 设计分E-R图,即各子模块的E-R图;
(2) 生成E-R图,通过合并方法,做到各子系统实体、属性、联系统一,并消除冲突;
1、用户注册E-R图:用户可以通过输入个人信息注册添加用户信息表user,具体实现过程如图4-7所示:
图4-7 用户注册E-R图
2、用户登录E-R图:用户可以通过输入正确的账号密码进入游戏界面。如图4-8所示:
图4-8 用户登录E-R
4.4.2 逻辑结构设计
1、将E-R图转换为关系模型
实体型转换为关系模式。实体的属性就是关系的属性,实体的码就是关系的码。对于实体间的联系则有以下不同的情况:
一个m:n联系转换为一个关系模式。与该联系相连的各实体的码以及联系本身的属性均转换为关系的属性,而关系的码为各实体码的组合。
一个1:n联系可以转换为一个独立的关系模式,也可以与n端对应的关系模式合并。如果转换为一个独立的关系模式,则与该联系相连的各实体的码以及联系本身的属性均转换为关系的属性,而关系的码为n端实体的码。
一个1:1联系可以转换为一个独立的关系模式,也可以与任意一端对应的关系模式合并。三个或三个以上实体间的一个多元联系可以转换为一个关系模式。与该多元联系相连的各实体的码以及联系本身的属性均转换为关系的属性,而关系的码为各实体码的组合。具有相同码的关系模式可合并。
本实现所使用数据库简单,所以不需要转化。
用户表(用户姓名,密码) 已经达到第三范式。用户的结构如下表4.1所示:
表4.1 用户的结构
字段名 | 数据类型 | 是否为空 | 是否为主键 | 描述 |
用户名 | Varchar | 否 | 是 | 用户的用户名 |
密码 | varchar | 否 | 否 | 用户的密码 |
4.4.3 物理结构建立
数据库的物理设计就是为逻辑数据模型选取一个最合适应用要求的物理结构的过程,在这个阶段中要完成两大任务:
(1)确定数据库的物理结构,在关系数据库中主要是存取方法和存储结构;
(2)对物理结构进行评价,评价的重点是时间和空间效率。
4.4.4 数据库实施
(1)创建数据库
Create database jdbc;
(2)创建用户表
Use database;
Create table user(
用户名 varchar(32) not null primary key,
密码 varchar(32) not null
2、增删改查sql语句
(1)添加:"insert into user(username,password) values('%s','%s')" % (data)
(2)查询:"select * from "+user;
5 详细设计
5.1 任务目的
一、使用 scrapy 框架爬取河南各城市天气预报
1、熟练安装 Python 扩展库 scrapy。
2、熟悉常见 HTML 标签的用法。
3、理解网页源代码结构。
4、理解 scrapy 框架工作原理。
二、tkinter 版猜数游戏
1、理解 tkinter 标准库的用法。
2、熟悉创建窗体和组件的方法。
3、熟悉 tkinter 组件属性及其作用和设置方法。
4、了解如何为 tkinter 组件绑定事件处理方法。
5.2 任务内容
一、使用 scrapy 框架爬取河南各城市天气预报
安 装 Python 扩 展 库 scrapy , 然 后 编 写 爬 虫 项 目 , 从 网 站
http://www.weather.com.cn/shandong/index.shtml 爬取河南各城市的天气预报数
据,并把爬取到的天气数据写入本地文本 weather.txt。
二、tkinter 版猜数游戏
使用 Python 标准库 tkinter 编写 GUI 版本的猜数游戏。每次猜数之前要启动游戏并设置猜数范围和最大猜测次数等参数,退出游戏时显示战绩(共玩几次,猜对几次)信息。
5.3 程序描述
5.3.1 使用 scrapy框架爬取河南各城市天气预报
5.3.1.1 创建scrapy框架
1、使用scrapy startproject 项目名称 命令创建一个爬虫项目
2、创建爬虫文件,命令:scrapy genspider 文件名称 域名 创建一个爬虫文件。
5.3.1.2 操作爬虫文件提取数据
1、默认生成以下代码
import scrapy
class TestSpider(scrapy.Spider):
# 爬虫名称
name = 'test'
# 设置允许爬取的域(可以指定多个)
allowed_domains = ['baidu.com']
# 设置起始url(设置多个)
start_urls = ['http://baidu.com/']
def parse(self, response):
'''
是一个回调方法,起始url请求成功后,会回调这个方法
:param response: 响应结果
:return:
'''
Pass
2、在parse方法中做数据的提取,提取每个城市的URL。
def parse(self, response):
#处理start_url地址对应的响应
li_list=response.xpath("//div[@class='forecastBox']//dl")
for li in li_list:
url1 = li.xpath(".//dt//a/@href").extract_first()
yield scrapy.Request(
url1,
callback=self.parse1
)
3、模拟请求响应过程,通过创建处理parse1函数,提取每个城市的往后七天的天气状况信息,并把获得的数据传到piplines中储存。
def parse1(self, response):
li_list = response.xpath("//ul[@class='t clearfix']//li")
for li in li_list:
item = {}
item['城市']=response.xpath("//div[@class='con today clearfix']//div[@class='crumbs fl']//a/text()").extract()[2]
item['时间']=li.xpath(".//h1/text()").extract_first()
item['天气状况']=li.xpath(".//p[@class='wea']/text()").extract_first()
item['最高温度']=li.xpath(".//span/text()").extract_first()+"℃"
item['最低温度']=li.xpath(".//i/text()").extract_first()
item['风力']=li.xpath(".//i/text()").extract()[1]
# 把item中的值传到piplines中储存
yield item
5.3.1.3 操作piplines文件存储爬取数据
先创建打开weather.txt文件和关闭weather.txt文件的方法,再在函数process_item中操作传过来的爬取信息,保存到文件wether.txt中。
class MyspiderPipeline:
def open_spider(self,spider):
self.file=open('weather.txt','w',encoding='utf-8')
def close_spider(self,spider):
self.file.close()
def process_item(self, item, spider):
# self.file.write(str(item)+'\n')
# print(item)
for i in item.keys():
self.file.write("%-15s"%(i))
self.file.write('\n')
for i in item.values():
self.file.write("%-15s"%(i))
self.file.write('\n\n\n\n')
return item
5.3.2 tkinter版猜数游戏
5.3.2.1 登录注册界面设计
1、初始化设计窗口布局,并且居中显示
# 显示窗口
window = Tk()
# 标题
window.title("登录")
#设置窗口居中
# 获取整个屏幕的大小
screen_width,screen_height=window.maxsize()
# 设置窗口的大小
width=800
height=600
# 设置窗体在屏幕中央显示
align='%dx%d+%d+%d'%(width,height,(screen_width-width)/2,(screen_height-height)/2)
# 设置窗口的宽高
window.geometry(align)
# 设置窗口是否可以拉索,True表示可以缩放
window.resizable(width=False,height=False)
2、设置标签和文本框
# 添加标签
label1 = tk.Label(window, text="欢迎来到猜数字小游戏", font=('song', 30))
label1.place(x=160, y=100)
username_label=tk.Label(window,text="账号",font=('song',18))
username_label.place(x=200,y=200)
password_label=tk.Label(window,text="密码",font=('song',18))
password_label.place(x=200,y=300)
# 设置输入框的文本
username_text = tk.StringVar()
username_entry = tk.Entry(window,textvariable=username_text,font=("song",18),width=15)
username_entry.place(x=300,y=200)
password_text = tk.StringVar()
password_entry = tk.Entry(window,textvariable=password_text,font=("song",18),width=15)
password_entry.place(x=300,y=300)
3、设置登录和注册按钮
userlogin_button = tk.Button(window,text='登录',font=('song',18),command=user_login)
userlogin_button.place(x=255,y=400)
userreg_button = tk.Button(window,text='注册',font=('song',18),command=pop_win)
userreg_button.place(x=400,y=400)
4、对登录按钮触发的功能
def user_login():
name=username_text.get()
pwd=password_text.get()
# user_dict=read_data()
sql='select * from user'
user_dict = mysql.select(sql)
if name!='' and pwd!='':
if name in user_dict.keys():
if pwd==user_dict[name]:
# print('ok')
# messagebox.showinfo(title='成功',message='恭喜成功登录')
window.destroy()
game.welcome()
else:
# print('密码不正确')
messagebox.showerror(title='错误', message='密码不正确')
else:
# print('用户不存在')
messagebox.showerror(title='错误', message='用户不存在')
else:
# print('账号和密码不能为空')
messagebox.showerror(title='错误',message='账号和密码不能为空')
4、对注册按钮触发事件进行处理
# 注册
def pop_win():
window.destroy()
top = Tk()
top.title('注册')
width = 800
height =600
align = '%dx%d+%d+%d' % (width, height, (screen_width - width) / 2, (screen_height - height) / 2)
top.geometry(align)
top.resizable(width=True, height=False)
label1 = tk.Label(top, text="账号注册", font=('song', 30))
label1.place(x=300, y=80)
label2 = tk.Label(top, text="账号", font=('song', 18))
label2.place(x=200, y=180)
label3 = tk.Label(top, text="密码", font=('song', 18))
label3.place(x=200, y=255)
label3 = tk.Label(top, text="确认密码", font=('song', 18))
label3.place(x=150, y=320)
text1 = tk.StringVar()
entry1 = tk.Entry(top, textvariable=text1, font=("song", 18), width=15)
entry1.place(x=300, y=180)
text2 = tk.StringVar()
entry2 = tk.Entry(top, textvariable=text2, font=("song", 18), width=15)
entry2.place(x=300, y=255)
text3 = tk.StringVar()
entry3 = tk.Entry(top, textvariable=text3, font=("song", 18), width=15)
entry3.place(x=300, y=320)
def user_register():
name = text1.get()
pwd = text2.get()
confirm_pwd = text3.get()
if pwd ==confirm_pwd:
# with open('date.txt','a') as f:
# f.writelines(name+":"+pwd+'\n')
# f.flush()
# f.close()
# messagebox.showinfo(title='成功',message='注册成功')
data = (name, pwd)
sql = "insert into user(username,password) values('%s','%s')" % (data)
mysql.insert(sql)
messagebox.showinfo(title='成功', message='注册成功')
top.destroy()
Login()
else:
messagebox.showerror(title='失败', message='请保持两次密码一致')
def Return():
top.destroy()
Login()
button1 = tk.Button(top, text='注册', font=('song', 18), command=user_register)
button1.place(x=255, y=400)
button2 = tk.Button(top, text='返回登陆', font=('song', 18), command=Return)
button2.place(x=400, y=400)
实现结果图如下所示:
图5-1 登录界面图
图5-2 注册界面图
5.3.2.2 规则介绍界面设计
本界面主要实现对游戏规则介绍,界面布局主要是由多个标签和一个进入游戏按钮组成,当点击按钮时进入下个界面。
from tkinter import Tk
import tkinter as tk
import rule
def welcome():
root =Tk()
root.title("猜数字")
screen_width, screen_height = root.maxsize()
width = 800
height =600
align = '%dx%d+%d+%d' % (width, height, (screen_width - width) / 2, (screen_height - height) / 2)
root.geometry(align)
root.resizable(width=True, height=False)
# tk.Label(root, text='欢迎来到猜数字小游戏',font=('Song', 14)).grid(row=1,column=0)
# tk.Label(root, text='请在下面设置猜数的最大值和最小值以及最大猜测次数', font=('Song', 14)).grid(row=3, column=0)
label1 = tk.Label(root, text="欢迎来到猜数字小游戏", font=('Fangsong', 24))
label1.place(x=200, y=30)
label2 = tk.Label(root, text="游戏规则如下:", font=('Fangsong', 18))
label2.place(x=100, y=100)
label3 = tk.Label(root, text="1、玩家在开始游戏前需要设置猜数范围和最大猜测次数", font=('Fangsong', 18))
label3.place(x=150, y=150)
label4 = tk.Label(root, text="2、玩家在完成游戏后,若是失败,则会显示“游戏失败”", font=('Fangsong', 18))
label4.place(x=150, y=200)
label5 = tk.Label(root, text="3、玩家在完成游戏后,若是成功,则会显示“游戏成功\n本次通关一共?次机会,您在第?次成功猜对来”", font=('Fangsong', 18))
label5.place(x=150, y=250)
label6 = tk.Label(root, text="4、玩家在退出游戏后,系统会显示“您一共玩了?次,\n一共猜对了?次”", font=('Fangsong', 18))
label6.place(x=150, y=320)
def dest():
# global root
root.destroy()
rule.make_rule(1,0)
button = tk.Button(root, text='进入游戏', font=('song', 18), command=dest)
button.place(x=300, y=450)
root.mainloop()
规则介绍实现代码图如下图所示:
图5-3 规则介绍图
5.3.2.3 规则制定界面设计
1、本界面主要实现设置猜数的最大值、最小值和最大猜的次数,由四个标签、一个按钮和三个文本框组成,当输入完信息点击按钮会进入下个游戏界面。
2、代码如下:
from tkinter import Tk
import tkinter as tk
import game_process
def make_rule(con1,con2):
root1 = Tk()
root1.title("制定规则")
screen_width, screen_height = root1.maxsize()
width = 800
height = 600
align = '%dx%d+%d+%d' % (width, height, (screen_width - width) / 2, (screen_height - height) / 2)
root1.geometry(align)
root1.resizable(width=True, height=False)
label2 = tk.Label(root1, text="请在下面设置猜数的最大值和最小值以及最大猜测次数", font=('Fangsong', 18))
label2.place(x=100, y=100)
maxnum_label = tk.Label(root1, text="最大数", font=('Fangsong', 14))
maxnum_label.place(x=255, y=150)
maxnum_text = tk.StringVar()
maxnum_entry = tk.Entry(root1, textvariable=maxnum_text, font=("Fanfsong", 14), width=15)
maxnum_entry.place(x=350, y=150)
minnum_label = tk.Label(root1, text="最小数", font=('Fangsong', 14))
minnum_label.place(x=255, y=200)
minnum_text = tk.StringVar()
minnum_entry = tk.Entry(root1, textvariable=minnum_text, font=("Fanfsong", 14), width=15)
minnum_entry.place(x=350, y=200)
count_label = tk.Label(root1, text="最大猜测次数", font=('Fangsong', 14))
count_label.place(x=200, y=250)
count_text = tk.StringVar()
count_entry = tk.Entry(root1, textvariable=count_text, font=("Fanfsong", 14), width=15)
count_entry.place(x=350, y=250)
def dest():
root1.destroy()
maxnum = int(maxnum_text.get())
minnum = int(minnum_text.get())
count = int(count_text.get())
game_process.process(maxnum,minnum,count,con1,con2)
button = tk.Button(root1, text='开始游戏', font=('song', 18), command=dest)
button.place(x=300, y=400)
root1.mainloop()
3、规则制定实现代码图如下图所示:
图5-4 规则制定图
5.3.2.4 游戏过程界面设计
1、本界面主要实现游戏过程操作,后台自动生成一个随机数,用户输入答案,系统会判断用户猜的是否正确,如果正确,进入成功界面,如果机会用完还没猜对,进入失败界面,本界面主要使用三个标签、一个文本框和一个按钮组成。
2、代码如下:
from tkinter import Tk, messagebox
import tkinter as tk
import random
import success
import fail
con=0 #剩余次数
# con1=0 #玩的次数
# con2 =0 #成功次数
def random_num(maxnum,minnum):
num=random.randint(minnum,maxnum+1)
return num
def process(maxnum,minnum,count,con1,con2):
# print(maxnum,minnum)
num=random_num(maxnum,minnum) #随机生成的数
con=count #剩余次数
def compare(num, con):
# print('count:%d'%count)
# print('con:%d' %con)
root = Tk()
root.title("猜数字游戏")
screen_width, screen_height = root.maxsize()
width = 800
height = 600
align = '%dx%d+%d+%d' % (width, height, (screen_width - width) / 2, (screen_height - height) / 2)
root.geometry(align)
root.resizable(width=True, height=False)
label1 = tk.Label(root, text="您一共有"+str(count)+"次机会", font=('song', 24))
label1.place(x=280, y=50)
label2 = tk.Label(root, text="您还剩余" + str(con) + "次机会", font=('song', 24))
label2.place(x=280, y=120)
label2 = tk.Label(root, text="请输入答案", font=('song', 18))
label2.place(x=150, y=200)
answer_text = tk.StringVar()
answer_entry = tk.Entry(root, textvariable=answer_text, font=("Fanfsong", 18), width=15)
answer_entry.place(x=300, y=200)
def judge():
# print("11111111")
nonlocal con
nonlocal con1
nonlocal con2
# print(con1, con2)
num1 = int(answer_text.get())
# print(num1)
if con>0:
if num1==num:
messagebox.showinfo(title='正确', message='恭喜你猜对了')
con2 = con2 + 1
root.destroy()
success.suc(count,con,con1,con2)
elif num1>num and con !=1 :
con = con-1
messagebox.showinfo(title='错误', message='你猜大了')
root.destroy()
compare(num, con)
elif con !=1 :
con = con - 1
messagebox.showinfo(title='错误', message='你猜小了')
root.destroy()
compare(num, con)
elif num1>num and con ==1:
con = con-1
messagebox.showinfo(title='错误', message='你猜大了,并且你的机会已经用完,很遗憾你没有猜对')
root.destroy()
fail.test_fail(count, con, con1, con2)
else:
con = con-1
messagebox.showinfo(title='错误', message='你猜小了,并且你的机会已经用完,很遗憾你没有猜对')
root.destroy()
fail.test_fail(count, con, con1, con2)
button1 = tk.Button(root, text='提交', font=('song', 18), command=judge)
button1.place(x=350, y=270)
root.mainloop()
compare(num, con)
3、游戏过程实现结果图如下图所示:
图5-5 游戏过程图
5.3.2.5 猜数成功界面设计
1、本界面主要实现用户猜数成功后,对结果进行返回,并且提示用户猜对了,用户可以选择退出,或者再玩一次,选择退出会进入退出界面,选择再玩一次会选择规则制定界面。
2、代码实现:
from tkinter import Tk, messagebox
import tkinter as tk
import rule
def suc(count,con,con1,con2):
con=count-con+1
root = Tk()
root.title("成功")
screen_width, screen_height = root.maxsize()
width = 800
height = 600
align = '%dx%d+%d+%d' % (width, height, (screen_width - width) / 2, (screen_height - height) / 2)
root.geometry(align)
root.resizable(width=True, height=False)
label1 = tk.Label(root, text="恭喜你猜对了,你真厉害", font=('Fangsong', 24))
label1.place(x=200, y=100)
label5 = tk.Label(root, text="本次通关一共"+str(count)+"次机会,您在第"+str(con)+"次成功猜对来", font=('Fangsong', 18))
label5.place(x=150, y=200)
def again():
nonlocal con1
root.destroy()
con1 = con1 + 1
rule.make_rule(con1,con2)
def sign_out():
root.destroy()
root1 = Tk()
root1.title("确认退出")
screen_width1, screen_height1 = root1.maxsize()
width1 = 800
height1 = 600
align1 = '%dx%d+%d+%d' % (width1, height1, (screen_width1 - width1) / 2, (screen_height1 - height1) / 2)
root1.geometry(align1)
root1.resizable(width=True, height=False)
label = tk.Label(root1, text="您一共玩了" + str(con1) + "次,一共猜对了" + str(con2) + "次", font=('Fangsong', 18))
label.place(x=200, y=200)
def sign_out1():
root1.destroy()
button1 = tk.Button(root1, text='确认退出', font=('song', 18), command=sign_out1)
button1.place(x=300, y=380)
root1.mainloop()
button2 = tk.Button(root, text='再玩一次', font=('song', 18), command=again)
button2.place(x=250, y=380)
button3 = tk.Button(root, text='退出', font=('song', 18), command=sign_out)
button3.place(x=450, y=380)
root.mainloop()
3、猜数成功结果图如下图5-6所示:
图5-6 猜数成功图
5.3.2.6 猜数失败界面设计
1、本界面主要实现用户猜数失败后,对结果进行返回,并且提示用户猜错了,用户可以选择退出,或者再玩一次,选择退出会进入退出界面,选择再玩一次会选择规则制定界面。
2、代码实现:
from tkinter import Tk, messagebox
import tkinter as tk
import rule
def test_fail(count,con,con1,con2):
con=count-con+1
root = Tk()
root.title("失败")
screen_width, screen_height = root.maxsize()
width = 800
height = 600
align = '%dx%d+%d+%d' % (width, height, (screen_width - width) / 2, (screen_height - height) / 2)
root.geometry(align)
root.resizable(width=True, height=False)
label1 = tk.Label(root, text="本次通关一共"+str(count)+"次机会", font=('Fangsong', 24))
label1.place(x=200, y=100)
label2 = tk.Label(root, text="你的机会已经用完,很遗憾你没有猜了", font=('Fangsong', 24))
label2.place(x=200, y=200)
def again():
nonlocal con1
root.destroy()
con1 = con1 + 1
rule.make_rule(con1,con2)
def sign_out():
root.destroy()
root1 = Tk()
root1.title("确认退出")
screen_width1, screen_height1 = root1.maxsize()
width1 = 800
height1 = 600
align1 = '%dx%d+%d+%d' % (width1, height1, (screen_width1 - width1) / 2, (screen_height1 - height1) / 2)
root1.geometry(align1)
root1.resizable(width=True, height=False)
label = tk.Label(root1, text="您一共玩了" + str(con1) + "次,一共猜对了" + str(con2) + "次", font=('Fangsong', 18))
label.place(x=200, y=200)
def sign_out1():
root1.destroy()
button1 = tk.Button(root1, text='确认退出', font=('song', 18), command=sign_out1)
button1.place(x=300, y=380)
root1.mainloop()
button2 = tk.Button(root, text='再玩一次', font=('song', 18), command=again)
button2.place(x=250, y=380)
button3 = tk.Button(root, text='退出', font=('song', 18), command=sign_out)
button3.place(x=450, y=380)
root.mainloop()
3、猜数失败结果图如下图5-7所示:
图5-7 猜数失败图
5.3.2.7 数据库操作设计
1、查询操作设计
def select(sql):
connection = pymysql.connect(host='localhost', port=3306, user='root', passwd='514863',db = 'pythongame')
try:
cursor = connection.cursor()
cursor.execute(sql)
result = cursor.fetchall()
userinfo_dict = {}
for data in result:
userinfo_dict[data[0]]=data[1]
return userinfo_dict
except Exception:
print('操作失败')
finally:
cursor.close()
connection.close()
2、插入操作设计
def insert(sql):
connection = pymysql.connect(host='localhost', port=3306, user='root', passwd='514863',db = 'pythongame')
try:
cursor = connection.cursor()
cursor.execute(sql)
connection.commit()
except Exception:
print('操作失败')
finally:
cursor.close()
connection.close()
6 软件测试
6.1 使用scrapy框架爬取河南各城市天气预报
本次爬虫爬取河南各个城市的七天的天气预报信息,并保存在weather.txt文件中,爬取结果图显示结果如下图6-1所示:
图6-1 爬取结果图
6.2 tkinter版猜数游戏
6.2.1 用户注册
当用户没有游戏账号时,要先注册一个账号,本次测试信息是注册一个账号为zxc,密码为123的用户,注册结果图如下图6-2所示:
图6-2 注册结果图
6.2.2 用户登录
注册完成后,用户输入账号:zxc,密码:123,可以进入下一个界面,实现结果图如下图6-3所示:
图6-3 登录结果图
6.2.3 游戏规则
进入游戏后,则需要设置规则,最大值:10,最小值:1,最大次数:3,结果图如下图6-4所示:
图6-4 游戏规则制定图
6.2.4 游戏实现
开始游戏后,用户输入自己猜的数字,点击提交开始比较。
若用户猜的数大了,则弹出提示框,内容为“你猜大了!”,结果图如下图6-5所示:
图6-5 猜数过大结果图
若用户猜的数小了,则弹出提示框,内容为“你猜小了!”,详细内容可见下图6-6:
图6-6 猜数过小结果图
若用户猜错了,且机会已经用完,则弹出失败提示,提示内容为“你猜小/大了,且机会已用完,很遗憾你没有猜对”,详细内容可见下图6-7:
图6-7 机会用完提示框
6.2.5 游戏结束
若用户在有限机会内没有猜对,则弹出失败界面,在该界面会提示“你的机会用完了,很遗憾你没有猜对”,详细内容如下图6-8所示:
图6-8 失败界面图
若用户在有限机会内猜对,则弹出成功界面,在该界面会提示你猜对了,并显示本次猜数机会以及您在第几次成功猜对了,详细内容如下图6-9所示:
图6-9 成功界面图
在成功界面或失败界面内,若点击按钮“再玩一次”,即可返回规则制定界面重新开始游戏,详细内容如下图6-10所示:
图6-10 再玩一次界面图
在成功界面或失败界面内,若点击按钮“退出”,则弹出“确认退出”提示框,在提示框中显示“您一共玩了几次,一共猜对了几次”,再次点击“确认退出”后,即自动关闭该界面,详细内容如下图6-11所示:
图6-11 退出界面图