用Python实现一个电影订票系统

news2024/12/27 1:16:23

一、效果展示

通过Python实现一个电影订票系统,效果如下所示:

二、整体结构图

三、代码分解

3.1 infos.py

一部电影的详细信息适合用 字典 结构来存储,我们可以给字典里添加多个键值对来保存电影的名称、座位表和宣传时用的字符画,比如电影《泰坦尼克号》的详细信息就可以按下面的形式保存到字典 titanic 中:

infos = [
  {
    'name': '泰坦尼克号',
    'symbol': '''
+==================== 泰坦尼克号 =====================+
  ▄▄▄▄▄▪   ▄▄▄▄▄  ▄▄▄·   ▐ ▄ ▪      ▄▄· 
  •██   ██  •██   ▐█ ▀█  •█▌▐█  ██  ▐█ ▌▪
  ▐█.▪ ▐█·  ▐█. ▪▄█▀▀█  ▐█▐▐▌  ▐█· ██ ▄▄
  ▐█▌ ·▐█▌  ▐█▌· ▐█ ▪▐▌ ██▐█▌  ▐█▌ ▐███▌
  ▀▀▀  ▀▀▀  ▀▀▀   ▀  ▀  ▀▀ █  ▪▀▀▀ ·▀▀▀ 
+===================== Titanic =====================+
''',
    'seats': [['○', '○', '○', '○', '○', '○', '○', '○'],
              ['○', '○', '○', '○', '●', '○', '○', '●'],
              ['○', '○', '●', '○', '●', '○', '○', '○'],
              ['○', '○', '●', '○', '○', '○', '○', '●'],
              ['○', '○', '●', '○', '○', '○', '●', '○'],
              ['●', '○', '○', '○', '●', '●', '●', '●']]
  },
  {
    'name': '雨人',
    'symbol': '''
+====================== 雨人 =======================+
  ,---.    .--.  ,-..-. .-.           .--.  .-. .-. 
  | .-.\  / /\ \ |(||  \| | |\    /| / /\ \ |  \| | 
  | `-'/ / /__\ \(_)|   | | |(\  / |/ /__\ \|   | | 
  |   (  |  __  || || |\  | (_)\/  ||  __  || |\  | 
  | |\ \ | |  |)|| || | |)| | \  / || |  |)|| | |)| 
  |_| \)\|_|  (_)`-'/(  (_) | |\/| ||_|  (_)/(  (_) 
      (__)         (__)     '-'  '-'       (__)     
+===================== Rain Man ====================+
''',
    'seats': [['○', '○', '○', '○', '●', '○', '○', '●'],
              ['○', '○', '○', '●', '●', '○', '○', '○'],
              ['○', '●', '○', '○', '○', '○', '○', '○'],
              ['○', '○', '○', '○', '○', '○', '○', '○'],
              ['○', '○', '●', '○', '○', '○', '○', '○'],
              ['○', '○', '○', '○', '○', '○', '○', '○']]
  },
  {
    'name': '卡门',
    'symbol': '''
+======================= 卡门 =======================+
  ▄█▄    ██   █▄▄▄▄ █▀▄▀█ ▄███▄      ▄   
  █▀ ▀▄  █ █  █  ▄▀ █ █ █ █▀   ▀      █  
  █   ▀  █▄▄█ █▀▀▌  █ ▄ █ ██▄▄    ██   █ 
  █▄  ▄▀ █  █ █  █  █   █ █▄   ▄▀ █ █  █ 
  ▀███▀     █   █      █  ▀███▀   █  █ █ 
            █   ▀      ▀           █   ██ 
          ▀                              
+====================== Carmen =====================+
''',
    'seats': [['○', '○', '○', '○', '○', '○', '○', '○'],
              ['○', '○', '●', '●', '○', '○', '●', '●'],
              ['○', '○', '○', '○', '○', '○', '●', '○'],
              ['○', '○', '○', '○', '○', '○', '○', '○'],
              ['○', '○', '○', '○', '○', '○', '○', '○'],
              ['○', '○', '○', '●', '○', '○', '○', '●']]
  },
  {
    'name': '机器人总动员',
    'symbol': '''
+==================== 机器人总动员 ===================+
   (`\ .-') /`  ('-.                           ('-.   
    `.( OO ),' ( OO ).-.                     _(  OO)  
 ,--./  .--.   / . --. / ,--.      ,--.     (,------. 
 |      |  |   | \-.  \  |  |.-')  |  |.-')  |  .---' 
 |  |   |  |,.-'-'  |  | |  | OO ) |  | OO ) |  |     
 |  |.'.|  |_)\| |_.'  | |  |`-' | |  |`-' |(|  '--.  
 |         |   |  .-.  |(|  '---.'(|  '---.' |  .--'  
 |   ,'.   |   |  | |  | |      |  |      |  |  `---. 
 '--'   '--'   `--' `--' `------'  `------'  `------'  
+====================== WALL·E =====================+
''',
    'seats': [['●', '○', '○', '○', '○', '○', '○', '○'],
              ['●', '○', '○', '○', '○', '○', '○', '●'],
              ['○', '○', '●', '○', '●', '○', '●', '○'],
              ['○', '○', '○', '○', '○', '○', '○', '●'],
              ['○', '○', '○', '○', '●', '○', '○', '○'],
              ['●', '●', '○', '○', '○', '●', '○', '○']]
  },
  {
    'name': '黑客帝国',
    'symbol': '''
+===================== 黑客帝国 =====================+
   ________            __  ___      __       _     
  /_  __/ /_  ___     /  |/  /___ _/ /______(_)  __
   / / / __ \/ _ \   / /|_/ / __ `/ __/ ___/ / |/_/
  / / / / / /  __/  / /  / / /_/ / /_/ /  / />  <  
 /_/ /_/ /_/\___/  /_/  /_/\__,_/\__/_/  /_/_/|_|  
+==================== The Matrix ===================+
''',
    'seats': [['○', '●', '○', '○', '○', '○', '○', '○'],
              ['○', '○', '○', '●', '●', '○', '○', '●'],
              ['○', '○', '○', '○', '○', '○', '○', '○'],
              ['○', '○', '○', '○', '○', '○', '○', '○'],
              ['○', '○', '○', '○', '○', '○', '○', '●'],
              ['○', '○', '●', '○', '○', '○', '○', '○']]
  },
]

