avatarRuslan Brilenkov

Summary

The web content describes the development of a customizable Pomodoro productivity application using Python, emphasizing the importance of time management and personalization while working from home during the pandemic.

Abstract

The provided content outlines the creation of a Pomodoro productivity application by the author, Ruslan Brilenkov, using Python. The Pomodoro technique, a time management method involving focused work sessions followed by short breaks, is introduced as a means to enhance productivity while working from home amidst the pandemic. The author explains the limitations of existing Pomodoro apps, such as the lack of progress tracking and customization options, which prompted the creation of a personalized app. The article details the initial steps in building the application's graphical user interface (GUI) with Python's Tkinter package, including the layout design, frame switching, and the addition of buttons and a tomato image to represent the Pomodoro theme. The author also provides a brief tutorial on GUI basics and the importance of having fun while coding. The project's future steps include adding the Pomodoro logic, breaks, session number recording, and customizable features like colors and buttons. The article concludes with an invitation for readers to continue following the tutorial series and an advertisement for the author's e-book on prompt engineering.

Opinions

  • The author expresses that staying efficiently productive at home is challenging and that the Pomodoro technique can help focus on single activities.
  • Existing Pomodoro apps were found lacking in features such as progress tracking and customization, which led to the author's decision to create a personalized app.
  • The author believes in the importance of challenging one's programming skills and increasing knowledge of Python through practical projects like this one.
  • The author emphasizes the fun aspect of the project as a significant motivator for both starting and continuing the development of the Pomodoro app.
  • The author values the ability to track and visualize one's work progress and considers it an important feature for personal motivation and accomplishment.
  • The author encourages readers to learn and apply GUI programming in Python, providing resources and a step-by-step approach to facilitate the learning process.

Create Productivity App in Python from Scratch— Part 1

Python for time management. Pomodoro application.

Photo by Daria Nepriakhina on Unsplash

Introduction

The pandemic is hitting hard. It is necessary to limit any physical contact with the “outside” world and to stay indoors as much as possible. If you have an opportunity to work from home, it is great. However, there is a price to pay as well.

Staying efficiently productive at home is not an easy task. A home environment is not a work environment. Assuming you are not living alone, you cannot just say bye to your kids/family for the next ~8 hours and leave the house for work. Often, the workplace is the same room where you rest, eat, cultivate a hobby, and sleep. Besides, staying indoors 24/7 can drive people nuts.

Overall, it is almost impossible to separate life from work during these turbulent times. But we, humans, are not capable of doing multiple tasks simultaneously. As a result, we have difficulties concentrating on work efficiently.

Here, I want to share with you one powerful productivity technique, called Pomodoro. This way helps you concentrate on one single activity at a time.

Also, I will tell you how to create it from scratch using Python. I will tell you why I decided to create this app myself and why reinventing this bicycle is worth doing, at least in my opinion. I want to encourage everyone to use Python in everyday life.

Pomodoro as Productivity App

Photo by Lukas Blazek on Unsplash

The Pomodoro method is a time management technique that was developed by Francesco Cirillo in the late 1980s. This method uses a timer to break down the work into intervals, traditionally 25 minutes in length, separated by short 5-minute breaks. Later on, with a long 15-minute break once in a while.

In Italian, pomodoro means tomato. The technique was named after the tomato-shaped kitchen timer that Cirillo used as a university student.

My Pomodoro Frustrations

There are many free versions of this app out there. Grab any and start using it right away: push the button and start working. Still, not every version includes an option to record/store the number of sessions you have completed. In my view, tracking your progress is important — be it the number of hours you spend working or tracking your weight loss/gain.

Not every Pomodoro app has this option of saving or displaying the number of completed sessions. It happened, that the app I have been using did not have that option. Of course, it is not necessary to know how many Pomodoro sessions you have accomplished. However, I would like to know that number. Maybe, I take a look at that number at the end of the day, and it will make me feel a bit more accomplished. Or at the end of the week, I can see how many Pomodoro/working sessions I accomplished per day. Here we go, Ruslan_Frustrations += 1.

Moreover, at some point, I got bored with that one standard white background color of the app. So, I decided to check if there is an option to change it. Again, some apps might provide it. But it happened, that the app I have been using did not have that option and I did not check any other app at that point — up until I created my app …

Once more, does it make my work better/worse if I cannot change the background color? Of course, not. But I would like to have the possibility to change the colors in the app as I like. So, Ruslan_Frustrations += 1.

An Idea of Creating My App

As a result, I decided to create my Pomodoro app using Python. To sum up, here are a few reasons for this

  • to have my own cool customizable-buttons-and-colors Pomodoro app
  • to challenge my programming skills
  • to increase my knowledge of Python down the road
  • to have some fun as well

At this point, I would say that the last reason is not the least. Probably, I would not start/continue that project if it was not for fun. Now, I am even happier as I can share my knowledge and ideas with you.

Stay tuned because we are going to break down the project into small parts (similar to dividing the work into short intervals).

