Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Binary Clock
#1
So I started what I thought would be a pretty simple project, but through perseverance was able to turn it into something complicated.  It's rather long, 227 lines, and works with Python 3.4 and 3.6, on Windows 10 and OpenSuse 42.2 Linux.  You will need the third party libraries "colorama" and "cursor", both of which can be installed with "pip".  Right now, the display is in "cheater" mode, in that it shows the numbers, but if you're nerdy enough, you can change it to display any single character you want (within reason) (no, I did not try the unicode 'Pile of Poo').  I could only think of using a counter (default is 1 minute) and using "Control + C" to exit before the timer runs out.  I tried to make it as a gui, but, well I have no talent what so ever in that regard and it rapidly turned into a major cluster f--k, so a plain terminal is what you get  Angel

Any suggestions would be appreciated. Enjoy  Smile

If it ain't broke, I just haven't gotten to it yet.
OS: Windows 10, openSuse 42.3, freeBSD 11, Raspian "Stretch"
Python 3.6.5, IDE: PyCharm 2018 Community Edition
Reply
#2
200+ lines of code... You should put it on github or somewhere else as a file.  Smile

I don't feel it like a binary. No 0 1 sequence. But is a quite interesting idea. :D

I have another one. Or two. Hex clock. Percentage clock ( instead of hours, minutes and seconds percent from 24 hours as HH, percent from 60 minutes for MM and so on)

00%:90% for 00:54 as it is now. No seconds here
"As they say in Mexico 'dosvidaniya'. That makes two vidaniyas."
https://freedns.afraid.org
Reply
#3
i like the % clock idea ... basically base 100

could just have a clock with a choosable number base
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#4
Can't promise you I didn't make any mistakes here, but something to think about in terms of reducing a lot of that redundant code:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
 
import os
import time
import cursor
import colorama as cr
 

COLUMN_POSITIONS = (5, 8, 13, 16, 21, 24)
 

def get_cursor_locations(column):
    locations = {2**i : cr.Cursor.POS(column, 11-2*i) for i in range(5)}
    locations[0] = cr.Cursor.POS(column, 13)
    return locations


def render(display, digit, cursors):
    binary = bin(int(digit))[:1:-1]
    if not any(int(bit) for bit in binary):
        print("{}{}{}".format(display, cursors[0], 0))
    else:
        for i,bit in enumerate(binary):
            if int(bit):
                print("{}{}{}".format(display, cursors[2**i], 2**i))


def main():
    cursor.hide()
    try:
        for c in range(60):    # Currently set for 1 min. (1 hr = 3600, 24 hrs = 86400)
            os.system('cls' if os.name == 'nt' else 'clear')
 
            # Get current time: hours (24 hour clock), minutes, seconds) and put in a list
            t_now = [time.strftime("%H"), time.strftime("%M"), time.strftime("%S")]
            str_t = "".join(t_now)
 
            # Initialize and set some colors for colorama
            cr.init()
            off = cr.Back.BLACK
            on = cr.Fore.RED
 
            # Print Header
            tab = " " * 4
            print(off)
            print(on + tab + 'HRS' + tab + ' MIN' + tab + ' SEC' + "\n")
 
            # Run clock
            display = cr.Fore.RED
            for digit, column in zip(str_t, COLUMN_POSITIONS):
                render(display, digit, get_cursor_locations(column))
            
            time.sleep(1)
    except KeyboardInterrupt:
        print("\n" * 8)
        print("Program stopped")
        print(cr.deinit())
        cursor.show()  # Show cursor again
        exit(0)
 
    print("\n" * 8)
    print(cr.deinit())
    cursor.show()    # Show cursor again

 
if __name__ == "__main__":
    main()
Reply
#5
Sweet sassy molassey.  First, it runs fine. Second, I am in awe that you were able to reduce it to so few lines of code.  I will have to look at it more closely later today and see if I can follow along with what you did.  Just amazing.  Clap
If it ain't broke, I just haven't gotten to it yet.
OS: Windows 10, openSuse 42.3, freeBSD 11, Raspian "Stretch"
Python 3.6.5, IDE: PyCharm 2018 Community Edition
Reply
#6
Mucked around with it a bit more and tried to clean things up (also changed display to binary):
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
 
import os
import time
import cursor
import colorama as cr
 

TAB = " " * 4
DISPLAY = cr.Style.BRIGHT + cr.Fore.RED
ON = cr.Style.BRIGHT + cr.Fore.GREEN
OFF = DISPLAY
COLUMN_POSITIONS = (5, 8, 13, 16, 21, 24)
 

def get_cursor_locations(column):
    locations = {2**i : cr.Cursor.POS(column, 9-2*i) for i in range(4)}
    locations[0] = cr.Cursor.POS(column, 11)
    return locations