3.2 seat_book.py

选座系统,需要实现下面这两样需求:

展示所有座位的预订状态,方便用户查看哪些座位还可以预订;

根据用户输入的座位号完成预订。

可以把选座系统抽象成一个类:SeatBooking,这个类包含了两种方法,check_bookings() 用于展示所有座位的预订状态,book_seat() 用于完成预订。

import time
 
class SeatBooking:
  # 展示所有座位的预订信息
  def check_bookings(self, seats):
    print("正在为您查询该场次电影的预订状态...")
    time.sleep(0.7)
    print('从上到下为 1~6 排,从左至右为 1~8 座')
    print("======================")
    for row in seats:
      time.sleep(0.1)
      print('  '.join(row))
    print("======================")
    time.sleep(0.7)
  
  # 获取符合要求的行索引
  def get_row(self):
    input_row = input("预订第几排的座位呢?请输入 1~6 之间的数字")
    valid_row = [str(i + 1) for i in range(6)]
 
    while input_row not in valid_row:
      input_row = input('没有按要求输入哦,请输入 1~6 之间的数字')
 
    row = int(input_row) - 1
    return row
  
  # 获取符合要求的列索引
  def get_col(self):
    input_column = input('预订这一排的第几座呢?请输入 1~8 之间的数字')
    valid_column = [str(i + 1) for i in range(8)]
 
    while input_column not in valid_column:
      input_column = input('没有按要求输入哦,请输入 1~8 之间的数字')
 
    column = int(input_column) - 1
    return column
 
  # 预订指定座位
  def book_seat(self, seats):
    while True:
      row = self.get_row()
      column = self.get_col()
      # 指定座位没有被预订
      if seats[row][column] == '○':
        print("正在为您预订指定座位...")
        time.sleep(0.7)
        seats[row][column] = '●'
        print("预订成功!座位号:{}排{}座".format(row + 1, column + 1))
        break  # 结束循环,退出选座
      # 指定座位已经被预订了
      else:
        print("这个座位已经被预订了哦,试试别的吧")
        time.sleep(0.7)
 
  # 预订最靠前的座位
  def book_seat_at_front(self, seats):
    print("正在为您预订最靠前的座位...")
    time.sleep(0.7)
    # 外循环:遍历 seats 的行
    for row in range(6):
      # 内循环:遍历 seats 的列
      for column in range(8):
        # 若碰到没有被预订的座位
        if seats[row][column] == '○':
          seats[row][column] = '●' # 预订该座位
          print("预订成功!座位号:{}排{}座".format(row + 1, column + 1))
          return # 结束函数的执行,返回到它被调用的地方
    # 没有在循环内部结束程序,说明不存在没有被预订的座位
    print("非常抱歉 ,所有座位都被订满了,无法为您保留座位")

