专栏首页Python高效编程python 在命令行模拟浏览器的进退功能

python 在命令行模拟浏览器的进退功能

简介

这一讲,我们介绍一种简单的数据结构------栈。栈这种数据结构,就像整齐堆在一起的盘子,你需要用的时候,就从最上面取走一个。当你洗碗餐具,就把洗好的新盘子放在原先盘子的上面。你能拿到的总是最上面的一个盘子,最下面的盘子总是被最后取出。抽象的说,就是 first in last out(先进去的元素,最后出来)。

图像解释

栈出栈、入栈、查看栈顶元素,由于只操作单个元素,时间复杂度为 O(1)。

python 实现栈

由于 python 的 list 数据结构十分强大,所以使用 list 的内置操作,我们很轻松地就实现了栈这种数据结构。栈作为一种受限的线性表,我们只能操作栈尾部的元素。push函数用于向栈尾部添加一个元素,pop函数用于删除栈尾的一个元素。但需要注意的是,我们需要判断栈是否为空,如果为空,我们不能进行删除元素的操作;还要判断栈是否已满,如果已满的话,我们不能进行添加元素的操作。top函数返回栈尾部的一个元素,size函数返回栈的大小。

class StackArray(object):
    def __init__(self, length):
        # length 栈被限制的大小
        self.item = []
        self.length = length

    def push(self, value):
        if self.is_full():
            raise Exception('栈已满')
        else:
            self.item.append(value)

    def pop(self):
        if self.is_empty():
            raise Exception('栈为空')
        self.item.pop()

    def top(self):
        if self.is_empty():
            raise Exception('栈为空')
        return self.item[-1]

    def is_empty(self):
        return len(self.item) == 0

    def is_full(self):
        if len(self.item) >= self.length:
            return True

    def size(self):
        return len(self.item)

接下来,我们介绍使用栈模拟浏览器进退功能的简单案例。

栈实现模拟浏览器进退功能

linux 系统下实现效果图:

浏览器进退功能是指,我连续开了a,b,c,d四个页面。退:是指从页面 d 返回页面 c ;进:是指返回页面 c 后再前进到页面 d。通过两个线性栈,就可以保存前进与后退所有的元素。但是,如果我退到页面 b 之后,我又新开了页面 e,我就无法通过页面 e 返回到页面 c,d。

第一节curses 库的安装与使用讲了curses库安装与使用,这里我就简单介绍一下:

# 屏幕不显示用户输入的字符
curses.noecho()
# 使用 curses 首先需要初始化
stdscr = curses.initscr()
# stdscr.getchar() 返回的是
# 输入的单个字符的 ascii 码值
# 假如输入'p',返回 112
stdscr.getch()
# 清除屏幕
stdscr.clear()
# 打印字符
stdscr.addstr('You win')

那么如何用 python 实现呢?

我们需要建立两个线性栈,一个主栈用来保存当前的页面和之前的几个页面,一个副栈用来保存当前页面之后的几个页面。

当进行后退操作时,副栈获取主栈最上面的元素,主栈删除这个元素,从而后退到前一个页面。

当进行前进操作时,主栈获取副栈最上面的元素,副栈删除这个元素,从而前进到下一个页面。

当新的页面被创建,显然新页面前面不存在其他页面,这是我们要清空副栈。即下面的代码:

while not temp_stack.is_empty():
  temp_stack.pop()

当主栈中只有一个元素时,显然浏览器已经后退到第一个页面,不能再后退了;当副栈没有元素时,显然浏览器已经前进到最后一个页面了,不能再前进了。用代码限制为:

length = stack.size()
if length > 1:
  temp_stack.push(stack.top())
    stack.pop()

以下为全部代码:

注:stack 为主栈,temp_stack 为副栈

在命令行执行: python + 文件名 即可运行

import curses
from curses import wrapper
from datetime import datetime

stdscr = curses.initscr()
count = 1

class StackBrowser(object):
    def __init__(self, length=200):
        self.item = []
        self.length = length

    def push(self, value):
        if self.is_full():
            return None
        else:
            self.item.append(value)

    def pop(self):
        if self.is_empty():
            return None
        self.item.pop()

    def top(self):
        if self.is_empty():
            return None
        return self.item[-1]

    def is_empty(self):
        return len(self.item) == 0

    def is_full(self):
        if len(self.item) >= self.length:
            return True

    def size(self):
        return len(self.item)

    def show_stack(self):
        print(self.item)


def print_board(stdscr):
    # stdscr.clear()
    # 清除屏幕
    for i in range(4):
        stdscr.addstr('-' * 22 + '\n')
        for j in range(4):
            stdscr.addstr('|')
            if board[i, j]:
                stdscr.addstr('{:^4d}'.format(board[i, j]))
            else:
                stdscr.addstr('    '.format())
        stdscr.addstr('|')
        stdscr.addstr('\n')
    stdscr.addstr('-' * 22 + '\n')


