计算器7段显示w /宽度

时间:2013-08-25 02:06:16

标签: python python-3.x image-segmentation

我需要编写一个程序来进行七段显示。它会像这样工作:

def numbers(number, width):
  # Code to make number

典型的输出可能如下所示:

numbers(100, 2)

    --   -- 
 | |  | |  |
 | |  | |  |

 | |  | |  |
 | |  | |  |
    --   --

numbers(24, 1)

 -  
  | | |
 -   -
|     |
 -

numbers(1234567890, 1)

   -   -       -   -   -   -   -   - 
|   |   | | | |   |     | | | | | | |
   -   -   -   -   -       -   -     
| |     |   |   | | |   | | |   | | |
   -   -       -   -       -   -   - 

numbers(8453, 3)

 ---         ---   --- 
|   | |   | |         |
|   | |   | |         |
|   | |   | |         |
 ---   ---   ---   --- 
|   |     |     |     |
|   |     |     |     |
|   |     |     |     |
 ---         ---   --- 

无论如何,这些是一些例子(打字需要很长时间,请注意)。我知道我可以使用诸如'-' * number之类的东西,但这只是令人沮丧,因为我无法弄明白!我觉得我应该使用课程或其他东西,但我不能完全指责它。

谢谢。

4 个答案:

答案 0 :(得分:3)

不要尝试以编程方式生成细分。手动输入,但采用通常编码的方式。此编码应允许您生成不同的输出。 执行编程。

请考虑以下代码

class SSDigit(object):
    """A 7-segment digit"""
    def __init__(self):
        self.lines= []

ssdig0= SSDigit()
ssdig1.lines.append("     ")
ssdig0.lines.append("  -  ")
ssdig0.lines.append(" | | ")
ssdig0.lines.append("     ")
ssdig0.lines.append(" | | ")
ssdig0.lines.append("  -  ")
ssdig1.lines.append("     ")

ssdig1= SSDigit()
ssdig1.lines.append("     ")
ssdig1.lines.append("     ")
ssdig1.lines.append("   | ")
ssdig1.lines.append("     ")
ssdig1.lines.append("   | ")
ssdig1.lines.append("     ")
ssdig1.lines.append("     ")

.....

class LineType(object):
    """Each of the 2 line types (1 horizontal segment or 2 vertical),
       with their possible representations and segment positions"""
    def __init__(self):
        self.valueForRepr= {}
        self.segmentPos= []

class Line(object):
    """Each of the 5 lines a SSDigit has, with its LineType"""
    def __init__(self):
        self.type= None

digits= [ ssdig0, ssdig1, ssdig2, ssdig3, ssdig4, ssdig5, ssdig6, ssdig7, ssdig8, ssdig9 ]

linetype1= LineType()
linetype1.valueForRepr["     "]= [0]
linetype1.valueForRepr["  -  "]= [1]
linetype1.segmentPos= [3]

linetype2= LineType()
linetype2.valueForRepr["     "]= [0,0]
linetype2.valueForRepr["   | "]= [0,1]
linetype2.valueForRepr[" |   "]= [1,0]
linetype2.valueForRepr[" | | "]= [1,1]
linetype2.segmentPos= [2,4]

typeforline= [ linetype1, linetype2, linetype1, linetype2, linetype1 ]

# Validate error-prone typing !!!
for digit in digits :
    for linenum, linetype in enumerate(typeforline) :
        if digit.lines[linenum] not in linetype.valueForRepr :
            print("Error in digit {:d}, line {:d}".format(digit,linenum))

def printNumber(num):
    num= str(num)
    for linenum, linetype in enumerate(typeforline) :
        line= ""
        for d in num :
            line+= digits[int(d)].lines[linenum]
        print( line )

printNumber(3475649560458)

为每个SSDigit输入的字符串只是规范表示。其结构仅用于简化开发人员可视化。生成不同大小和形式所需的信息通过这些表示和其他结构进行编码。

例如,

def printNumberDoubleSize(num):
    num= str(num)
    for linenum, linetype in enumerate(typeforline) :
        line= ""
        for d in num :
            line+= digits[int(d)].lines[linenum]
        print( line )

printNumberDoubleSize(3475649560458)

下一步是要意识到,允许间距,显示器由7x5矩阵组成:

  01234
0   
1   -
2  | |
3   -
4  | |
5   -
6

矩阵中的每一行和每列都是逻辑的,即可以包含几个物理行和/或列,如:

   012   34
   00012300 
00   
10   ----
20  |    |
 1  |    |
30   ----
40  |    |
 1  |    |
50   ----
60

这里,大多数逻辑行和列分别只包含一个物理行和列,逻辑行2和4(每行有2条物理行)除外,逻辑列2有4个物理列。