3.3 film_selector.py

先来解决ling一项任务:电影选择系统。出于人性化考虑,我们希望用户既可以输入序号选择观看电影,也可以输入 x 选择退出系统。为此,我们需要完成下面两样需求:

和选座系统一样,我们可以把“选择电影场次”功能抽象成一个类,称为 电影选择系统。

而根据用户选择,预订某一场次的座位,实际上是先调用 电影选择系统 选择电影,再调用 选座系统 预订座位。这中间涉及到多次类的实例化与方法调用,为了更清晰地组织代码,我们将这部分内容也抽象成一个类,称为 控制系统。

import time
 
class FilmSelector:
  # 展示所有可选项
  def display_options(self, films):
    print("今日影院排片列表:")
    print('+================+')
    # 按行打印每部电影
    for i in range(len(films)):
      print('{} - {}'.format(i + 1, films[i]['name']))
      time.sleep(0.2)
    # 打印退出选项
    print('x - 退出')
    print('+================+')
    time.sleep(0.7)
 
  # 获取用户的选择
  def get_choice(self, films):
    # 符合要求的输入列表
    valid_choice = [str(i + 1) for i in range(len(films))]
    valid_choice.append('x')
 
    choice = input('你的选择是?')
    # 当不符合要求时,循环获取新的选项
    while choice not in valid_choice:
      choice = input('没有按照要求输入哦,请重新输入')
    # 返回用户做出的选择
    return choice

3.4 main.py

import time
from infos import infos
from film_selector import FilmSelector
from seat_booking import SeatBooking
 
class Controller:
  def __init__(self, infos):
    self.films = infos  # 电影库所有电影
    # 打印欢迎语
    self.welcome()
    # 用户选择想观看的电影
    self.choose_film()
    # 根据用户选择,执行不同流程
    if self.choice != 'x':
      # 为指定场次预订座位
      self.choose_seat()
    # 打印结束语
    self.bye()
 
  # 用户选择想观看的电影
  def choose_film(self):
    # 实例化 FilmSelector 类
    selector = FilmSelector()
    # 展示所有用户可以选择的选项
    selector.display_options(self.films)
    # 通过 get_choice() 方法获取用户选择
    self.choice = selector.get_choice(self.films)
 
  # 为指定场次预订座位
  def choose_seat(self):
    # 取出用户所选择的电影
    film = self.films[int(self.choice) - 1]
    # 取出所选择电影的电影名、座位表、宣传画
    name = film['name']
    seats_list = film['seats']
    symbol = film['symbol']
 
    # 打印提示信息和电影宣传画
    print('正在为您预订电影《{}》的座位...'.format(name))
    time.sleep(0.7)
    print(symbol)
    time.sleep(0.7)
 
    # 打印预订座位的方法列表
    print('支持的座位预订方式如下:')
    time.sleep(0.7)
    print('+==========================+')
    print("1 - 指定行列号预定座位")
    print("2 - 给我预订一个最靠前的座位!")
    print('+==========================+')
    time.sleep(0.7)
    print('')
 
    # 获取座位预订方式
    method = input('请选择座位预订方式')
    # 定义符合要求输入列表 valid_method
    valid_method = ['1','2']
    # 当不符合要求时,循环获取新的选项
    while method not in valid_method:
      method = input('没有按照要求输入哦,请重新输入')
 
    # 实例化 SeatBooking 类
    booking = SeatBooking()
    # 打印所有座位的预订信息
    booking.check_bookings(seats_list)
    # 方法 1:指定行列号
    if method == '1':
      booking.book_seat(seats_list)
    # 方法 2:预订最靠前的座位
    else:
      booking.book_seat_at_front(seats_list)
 
  # 打印欢迎语
  def welcome(self):
    print('+============================+')
    print('+      欢迎来到时光电影院       +')
    print('+============================+')
    print('')
    time.sleep(0.7)
 
  # 打印结束语
  def bye(self):
    print('')
    time.sleep(0.7)
    print('+============================+')
    print('+    已经退出系统,下次见!     +')
    print('+============================+')
 
 <br/># 实例化 Controller 类