def print_browser(stdscr, order, stack, temp_stack):
    global count
    # datetime.now() 获取当前时间和日期
    # strftime 将日期格式化输出 年-月-日 时:分:秒
    now = '网页创建时间:{}'.format(datetime.now().strftime('%Y-%m-%d %H:%M:%S \n'))
    stdscr.clear()
    
  # 退出程序
    if order == ord('q'):
        exit()
    # 新建页面
    elif order == ord('n'):
        count += 1
        stack.push(now)
        while not temp_stack.is_empty():
            temp_stack.pop()
    # 后退功能
    elif order == ord('b'):
        length = stack.size()
        if length > 1:
            temp_stack.push(stack.top())
            stack.pop()
    # 前进功能
    elif order == ord('f'):
        length = temp_stack.size()
        if length >= 1:
            stack.push(temp_stack.top())
            temp_stack.pop()
  # 打印功能
    if stack.top():
        stack_size = stack.size()
        sum_size = stack.size() + temp_stack.size()
        stdscr.addstr(stack.top())
        stdscr.addstr('共创建了 {} 个页面 \n'.format(count))
        stdscr.addstr('当前页面:第 {} 页 \n'.format(stack_size))
        stdscr.addstr('共 {} 页 \n'.format(sum_size))


def main(stdscr):
    global count
    # 不显示输入
    curses.noecho()
    # 创建 stack 类
    # stack 为主栈
    # temp_stack 为副栈
    stack = StackBrowser()
    temp_stack = StackBrowser()
    # 获取当前时间
    now = '网页创建时间:{}'.format(datetime.now().strftime('%Y-%m-%d %H:%M:%S \n'))
    # 栈保存网页创建时间
    stack.push(now)
    stack_size = stack.size()
    sum_size = stack.size() + temp_stack.size()
    stdscr.addstr(stack.top())
    stdscr.addstr('共创建了 {} 个页面 \n'.format(count))
    stdscr.addstr('当前页面:第 {} 页 \n'.format(stack_size))
    stdscr.addstr('共 {} 页 \n'.format(sum_size))
    while 1:
        order = stdscr.getch()
        print_browser(stdscr=stdscr, order=order, stack=stack, temp_stack=temp_stack)


if __name__ == '__main__':
    wrapper(main)

本文分享自微信公众号 - Python高效编程(gh_53af3cd256b6),作者:flywind

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-12-24

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • PyQt5 从零开始制作 PDF 阅读器(二)

    上一篇文章中,我们实现了 PDF 阅读器的初始界面。这一次,新增了阅读功能,可以实现基本的翻页以及缩放等操作。不过,暂时只可以同时阅读一本书。(文末小程序留言)

    用户2870857
  • 超级简单的虚拟机(Python 实现)

    我们这次实现的简单虚拟机,和计算机的 cpu 有点类似。无非就是取指令,执行指令之类的操作。

    用户2870857
  • PyQt5 从零开始制作 PDF 阅读器(一)

    此前,我已经写了三篇关于 Ui 界面的文章,分别是:猜数游戏、计时器程序和天气查询软件。这次,我们使用 Python 实现 PDF 阅读器。

    用户2870857
  • PyQt5--QCalendar

    用户2398817
  • 爬取数据不保存,就是耍流氓 !

    OK,通过前面两篇文章《爬虫利器初体验(1)》《听说你的爬虫又被封了?(2)》,我们初体验也过了,爬虫代码健壮性也升级为 PLUS 了。都分析到这个地步了,是不...

    小小詹同学
  • iOS开发实战-基于SpriteKit的FlappyBird小游戏写在前面SpriteKit简介效果分析代码关于游戏上架TipsDemo地址还没结束

    蛋疼广电粽菊要求国内游戏必须备案... 我们只是想上个小游戏而已~难道还要再等个大半个月去备案么? Apple也妥协了 在备注那里要求中国区上架游戏必须填写...

    gwk_iOS
  • Scrapy框架系列--数据不保存,就是耍流氓(3)

    OK,通过签名两篇文章《爬虫利器初体验(1)》《听说你的爬虫又被封了?(2)》,我们初体验也过了,爬虫代码健壮性也升级为 PLUS 了。都分析到这个地步了,是不...

    1480
  • iOS原生的搜索:UISearchController

    王大锤
  • ARKit中控制.dae动画的播放

    4.用时间控制动画--CAAnimation 里的 timeOffset 控制开始时间 duration控制播放时间

  • Python3使用requests模块显

    请求关键参数:stream=True。默认情况下,当你进行网络请求后,响应体会立即被下载。你可以通过 stream 参数覆盖这个行为,推迟下载响应体直到访问 R...

    用户2398817

扫码关注云+社区

领取腾讯云代金券

玩转腾讯云 有奖征文活动