The plan of the project is the following:

  1. Create a user-friendly interface (GUI)
  2. Add the Pomodoro logic (countdown timer)
  3. Add the breaks between the work sessions
  4. Add the session numbers recorder
  5. Make a signal (sound/ring a bell) upon switching between the sessions
  6. The fun part: customize the colors and buttons (maybe)

It is hardly possible to fit all of these topics in one article with a reasonable level of detail. Depending on the length of this article, I will decide on how to break down the above-mentioned plan. But for a moment, let us break it down as follows:

  • This part (Part 1) includes the fundamentals of our Pomodoro GUI — graphical user interface. And a brief intro to classes.
  • Part 2 includes the Pomodoro logic (a timer, session switching, etc.)
  • In Part 3 (the fun part), we will come back to the GUI part and see how we can modify/customize our app (buttons, colors, background, etc.)

Part 1

If you would like to learn the fundamentals of GUI in Python or brush up your knowledge a bit, I have prepared this article about GUI basics.

Quick Recap

Just in case, if you would like to skip all the previous tutorials I give you a quick recap on how to start using the Tkinter package for GUI in Python:

Note: Tkinter is pre-installed for Windows and macOS. The Linux users (including me) need to run the following commands to install the package:

For Python 3 sudo apt-get install python3-tk

For Python 2.7 sudo apt-get install python-tk

The usage of the Tkinter is a bit different for Python 2 and Python 3, so we will have to explicitly import the right package:

import sys
if (sys.version_info.major == 3):
    print('Python 3')
    import tkinter as tk# for Python 3
    from tkinter import messagebox
else:
    print('Python 2')
    import Tkinter as tk# for Python 2.7
    import tkMessageBox

Now, we are on the same page. So let us start with the application layout.

Pomodoro App Layout

A little spoiler. By the end of this article, you will be able to create a GUI like:

Made by Author.

Creating the Base

We are going to have two pages in our application. One will describe the app (like README). Another will contain the “meat” of the program, the logic of the Pomodoro count-down timer. Here, I will be using classes to separate the pages from each other.

We will have 4 classes:

  1. The application layout, that connects all the other frames. Such as an invisible master window PomodoroApp.
  2. The Starting page is the initial frame we will see upon entering the application. It contains the buttons to go to other pages.
  3. The README page that contains some information about the application.
  4. The Pomodoro timer page that contains the main logic of the program (will be discussed in the next Part 2)

Creating the Pomodoro App:

  • initialize the Tkinter window with __init__ similar to root = tk.Tk(). We do not put any frame yet.
  • define a function switch_frame that will switch between frames (pages).