这可以表示为一系列字符串。并且可以非常方便地表达我们希望在关闭和开启状态下看到它的每个元素。在下面的定义中,我为了这个例子而沉迷于某种艺术自由:

phyLineN= []
phyLineN.append([])
phyLineN[0]= []
phyLineN[0].append([ "....", ".", "....",".", "...." ])
phyLineN.append([])
phyLineN[1]= []
phyLineN[1].append([ ".   ", " ", ". . "," ", "    " ])
phyLineN.append([])
phyLineN[2]= []
phyLineN[2].append([ ".   ", ".", "    ",".", "    " ])
phyLineN[2].append([ ".   ", " ", "    "," ", "    " ])
phyLineN.append([])
phyLineN[3]= []
phyLineN[3].append([ ".   ", " ", ". . "," ", "    " ])
phyLineN.append([])
phyLineN[4]= []
phyLineN[4].append([ ".   ", ".", "    ",".", "    " ])
phyLineN[4].append([ ".   ", " ", "    "," ", "    " ])
phyLineN.append([])
phyLineN[5]= []
phyLineN[5].append([ ".   ", " ", ". . "," ", "    " ])
phyLineN.append([])
phyLineN[6]= []
phyLineN[6].append([ "....", ".", "....",".", "...." ])

phyLineY= []
phyLineY.append([])
phyLineY[0]= []
phyLineY[0].append([ "    ", " ", "    "," ", "    " ])
phyLineY.append([])
phyLineY[1]= []
phyLineY[1].append([ "    ", " ", "===="," ", "    " ])
phyLineY.append([])
phyLineY[2]= []
phyLineY[2].append([ "    ", "H", "    ","H", "    " ])
phyLineY[2].append([ "    ", "H", "    ","H", "    " ])
phyLineY.append([])
phyLineY[3]= []
phyLineY[3].append([ "    ", " ", "===="," ", "    " ])
phyLineY.append([])
phyLineY[4]= []
phyLineY[4].append([ "    ", "H", "    ","H", "    " ])
phyLineY[4].append([ "    ", "H", "    ","H", "    " ])
phyLineY.append([])
phyLineY[5]= []
phyLineY[5].append([ "    ", " ", "===="," ", "    " ])
phyLineY.append([])
phyLineY[6]= []
phyLineY[6].append([ "    ", " ", "    "," ", "    " ])

def printNumberNY(num,structN,structY):

    phyRowH= [ len(structN[0]), len(structN[1]), len(structN[2]), len(structN[3]), len(structN[4]), len(structN[5]), len(structN[6]) ]

    # Validate structure and compute phyColW
    # This could be moved to an object constructor so is computed only once
    first= 1
    for line in structN :
        for phyLine in line :
            if first :
                phyColW= [ len(phyLine[0]), len(phyLine[1]), len(phyLine[2]), len(phyLine[3]), len(phyLine[4]) ] 
                first= 0
            else:
                for i, _ in enumerate(phyLine) :
                    if len(phyLine[i]) != phyColW[i] : raise "Inconsistent physical column width"

    # Real rendering of the (full) number in 7-segment form
    num= str(num)
    for linenum, linetype in enumerate(typeforline) :
        for phyLine in range(phyRowH[linenum]) :
            line= ""
            for d in num :
                for col, qq in enumerate(phyColW) :
                    if digits[int(d)].lines[linenum][col] != " " :
                        line+= structY[linenum][phyLine][col]
                    else:
                        line+= structN[linenum][phyLine][col]
            print( line )

printNumberNY(3475649560458,phyLineN,phyLineY)

printNumberNY的代码并不比宽度为* n的简单情况的代码困难得多。

宽度* n的情况实际上是此设置的特例,可以使用以下内容构建:

