Search code examples
pythonasciiclock

How do I iterate through a list of dictionaries?


I need to take an inputted time, for example "12:20", and print a 5x3 ASCII clock representation of it. But I don't know how how iterate through a list of dictionaries, which I think is the simplest way to solve this problem.

time = input("enter a time HH:MM")
my_list = [
{"0": "000", "1": " 1 ","2":"222","3":"333","4":"44","5":"555","6":"666","7":"777","8":"888","9":"999"},
{"0": "000", "1": "11 ", "2": "  2", "3":"  3","4":"4 4","5":"5  ","6":"6  ","7":"  7","8":"8 8","9":"9 9"},
{"0": "000", "1": " 1 ", "2": "222", "3":"333","4":"444","5":"555","6":"666","7":"  7","8":"888","9":"999"},
{"0": "000", "1": " 1 ", "2": "2  ", "3":"  3","4":"  4","5":"  5","6":"6 6","7":"  7","8":"8 8","9":"  9"},
{"0": "000", "1": "111", "2": "222", "3":"333","4":"  4","5":"555","6":"666","7":"  7","8":"888","9":"  9"}
]
for i in my_list:
    for l in my_list.keys():
        if l == time[i]:
            print(my_list[i][l])

I tried making a list of dictionaries with two for loops: one for iterating through the list and one for iterating through each dictionary. If the input is 12:20, I need to print a 5x3 12:00 like so:

 1    222    222  000
11      2  :   2  0 0
 1    222    222  0 0
 1    2    : 2    0 0 
111   222    222  000

Solution

  • You were almost there. You just overlooked a few fundamentals. Such as: you have to get the entire line before you print it, names matter, and you can't print a colon if you don't include one in your segments.

    import re
    
    time_valid = re.compile(r'^\d{2}:\d{2}$')
    
    while not time_valid.match((time := input("enter a time HH:MM: "))):
        #keep asking this question til the user get's it right
        pass
        
    segments = [
    {"0":"000", "1":" 1 ", "2":"222", "3":"333", "4":"4 4", "5":"555", "6":"666", "7":"777", "8":"888", "9":"999", ":":" "},
    {"0":"0 0", "1":"11 ", "2":"  2", "3":"  3", "4":"4 4", "5":"5  ", "6":"6  ", "7":"  7", "8":"8 8", "9":"9 9", ":":":"},
    {"0":"0 0", "1":" 1 ", "2":"222", "3":"333", "4":"444", "5":"555", "6":"666", "7":"  7", "8":"888", "9":"999", ":":" "},
    {"0":"0 0", "1":" 1 ", "2":"2  ", "3":"  3", "4":"  4", "5":"  5", "6":"6 6", "7":"  7", "8":"8 8", "9":"  9", ":":":"},
    {"0":"000", "1":"111", "2":"222", "3":"333", "4":"  4", "5":"555", "6":"666", "7":"  7", "8":"888", "9":"  9", ":":" "}
    ]
    
    for segment in segments:
        line = ''
        for c in time: #gather the entire line before printing
            line = f'{line} {segment[c]}'
        print(line)
           
    

    With very little work this can be made into a console clock.

    import threading
    from datetime import datetime
    from os       import system, name
    
    #repeating timer
    class Poll(threading.Timer):  
        def run(self):  
            while not self.finished.wait(self.interval):  
                self.function(*self.args,**self.kwargs) 
                
    segments = [
    {"0":"000", "1":" 1 ", "2":"222", "3":"333", "4":"4 4", "5":"555", "6":"666", "7":"777", "8":"888", "9":"999", ":":" "},
    {"0":"0 0", "1":"11 ", "2":"  2", "3":"  3", "4":"4 4", "5":"5  ", "6":"6  ", "7":"  7", "8":"8 8", "9":"9 9", ":":":"},
    {"0":"0 0", "1":" 1 ", "2":"222", "3":"333", "4":"444", "5":"555", "6":"666", "7":"  7", "8":"888", "9":"999", ":":" "},
    {"0":"0 0", "1":" 1 ", "2":"2  ", "3":"  3", "4":"  4", "5":"  5", "6":"6 6", "7":"  7", "8":"8 8", "9":"  9", ":":":"},
    {"0":"000", "1":"111", "2":"222", "3":"333", "4":"  4", "5":"555", "6":"666", "7":"  7", "8":"888", "9":"  9", ":":" "}
    ]
    
    def display():
        #get time
        time = datetime.now().strftime("%H:%M:%S")
    
        #clear console
        system(('clear','cls')[name=='nt'])
    
        #draw console
        for segment in segments:
            line = ''
            for c in time: 
                #illustrates a simple method to replace graphics
                line = f'{line} {segment[c].replace(c,chr(9608))}'
            print(line)
    
    #start clock    
    Poll(.1, display).start()