class PomodoroApp(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.frame = None
        #here, we will switch to the starting page (frame) as:
        #self.switch_frame(StartPage)
    def switch_frame(self, frame_class):
        new_frame = frame_class(self)
        # checking if the current frame is not empty,
        # we destroy it before switching to the next frame:
        if self.frame is not None:
            self.frame.destroy()
        self.frame = new_frame
        self.frame.pack()

Note: Method __init__ is called a constructor method. This method allows the class to initialize the attributes of the class. It is called when an object is created from a class. Here, we create the window object (tk.Tk) to hold all the other frames.

A brief explanation of this piece of code. When calling the switch_frame() method of the PomodoroApp() class, we assign a new frame from that new class to a new_frame variable. Before replacing the current frame with a new one, we delete (destroy) the current frame if it is not empty (not None), otherwise, there is nothing to destroy. And in the end, we place a new frame with a familiar method .pack().

To call that class/app, we use the following commands:

app = PomodoroApp() # <- calling our main class
app.mainloop() # <- needed to keep the GUI running

We start our app by calling the python code.py from the terminal, as usual. We will see only an empty window for a moment. Because we did not load any frame yet. However, all the logic to switch between the frames is there already!

Made by Author

Note: The self representing the instance of the class. It is used to call the functions/methods of the current class in comparison to calling the functions from the other classes.

Creating the Starting Page

Now, we can create another class called StartPage() representing our starting page, i.e., starting frame. To switch to the starting page we call self.switch_frame(StartPage) inside the __init__ method of the PomodoroApp() class.

But firstly, we need to create our StartPage() class:

class StartPage(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master, bg='khaki')
        tk.Label(self, text="Start page", font=('MathJax_SansSerif-Bold', 18, "bold")).pack(side="top", fill="x", pady=5)

A brief explanation of this piece of code. Here, we created

  • A new frame with a chosen background color (khaki).
  • A label saying that it is our “Start page”, with a chosen font parameters. You can play around with the size/style of the text. The .pack() method also has several parameters, such as side, fill and pady to place a label to the side, fill in the x-direction, and crate padding in the y-direction.

To show that starting page upon running the app, let us come back to our first class. We call a self.switch_frame(StartPage) method from thePomodoroApp(). Additionally, let us add a title and a custom size of the app:

class PomodoroApp(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.title("Cool Pomodoro title") # <-- new line!
        self.geometry("250x250") # <-- new line!
        self.frame = None
        self.switch_frame(StartPage) # <-- new line!

As a result, we get our starting page

Made by Author

Adding Buttons

No, we can add two buttons to our StartPage class.

class StartPage(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master, bg='khaki')
        tk.Label(self, text="Start page", font=('MathJax_SansSerif-Bold', 18, "bold")).pack(side="top", fill="x", pady=5)
        tk.Button(self, text="README", font=('MathJax_SansSerif-Bold', 18, "bold"),
                  command=lambda: master.switch_frame(READMEPage)).pack(fill='x', pady = 10)
        tk.Button(self, text="START POMODORO", font=('MathJax_SansSerif-Bold', 18, "bold"),
                  command=lambda: master.switch_frame(PomodoroPage)).pack(fill='x', pady = 10)

Note: We use a lambda function. It is called an anonymous function. These functions are usually the arguments that are passed to higher-order functions. It is useful to employ the lambda functions if they need to do some job only a few times in the code here and there. Because it is computationally cheaper to use these law-order functions.

As a result, we have a visually-completed starting page! Bear in mind, the buttons are pointing out to the non-existing pages. We create these other pages in our next steps. But for a moment, let us enjoy the result of our hard work!

Made by Author

Adding README Page

We will start with the README page. We plan to have a button “Back to the main page” and a text describing the app. But of course, one can do whatever one’s heart desires. Because

Your app — your rules.

I give an example of what I did:

class READMEPage(tk.Frame):
    def __init__(self, master):
        tk.Frame.__init__(self, master)
        tk.Frame.configure(self,bg='brown')
        tk.Label(self, text="README", font=('MathJax_SansSerif-Bold', 18, "bold")).pack(side="top", fill="x", pady=5)
        
        tk.Button(self, text="Go back", font=('MathJax_SansSerif-Bold', 14, "bold"),
                  command=lambda: master.switch_frame(StartPage)).pack()
        
        text_for_label = "Welcome!\nHere goes \n app's description"
        text_for_contacts = " \n\n ~~~ \n\n Author: Ruslan Brilenkov \n\n ~~~ \n\n "
        
        tk.Label(self, text=text_for_label, font=('MathJax_SansSerif-Bold', 14, "bold")).pack()
        tk.Label(self, text=text_for_contacts, font=('MathJax_SansSerif-Bold', 14, "bold"), bg='green').pack(side="top", fill="both")
        
        tk.Button(self, text="Go back", font=('MathJax_SansSerif-Bold', 14, "bold"),
                  command=lambda: master.switch_frame(StartPage)).pack()

I hope, by now you can immediately grasp the code. Still, I would like to mention:

  • we are adding two “Go Back” buttons to prevent endless scrolling in case our description becomes too long. These buttons are linked to switch to the starting page.
  • the labels have the text describing the app and giving the Author’s contacts, etc.

As a result, we have a simple explanatory README page:

Made by Author

Bonus — a Tomato Image

We will add the final “Start Pomodoro” page in the next part (Part 2) of this tutorial. For a moment enjoy a bonus part — inserting an image into a label widget.

Note: We will be using Python Imaging Library (PIL). To install that package, write in the terminal the following: pip install pillow

Do not forget to import these two packages Image and ImageTk:

from PIL import Image, ImageTk
...
class StartPage(tk.Frame):
    def __init__(self, master):
        . # this part
        . # is
        . # the same
                  
        im = Image.open("pomodoro_image.png")
        im_resized = im.resize((250, 200))
        render = ImageTk.PhotoImage(im_resized)
        img = tk.Label(self, image=render)
        img.image = render
        img.pack(fill='both')

I have resized the image to 250x200 pixels to fit in the window. Resizing an image, in this case, is a matter of trial and error. The result looks like this:

Made by Author.

In Conclusion

Fortunately for us, this journey is not over yet. While this has been our first leap to creating the Pomodoro GUI application from scratch, there are still things to do. In the next tutorial, we will be creating the main work/break timer logic and a few more things. So, stay tuned.

Overall, this exercise has been a great investment of my time, and I hope that it will be useful for you as well! Thank you for reading my article.

Are you curious about the emerging field of Prompt Engineering? Grab my new e-book! You will learn and master everything from fundamental concepts to practical tips and real-world applications. Additionally, you will receive a bonus of 300 prompts and some of the free resources to kick-start your AI-driven journey. With all this value packed into one e-book, what is the price? The cost of a cup of coffee! Do not miss out on this opportunity to take your skills to the next level!

Contact

LinkedIn

I recently started a YouTube channel where I talk about different topics, including data science and AI news, research, and life in general among others. It is a steep learning curve for me but I invite you to check it out here.

Never miss a story, join my mailing list!

Gain Access to Expert View — Subscribe to DDI Intel

Python
Programming
Productivity Tools
Productivity Apps
GUI
Recommended from ReadMedium