def sizeVH(vSegHeight,hSegWidth,vSep,hSep):

    hSepStr= " " *hSep
    hSegN= " "* hSegWidth 
    hSegY= "-"* hSegWidth

    phyLineN= []
    phyLineN.append([])
    phyLineN[0]= []
    phyLineN.append([])
    phyLineN[1]= []
    phyLineN[1].append([ "", " ", hSegN," ", hSepStr ])
    phyLineN.append([])
    phyLineN[2]= []
    for i in range(vSegHeight) :
        phyLineN[2].append([ "", " ", hSegN," ", hSepStr ])
    phyLineN.append([])
    phyLineN[3]= []
    phyLineN[3].append([ "", " ", hSegN," ", hSepStr ])
    phyLineN.append([])
    phyLineN[4]= []
    for i in range(vSegHeight) :
        phyLineN[4].append([ "", " ", hSegN," ", hSepStr ])
    phyLineN.append([])
    phyLineN[5]= []
    phyLineN[5].append([ "", " ", hSegN," ", hSepStr ])
    phyLineN.append([])
    phyLineN[6]= []
    for i in range(vSep) :
        phyLineN[6].append([ "", " ", hSegN," ", hSepStr ])

    phyLineY= []
    phyLineY.append([])
    phyLineY[0]= []
    phyLineY.append([])
    phyLineY[1]= []
    phyLineY[1].append([ "", " ", hSegY," ", hSepStr ])
    phyLineY.append([])
    phyLineY[2]= []
    for i in range(vSegHeight) :
        phyLineY[2].append([ "", "|", hSegN,"|", hSepStr ])
    phyLineY.append([])
    phyLineY[3]= []
    phyLineY[3].append([ "", " ", hSegY," ", hSepStr ])
    phyLineY.append([])
    phyLineY[4]= []
    for i in range(vSegHeight) :
        phyLineY[4].append([ "", "|", hSegN,"|", hSepStr ])
    phyLineY.append([])
    phyLineY[5]= []
    phyLineY[5].append([ "", " ", hSegY," ", hSepStr ])
    phyLineY.append([])
    phyLineY[6]= []
    for i in range(vSep) :
        phyLineY[6].append([ "", " ", hSegN," ", hSepStr ])

    return (phyLineN,phyLineY)

phyLineN, phyLineY= sizeVH(4,6,1,3)
printNumberNY(3475649560458,phyLineN,phyLineY)

我知道我没有使用我在开始时定义的一些元素,但这就是我将它建模的方式。如果我们继续扩展解决方案,它们可能会很有用。

答案 1 :(得分:1)

哈哈,多么有趣的问题!

DISP = 7
#  1
#2   3
#  4
#5   6
#  7

def digit(cur, size = 5, ch = '*'):
    def draw(led_code):    
        for a, b, c in led_code:
            if a:
                print ' ' + ch * size + ' '
            if b and c:
                print (ch + ' ' * size + ch + '\n') * size
                continue

            if b:
                print (ch + ' ' * size + ' ' + '\n') * size
            if c:
                print (' ' + ' ' * size + ch + '\n') * size
    digits = {
        1 : [(0,0,1),(0,0,1),(0,0,0)],
        0 : [(1,1,1),(0,1,1),(1,0,0)]
    }

    draw(digits.get(cur, digits[1]))
    print


for x in bin(42).split('b')[1]:
    digit(int(x))

答案 2 :(得分:1)

我会把这作为一个有趣的练习(也许我的解决方案会给你一些想法):

from collections import defaultdict

class Cell:
    def __init__ (self, width = 4, height = 2, hChar = '*', vChar = '*'):
        self.width = width
        self.height = height
        self.hChar = hChar
        self.vChar = vChar

    def showSegments (self, segments):
        def char (segment):
            if segment not in segments: return ' '
            return self.hChar if segment in (0, 3, 6) else self.vChar
        lines = []
        lines.append (' ' + char (0) * self.width + ' ')
        for _ in range (self.height):
            lines.append (char (1) + ' ' * self.width + char (2) )
        lines.append (' ' + char (3) * self.width + ' ')
        for _ in range (self.height):
            lines.append (char (4) + ' ' * self.width + char (5) )
        lines.append (' ' + char (6) * self.width + ' ')
        return lines

class Display:
    def __init__ (self, encoding, cells, padding = 1, width = 4, height = 2, hChar = '*', vChar = '*'):
        self.encoding = encoding
        self.padding = padding
        self.cells = [Cell (width, height, hChar, vChar) for _ in range (cells) ]

    def show (self, string):
        cellLines = []
        for idx, c in enumerate (string):
            if idx >= len (self.cells): break
            cellLines.append (self.cells [idx].showSegments (self.encoding [c] ) )
        if not cellLines: return
        cellLines = zip (*cellLines)
        print ('\n'.join ( (' ' * self.padding).join (line) for line in cellLines) )

encoding = defaultdict (lambda: {} )
encoding ['0'] = {0, 1, 2, 4, 5, 6}
encoding ['1'] = {2, 5}
encoding ['2'] = {0, 2, 3, 4, 6}
encoding ['3'] = {0, 2, 3, 5, 6}

d = Display (encoding, 5, 2)
d.show ('12301')

答案 3 :(得分:0)

我认为这里的解决方案是从小做起,继续前进,直到整个程序完成。

首先编写一个可以绘制单个数字的函数,比如drawTwo(),它绘制数字2。一旦弄清楚这一点,将其重构为drawTwo(width),它绘制正确宽度的数字。现在您已经弄明白了,为每个数字0到10编写一个应该不会太难。

一旦掌握了十个函数,编写一个函数将输入数字拆分为数字,并为每个数字调用正确的函数(可能使用switch语句)。

一步一步。