s = Controller(infos)

就分享到这里了,赶快上手试试吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/352704.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

学自动化测试可以用这几个练手项目

练手项目的业务逻辑比较简单&#xff0c;只适合练手&#xff0c;不能代替真实项目。 学习自动化测试最难的是没有合适的项目练习。 测试本身既要讲究科学&#xff0c;又有艺术成分&#xff0c;单单学几个 api 的调用很难应付工作中具体的问题。 你得知道什么场景下需要添加显…

Webpack(应用二:HtmlWebpackPlugin)

上一文章介绍了Webpack的基本使用。 这章介绍webpack的HtmlWebpackPlugin&#xff0c;也就是上一章节遗留每次打包后&#xff0c;html都得重新链接打包地址名称&#xff0c;现在通过HtmlWebpackPlugin来实现一起打包。 提示&#xff1a;没有学习上一章的小伙伴&#xff0c;可以…

ZenBuster:一款功能强大的多线程跨平台URL枚举工具

关于ZenBuster ZenBuster是一款功能强大的多线程跨平台URL枚举工具&#xff0c;该工具基于Python开发&#xff0c;同时还具备暴力破解功能。 该工具适用于安全专业人员&#xff0c;可以在渗透测试或CTF比赛中为广大研究人员提供帮助&#xff0c;并收集和目标相关的各种信息。…

全网多种方法分析解决HTTP Status 404资源未找到的错误,TCP的3次握手,dns域名解析,发起http请求以及cookie和session的区别

文章目录1. 文章引言2. 简述URL3. http完整请求3.1 DNS域名解析3.2 TCP的3次握手3.3 发起http请求3.4 浏览器解析html代码3.5 浏览器对页面进行渲染呈现给用户4. 解决404错误的方法5. 补充知识点5.1 cookie和session的区别5.2 ChatGPT的介绍1. 文章引言 正赶上最近ChatGPT很火…

将springboot项目生成可依赖的jar,并引入到项目中

1、将springboot项目生成可依赖的jar包的方法 SpringBoot项目默认打包的是可运行jar包&#xff0c;也可以打包成不可运行的jar包。 能打成可运行的jar包是因为&#xff0c;Spring Boot 项目引入了 spring-boot-maven-plugin 依赖包。 spring-boot-maven-plugin具有repackage …

【自学Linux】 Linux文件目录结构

Linux文件目录结构 Linux文件目录结构教程 在 Linux 中&#xff0c;有一个很经典的说法&#xff0c;叫做一切皆文件&#xff0c;因此&#xff0c;我们在系统学习 Linux 之前&#xff0c;首先要了解 Linux 的文件目录结构。Linux 主要的目录有三大类&#xff0c;即根目录(/)&a…

火山引擎 DataTester:A/B 测试,让企业摆脱广告投放“乱烧钱”

更多技术交流、求职机会&#xff0c;欢迎关注字节跳动数据平台微信公众号&#xff0c;回复【1】进入官方交流群 在广告投放的场景下&#xff0c;一线广告优化师通常会创建多个计划&#xff0c;去测试不同的广告素材效果。这套方法看似科学&#xff0c;实际上却存在诸多问题&…

NJ/NX将数据写入到SD中,保存为CSV文件格式

NJ/NX将数据写入到SD中&#xff0c;保存为CSV文件格式 实验时间&#xff1a;2022.10.31 实验人员&#xff1a;钱少青 实验器材&#xff1a;NJ501-1300(Ver:1.12)&#xff0c;HMC-SD291(2G)&#xff0c;SysmacStudio(ver:1.52) 实验目的&#xff1a;将Byte、Int、Real、Stri…

3年功能3年自动化,从8k到23k的学习过程

简单的先说一下&#xff0c;坐标杭州&#xff0c;14届本科毕业&#xff0c;算上年前在阿里巴巴的面试&#xff0c;一共有面试了有6家公司&#xff08;因为不想请假&#xff0c;因此只是每个晚上去其他公司面试&#xff0c;所以面试的公司比较少&#xff09;其中成功的有4家&…

