前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python 在命令行模拟浏览器的进退功能

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

作者头像
用户2870857
发布2019-12-20 12:47:20
7250
发布2019-12-20 12:47:20
举报
文章被收录于专栏:Python高效编程Python高效编程

简介

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

图像解释

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

python 实现栈

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

代码语言:javascript
复制
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库安装与使用,这里我就简单介绍一下:

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

那么如何用 python 实现呢?

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

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

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

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

代码语言:javascript
复制
while not temp_stack.is_empty():
  temp_stack.pop()

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

代码语言:javascript
复制
length = stack.size()
if length > 1:
  temp_stack.push(stack.top())
    stack.pop()

以下为全部代码:

注:stack 为主栈,temp_stack 为副栈

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

代码语言:javascript
复制
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)
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-12-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Python高效编程 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 图像解释
  • python 实现栈
  • 栈实现模拟浏览器进退功能
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档