编程珠玑3-8

问题

8.[S.C.Johnnson]七段显示设备实现十进制数字:

在这里插入图片描述

的廉价显示。七段显示通常如下编号:

在这里插入图片描述

编写一个使用5个七段显示数字来显示16位正整数的程序。输出为一个5个字节的数组,当且仅当数字j中的第i段点亮时,字节j中的位i置1

分析

简单翻译一下题目的意思,编写一个程序,实现给定一个数字,包含5位,在终端输出图像

举个例子,向程序输入82367,在终端显示
在这里插入图片描述

这题需要解决的核心问题时,如何将数转换为图像(二维数组)

举个例子
在这里插入图片描述
这是7段显示的编码,如果我们提前知道所有数对应的编码同时知道编码对应二维数组的坐标。那么我们就可以通过数转换为编码,编码对应坐标,最后根据坐标进行可视化

现在,我们拥有一个7 x 4的二维数组,如果我们要绘制8,如上图所示,8对应的七段编码为[0, 1, 2, 3, 4, 5, 6, 7]

以编码0为例子,0对应7 x 4的二维数组的坐标是:(6, 1), (6, 2)。以此类推,获取剩下编码对应的坐标,即可将数字转换为二维数组的坐标。然后在数组中填充对应的内容,最后就完成了对应过程
在这里插入图片描述

代码

为了程序可维护性,做了一些抽象。

聚合
聚合
聚合
Rule
int number_row
int number_col
int interval
map id_pos # 七段显示的编号对应的坐标
map number_ids # 每个数字对应的编号集合
Number
Rule rule
int number
set_number(number)
gen_graphic() : List[][]
Display
List[][] graphic # 最终显示的图像
List[] number_list # 5个7段显示
displat(number)
reader(number)
writer()

Rule是规则类,定义了一些列规则

  • 一个七段显示,对应数组的维度
  • 每个七段显示之间的间隔
  • 每个数字对应的编号
  • 编号对应的坐标

Number是数字类,用于维护一个0~9之间数字与二维数组之间的转换

Display是显示屏类,用于集中维护5个7段显示,并打印数字

代码

from typing import List

'''
定义规则
'''
class Rule:
    # 七段显示数字的数组维度
    number_row = 7
    number_col = 4
    # 5个七段显示数字之间的间隔
    interval = 2

    const = {
        'horizon': '-',
        'vertical': '|',
    }

    def __init__(self):
        # 七段显示的编号坐标
        self.id_pos = {
            0: [(6, 1, Rule.const['horizon']), (6, 2, Rule.const['horizon'])]
            , 1: [(3, 1, Rule.const['horizon']), (3, 2, Rule.const['horizon'])]
            , 2: [(0, 1, Rule.const['horizon']), (0, 2, Rule.const['horizon'])]
            , 3: [(1, 0, Rule.const['vertical']), (2, 0, Rule.const['vertical'])]
            , 4: [(1, 3, Rule.const['vertical']), (2, 3, Rule.const['vertical'])]
            , 5: [(4, 0, Rule.const['vertical']), (5, 0, Rule.const['vertical'])]
            , 6: [(4, 3, Rule.const['vertical']), (5, 3, Rule.const['vertical'])]
        }
        # 数字通过七段显示展示时, 需要的七段显示编号
        self.number_ids = {
            0: [x for x in range(7) if x not in (1,)]
            , 1: [4, 6]
            , 2: [x for x in range(7) if x not in (3, 6)]
            , 3: [x for x in range(7) if x not in (3, 5)]
            , 4: [x for x in range(7) if x not in (2, 5)]
            , 5: [x for x in range(7) if x not in (4, 5)]
            , 6: [x for x in range(7) if x not in (4,)]
            , 7: [x for x in range(7) if x not in (1, 3, 5, 0)]
            , 8: range(7)
            , 9: [x for x in range(7) if x not in (0, 5)]
        }


class Number:
    def __init__(self, number: int):
        self.rule = Rule()
        self.number = number

    def set_number(self, number):
        self.number = number

    '''
    将0-9中的数字转换为图像(二维数组) 
    '''
    def gen_graphic(self) -> List[List]:
        # 获取数字对应7段显示的编号
        ids = self.rule.number_ids[self.number]
        graphic = [[' ' for _ in range(Rule.number_col)] for _ in range(Rule.number_row)]
        # 遍历所有编号, 获取编号对应的坐标集合
        for id in ids:
            # (x, y) -> 数组坐标; w -> 数组需要填充的字符内容
            for x, y, w in self.rule.id_pos[id]:
                graphic[x][y] = w
        return graphic


class Display:
    def __init__(self):
        # 5个7段显示需要的数组维度
        self.graphic = [[' ' for _ in range(5 * Rule.number_col + 4 * Rule.interval)] for _ in range(Rule.number_row)]
        # 5个7段显示
        self.number_list = [Number(i) for i in range(5)]

    '''
    图像归位 
    '''
    def clear(self):
        self.graphic = [[' ' for _ in range(5 * Rule.number_col + 4 * Rule.interval)] for _ in range(Rule.number_row)]

    '''
    显示数字
    '''
    def display(self, number: int):
        self.clear()
        self.reader(number)
        self.writer()

    '''
    读取需要显示的数字
    '''
    def reader(self, number: int):
        params = []
        while number != 0:
            params.append(number % 10)
            number //= 10
        size = len(params)
        for _ in range(size, 5):
            params.append(0)
        params.reverse()
        # 赋值不同的数字
        for idx, n in enumerate(self.number_list):
            n.set_number(params[idx])

    '''
    赋值graphic, 打印图像
    '''
    def writer(self):
        for idx, n in enumerate(self.number_list):
            # 数组拷贝, 将5个七段显示绘制的二维数组拷贝到display中的数组
            new_gra = n.gen_graphic()
            for i in range(len(new_gra)):
                # col_len需要考虑每个七段显示之间的间隔
                col_len = Rule.number_col + Rule.interval
                self.graphic[i][idx * col_len: (idx + 1) * col_len] = new_gra[i]
        # 绘图
        for row in self.graphic:
            for r in row:
                print(r, end='')
            print()

测试

display = Display()
print(82367)
display.display(82367)
print(12345)
display.display(12345)
print(53245)
display.display(53245)

在这里插入图片描述

  • 21
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值