ICLR 2022—你不应该错过的 10 篇论文(下)

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 ICLR 2023已经放榜&#xff0c;但是今天我们先来回顾一下去年的ICLR 2022&#xff01; ICLR 2022将于2022年 4 月 25 日星期一至 4 月 29 日星期五在线举行&#xff08;连续第三年&#xff01;&#x…

Java中ThreadLocal类详解

ThreadLocal从名字上我们看出&#xff0c;它叫做本地线程变量&#xff0c;每个线程都有各自的的变量&#xff0c;而不再是我们之前的两个线程共用同一个变量&#xff1b;以这个类创建的变量&#xff0c;在多个线程都用到这个变量时&#xff0c;可以为每一个线程创建一个变量副本…

sql server执行md5加密的时候,字符串前带N和不带N的结果是不一样的

最近因为项目的需要&#xff0c;报表中需要对数据进行MD5加密&#xff0c;结果报表系统得出来的sql语句&#xff0c;字符串前都自动带了N&#xff0c;执行时&#xff0c;发现得到的结果跟在数据库中执行的sql&#xff08;字符串不带N&#xff09;得的值不一样&#xff0c;最后自…

RocketMQ高性能原理分析

目录一、读队列与写队列1.概念介绍2.读写队列个数关系分析二、消息持久化1.持久化文件介绍2.持久化结构介绍&#xff1a;三、过期文件删除1.如何判断文件过期2.什么时候删除过期文件四、高效文件写1.零拷贝技术加速文件读写2.文件顺序写3.刷盘机制五、 消息主从复制六、负载均衡…

微服务项目【消息推送(RabbitMQ)】

创建消费者 第1步&#xff1a;基于Spring Initialzr方式创建zmall-rabbitmq消费者模块 第2步&#xff1a;在公共模块中添加rabbitmq相关依赖 <!--rabbitmq--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-bo…

有趣的HTML实例(十三) 咖啡选择(css+js)

一个人追求目标的路途是孤单的&#xff0c;一个人独品辛酸的时候是寂寥的&#xff0c;一个人马不停蹄的追赶着&#xff0c;狂奔着&#xff0c;相信前方是一片光明&#xff0c;我从不放弃希望&#xff0c;就像我对生活的信念&#xff0c;没有人可以动摇。 ——《北京青年》 目录…

Qt扫盲- QLocalSocket类

QLocalSocket类总结一、概述二、使用一、概述 QLocalSocket类是一个比较特殊的传输数据的的一个工具类&#xff0c;它和 QTcpSocket 的区别就是&#xff0c;这个QLocalServer 只是在connectToServer 的时候连接主机是用的一个字符串或者标识符来表示主机&#xff0c;而QTcpSoc…

基于模型预测控制(MPC)的悬架系统仿真分析

目录 前言 1.悬架系统 2.基于MPC的悬架系统仿真分析 2.1 simulink模型 2.2仿真结果 2.3 结论 3 总结 前言 模型预测控制是无人驾驶中较为热门的控制算法&#xff0c;但是对于悬架等这类系统的控制同样适用。 我们知道模型预测控制主要可以划分为三个部分&#xff1a; …

ForkJoinPool原理

1、概述 Fork/Join框架是Java7提供了的一个用于并行执行任务的框架。ForkJoinPool是Java中提供了一个线程池&#xff0c;特点是用来执行分治任务。主题思想是将大任务分解为小任务&#xff0c;然后继续将小任务分解&#xff0c;直至能够直接解决为止&#xff0c;然后再依次将任…

再谈Java的String字符串

我们先看下面几个常见的面试题&#xff1a; String s1 "abc";String s2 new String("abc");String s3 "a" "b" "c";String s4 s2.intern();System.out.printf("s1s2:%s\n", s1 s2);System.out.printf(&quo…

IOS安全区域适配

对于 iPhone 8 和以往的 iPhone&#xff0c;由于屏幕规规整整的矩形&#xff0c;安全区就是整块屏幕。但自从苹果手机 iphoneX 发布之后&#xff0c;前端人员在开发移动端Web页面时&#xff0c;得多注意一个对 IOS 所谓安全区域范围的适配。这其实说白了就是 iphoneX 之后的苹果…