Skip to content Skip to sidebar Skip to footer

Calculator 7 Segment Display W/ Width

I need to write a program to make a seven segment display. It will work like this: def numbers(number, width): # Code to make number A typical output could look something like t

Solution 1:

Don't try to produce segments programmatically. Enter them manually, but in a generally encoded way. This encoding should allow you to produce different outputs. Do program these.

Please consider the following code

classSSDigit(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("     ")

.....

classLineType(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= []

classLine(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 inenumerate(typeforline) :
        if digit.lines[linenum] notin linetype.valueForRepr :
            print("Error in digit {:d}, line {:d}".format(digit,linenum))

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

printNumber(3475649560458)

The strings entered for each SSDigit are just canonical representations. Its structure is only for easy developer visualization. The information required to produce different sizes and forms is encoded through these representations and the other structures.

For example,

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

printNumberDoubleSize(3475649560458)

Next step is to realize that, allowing for spacing, the display consists of a 7x5 matrix:

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

And that each line and column in the matrix are logical ones, i.e. can consist of several physical lines and/or columns, like in:

01234000123000010----20  |    |
 1  |    |
30----40  |    |
 1  |    |
50----60

Here, most logical rows and columns consist of only one physical row and column, respectively, except logical rows 2 and 4 (with 2 physical lines each), and logical column 2, with 4 physical columns.

This can be represented as a series of strings. And it can result very convenient to express for each element how we would like to see it in an off and on state. In the following definitions I indulged in some artistic liberty just for the sake of the example:

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([ "    ", " ", "    "," ", "    " ])

defprintNumberNY(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= 1for 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= 0else:
                for i, _ inenumerate(phyLine) :
                    iflen(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 inenumerate(typeforline) :
        for phyLine inrange(phyRowH[linenum]) :
            line= ""for d in num :
                for col, qq inenumerate(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)

The code for printNumberNY is not much more difficult than the one for the simple case of width*n.

The case of width*n is, in fact, a particular case of this setup, and can be constructed with:

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)

I know that I didn't use some of the elements I defined at the beginning, but this is how I would have modeled it. They could be useful if we continue extending the solution.

Solution 2:

Haha, what a fun problem!

DISP = 7#  1#2   3#  4#5   6#  7defdigit(cur, size = 5, ch = '*'):
    defdraw(led_code):    
        for a, b, c in led_code:
            if a:
                print' ' + ch * size + ' 'if b and c:
                print (ch + ' ' * size + ch + '\n') * size
                continueif 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]))
    printfor x inbin(42).split('b')[1]:
    digit(int(x))

Solution 3:

I will take this as a fun exercise (and maybe my solution gives you some ideas):

from collections import defaultdict

classCell:
    def__init__ (self, width = 4, height = 2, hChar = '*', vChar = '*'):
        self.width = width
        self.height = height
        self.hChar = hChar
        self.vChar = vChar

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

classDisplay:
    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 _ inrange (cells) ]

    defshow (self, string):
        cellLines = []
        for idx, c inenumerate (string):
            if idx >= len (self.cells): break
            cellLines.append (self.cells [idx].showSegments (self.encoding [c] ) )
        ifnot 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')

Solution 4:

I think the solution here is to just start small and work your way forward until the whole program is finished.

First write a function that can draw a single digit, say, drawTwo(), which draws the digit two. Once you have this figured out, refactor this into drawTwo(width), which draws the digit with the right width. Now that you have this figured out, it shouldn't be too hard to write one for each digit zero through ten.

Once you have your ten functions, write a function that splits your input number into its digits and calls the correct function (possibly using a switch statement) for each digit.

Just take it one step at a time.

Post a Comment for "Calculator 7 Segment Display W/ Width"