Pomodoro Timer in Python I wrote a simple Pomodoro Timer in Python 3:

from datetime import datetime, timedelta
from gi import require_version
require_version('Notify', '0.7')
from gi.repository import Notify
import sys 

class State:
    #length: the length of the state in minutes
    def __init__(self, length):
        if not length == None:
            self.length = length

class Clock:
    work = None
    sBreak = None 
    lBreak = None

    numWork = 4
    remWork = numWork #number of work sessions remaining
    remBreaks = numWork - 1 #number of short break sessions remaining
    current = None #the current state
    endtime = None #datetime object for end time of current 

    def __init__(self, workTime, sBreakTime, lBreakTime):
        if workTime == None or sBreakTime == None or lBreakTime == None:
            exit(1)
        self.work = State(workTime)
        self.sBreak = State(sBreakTime)
        self.lBreak = State(lBreakTime)
        self.states = [self.work, self.sBreak, self.lBreak]

    def change(self):    
        if not self.current == None and not self.current in self.states:
            exit(1)

        title = ''
        timeStr = 'End Time: '

        #current doesn't exist: start the first work period
        if self.current == None:
            self.current = self.work 
            title = 'Work Period'

        #in work state now: either short or long break
        elif self.current == self.work:
            self.remWork -= 1
            if self.remBreaks == 0:
                self.current = self.lBreak
                title = 'Long Break'
            else:
                self.current = self.sBreak
                title = 'Short Break'
        #in short break now: start work
        elif self.current == self.sBreak:
            self.remBreaks -= 1
            self.current = self.work
            title = 'Work Period'
        #in long break now: reset number of work and short break periods
        elif self.current == self.lBreak:
            self.current = self.work
            title = 'Work Period'
            self.remWork = self.numWork
            self.remBreaks = self.numWork - 1
        self.endtime = datetime.now() + timedelta(seconds = self.current.length)
        timeStr +=  self.endtime.strftime("%H:%M")
        Notify.init("a")
        notifyme=Notify.Notification.new(title,timeStr)
        notifyme.show()

    def tickTock(self):
        self.change()
        while True:
            if datetime.now() &gt;= self.endtime:
                self.change()

def main():
    try:
        lengths = sys.argv[1:]
        workLen = int(lengths[0])
        sbLen = int(lengths[1])
        lbLen = int(lengths[2])

        clock = Clock(workLen, sbLen, lbLen)
        clock.tickTock()
    except:
        print("One or more arguments were invalid.")
        exit(1)

if __name__ == '__main__':
    main()


First of all, is this a good way to simulate the timer? Also, is there a way to get around using self.variable_name every time I want to use a variable in the Clock class? Finally, what would be a good package to look into if I wanted to extend this into a GUI application?
Just some quick tips, I might append some later. You might disagree with me, it's just my vision.

1) AFAIK, Pomodoro has some "classic" times for work and break sessions. It might be good to create them as default ones so the user wouldn't have to enter them manually via command line each time. I suggest using argparse module for that. A really quick and dirty rewriting of your main function:

def main():
    try:
        argparser = argparse.ArgumentParser()

        argparser.add_argument("--workLen", help="the length of a work session", type=int, default=25)
        argparser.add_argument("--sbLen", help="the length of a short break", type=int, default=5)
        argparser.add_argument("--lbLen", help="the length of a long break", type=int, default=30)

        # parse the arguments. They can be accessed in form args.argument
        args = argparser.parse_args()

        clock = Clock(args.workLen, args.sbLen, args.lbLen)
        clock.tickTock()
    except Exception as e:
        print("One or more arguments were invalid.", str(e))
        exit(1)


2) No need to put your work, sBreak and lBreak (and, probably, others too) variables right after class Clock: because that way you're declaring them as static. When you're declaring them in __init__, you basically declare other variables - the variables for this particular instance. And the static ones just remain None and are useless. So you may safely remove them. More info

3) Not sure if it is a common practice, but I would do if workTime == None or sBreakTime == None or lBreakTime == None: as if None in (workTime,sBreakTime,lBreakTime,):. You're testing for the same value anyway (None). I'm not sure if you want this behaviour, but if you want your program to exit if any of these values is 0 as well, you may use if not all((workTime,sBreakTime,lBreakTime,)):, because 0 is treated as false by Python.

I agree with Matthias on exit. As for naming conventions, I prefer being more liberal: do as you find comfortable, especially if it is your personal project. I would also use the PEP8 convention for variables (small_letters_with_underscore), but when it comes to function names, I'm more used to camelCaseStartingWithSmallLetter ;)

UPD1:
4) Add a sleep(0.1) at the end of your while loop in tickTock, because otherwise it uses up too much CPU.