def render(digit, cursors):
    binary = "{:0<4}".format(bin(digit)[:1:-1])
    for i,bit in enumerate(binary):
        color = ON if int(bit) else OFF
        print("{}{}{}".format(color, cursors[2**i], bit))


def startup():
    cursor.hide()
    cr.init()
    

def cleanup(message):
    print(DISPLAY + "\n" * 8)
    print(message)
    cursor.show()
    cr.deinit()


def run(seconds):
    for _ in range(seconds):
        os.system('cls' if os.name == 'nt' else 'clear')
        time_digits = map(int, time.strftime("%H%M%S"))
        print(TAB.join([DISPLAY, "HRS", " MIN", " SEC"]))
        for digit, column in zip(time_digits, COLUMN_POSITIONS):
            render(digit, get_cursor_locations(column))
        time.sleep(1)

    
def main():
    startup()
    seconds_to_run = 500
    try:
        run(seconds_to_run)
        cleanup("{} second timer expired.".format(seconds_to_run))
    except KeyboardInterrupt:
        cleanup("Program stopped.")

 
if __name__ == "__main__":
    main()
Anyway, not trying to steal your thunder; just having a bit of fun.
Reply
#7
Nice. And pretty holiday colors  Smile  .  The one thing I notice is the lack of row 5 (0), so midnight 00:00:00 won't show up.

Quote:Anyway, not trying to steal your thunder; just having a bit of fun.

Steal all the thunder you want; you get some fun and I get some educating, it's all good  Dance
If it ain't broke, I just haven't gotten to it yet.
OS: Windows 10, openSuse 42.3, freeBSD 11, Raspian "Stretch"
Python 3.6.5, IDE: PyCharm 2018 Community Edition
Reply
#8
(Dec-31-2016, 10:17 PM)sparkz_alot Wrote: The one thing I notice is the lack of row 5 (0), so midnight 00:00:00 won't show up.
Midnight should work just fine.  It will be all zeros.  

Anyway, latest version.  Flickering fixed; update speed increased so we don't miss some seconds (as could happen before); deciseconds added; some overall simplifications:  
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os
import time
import cursor
import colorama as cr

from datetime import datetime


TAB = " " * 4
UPDATE_SPEED = 1 / 60.0
DISPLAY = cr.Style.BRIGHT + cr.Fore.RED
ON = cr.Style.BRIGHT + cr.Fore.GREEN
OFF = DISPLAY
COLUMN_POSITIONS = (5, 7, 13, 15, 21, 23, 29)
START_ROW = 3


def get_cursor_locations(column):
   return [cr.Cursor.POS(column, START_ROW+2*i) for i in range(4)]


def render(digit, cursors):
   binary = bin(digit)[2:].zfill(4)
   for bit, cursor in zip(binary, cursors):
       color = ON if int(bit) else OFF
       print("{}{}{}".format(color, cursor, bit))


def startup():
   cursor.hide()
   cr.init()


def cleanup(message):
   print(DISPLAY + "\n" * 8)
   print(message)
   cursor.show()
   cr.deinit()


def run(seconds):
   print(TAB.join([DISPLAY, "HRS", " MIN", " SEC"]))
   start_time = time.clock()
   while time.clock() - start_time < seconds:
       time_digits = map(int, datetime.now().strftime("%H%M%S%f"))      
       for digit, column in zip(time_digits, COLUMN_POSITIONS):
           render(digit, get_cursor_locations(column))
       time.sleep(UPDATE_SPEED)


def main():
   startup()
   seconds_to_run = 60
   try:
       run(seconds_to_run)
       cleanup("{} second timer expired.".format(seconds_to_run))
   except KeyboardInterrupt:
       cleanup("Program stopped.")

 
if __name__ == "__main__":
   main()
Reply
#9
turn the volume up, there be thunder emanating from the board!
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#10
Fantastic and I like the way the flicker is completely gone.

I did make 2 minor changes (my turn to apologize  Angel ) . 

First, I added the 'clear screen' to your 'startup' function:

def startup():
    os.system('cls' if os.name == 'nt' else 'clear')
    cursor.hide()
    cr.init()
and second, I added "DS" to the new deci-second column:

    print(TAB.join([DISPLAY, "HRS", " MIN", " SEC", " DS"]))
Great to see how you turned my clunker into a Rolls Royce.  :-D
If it ain't broke, I just haven't gotten to it yet.
OS: Windows 10, openSuse 42.3, freeBSD 11, Raspian "Stretch"
Python 3.6.5, IDE: PyCharm 2018 Community Edition
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Playing around with a clock's seconds in tkinter menator01 1 2,422 Feb-12-2022, 04:32 PM
Last Post: menator01
  Simple wxpython digital clock menator01 2 4,019 Feb-20-2021, 05:47 PM
Last Post: menator01
  My Attempt at an alarm clock menator01 0 2,424 May-15-2020, 06:28 PM
Last Post: menator01

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020