<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ tkinter - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ tkinter - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sat, 30 May 2026 22:25:11 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/tkinter/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Build a Calculator with Tkinter in Python  ]]>
                </title>
                <description>
                    <![CDATA[ In this tutorial, you'll learn how to create a simple arithmetic calculator in Python with Tkinter. The project will be one of your first steps towards building an actual GUI in Python. This is a hand ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-a-calculator-with-tkinter-in-python/</link>
                <guid isPermaLink="false">6a07203c99d875f5cd667635</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GUI ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tkinter ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Sara Jadhav ]]>
                </dc:creator>
                <pubDate>Fri, 15 May 2026 13:31:40 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5fc16e412cae9c5b190b6cdd/0ae14c91-3e47-464c-b392-1026321a7764.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this tutorial, you'll learn how to create a simple arithmetic calculator in Python with Tkinter. The project will be one of your first steps towards building an actual GUI in Python.</p>
<p>This is a hands-on tutorial, which will help you form your early GUI projects. It's meant for anyone who wants to start building visual projects in Python.</p>
<p>The Tkinter library is a standard built-in Python library which helps us make Graphical User Interfaces in Python. Since it's a built-in library, we don't have to separately install it. So, once you have Python installed on your computer, you just have to set it up and you're good to follow along here.</p>
<p>But keep in mind that Tkinter may not be installed with your Python from the distributor end. To check if it's installed or not, open your command prompt and type:</p>
<pre><code class="language-plaintext">python -m tkinter
</code></pre>
<p>This will open up a Tkinter specimen window if Tkinter is installed and working on your computer.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a href="#heading-what-do-we-want-to-see-in-our-project">What Do We Want to See in Our Project?</a></p>
</li>
<li><p><a href="#heading-how-to-set-up-the-window">How to Set Up the Window</a></p>
</li>
<li><p><a href="#heading-how-to-name-the-window">How to Name the Window</a></p>
</li>
<li><p><a href="#heading-how-to-create-frames-in-the-window">How to Create Frames in the Window</a></p>
</li>
<li><p><a href="#heading-how-to-add-buttons-to-the-window">How to Add Buttons to the Window</a></p>
</li>
<li><p><a href="#heading-how-to-add-the-output-screen-of-the-calculator">How to Add the Output Screen of the Calculator</a></p>
</li>
<li><p><a href="#heading-how-to-make-the-numbers-visible-on-the-output-screen">How to Make the Numbers Visible on the Output Screen</a></p>
</li>
<li><p><a href="#heading-how-to-add-a-scrollbar-to-the-output-screen">How to Add a Scrollbar to the Output Screen</a></p>
</li>
<li><p><a href="#heading-how-to-add-the-equal-to-button">How to Add the Equal To Button</a></p>
</li>
<li><p><a href="#heading-how-to-add-the-ac-button">How to Add the AC Button</a></p>
</li>
<li><p><a href="#heading-wrapping-up">Wrapping Up</a></p>
</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before starting, here are some prerequisites for this tutorial which will help you get the most out of it:</p>
<ul>
<li><p>Basic Python Syntax</p>
</li>
<li><p>Understanding of how to import and use libraries and its different functions</p>
</li>
<li><p>Understanding of how to use different attributes of the module</p>
</li>
</ul>
<p>Now that we know what we need to proceed in this tutorial, let's actually dive-in the process!</p>
<p>The first step for building any project is to create a clear-cut idea of what you want to build. Let's look at what we're going to make.</p>
<h2 id="heading-what-do-we-want-to-see-in-our-project">What Do We Want to See in Our Project?</h2>
<p>We're going to build a simple arithmetic calculator. The calculator works as follows:</p>
<ul>
<li><p>It has all the numerals (0, 1, 2, ...., 9) in a keyboard.</p>
</li>
<li><p>It has basic arithmetic (+, -, /, *, =) operators lining the keyboard.</p>
</li>
<li><p>The calculator is non-resizable, that is the user can't extend the width or the height of the application window.</p>
</li>
<li><p>The calculator has a screen above the keyboard which shows the user input and the final answer.</p>
</li>
<li><p>Finally, the calculator has an 'AC' button which stands for 'All Clear' which erases everything on the output screen of the window and allows the user to use it again.</p>
</li>
</ul>
<p>With this, we have a clear idea about what we're going to build.</p>
<p>Also, you can create the UI beforehand and place the widgets accordingly on the window. Here's an image of the UI we'll create in this tutorial:</p>
<img src="https://cdn.hashnode.com/uploads/covers/67e55054a0be57d730442ec0/93d8458d-f829-4edb-9651-622a14f9444a.png" alt="UI of the calculator " style="display:block;margin:0 auto" width="249" height="388" loading="lazy">

<h2 id="heading-how-to-set-up-the-window">How to Set Up the Window</h2>
<p>To set up our main window where we'll later add our widgets, first we need to import the Tkinter library into our program. Then we'll initialize the window using the <code>tk.Tk()</code> function. To display the window on the screen continuously until we quit manually, we'll use the <code>mainloop()</code> function. Here's what the code looks like:</p>
<pre><code class="language-python">import tkinter as tk

# screen initialization
root = tk.Tk()

# This keeps the window active
root.mainloop()
</code></pre>
<p>The<code>root</code> variable represents our window. So, from now on, we'll be adding the widgets to this window.</p>
<p>When a user hits "Run", you'll see a blank window on your screen as shown in the image below. Congrats! This is your first GUI.</p>
<img src="https://cdn.hashnode.com/uploads/covers/67e55054a0be57d730442ec0/ee60f1d8-ea5b-415d-96bf-90941ecd9424.png" alt="Blank tkinter window " style="display:block;margin:0 auto" width="214" height="241" loading="lazy">

<h2 id="heading-how-to-name-the-window">How to Name the Window</h2>
<p>The 'tk' written on the Title Bar is the default title of the window. To set our own window title, we can use the <code>title()</code> function. The following code shows how you can do that:</p>
<pre><code class="language-python">import tkinter as tk

root = tk.Tk()

# Naming the window
root.title("Calculator")

root.mainloop()
</code></pre>
<p>On executing the program, we get the following window:</p>
<img src="https://cdn.hashnode.com/uploads/covers/67e55054a0be57d730442ec0/ef6ca391-3744-4915-9118-4996124adc85.png" alt="Blank window with title changed to 'Calculator'" style="display:block;margin:0 auto" width="302" height="281" loading="lazy">

<p>Now you should be able to see that the title of the window changed successfully.</p>
<h2 id="heading-how-to-create-frames-in-the-window">How to Create Frames in the Window</h2>
<p>After setting up the window, now we have to place the buttons on it. For placing the buttons, we need to create a container in which we'll put them.</p>
<p>The container could be the main window, but we'll avoid that for this project. This is because we want to place some buttons to the side of and below others to create our keyboard. To make it easier, we'll create Frame containers.</p>
<p>A Frame container represents a vertical column of the window. The initial dimension of the frame is 0 x 0. The frame resizes accordingly when we place a widget in it.</p>
<p>We'll create four frames in our window. The first frame will contain the buttons 1, 4, 7, and AC. The second frame will contain the buttons 2, 5, 8, and 0, the third frame will contain the buttons 3, 6, 9, and =, and the last frame will contain the buttons +, -, x, and / (just like in the UI shown above).</p>
<p>We can create frames in Tkinter using <code>tk.Frame()</code>. We'll pass the parent container for the Frame – that is, the main window in its argument. The following code should make it clear:</p>
<pre><code class="language-python">import tkinter as tk

# screen initialization
root = tk.Tk()

# Naming the window
root.title("Calculator")

# Creating Frames
frame1 = tk.Frame(root)
frame1.pack(side='left', anchor='n')
frame2 = tk.Frame(root)
frame2.pack(side='left', anchor='n')
frame3 = tk.Frame(root)
frame3.pack(side='left', anchor='n')
frame4 = tk.Frame(root)
frame4.pack(side='left', anchor='n')

# This keeps the window active
root.mainloop()
</code></pre>
<p>The <code>pack()</code> function embeds the Frame geometrically on the window. The <code>side='left'</code> parameter embeds the Frames to the extreme left of the screen. By default, this is set to the center. <code>anchor='n'</code> tells us that the widgets should be placed starting from the very top of the frame. By default, the widgets start adding from the center of the Frame. The 'n' in the <code>anchor='n'</code> stands for 'North'.</p>
<p>An important thing to note is that, since we defined <code>frame1</code> early in the program, it will occupy the extreme left portion of the window. But even though <code>frame2</code> is also set to occupy extreme left, the two frames <code>frame1</code> and <code>frame2</code> won't overlap. Instead <code>frame2</code> will take a position so that it goes as far left as it can go on the window without overlapping <code>frame1</code>. So frames <code>frame1</code>, <code>frame2</code>, <code>frame3</code> and <code>frame4</code> are side by side on the left side of the window.</p>
<h2 id="heading-how-to-add-buttons-to-the-window">How to Add Buttons to the Window</h2>
<p>We can create a button widget in Tkinter by using the <code>tk.Button()</code> function. The <code>tk.Button()</code> function consists of various parameters:</p>
<ul>
<li><p><strong>master:</strong> This allows us to provide the parent container in which we have to place our button. This expects a container object.</p>
</li>
<li><p><strong>text:</strong> In this parameter, we have to pass the text which we want to display on our button. This expects a string.</p>
</li>
<li><p><strong>font:</strong> This expects a tuple with the first element providing the name of the font and the next element providing the font size.</p>
</li>
<li><p><strong>image:</strong> This allows us to put an image over our button.</p>
</li>
<li><p><strong>bg:</strong> This allows us to set the background colour for our button.</p>
</li>
<li><p><strong>fg:</strong> This allows us to set the foreground colour for our button.</p>
</li>
<li><p><strong>activebackground:</strong> When the button is clicked, the colour passed in this parameter becomes visible.</p>
</li>
<li><p><strong>command:</strong> This allows us to link a command to the button.</p>
</li>
</ul>
<p>Now that we know the basics of creating a button, lets actually create the keyboard of our calculator.</p>
<p>To create the keyboard, we have to put quite a few buttons on the window. To make our work easier, we'll define a function to create our buttons, just with different text. Let's look at the code below:</p>
<pre><code class="language-python">import tkinter as tk

# screen initialization
root = tk.Tk()

# Naming the window
root.title("Calculator")

frame1 = tk.Frame(root)
frame1.pack(side='left', anchor='n')
frame2 = tk.Frame(root)
frame2.pack(side='left', anchor='n')
frame3 = tk.Frame(root)
frame3.pack(side='left', anchor='n')
frame4 = tk.Frame(root)
frame4.pack(side='left', anchor='n')

pixel = tk.PhotoImage(width=55, height=55)

def buttons(text, frame):
    button = tk.Button(frame, text=text, font=('Arial', 20), image=pixel, bg="#333300", fg="white", compound="center")
    return button


def buttons_ops(text, frame, bg, fg):
    button = tk.Button(frame, text=text, font=('Arial', 20), image=pixel, bg=bg, fg=fg, activebackground="black",
                        compound="center")
    return button

btn1 = buttons('1',frame1).pack()
btn4 = buttons('4', frame1).pack()
btn7 = buttons('7', frame1).pack()

btn2 = buttons('2', frame2).pack()
btn5 = buttons('5', frame2).pack()
btn8 = buttons('8', frame2).pack()
btn0 = buttons_ops('0', frame2, '#333300', 'white').pack()

plus = buttons_ops('+', frame4, 'black', 'white').pack()
minus= buttons_ops('-', frame4,  'black', 'white').pack()
mul = buttons_ops('x', frame4, 'black', 'white').pack()
div = buttons_ops('/', frame4, 'black', 'white').pack()

btn3 = buttons('3', frame3).pack()
btn6 = buttons('6', frame3).pack()
btn9 = buttons('9', frame3).pack()

# This keeps the window active
root.mainloop()
</code></pre>
<p>Now let's break it down:</p>
<p>First, we created an Tkinter image object via <code>tk.PhotoImage()</code>. This is a transparent image. The purpose behind creating this image is to set a perfect width and height of the button pixel-wise. The <code>compound='center'</code> ensures that the button text is aligned at the center of the transparent image.</p>
<p>You can change the size of the button by changing the <code>width</code> and <code>height</code> parameters of the <code>pixel</code> object.</p>
<p>Secondly, we created a function which takes the 'text' and the 'container frame' as the argument. Inside the function, we created a button object and returned it. For the numerical buttons, we've created the function <code>buttons</code> whereas for operator buttons, we've created the function <code>buttons_ops</code>. This was done only to ensure different style of buttons (in terms of background and foreground, and so on).</p>
<p>You can change the colours of the buttons by making changes in the <code>bg</code> and <code>fg</code> parameters of the <code>tk.Button()</code> function.</p>
<p>Then we created all the buttons with these two functions. The <code>pack()</code> function puts the buttons in their respective places. Remember that we haven't created the <code>=</code> and <code>AC</code> buttons.</p>
<p>When we execute the program, the following window will pop up:</p>
<img src="https://cdn.hashnode.com/uploads/covers/67e55054a0be57d730442ec0/012c6883-d79b-44fa-8171-0c6cfc837b4e.png" alt="Window with embedded buttons " style="display:block;margin:0 auto" width="269" height="289" loading="lazy">

<p>You can try clicking the buttons to make sure that everything is working great up to this point.</p>
<h2 id="heading-how-to-add-the-output-screen-of-the-calculator">How to Add the Output Screen of the Calculator</h2>
<p>For the output screen of the calculator, we'll be using the <code>Entry</code> object in Tkinter. The <code>Entry</code> object will be the best match in this case because we want a single line screen to showcase the user input. We could also use a <code>Text</code> object, but it provides a multiline area. So here, we'll just be using the <code>Entry</code> object.</p>
<p>Also, since we want the output screen to be on the top of the keyboard, we need to define and embed this object before embedding the frames.</p>
<p>The <code>Entry</code> object is created using the <code>tk.Entry()</code> function. This has similar parameters to the <code>tk.Button()</code> function. The following code creates an entry box:</p>
<pre><code class="language-python">import tkinter as tk

# screen initialization
root = tk.Tk()

# Naming the window
root.title("Calculator")

# creating the output screen
entry = tk.Entry(root, width=9, font=('Arial', 38, 'bold'), state='readonly')
entry.pack(pady=(30, 10))


frame1 = tk.Frame(root)
frame1.pack(side='left', anchor='n')
frame2 = tk.Frame(root)
frame2.pack(side='left', anchor='n')
frame3 = tk.Frame(root)
frame3.pack(side='left', anchor='n')
frame4 = tk.Frame(root)
frame4.pack(side='left', anchor='n')

pixel = tk.PhotoImage(width=55, height=55)

def buttons(text, frame):
    button = tk.Button(frame, text=text, font=('Arial', 20), image=pixel, bg="#333300", fg="white", compound="center")
    return button


def buttons_ops(text, frame, bg, fg):
    button = tk.Button(frame, text=text, font=('Arial', 20), image=pixel, bg=bg, fg=fg, activebackground="black",
                        compound="center")
    return button

btn1 = buttons('1',frame1).pack()
btn4 = buttons('4', frame1).pack()
btn7 = buttons('7', frame1).pack()

btn2 = buttons('2', frame2).pack()
btn5 = buttons('5', frame2).pack()
btn8 = buttons('8', frame2).pack()
btn0 = buttons_ops('0', frame2, '#333300', 'white').pack()

plus = buttons_ops('+', frame4, 'black', 'white').pack()
minus= buttons_ops('-', frame4,  'black', 'white').pack()
mul = buttons_ops('x', frame4, 'black', 'white').pack()
div = buttons_ops('/', frame4, 'black', 'white').pack()

btn3 = buttons('3', frame3).pack()
btn6 = buttons('6', frame3).pack()
btn9 = buttons('9', frame3).pack()

# This keeps the window active
root.mainloop()
</code></pre>
<p>In the code above, we put the parent container of the <code>entry</code> object as the main window <code>root</code>. I set the <code>width</code> parameter to 9 as it fit well with the dimensions of the window and the keyboard. You can try it out with different values for width and set a perfectly sized output screen.</p>
<p>You may have noticed that we didn't use the <code>pack()</code> on the same line as object definition. This is because using <code>pack()</code> on the same line as object definition is a bad practice as it limits certain functionality.</p>
<p>So, why did we use the <code>pack()</code> function on the same line while creating buttons? This is because we didn't work heavily with the buttons in this project, so we attempted to reduce the lines of code.</p>
<p>In the <code>tk.Entry()</code> function, we set <code>state='readonly'</code>. This prohibits any direct text input into the the output screen. That means, we can only use the buttons to show the characters on the output screen. By default, this is set to <code>state='normal'</code>, which allows direct input from the keyboard into the entry box.</p>
<p>The <code>pady</code> parameter inside the <code>pack()</code> function leaves the given amount of pixels above and below the object. To perform such an operation, let's say to pad 10 pixels on both sides of the object, we can write <code>pady=10</code> .</p>
<p>Here, we didn't want the same amount of padding above and below the object. So we used a tuple with first element representing the pixels to pad above the output screen, and the second element representing the pixels to pad below the output screen.</p>
<p>Up until now, our GUI looks as shown below:</p>
<img src="https://cdn.hashnode.com/uploads/covers/67e55054a0be57d730442ec0/dc15d02d-2243-4751-b825-53d5b4061daf.png" alt="Window with embedded output screen" style="display:block;margin:0 auto" width="262" height="389" loading="lazy">

<p>We can now see that the output screen is set perfectly.</p>
<h2 id="heading-how-to-make-the-numbers-visible-on-the-output-screen">How to Make the Numbers Visible on the Output Screen</h2>
<p>Next step is to make characters visible on the output screen. Every button that we click should render on the output screen. For this, we have to link commands to each button. Let's first look at the code and then see how it works:</p>
<pre><code class="language-python">import tkinter as tk

# screen initialization
root = tk.Tk()

# Naming the window
root.title("Calculator")

entry = tk.Entry(root, width=9, font=('Arial', 38, 'bold'),state='readonly')
entry.pack(pady=(30, 10))


frame1 = tk.Frame(root)
frame1.pack(side='left', anchor='n')
frame2 = tk.Frame(root)
frame2.pack(side='left', anchor='n')
frame3 = tk.Frame(root)
frame3.pack(side='left', anchor='n')
frame4 = tk.Frame(root)
frame4.pack(side='left', anchor='n')

pixel = tk.PhotoImage(width=55, height=55)

def command(text):
    entry.config(state='normal')
    entry.insert(tk.END, text) 
    entry.config(state='readonly')  


def buttons(text, frame):
    button = tk.Button(frame, text=text, font=('Arial', 20), image=pixel, bg="#333300", fg="white", compound="center",
                       command=lambda :command(text))
    return button


def buttons_ops(text, frame, bg, fg):
    button = tk.Button(frame, text=text, font=('Arial', 20), image=pixel, bg=bg, fg=fg, activebackground="black",
                        compound="center", command=lambda:command(text))
    return button

btn1 = buttons('1',frame1).pack()
btn4 = buttons('4', frame1).pack()
btn7 = buttons('7', frame1).pack()

btn2 = buttons('2', frame2).pack()
btn5 = buttons('5', frame2).pack()
btn8 = buttons('8', frame2).pack()
btn0 = buttons_ops('0', frame2, '#333300', 'white').pack()

plus = buttons_ops('+', frame4, 'black', 'white').pack()
minus= buttons_ops('-', frame4,  'black', 'white').pack()
mul = buttons_ops('x', frame4, 'black', 'white').pack()
div = buttons_ops('/', frame4, 'black', 'white').pack()

btn3 = buttons('3', frame3).pack()
btn6 = buttons('6', frame3).pack()
btn9 = buttons('9', frame3).pack()

# This keeps the window active
root.mainloop()
</code></pre>
<p>In the code above, we defined a new function called <code>command()</code>. This function takes one argument <code>text</code>. Inside the function, we changed the <code>state</code> of the <code>entry</code> object to <code>normal</code> via <code>config</code>. By doing this, we can now make changes in the text of the <code>entry</code> object.</p>
<p>Then we used the <code>insert()</code> function for the <code>entry</code> object. The <code>insert()</code> function appends the <code>text</code> argument to the existing set of characters.</p>
<p>The first argument of the <code>insert()</code> function takes the index where the text will be inserted. <code>tk.END</code> represents the last character of the text in the object. The second argument of the <code>insert()</code> function takes the text that is to be inserted.</p>
<p>Finally, we change the <code>state</code> of the object again to <code>readonly</code> to prohibit any outside input other than our defined calculator keyboard.</p>
<p>Now let's look at the <code>buttons</code> and the <code>buttons_ops</code> functions. You may have noticed that we've added the <code>command</code> parameter to the <code>tk.Button()</code> function. The <code>lambda</code> tells the program to perform the command only when the button is clicked.</p>
<p>Collectively, <code>command=lambda:command(text)</code> means that, on clicking the buttons which we have defined up until now, it executes the <code>command()</code> function and shows the pressed button character on the output screen.</p>
<p>Now try clicking some buttons on your window. They should appear on the output screen as shown below:</p>
<img src="https://cdn.hashnode.com/uploads/covers/67e55054a0be57d730442ec0/e8cc0cd5-dc0c-4f01-9b21-7dec6874d00f.png" alt="Image of the calculator showing input on the calculator screen" style="display:block;margin:0 auto" width="262" height="395" loading="lazy">

<h2 id="heading-how-to-add-a-scrollbar-to-the-output-screen">How to Add a Scrollbar to the Output Screen</h2>
<p>Now, you might have encountered a problem: when you input a large number of characters, you were able to see only the first few characters. The rest were invisible.</p>
<p>To tackle this, we'll add a scrollbar to the output screen.</p>
<p>First, we'll create a scrollbar object via <code>tk.Scrollbar()</code> before the <code>entry</code> object. The following code shows how:</p>
<pre><code class="language-python">import tkinter as tk

# screen initialization
root = tk.Tk()

# Naming the window
root.title("Calculator")

scrollbar = tk.Scrollbar(root, orient='horizontal')

entry = tk.Entry(root, width=9, font=('Arial', 38, 'bold'), state='readonly', xscrollcommand=scrollbar.set)
entry.pack(pady=(30, 10))

scrollbar.config(command=entry.xview)
scrollbar.pack()

frame1 = tk.Frame(root)
frame1.pack(side='left', anchor='n')
frame2 = tk.Frame(root)
frame2.pack(side='left', anchor='n')
frame3 = tk.Frame(root)
frame3.pack(side='left', anchor='n')
frame4 = tk.Frame(root)
frame4.pack(side='left', anchor='n')

pixel = tk.PhotoImage(width=55, height=55)

def command(text):
    entry.config(state='normal')
    entry.insert(tk.END, text)
    entry.config(state='readonly')


def buttons(text, frame):
    button = tk.Button(frame, text=text, font=('Arial', 20), image=pixel, bg="#333300", fg="white", compound="center",
                       command=lambda :command(text))
    return button


def buttons_ops(text, frame, bg, fg):
    button = tk.Button(frame, text=text, font=('Arial', 20), image=pixel, bg=bg, fg=fg, activebackground="black",
                        compound="center", command=lambda:command(text))
    return button

btn1 = buttons('1',frame1).pack()
btn4 = buttons('4', frame1).pack()
btn7 = buttons('7', frame1).pack()

btn2 = buttons('2', frame2).pack()
btn5 = buttons('5', frame2).pack()
btn8 = buttons('8', frame2).pack()
btn0 = buttons_ops('0', frame2, '#333300', 'white').pack()

plus = buttons_ops('+', frame4, 'black', 'white').pack()
minus= buttons_ops('-', frame4,  'black', 'white').pack()
mul = buttons_ops('x', frame4, 'black', 'white').pack()
div = buttons_ops('/', frame4, 'black', 'white').pack()

btn3 = buttons('3', frame3).pack()
btn6 = buttons('6', frame3).pack()
btn9 = buttons('9', frame3).pack()

# This keeps the window active
root.mainloop()
</code></pre>
<p>The <code>orient</code> parameter in the <code>tk.Scrollbar()</code> object determines the nature of the scrollbar. Here, we've aligned it with the X-axis. We also added a parameter in the original <code>entry</code> object. The <code>xscrollcommand</code> sets the scrollbar to the output screen.</p>
<p>Then we connected the scrollbar to the entry object by setting <code>command=entry.xview</code> and embedded the scrollbar in the output screen.</p>
<p>The following image shows the scrollbar. You can use the arrow signs to navigate forward or backward through the text:</p>
<img src="https://cdn.hashnode.com/uploads/covers/67e55054a0be57d730442ec0/29d0fd37-a94f-4bad-af24-6627055fd4b3.png" alt="Image of calculator with the scrollbar" style="display:block;margin:0 auto" width="283" height="429" loading="lazy">

<h2 id="heading-how-to-add-the-equal-to-button">How to Add the Equal To Button</h2>
<p>We haven't yet made the <code>equal to</code> button – so let's do that now. To start, we'll define a function called <code>cmd_equal()</code>. In this function, we'll first change the <code>state</code> of the <code>entry</code> to <code>normal</code>. Then we'll extract the text in the output screen using the <code>entry.get()</code> function and replace 'x' by '*'. We do this because multiplication is represented by '*' and not 'x'.</p>
<p>Then we'll add a <code>try-except</code> block. We'll try to evaluate the mathematical expression that we extracted using Python's built-in <code>eval()</code> function. If that's invalid, instead of throwing an error, we'll output 'Invalid' onto our screen.</p>
<pre><code class="language-python">import tkinter as tk

# screen initialization
root = tk.Tk()

# Naming the window
root.title("Calculator")

scrollbar = tk.Scrollbar(root, orient='horizontal')

entry = tk.Entry(root, width=9, font=('Arial', 38, 'bold'), state='readonly', xscrollcommand=scrollbar.set)
entry.pack(pady=(30, 10))

scrollbar.config(command=entry.xview)
scrollbar.pack()

frame1 = tk.Frame(root)
frame1.pack(side='left', anchor='n')
frame2 = tk.Frame(root)
frame2.pack(side='left', anchor='n')
frame3 = tk.Frame(root)
frame3.pack(side='left', anchor='n')
frame4 = tk.Frame(root)
frame4.pack(side='left', anchor='n')

pixel = tk.PhotoImage(width=55, height=55)

def command(text):
    entry.config(state='normal')
    entry.insert(tk.END, text)
    entry.config(state='readonly')

def cmd_equal():
    entry.config(state='normal')
    txt = entry.get().replace('x', '*')

    try:
        result = eval(txt)

    except:
        result = 'INVALID'
    entry.delete(0, tk.END)
    entry.insert(tk.END, result)
    entry.config(state='readonly')   


def buttons(text, frame):
    button = tk.Button(frame, text=text, font=('Arial', 20), image=pixel, bg="#333300", fg="white", compound="center",
                       command=lambda :command(text))
    return button


def buttons_ops(text, frame, bg, fg):
    button = tk.Button(frame, text=text, font=('Arial', 20), image=pixel, bg=bg, fg=fg, activebackground="black",
                        compound="center", command=lambda:command(text))
    return button

btn1 = buttons('1',frame1).pack()
btn4 = buttons('4', frame1).pack()
btn7 = buttons('7', frame1).pack()

btn2 = buttons('2', frame2).pack()
btn5 = buttons('5', frame2).pack()
btn8 = buttons('8', frame2).pack()
btn0 = buttons_ops('0', frame2, '#333300', 'white').pack()

plus = buttons_ops('+', frame4, 'black', 'white').pack()
minus= buttons_ops('-', frame4,  'black', 'white').pack()
mul = buttons_ops('x', frame4, 'black', 'white').pack()
div = buttons_ops('/', frame4, 'black', 'white').pack()

btn3 = buttons('3', frame3).pack()
btn6 = buttons('6', frame3).pack()
btn9 = buttons('9', frame3).pack()
equal= tk.Button(frame3, text='=', font=('Arial', 20), image=pixel, bg='white', fg='black', activebackground="black",
                        compound="center", command=lambda: cmd_equal()).pack()

# This keeps the window active
root.mainloop()
</code></pre>
<p>Here, we've also used <code>entry.delete()</code>. This function will delete all the text on the output screen from the first argument's index (that is from the 0th index) to the last argument's index, that is to the end of the text (represented by <code>tk.END</code>).</p>
<p>Then we inserted our result onto the output screen using <code>entry.insert()</code>. An important thing to note is that we've embedded the <code>equal to</code> button below the definition of <code>btn9</code> in the same frame. This puts our <code>equal to</code> button in just the right place.</p>
<p>The following images show the initial and final screens, respectively.</p>
<img src="https://cdn.hashnode.com/uploads/covers/67e55054a0be57d730442ec0/8051ce51-5139-4668-97e2-b5c742c687a1.png" alt="Calculator window showing mathematical expression " style="display:block;margin:0 auto" width="270" height="407" loading="lazy">

<p>On clicking the equal to button:</p>
<img src="https://cdn.hashnode.com/uploads/covers/67e55054a0be57d730442ec0/1ddc6b4c-3e51-4237-b9f6-90986bff1963.png" alt="Calculator window showing evaluated mathematical expression" style="display:block;margin:0 auto" width="267" height="407" loading="lazy">

<h2 id="heading-how-to-add-the-ac-button">How to Add the AC Button</h2>
<p>Now finally, we'll define our last function: <code>cmd_ac()</code>. This function will delete everything on the output screen. We'll do this by first changing the <code>state</code> to <code>normal</code>, then using <code>entry.delete()</code>, and lastly changing the <code>state</code> back to <code>readonly</code>. Then we'll put this function in the <code>command()</code> parameter of the <code>ac</code> button.</p>
<p>To keep the UI from dismantling when we expand the window, we'll use the <code>resizable()</code> function. This functions takes two arguments: one corresponds to the permission to expand the width and the other to the height. To prohibit expansion of the window, we'll set both the parameters to <code>False</code>.</p>
<p>So the final code will be:</p>
<pre><code class="language-python">import tkinter as tk

# screen initialization
root = tk.Tk()

# Naming the window
root.title("Calculator")

scrollbar = tk.Scrollbar(root, orient='horizontal')

entry = tk.Entry(root, width=9, font=('Arial', 38, 'bold'), state='readonly', xscrollcommand=scrollbar.set)
entry.pack(pady=(30, 10))

scrollbar.config(command=entry.xview)
scrollbar.pack()

frame1 = tk.Frame(root)
frame1.pack(side='left', anchor='n')
frame2 = tk.Frame(root)
frame2.pack(side='left', anchor='n')
frame3 = tk.Frame(root)
frame3.pack(side='left', anchor='n')
frame4 = tk.Frame(root)
frame4.pack(side='left', anchor='n')

pixel = tk.PhotoImage(width=55, height=55)

def command(text):
    entry.config(state='normal')
    entry.insert(tk.END, text)
    entry.config(state='readonly')

def cmd_ac():
    entry.config(state='normal')
    entry.delete(0, tk.END)
    entry.config(state='readonly')

def cmd_equal():
    entry.config(state='normal')
    txt = entry.get().replace('x', '*')

    try:
        result = eval(txt)

    except:
        result = 'INVALID'
    entry.delete(0, tk.END)
    entry.insert(tk.END, result)
    entry.config(state='readonly')


def buttons(text, frame):
    button = tk.Button(frame, text=text, font=('Arial', 20), image=pixel, bg="#333300", fg="white", compound="center",
                       command=lambda :command(text))
    return button


def buttons_ops(text, frame, bg, fg):
    button = tk.Button(frame, text=text, font=('Arial', 20), image=pixel, bg=bg, fg=fg, activebackground="black",
                        compound="center", command=lambda:command(text))
    return button

btn1 = buttons('1',frame1).pack()
btn4 = buttons('4', frame1).pack()
btn7 = buttons('7', frame1).pack()
ac = tk.Button(frame1, text="AC", font=('Arial', 20), image=pixel, bg="#666699", fg="white", compound="center",
                        command=lambda: cmd_ac()).pack()

btn2 = buttons('2', frame2).pack()
btn5 = buttons('5', frame2).pack()
btn8 = buttons('8', frame2).pack()
btn0 = buttons_ops('0', frame2, '#333300', 'white').pack()

plus = buttons_ops('+', frame4, 'black', 'white').pack()
minus= buttons_ops('-', frame4,  'black', 'white').pack()
mul = buttons_ops('x', frame4, 'black', 'white').pack()
div = buttons_ops('/', frame4, 'black', 'white').pack()

btn3 = buttons('3', frame3).pack()
btn6 = buttons('6', frame3).pack()
btn9 = buttons('9', frame3).pack()
equal= tk.Button(frame3, text='=', font=('Arial', 20), image=pixel, bg='white', fg='black', activebackground="black",
                        compound="center", command=lambda: cmd_equal()).pack()


root.resizable(0,0) 
# This keeps the window active
root.mainloop()
</code></pre>
<p>When we hit run, this should display our final project.</p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>So now you know how to build a simple arithmetic calculator. To strengthen and build upon the concepts that you learned here, you can try to add some more functionality to this calculator. Here are some ideas for you to practice the things learnt here:</p>
<ul>
<li><p>Adding a decimal point button to the calculator to allow users work with fractional numbers.</p>
</li>
<li><p>Adding percentage button to the calculator to allow users calculate percentages.</p>
</li>
<li><p>Adding a delete button to the calculator which, instead of clearing entire screen, deletes one character at a time.</p>
</li>
<li><p>Making the calculator 'computer keyboard interactive', that is, allowing input directly from the computer keyboard. (Hint for this task: changing the <code>state</code> of the <code>entry</code> object to <code>normal</code>, and adding conditions for 'invalid' expressions).</p>
</li>
</ul>
<p>Thanks for reading!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build a Whiteboard App with Python and Tkinter ]]>
                </title>
                <description>
                    <![CDATA[ In this tutorial, you will learn how to build a simple whiteboard app using Python and Tkinter. Some months ago, I was teaching a Python course. I was struggling to convey certain concepts because it was an online course, and I couldn't use a whitebo... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-a-whiteboard-app/</link>
                <guid isPermaLink="false">66d45f623a8352b6c5a2aa96</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tkinter ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Juan P. Romano ]]>
                </dc:creator>
                <pubDate>Tue, 07 Nov 2023 22:23:59 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/11/whiteboard_tkinter_python_banner_pic.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this tutorial, you will learn how to build a simple whiteboard app using Python and Tkinter.</p>
<p>Some months ago, I was teaching a Python course. I was struggling to convey certain concepts because it was an online course, and I couldn't use a whiteboard or even a traditional board. The built-in whiteboard feature in Google Meet was also quite complex to use and share.</p>
<p>So, I decided to search on Google to see if there were any GitHub repositories with whiteboard apps.</p>
<p>I found many such repositories. But after trying a lot of them, I found that the apps were often too complicated for my needs. I wanted something simpler, where I could choose colors and line sizes, and then I could do the drawing myself.</p>
<p>So, what did I do? I decided to code my own app. And for this process, I chose to use Python and Tkinter, the default GUI (Graphics User Interface) toolkit that comes with Python.</p>
<p>The end result?</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/image-10.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>The whiteboard app windows with a white canvas to start drawing and writing and the RGB color picker.</em></p>
<p>So in this tutorial, I'll walk you through the process so you can build it yourself. This will help you sharpen your Python skills and learn about Tkinter, too.</p>
<h2 id="heading-how-to-build-the-apps-functionality">How to Build the app's functionality</h2>
<h3 id="heading-setup-your-development-environment">Setup your development environment</h3>
<p>Building this app is pretty straightforward. You will need the latest Python version installed, which you can download and install from here:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.python.org/">https://www.python.org/</a></div>
<p> </p>
<p>If you're a Linux user, you won't need to install it as it comes with your distro. Also, you need to have a basic understanding of Python and know how to create functions.</p>
<p>After verifying that you already have Python installed on your computer, open Visual Studio Code or your preferred code editor to start writing code.</p>
<h3 id="heading-how-to-build-the-drawing-feature">How to build the drawing feature</h3>
<p>Create a Python file and begin by importing the Tkinter and color chooser modules, like this:</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> tkinter <span class="hljs-keyword">as</span> tk
<span class="hljs-keyword">from</span> tkinter.colorchooser <span class="hljs-keyword">import</span> askcolor
</code></pre>
<p>After importing Tkinter and the colorchooser module, which will open a modal to select our RGB color combinations, you can begin writing the functions to make this whiteboard work.</p>
<p>First, create a function to start drawing, like this:</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">start_drawing</span>(<span class="hljs-params">event</span>):</span>
    <span class="hljs-keyword">global</span> is_drawing, prev_x, prev_y
    is_drawing = <span class="hljs-literal">True</span>
    prev_x, prev_y = event.x, event.y
</code></pre>
<p>This code defines a function named <code>start_drawing</code> that is meant to handle the beginning of a drawing action in a graphical user interface (GUI) application.</p>
<p>Let's break down what this function does:</p>
<ol>
<li><p><code>def start_drawing(event):</code>: This line defines a function named <code>start_drawing</code> that takes an <code>event</code> as its parameter. In GUI programming, events are actions or occurrences (like mouse clicks, key presses and so on) that trigger specific functions when they happen.</p>
</li>
<li><p><code>global is_drawing, prev_x, prev_y</code>: This line declares that the variables <code>is_drawing</code>, <code>prev_x</code>, and <code>prev_y</code> are global variables. In Python, global variables are accessible from anywhere in the code and can be modified within functions. This line ensures that these variables are accessible within the function.</p>
</li>
<li><p><code>is_drawing = True</code>: This line sets the <code>is_drawing</code> variable to <code>True</code>. This variable is typically used to indicate whether a drawing action is in progress. By setting it to <code>True</code>, the function signals that a drawing action has started.</p>
</li>
<li><p><code>prev_x, prev_y = event.x, event.y</code>: This line captures the current coordinates of the mouse cursor when the <code>start_drawing</code> function is called. It assigns the <code>x</code> and <code>y</code> coordinates of the mouse cursor at that moment to the <code>prev_x</code> and <code>prev_y</code> variables. These variables are used to track the starting point of the drawing action.</p>
</li>
</ol>
<p>So when this function is called (usually in response to a mouse click event), it sets the <code>is_drawing</code> flag to <code>True</code> to indicate that a drawing action is in progress and records the initial position of the mouse cursor using the <code>prev_x</code> and <code>prev_y</code> variables. These variables are then used in the subsequent drawing actions to connect the starting point with the current cursor position to create a drawing on the canvas.</p>
<p>Now let's keep coding. Next up, we need to write a function to actually draw on the whiteboard, like this:</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">draw</span>(<span class="hljs-params">event</span>):</span>
    <span class="hljs-keyword">global</span> is_drawing, prev_x, prev_y
    <span class="hljs-keyword">if</span> is_drawing:
        current_x, current_y = event.x, event.y
        canvas.create_line(prev_x, prev_y, current_x, current_y, fill=drawing_color, width=line_width, capstyle=tk.ROUND, smooth=<span class="hljs-literal">True</span>)
        prev_x, prev_y = current_x, current_y
</code></pre>
<p>A drawing is essentially a combination of points filled with colors, functioning as a vector. To work as a vector, it needs to have a starting and ending point. So after creating a function to start drawing, you'll need a function to stop drawing, like this:</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">stop_drawing</span>(<span class="hljs-params">event</span>):</span>
    <span class="hljs-keyword">global</span> is_drawing
    is_drawing = <span class="hljs-literal">False</span>
</code></pre>
<h3 id="heading-how-to-build-the-color-changing-feature">How to build the color changing feature</h3>
<p>Now that you have the primary drawing functionality, the next step is to implement the color-changing function. This is a simple function that calls the <code>askcolor</code> module, which is already part of Tkinter, like this:</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">change_pen_color</span>():</span>
    <span class="hljs-keyword">global</span> drawing_color
    color = askcolor()[<span class="hljs-number">1</span>]
    <span class="hljs-keyword">if</span> color:
        drawing_color = color
</code></pre>
<p>For the last functionality, you'll create a function to adjust the line width, allowing you to choose the thickness of your lines. Here's how to implement it:</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">change_line_width</span>(<span class="hljs-params">value</span>):</span>
    <span class="hljs-keyword">global</span> line_width
    line_width = int(value)
</code></pre>
<p>Now you've completed the functions. Next, you'll use Tkinter to create the window for your app and buttons for choosing colors, clearing the whiteboard, and selecting your line width.</p>
<h2 id="heading-how-to-build-the-gui">How to Build the GUI</h2>
<p>GUI stands for Graphical User Interface, representing the windows you interact with on your computer, smartphone, tablets, and so on.</p>
<p>When coding a desktop app using Python and Tkinter, you define the size, position, buttons, and any other elements you want for your program. In this case, you need to create the following assets:</p>
<ul>
<li><p>A title for your app.</p>
</li>
<li><p>A white blank canvas for drawing.</p>
</li>
<li><p>A frame to hold the controls of your app in the same line.</p>
</li>
<li><p>A color button.</p>
</li>
<li><p>A clear canvas button to erase all your work and start drawing again.</p>
</li>
<li><p>A slider to select your line width.</p>
</li>
</ul>
<h3 id="heading-how-to-create-your-window">How to create your window</h3>
<p>Start by creating a window with a title and a white canvas:</p>
<pre><code class="lang-python">root = tk.Tk()
root.title(<span class="hljs-string">"Whiteboard App"</span>)

canvas = tk.Canvas(root, bg=<span class="hljs-string">"white"</span>)
canvas.pack(fill=<span class="hljs-string">"both"</span>, expand=<span class="hljs-literal">True</span>)

is_drawing = <span class="hljs-literal">False</span>
drawing_color = <span class="hljs-string">"black"</span>
line_width = <span class="hljs-number">2</span>

root.geometry(<span class="hljs-string">"800x600"</span>)
</code></pre>
<p>Let's break down what each part does:</p>
<ol>
<li><p><code>root = tk.Tk()</code>: This line creates the main application window. It initializes a Tkinter application and assigns it to the variable <code>root</code>. This window serves as the container for all the graphical elements of the whiteboard application.</p>
</li>
<li><p><code>root.title("Whiteboard App")</code>: This sets the title of the application window to "Whiteboard App." The title appears in the title bar of the window and provides a name for the application.</p>
</li>
<li><p><code>canvas = tk.Canvas(root, bg="white")</code>: This line creates a drawing canvas within the main application window. The canvas is a white rectangular area where users can draw. It is initialized with a white background color. The canvas is assigned to the variable <code>canvas</code>.</p>
</li>
<li><p><code>canvas.pack(fill="both", expand=True)</code>: This configures the canvas to fill both the horizontal and vertical space of the application window. It allows the canvas to expand and occupy the entire window.</p>
</li>
<li><p><code>is_drawing = False</code>: This initializes a variable <code>is_drawing</code> to <code>False</code>. It's typically used to track whether the user is currently drawing or not. When the user starts drawing, this variable is set to <code>True</code> to indicate an ongoing drawing action.</p>
</li>
<li><p><code>drawing_color = "black"</code>: This initializes a variable <code>drawing_color</code> to "black." It specifies the color that will be used for drawing on the canvas. You can change this color as needed to draw with different colors with the functions you will add later on this tutorial</p>
</li>
<li><p><code>line_width = 2</code>: This initializes a variable <code>line_width</code> to 2. It specifies the width of the lines or strokes used for drawing. You can adjust this value to change the thickness of the lines.</p>
</li>
<li><p><code>root.geometry("800x600")</code>: This sets the initial size of the application window to 800 pixels in width and 600 pixels in height. It defines the dimensions of the window when it is first displayed but you can resize your window and with it, your canvas space.</p>
</li>
</ol>
<h3 id="heading-how-to-build-your-navbar-and-controls">How to build your navbar and controls</h3>
<p>Next thing you need to do is create a frame to hold the buttons or controls in the same line. This is the most comfortable way to have buttons, and it's kind of a navbar.</p>
<pre><code class="lang-python">controls_frame = tk.Frame(root)
controls_frame.pack(side=<span class="hljs-string">"top"</span>, fill=<span class="hljs-string">"x"</span>)
</code></pre>
<p>Then, create two buttons and give them default fixed positions in your screen, like this:</p>
<pre><code class="lang-python">color_button = tk.Button(controls_frame, text=<span class="hljs-string">"Change Color"</span>, command=change_pen_color)
clear_button = tk.Button(controls_frame, text=<span class="hljs-string">"Clear Canvas"</span>, command=<span class="hljs-keyword">lambda</span>: canvas.delete(<span class="hljs-string">"all"</span>))

color_button.pack(side=<span class="hljs-string">"left"</span>, padx=<span class="hljs-number">5</span>, pady=<span class="hljs-number">5</span>)
clear_button.pack(side=<span class="hljs-string">"left"</span>, padx=<span class="hljs-number">5</span>, pady=<span class="hljs-number">5</span>)
</code></pre>
<p>So, right now, if you run your app you will see something like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/image-14.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>The window of the app with the blank canvas and two buttons, one for changing colors and one to clear the canvas.</em></p>
<p>You already have the two main buttons for your app, one to change colors and one to clear the canvas. The last control you need to create is a slider for the line width function. For that, you will write the following code:</p>
<pre><code class="lang-python">line_width_label = tk.Label(controls_frame, text=<span class="hljs-string">"Line Width:"</span>)
line_width_label.pack(side=<span class="hljs-string">"left"</span>, padx=<span class="hljs-number">5</span>, pady=<span class="hljs-number">5</span>)

line_width_slider = tk.Scale(controls_frame, from_=<span class="hljs-number">1</span>, to=<span class="hljs-number">10</span>, orient=<span class="hljs-string">"horizontal"</span>, command=<span class="hljs-keyword">lambda</span> val: change_line_width(val))
line_width_slider.set(line_width)
line_width_slider.pack(side=<span class="hljs-string">"left"</span>, padx=<span class="hljs-number">5</span>, pady=<span class="hljs-number">5</span>)
</code></pre>
<p>And again, let's recap what is going on here:</p>
<ol>
<li><p><code>line_width_label = tk.Label(controls_frame, text="Line Width:")</code>: This line creates a label widget with the text "Line Width." The label is intended to display text to describe the purpose of the following slider (which controls the line width). It is placed within the <code>controls_frame</code> widget.</p>
</li>
<li><p><code>line_width_label.pack(side="left", padx=5, pady=5)</code>: This line configures the label's placement within the <code>controls_frame</code>.</p>
</li>
<li><p><code>side="left"</code>: This sets the label to be placed on the left side of the <code>controls_frame</code>. It ensures that the label is aligned to the left.</p>
</li>
<li><p><code>padx=5</code>: It adds horizontal padding of 5 pixels around the label, creating some spacing.</p>
</li>
<li><p><code>pady=5</code>: It adds vertical padding of 5 pixels around the label, creating spacing.</p>
</li>
<li><p><code>line_width_slider = tk.Scale(controls_frame, from_=1, to=10, orient="horizontal", command=lambda val: change_line_width(val))</code>: This line creates a horizontal slider widget (Scale widget) that allows the user to select a line width. The slider ranges from a minimum value of 1 (<code>from_=1</code>) to a maximum value of 10 (<code>to=10</code>). The <code>command</code> option is set to call the <code>change_line_width</code> function with the selected value whenever the slider position changes.</p>
</li>
<li><p><code>line_width_slider.set(line_width)</code>: This sets the initial position of the slider to the value stored in the <code>line_width</code> variable, which is initialized earlier in the code. This ensures that the slider starts at the default line width.</p>
</li>
<li><p><code>line_width_slider.pack(side="left", padx=5, pady=5)</code>: This line configures the slider's placement within the <code>controls_frame</code>. It is placed on the left side, and padding is added to create spacing around the slider.</p>
</li>
</ol>
<p>So, if you reach this point, your app should look like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/image-15.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-how-to-connect-your-features-with-your-gui">How to connect your features with your GUI</h3>
<p>But if you press the buttons or move the slider for line width, it won't work because you still need to bind or "link" the functions you coded at the beginning of this tutorial with the buttons and controls you created.</p>
<p>For that, you're going to write this code:</p>
<pre><code class="lang-python">canvas.bind(<span class="hljs-string">"&lt;Button-1&gt;"</span>, start_drawing)
canvas.bind(<span class="hljs-string">"&lt;B1-Motion&gt;"</span>, draw)
canvas.bind(<span class="hljs-string">"&lt;ButtonRelease-1&gt;"</span>, stop_drawing)

root.mainloop()
</code></pre>
<p>So, a last recap to understand the end of your code:</p>
<ul>
<li><p><code>canvas.bind("&lt;Button-1&gt;", start_drawing)</code>: When the left mouse button is clicked on the canvas, it triggers the <code>start_drawing</code> function.</p>
</li>
<li><p><code>canvas.bind("&lt;B1-Motion&gt;", draw)</code>: While the left mouse button is held down and the mouse is moved on the canvas, it triggers the <code>draw</code> function.</p>
</li>
<li><p><code>canvas.bind("&lt;ButtonRelease-1&gt;", stop_drawing)</code>: When the left mouse button is released (button released event), it triggers the <code>stop_drawing</code> function.</p>
</li>
<li><p>And finally, <code>root.mainloop()</code> starts the main loop of the application, allowing it to respond to user interactions and events.</p>
</li>
</ul>
<h2 id="heading-wrapping-up">Wrapping up</h2>
<p>I hope you enjoyed reading through this tutorial as much as I did writing it, and that the whiteboard helps you in whatever you need to do.</p>
<p>If you want to download the app, you can check it out here:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://github.com/jpromanonet/white_board_py">https://github.com/jpromanonet/white_board_py</a></div>
<p> </p>
<p>Until next time! Happy coding and keep coding forward to create a cool portfolio =D</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Modern Python App Design with ttkbootstrap ]]>
                </title>
                <description>
                    <![CDATA[ Are you looking to add a touch of modernity to your Python apps? Do you want to master Tkinter and ttkbootstrap for a sleek, contemporary design? freeCodeCamp.org has just launched a brand new video course on YouTube that will teach you how to easily... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/modern-python-app-design-with-ttkbootstrap/</link>
                <guid isPermaLink="false">66b205cb125aeccef6f65d03</guid>
                
                    <category>
                        <![CDATA[ tkinter ]]>
                    </category>
                
                    <category>
                        <![CDATA[ youtube ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Beau Carnes ]]>
                </dc:creator>
                <pubDate>Tue, 18 Jul 2023 18:39:10 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/07/ttkbootstrap.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Are you looking to add a touch of modernity to your Python apps? Do you want to master Tkinter and ttkbootstrap for a sleek, contemporary design?</p>
<p>freeCodeCamp.org has just launched a brand new video course on YouTube that will teach you how to easily implement modern designs in your Tkinter-based Python applications using ttkbootstrap.</p>
<p>John Elder teaches this course. He is an industry veteran in education and a prolific producer of technical educational courses. He is also a respected author in the area of computer programming.</p>
<p>In this comprehensive course, you will be introduced to the world of ttkbootstrap, a powerful library that empowers developers to bring a modern touch to their Tkinter-based Python applications. The course's hands-on approach will take you through the usage of all the primary ttkbootstrap widgets, providing you with the tools necessary to elevate your Tkinter applications to the next level of design and usability.</p>
<p>The course is designed to be accessible and engaging, systematically covering the following key areas:</p>
<ol>
<li><strong>Introduction</strong>: Acquaint yourself with ttkbootstrap and its potential to revolutionize your Python app designs.</li>
<li><strong>Labels and Buttons</strong>: Learn how to implement and customize these essential widgets.</li>
<li><strong>CheckButtons to Combo Boxes</strong>: Master the different types of interactive elements, including CheckButtons, Resizing Buttons, and Combo Boxes.</li>
<li><strong>Entry Boxes to Frames and Labels</strong>: Understand how to collect user input and manage GUI layout effectively.</li>
<li><strong>Menu Buttons to Progress Bars</strong>: Discover how to enhance user navigation and provide effective feedback.</li>
<li><strong>Radio Buttons to Spinboxes</strong>: Dive deeper into interactive elements and their customization.</li>
<li><strong>Treeview to Scrolled Frame</strong>: Learn how to present hierarchical data and manage large contents in your GUI.</li>
<li><strong>Message Boxes to Toast Messages</strong>: Get a handle on delivering alerts and messages to your users.</li>
<li><strong>Conclusion</strong>: Summarize your learnings and look ahead at how to apply these in your future projects.</li>
</ol>
<p>By the end of this course, you'll be equipped to create highly functional, modern, and visually appealing applications with Tkinter and ttkbootstrap. This course represents an invaluable opportunity for Python developers to add another powerful tool to their repertoire.</p>
<p>Watch the full course on <a target="_blank" href="https://youtu.be/0tM-l_ZsxjU">the freeCodeCamp.org YouTube channel</a> (3-hour watch). </p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/0tM-l_ZsxjU" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build a GUI Quiz App Using Tkinter and Open Trivia DB ]]>
                </title>
                <description>
                    <![CDATA[ In this article, we'll learn to build a Graphical User Interface (GUI) Quiz Application using the Tkinter Python built-in module.  The task is to ask multiple-choice questions, collect user answers, and finally display the results.  Before coding the... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-create-a-gui-quiz-application-using-tkinter-and-open-trivia-db/</link>
                <guid isPermaLink="false">66ba0e89a1a94b68c6ae9499</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tkinter ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Ashutosh Krishna ]]>
                </dc:creator>
                <pubDate>Fri, 10 Dec 2021 21:29:54 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/12/python-GUI-QUiz-application.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In this article, we'll learn to build a <a target="_blank" href="https://en.wikipedia.org/wiki/Graphical_user_interface">Graphical User Interface</a> (GUI) <strong>Quiz Application</strong> using the <a target="_blank" href="https://docs.python.org/3/library/tkinter.html">Tkinter</a> Python built-in module. </p>
<p>The task is to ask multiple-choice questions, collect user answers, and finally display the results. </p>
<p>Before coding the GUI, we'll first see how to fetch multiple-choice questions, their correct answers, and the choices from the <a target="_blank" href="https://opentdb.com/">Open Trivia DB API</a>. </p>
<p>The <strong>Open Trivia Database</strong> provides a completely free JSON API that you can use in your programming projects. Use of this API <strong>does not require</strong> an API Key. To make the task more interesting, we'll also randomize the order of choices.</p>
<p>Watch this video to see what we are building:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/2hYci86bmjs" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>We'll use the following modules and concepts in this project:</p>
<ul>
<li><a target="_blank" href="https://docs.python.org/3/library/tkinter.html">tkinter</a> is a standard GUI library for Python using which we can build desktop apps. This is the base of our project and we'll use it to create the User Interface of the application.</li>
<li><a target="_blank" href="https://docs.python.org/3/library/random.html">random module</a> implements pseudo-random number generators for various distributions. This module will help us shuffle the options for the questions.</li>
<li><a target="_blank" href="https://pypi.org/project/requests/">requests library</a> allows us to send HTTP/1.1 requests extremely easily. We'll need the library to fetch questions from the Open Trivia DB.</li>
<li><a target="_blank" href="https://docs.python.org/3/tutorial/classes.html">Python Classes</a> are a blueprint for creating objects. Objects are real-world entities. During the entire project development, we'll be separating our different functionalities into different classes and methods.</li>
</ul>
<h2 id="heading-workflow-of-the-project">Workflow of the Project</h2>
<p>The basic workflow of the application will go like this:</p>
<ol>
<li>We'll fetch questions from the Open Trivia DB API.</li>
<li>For each fetched question, we'll create a different object using a <em>Question</em> class. All these <em>Question</em> objects will be appended to a <code>question_bank</code> list.</li>
<li>This <code>question_bank</code> will be passed to the brain of the application, <em>QuizBrain</em> and a <code>quiz</code> object will be created<em>.</em> This class will be responsible for checking if there are more questions, for getting the next question, calculating the score, and so on.</li>
<li>Finally, this <code>quiz</code> object will be passed to the <em>QuizInterface</em> class, and the user will be able to interact with it.</li>
</ol>
<p>Alright, let's get started!</p>
<h2 id="heading-how-to-fetch-questions-from-the-open-trivia-db-api">How to Fetch Questions from the Open Trivia DB API</h2>
<p>As we discussed above, we'll be using the Open Trivia DB API to get the questions. Head over to <a target="_blank" href="https://opentdb.com/api_config.php">their API</a>, select the number of questions you want, along with the categories and difficulty. </p>
<p>The question type should be <em>Multiple Choice</em> and the encoding should be <em>Default Encoding</em>. Click on Generate API URL and you'll get an API URL.</p>
<p>Here's a sample API URL: <code>https://opentdb.com/api.php?amount=10&amp;type=multiple</code></p>
<p>For fetching the questions, we'll be using the <code>requests</code> module. You can install it like this:</p>
<pre><code class="lang-bash">$ pip install requests
</code></pre>
<p>Let's create a Python file <code>quiz_data.py</code> to fetch the quiz questions and answers using the API URL generated above.</p>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> requests

parameters = {
    <span class="hljs-string">"amount"</span>: <span class="hljs-number">10</span>,
    <span class="hljs-string">"type"</span>: <span class="hljs-string">"multiple"</span>
}

response = requests.get(url=<span class="hljs-string">"https://opentdb.com/api.php"</span>, params=parameters)
question_data = response.json()[<span class="hljs-string">"results"</span>]
</code></pre>
<p>In the above script, instead of directly adding the <code>amount</code> and <code>type</code> parameters in the URL, we have created a <code>parameters</code> dictionary and added the respective values. </p>
<p>After that, we're making a <strong>GET</strong> request using the <em>requests</em> library on the Open Trivia DB API URL. A sample JSON response looks like this:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"response_code"</span>: <span class="hljs-number">0</span>,
  <span class="hljs-attr">"results"</span>: [
    {
      <span class="hljs-attr">"category"</span>: <span class="hljs-string">"Entertainment: Video Games"</span>,
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"multiple"</span>,
      <span class="hljs-attr">"difficulty"</span>: <span class="hljs-string">"hard"</span>,
      <span class="hljs-attr">"question"</span>: <span class="hljs-string">"What was the name of the hero in the 80s animated video game &amp;#039;Dragon&amp;#039;s Lair&amp;#039;?"</span>,
      <span class="hljs-attr">"correct_answer"</span>: <span class="hljs-string">"Dirk the Daring"</span>,
      <span class="hljs-attr">"incorrect_answers"</span>: [<span class="hljs-string">"Arthur"</span>, <span class="hljs-string">"Sir Toby Belch"</span>, <span class="hljs-string">"Guy of Gisbourne"</span>]
    },
    {
      <span class="hljs-attr">"category"</span>: <span class="hljs-string">"Entertainment: Video Games"</span>,
      <span class="hljs-attr">"type"</span>: <span class="hljs-string">"multiple"</span>,
      <span class="hljs-attr">"difficulty"</span>: <span class="hljs-string">"medium"</span>,
      <span class="hljs-attr">"question"</span>: <span class="hljs-string">"Which of these game franchises were made by Namco?"</span>,
      <span class="hljs-attr">"correct_answer"</span>: <span class="hljs-string">"Tekken"</span>,
      <span class="hljs-attr">"incorrect_answers"</span>: [<span class="hljs-string">"Street Fighter"</span>, <span class="hljs-string">"Mortal Kombat"</span>, <span class="hljs-string">"Dragon Quest"</span>]
    }
  ]
}
</code></pre>
<p>The JSON data contains a dictionary with two keys: <code>response_code</code> and <code>results</code>. The <code>response_code</code> tells developers what the API is doing. The <code>results</code> is a list we are interested in. So, we have stored the value of results in a variable called <code>question_data</code>.</p>
<h2 id="heading-how-to-create-the-question-model">How to Create the Question Model</h2>
<p>Question model is nothing but a Python class with three attributes – <code>question_text</code>, <code>correct_answer</code> and <code>choices</code>. </p>
<p>_question<em>text</em> is the question, _correct<em>answer</em> is the correct answer for that question, and <em>choices</em> is a list of options for that question.</p>
<p>Let's create a <code>question_model.py</code> file and create the class in it:</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Question</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, question: str, correct_answer: str, choices: list</span>):</span>
        self.question_text = question
        self.correct_answer = correct_answer
        self.choices = choices
</code></pre>
<h2 id="heading-how-to-create-the-quiz-brain">How to Create the Quiz Brain</h2>
<p>The <em>QuizBrain</em>, as the name suggests, is the brain of the application. Let's create a <code>quiz_brain.py</code> file and add the following code there:</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">QuizBrain</span>:</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, questions</span>):</span>
        self.question_no = <span class="hljs-number">0</span>
        self.score = <span class="hljs-number">0</span>
        self.questions = questions
        self.current_question = <span class="hljs-literal">None</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">has_more_questions</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-string">"""To check if the quiz has more questions"""</span>

        <span class="hljs-keyword">return</span> self.question_no &lt; len(self.questions)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">next_question</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-string">"""Get the next question by incrementing the question number"""</span>

        self.current_question = self.questions[self.question_no]
        self.question_no += <span class="hljs-number">1</span>
        q_text = self.current_question.question_text
        <span class="hljs-keyword">return</span> <span class="hljs-string">f"Q.<span class="hljs-subst">{self.question_no}</span>: <span class="hljs-subst">{q_text}</span>"</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">check_answer</span>(<span class="hljs-params">self, user_answer</span>):</span>
        <span class="hljs-string">"""Check the user's answer against the correct answer and maintain the score"""</span>

        correct_answer = self.current_question.correct_answer
        <span class="hljs-keyword">if</span> user_answer.lower() == correct_answer.lower():
            self.score += <span class="hljs-number">1</span>
            <span class="hljs-keyword">return</span> <span class="hljs-literal">True</span>
        <span class="hljs-keyword">else</span>:
            <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_score</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-string">"""Get the number of correct answers, wrong answers, and score percentage."""</span>

        wrong = self.question_no - self.score
        score_percent = int(self.score / self.question_no * <span class="hljs-number">100</span>)
        <span class="hljs-keyword">return</span> (self.score, wrong, score_percent)
</code></pre>
<p>The <code>QuizBrain</code> class takes <code>questions</code>, a list of questions. Additionally, the <code>question_no</code> and <code>score</code> attributes are initialized with <code>0</code> and the <code>current_question</code> is set to <code>None</code> initially.</p>
<p>The first method <code>has_more_questions()</code> checks whether the quiz has more questions or not. </p>
<p>The next method <code>next_question()</code> gets the question from the <code>questions</code> list at index <code>question_no</code> and then increments the <code>question_no</code> attribute and returns a formatted question. </p>
<p>The <code>check_answer()</code> method takes <code>user_answer</code> as an argument and checks whether the user's answer is correct or not. It also maintains the <em>score</em> and returns boolean values. </p>
<p>The last method <code>get_score()</code> returns the number of <em>correct answers</em>, <em>wrong answers,</em> and <em>score percentage</em>.</p>
<h2 id="heading-how-to-build-the-quiz-ui">How to Build the Quiz UI</h2>
<p>Let's move on to the next part where we'll create the user interface of the application. Create a <code>quiz_ui.py</code> file for this section, and add the following code.</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">QuizInterface</span>:</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, quiz_brain: QuizBrain</span>) -&gt; <span class="hljs-keyword">None</span>:</span>
        self.quiz = quiz_brain
        self.window = Tk()
        self.window.title(<span class="hljs-string">"iQuiz App"</span>)
        self.window.geometry(<span class="hljs-string">"850x530"</span>)

        <span class="hljs-comment"># Display Title</span>
        self.display_title()

        <span class="hljs-comment"># Creating a canvas for question text, and dsiplay question</span>
        self.canvas = Canvas(width=<span class="hljs-number">800</span>, height=<span class="hljs-number">250</span>)
        self.question_text = self.canvas.create_text(<span class="hljs-number">400</span>, <span class="hljs-number">125</span>,
                                                     text=<span class="hljs-string">"Question here"</span>,
                                                     width=<span class="hljs-number">680</span>,
                                                     fill=THEME_COLOR,
                                                     font=(
                                                         <span class="hljs-string">'Ariel'</span>, <span class="hljs-number">15</span>, <span class="hljs-string">'italic'</span>)
                                                     )
        self.canvas.grid(row=<span class="hljs-number">2</span>, column=<span class="hljs-number">0</span>, columnspan=<span class="hljs-number">2</span>, pady=<span class="hljs-number">50</span>)
        self.display_question()

        <span class="hljs-comment"># Declare a StringVar to store user's answer</span>
        self.user_answer = StringVar()

        <span class="hljs-comment"># Display four options(radio buttons)</span>
        self.opts = self.radio_buttons()
        self.display_options()

        <span class="hljs-comment"># To show whether the answer is correct or wrong</span>
        self.feedback = Label(self.window, pady=<span class="hljs-number">10</span>, font=(<span class="hljs-string">"ariel"</span>, <span class="hljs-number">15</span>, <span class="hljs-string">"bold"</span>))
        self.feedback.place(x=<span class="hljs-number">300</span>, y=<span class="hljs-number">380</span>)

        <span class="hljs-comment"># Next and Quit Button</span>
        self.buttons()

        <span class="hljs-comment"># Mainloop</span>
        self.window.mainloop()
</code></pre>
<p>In the above code, we've created a <em>QuizInterface</em> class with a constructor. In Python, the <code>__init__()</code> method is called constructor and is called automatically whenever an object of that class is created. </p>
<p>As discussed in the workflow, the <em>QuizInterface</em> class takes an argument of type <em>QuizBrain</em>. So, within the constructor, we have passed that as <code>quiz_brain</code>. </p>
<p>The first thing we do in Tkinter is create a window using the <em>Tk</em> class. You can set the title and the geometry using the <code>title()</code> and <code>geometry()</code> methods respectively.</p>
<p>Next we called few methods which we'll be creating next. Apart from that, we've created a canvas using the <em>Canvas</em> class where our questions will be placed. Canvas is a rectangular area where we can place text, graphics, widgets, and so on.</p>
<p>Inside the canvas, we added a sample text for now using the <code>create_text()</code> method. We then declared a StringVar variable called <code>user_answer</code> to store the user's answer in String type. </p>
<p>Next we created a <code>feedback</code> label to show whether the answer is right or wrong using the <em>Label</em> widget. This widget implements a display box where we can place text or images. You can update the text displayed by this widget at any time you want. </p>
<p>At the very end, we enter the main event loop to take action against each event triggered by the user using the <code>mainloop()</code> method. Now, let's create the other methods that we'll use in this constructor.</p>
<h3 id="heading-to-display-the-title">To display the title</h3>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">display_title</span>(<span class="hljs-params">self</span>):</span>
    <span class="hljs-string">"""To display title"""</span>

    title = Label(self.window, text=<span class="hljs-string">"iQuiz Application"</span>,
                      width=<span class="hljs-number">50</span>, bg=<span class="hljs-string">"green"</span>, fg=<span class="hljs-string">"white"</span>, font=(<span class="hljs-string">"ariel"</span>, <span class="hljs-number">20</span>, <span class="hljs-string">"bold"</span>))
    title.place(x=<span class="hljs-number">0</span>, y=<span class="hljs-number">2</span>)
</code></pre>
<p>To display a title, we have created a <em>Label</em> widget on the main window. We set its <code>width</code>, <code>bg</code>, <code>fg</code> and <code>font</code> properties and it looks something like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Screenshot-2021-12-11-011507.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-to-display-a-question">To display a question</h3>
<p>As we know, we have already created a canvas for the question text. Since the <code>question_no</code> is initialized with 0 in the <em>QuizBrain</em> class, we can get the questions using the <code>next_question()</code> method:</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">display_question</span>(<span class="hljs-params">self</span>):</span>
    <span class="hljs-string">"""To display the question"""</span>

    q_text = self.quiz.next_question()
    self.canvas.itemconfig(self.question_text, text=q_text)
</code></pre>
<p>Using the <code>itemconfig()</code> method in the <em>Canvas</em> class, we can add question text dynamically.</p>
<h3 id="heading-to-create-the-radio-buttons">To create the radio buttons</h3>
<p>Since the options will be four radio buttons, we'll be using the <em>RadioButton</em> class from the Tkinter module.</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">radio_buttons</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-string">"""To create four options (radio buttons)"""</span>
    <span class="hljs-comment"># initialize the list with an empty list of options</span>
    choice_list = []

    <span class="hljs-comment"># position of the first option</span>
    y_pos = <span class="hljs-number">220</span>

    <span class="hljs-comment"># adding the options to the list</span>
    <span class="hljs-keyword">while</span> len(choice_list) &lt; <span class="hljs-number">4</span>:

        <span class="hljs-comment"># setting the radio button properties</span>
        radio_btn = Radiobutton(self.window, text=<span class="hljs-string">""</span>, variable=self.user_answer, value=<span class="hljs-string">''</span>, font=(<span class="hljs-string">"ariel"</span>, <span class="hljs-number">14</span>))

        <span class="hljs-comment"># adding the button to the list</span>
        choice_list.append(radio_btn)

        <span class="hljs-comment"># placing the button</span>
        radio_btn.place(x=<span class="hljs-number">200</span>, y=y_pos)

        <span class="hljs-comment"># incrementing the y-axis position by 40</span>
        y_pos += <span class="hljs-number">40</span>

    <span class="hljs-comment"># return the radio buttons</span>
    <span class="hljs-keyword">return</span> choice_list
</code></pre>
<p>First we created a <code>choice_list</code> list. We set the y-position of the first choice as 220. Using a while loop, we created four instances of the RadioButton class on the main window. Notice the variable attribute set as <code>user_answer</code> that we created earlier.</p>
<p>We'll append these radio buttons in the <code>choice_list</code> and place them at a distance of 40 units in the y-axis. We then return the <code>choice_list</code>.</p>
<h3 id="heading-to-display-options">To display options</h3>
<p>We'll use this method to set the <code>text</code> and <code>value</code> attribute of each radio button.</p>
<pre><code>def display_options(self):
    <span class="hljs-string">""</span><span class="hljs-string">"To display four options"</span><span class="hljs-string">""</span>

    val = <span class="hljs-number">0</span>

    # deselecting the options
    self.user_answer.set(None)

    # looping over the options to be displayed <span class="hljs-keyword">for</span> the
    # text <span class="hljs-keyword">of</span> the radio buttons.
    for option <span class="hljs-keyword">in</span> self.quiz.current_question.choices:
        self.opts[val][<span class="hljs-string">'text'</span>] = option
        self.opts[val][<span class="hljs-string">'value'</span>] = option
        val += <span class="hljs-number">1</span>
</code></pre><p>We first set the <code>user_answer</code> to None. Then we iterate over the <code>choices</code> for the <code>current_question</code> and set the two properties one after another for each option.</p>
<h3 id="heading-to-display-buttons">To display buttons</h3>
<p>As you can see, we've two buttons – Next and Quit.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Screenshot-2021-12-11-013502.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>We'll use the Next button to move to the next question (if any). And we'll use the Quit button to quit the quiz and destroy the window immediately. </p>
<p>We use the <em>Button</em> class from the Tkinter module to create them. The functionality for these buttons is added in the <code>command</code> attribute. </p>
<p>For the Next button, we'll be creating a separate method right after this section. For the Quit button, we just destroy the main window.</p>
<h3 id="heading-next-button-functionality">Next button functionality</h3>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">next_btn</span>(<span class="hljs-params">self</span>):</span>
    <span class="hljs-string">"""To show feedback for each answer and keep checking for more questions"""</span>

    <span class="hljs-comment"># Check if the answer is correct</span>
    <span class="hljs-keyword">if</span> self.quiz.check_answer(self.user_answer.get()):
        self.feedback[<span class="hljs-string">"fg"</span>] = <span class="hljs-string">"green"</span>
        self.feedback[<span class="hljs-string">"text"</span>] = <span class="hljs-string">'Correct answer! \U0001F44D'</span>
    <span class="hljs-keyword">else</span>:
        self.feedback[<span class="hljs-string">'fg'</span>] = <span class="hljs-string">'red'</span>
        self.feedback[<span class="hljs-string">'text'</span>] = (<span class="hljs-string">'\u274E Oops! \n'</span>
                                     <span class="hljs-string">f'The right answer is: <span class="hljs-subst">{self.quiz.current_question.correct_answer}</span>'</span>)

    <span class="hljs-keyword">if</span> self.quiz.has_more_questions():
        <span class="hljs-comment"># Moves to next to display next question and its options</span>
        self.display_question()
        self.display_options()
    <span class="hljs-keyword">else</span>:
        <span class="hljs-comment"># if no more questions, then it displays the score</span>
        self.display_result()

        <span class="hljs-comment"># destroys the self.window</span>
        self.window.destroy()
</code></pre>
<p>The next button has to do a lot of things. </p>
<p>First of all, it checks whether the answer selected by the user is correct or not using the <code>check_answer</code> method. It shows the feedback accordingly. </p>
<p>Next, it checks if the quiz has more questions or not. If there are more questions, it calls the <code>display_question</code> and <code>display_options</code> methods again. If there are no questions left, it calls the <code>display_result</code> method to show the result and then destroys the main window.</p>
<h3 id="heading-to-display-the-results">To display the results</h3>
<p>At the end of the quiz, we need to show the results to the user like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/12/Screenshot-2021-12-11-014531.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Here, as you can see, we are showing the score percentage based on correct answers and wrong answers.</p>
<pre><code class="lang-py"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">display_result</span>(<span class="hljs-params">self</span>):</span>
    <span class="hljs-string">"""To display the result using messagebox"""</span>
    correct, wrong, score_percent = self.quiz.get_score()

    correct = <span class="hljs-string">f"Correct: <span class="hljs-subst">{correct}</span>"</span>
    wrong = <span class="hljs-string">f"Wrong: <span class="hljs-subst">{wrong}</span>"</span>

    <span class="hljs-comment"># calculates the percentage of correct answers</span>
    result = <span class="hljs-string">f"Score: <span class="hljs-subst">{score_percent}</span>%"</span>

    <span class="hljs-comment"># Shows a message box to display the result</span>
    messagebox.showinfo(<span class="hljs-string">"Result"</span>, <span class="hljs-string">f"<span class="hljs-subst">{result}</span>\n<span class="hljs-subst">{correct}</span>\n<span class="hljs-subst">{wrong}</span>"</span>)
</code></pre>
<p>We use the <code>get_score</code> method to get the computations and then we use the <code>showinfo</code> method from the <code>messagebox</code> class to show such a popup message.</p>
<h3 id="heading-full-code-for-quizuipy">Full code for <code>quiz_ui.py</code></h3>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> tkinter <span class="hljs-keyword">import</span> Tk, Canvas, StringVar, Label, Radiobutton, Button, messagebox
<span class="hljs-keyword">from</span> quiz_brain <span class="hljs-keyword">import</span> QuizBrain

THEME_COLOR = <span class="hljs-string">"#375362"</span>


<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">QuizInterface</span>:</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self, quiz_brain: QuizBrain</span>) -&gt; <span class="hljs-keyword">None</span>:</span>
        self.quiz = quiz_brain
        self.window = Tk()
        self.window.title(<span class="hljs-string">"iQuiz App"</span>)
        self.window.geometry(<span class="hljs-string">"850x530"</span>)

        <span class="hljs-comment"># Display Title</span>
        self.display_title()

        <span class="hljs-comment"># Create a canvas for question text, and dsiplay question</span>
        self.canvas = Canvas(width=<span class="hljs-number">800</span>, height=<span class="hljs-number">250</span>)
        self.question_text = self.canvas.create_text(<span class="hljs-number">400</span>, <span class="hljs-number">125</span>,
                                                     text=<span class="hljs-string">"Question here"</span>,
                                                     width=<span class="hljs-number">680</span>,
                                                     fill=THEME_COLOR,
                                                     font=(
                                                         <span class="hljs-string">'Ariel'</span>, <span class="hljs-number">15</span>, <span class="hljs-string">'italic'</span>)
                                                     )
        self.canvas.grid(row=<span class="hljs-number">2</span>, column=<span class="hljs-number">0</span>, columnspan=<span class="hljs-number">2</span>, pady=<span class="hljs-number">50</span>)
        self.display_question()

        <span class="hljs-comment"># Declare a StringVar to store user's answer</span>
        self.user_answer = StringVar()

        <span class="hljs-comment"># Display four options (radio buttons)</span>
        self.opts = self.radio_buttons()
        self.display_options()

        <span class="hljs-comment"># To show whether the answer is right or wrong</span>
        self.feedback = Label(self.window, pady=<span class="hljs-number">10</span>, font=(<span class="hljs-string">"ariel"</span>, <span class="hljs-number">15</span>, <span class="hljs-string">"bold"</span>))
        self.feedback.place(x=<span class="hljs-number">300</span>, y=<span class="hljs-number">380</span>)

        <span class="hljs-comment"># Next and Quit Button</span>
        self.buttons()

        <span class="hljs-comment"># Mainloop</span>
        self.window.mainloop()

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">display_title</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-string">"""To display title"""</span>

        <span class="hljs-comment"># Title</span>
        title = Label(self.window, text=<span class="hljs-string">"iQuiz Application"</span>,
                      width=<span class="hljs-number">50</span>, bg=<span class="hljs-string">"green"</span>, fg=<span class="hljs-string">"white"</span>, font=(<span class="hljs-string">"ariel"</span>, <span class="hljs-number">20</span>, <span class="hljs-string">"bold"</span>))

        <span class="hljs-comment"># place of the title</span>
        title.place(x=<span class="hljs-number">0</span>, y=<span class="hljs-number">2</span>)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">display_question</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-string">"""To display the question"""</span>

        q_text = self.quiz.next_question()
        self.canvas.itemconfig(self.question_text, text=q_text)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">radio_buttons</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-string">"""To create four options (radio buttons)"""</span>

        <span class="hljs-comment"># initialize the list with an empty list of options</span>
        choice_list = []

        <span class="hljs-comment"># position of the first option</span>
        y_pos = <span class="hljs-number">220</span>

        <span class="hljs-comment"># adding the options to the list</span>
        <span class="hljs-keyword">while</span> len(choice_list) &lt; <span class="hljs-number">4</span>:

            <span class="hljs-comment"># setting the radio button properties</span>
            radio_btn = Radiobutton(self.window, text=<span class="hljs-string">""</span>, variable=self.user_answer,
                                    value=<span class="hljs-string">''</span>, font=(<span class="hljs-string">"ariel"</span>, <span class="hljs-number">14</span>))

            <span class="hljs-comment"># adding the button to the list</span>
            choice_list.append(radio_btn)

            <span class="hljs-comment"># placing the button</span>
            radio_btn.place(x=<span class="hljs-number">200</span>, y=y_pos)

            <span class="hljs-comment"># incrementing the y-axis position by 40</span>
            y_pos += <span class="hljs-number">40</span>

        <span class="hljs-comment"># return the radio buttons</span>
        <span class="hljs-keyword">return</span> choice_list

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">display_options</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-string">"""To display four options"""</span>

        val = <span class="hljs-number">0</span>

        <span class="hljs-comment"># deselecting the options</span>
        self.user_answer.set(<span class="hljs-literal">None</span>)

        <span class="hljs-comment"># looping over the options to be displayed for the</span>
        <span class="hljs-comment"># text of the radio buttons.</span>
        <span class="hljs-keyword">for</span> option <span class="hljs-keyword">in</span> self.quiz.current_question.choices:
            self.opts[val][<span class="hljs-string">'text'</span>] = option
            self.opts[val][<span class="hljs-string">'value'</span>] = option
            val += <span class="hljs-number">1</span>

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">next_btn</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-string">"""To show feedback for each answer and keep checking for more questions"""</span>

        <span class="hljs-comment"># Check if the answer is correct</span>
        <span class="hljs-keyword">if</span> self.quiz.check_answer(self.user_answer.get()):
            self.feedback[<span class="hljs-string">"fg"</span>] = <span class="hljs-string">"green"</span>
            self.feedback[<span class="hljs-string">"text"</span>] = <span class="hljs-string">'Correct answer! \U0001F44D'</span>
        <span class="hljs-keyword">else</span>:
            self.feedback[<span class="hljs-string">'fg'</span>] = <span class="hljs-string">'red'</span>
            self.feedback[<span class="hljs-string">'text'</span>] = (<span class="hljs-string">'\u274E Oops! \n'</span>
                                     <span class="hljs-string">f'The right answer is: <span class="hljs-subst">{self.quiz.current_question.correct_answer}</span>'</span>)

        <span class="hljs-keyword">if</span> self.quiz.has_more_questions():
            <span class="hljs-comment"># Moves to next to display next question and its options</span>
            self.display_question()
            self.display_options()
        <span class="hljs-keyword">else</span>:
            <span class="hljs-comment"># if no more questions, then it displays the score</span>
            self.display_result()

            <span class="hljs-comment"># destroys the self.window</span>
            self.window.destroy()

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">buttons</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-string">"""To show next button and quit button"""</span>

        <span class="hljs-comment"># The first button is the Next button to move to the</span>
        <span class="hljs-comment"># next Question</span>
        next_button = Button(self.window, text=<span class="hljs-string">"Next"</span>, command=self.next_btn,
                             width=<span class="hljs-number">10</span>, bg=<span class="hljs-string">"green"</span>, fg=<span class="hljs-string">"white"</span>, font=(<span class="hljs-string">"ariel"</span>, <span class="hljs-number">16</span>, <span class="hljs-string">"bold"</span>))

        <span class="hljs-comment"># palcing the button on the screen</span>
        next_button.place(x=<span class="hljs-number">350</span>, y=<span class="hljs-number">460</span>)

        <span class="hljs-comment"># This is the second button which is used to Quit the self.window</span>
        quit_button = Button(self.window, text=<span class="hljs-string">"Quit"</span>, command=self.window.destroy,
                             width=<span class="hljs-number">5</span>, bg=<span class="hljs-string">"red"</span>, fg=<span class="hljs-string">"white"</span>, font=(<span class="hljs-string">"ariel"</span>, <span class="hljs-number">16</span>, <span class="hljs-string">" bold"</span>))

        <span class="hljs-comment"># placing the Quit button on the screen</span>
        quit_button.place(x=<span class="hljs-number">700</span>, y=<span class="hljs-number">50</span>)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">display_result</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-string">"""To display the result using messagebox"""</span>
        correct, wrong, score_percent = self.quiz.get_score()

        correct = <span class="hljs-string">f"Correct: <span class="hljs-subst">{correct}</span>"</span>
        wrong = <span class="hljs-string">f"Wrong: <span class="hljs-subst">{wrong}</span>"</span>

        <span class="hljs-comment"># calculates the percentage of correct answers</span>
        result = <span class="hljs-string">f"Score: <span class="hljs-subst">{score_percent}</span>%"</span>

        <span class="hljs-comment"># Shows a message box to display the result</span>
        messagebox.showinfo(<span class="hljs-string">"Result"</span>, <span class="hljs-string">f"<span class="hljs-subst">{result}</span>\n<span class="hljs-subst">{correct}</span>\n<span class="hljs-subst">{wrong}</span>"</span>)
</code></pre>
<h2 id="heading-how-to-put-everything-together">How to Put Everything Together</h2>
<p>Since all the components are ready to be integrated together, let's create a <code>main.py</code> file and add the following content there:</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> question_model <span class="hljs-keyword">import</span> Question
<span class="hljs-keyword">from</span> quiz_data <span class="hljs-keyword">import</span> question_data
<span class="hljs-keyword">from</span> quiz_brain <span class="hljs-keyword">import</span> QuizBrain
<span class="hljs-keyword">from</span> quiz_ui <span class="hljs-keyword">import</span> QuizInterface
<span class="hljs-keyword">from</span> random <span class="hljs-keyword">import</span> shuffle
<span class="hljs-keyword">import</span> html

question_bank = []
<span class="hljs-keyword">for</span> question <span class="hljs-keyword">in</span> question_data:
    choices = []
    question_text = html.unescape(question[<span class="hljs-string">"question"</span>])
    correct_answer = html.unescape(question[<span class="hljs-string">"correct_answer"</span>])
    incorrect_answers = question[<span class="hljs-string">"incorrect_answers"</span>]
    <span class="hljs-keyword">for</span> ans <span class="hljs-keyword">in</span> incorrect_answers:
        choices.append(html.unescape(ans))
    choices.append(correct_answer)
    shuffle(choices)
    new_question = Question(question_text, correct_answer, choices)
    question_bank.append(new_question)


quiz = QuizBrain(question_bank)

quiz_ui = QuizInterface(quiz)


print(<span class="hljs-string">"You've completed the quiz"</span>)
print(<span class="hljs-string">f"Your final score was: <span class="hljs-subst">{quiz.score}</span>/<span class="hljs-subst">{quiz.question_no}</span>"</span>)
</code></pre>
<p>We first imported all the classes from the different files we created above. In addition to that, we also need the <code>shuffle</code> method from the <code>random</code> module and the <code>html</code> module. </p>
<p>We have a list called <code>question_bank</code>. We are iterating over the <code>question_data</code> that we receive from the <code>quiz_data.py</code> file. If you see the sample response, you will find some text such as <code>&amp;#039;Dragon&amp;#039</code>. These need to be unescaped using the <code>html.unescape</code> method. </p>
<p>We have a <code>choices</code> list that will contain the correct answer as well as the incorrect answers. The list will be shuffled using the <code>shuffle</code> method from the <code>random</code> module. </p>
<p>After shuffling, we create a question using the <code>Question</code> model from <code>quiz_model.py</code> file and append it the <code>question_bank</code> list.</p>
<p>Next, we're creating an object called <code>quiz</code> of the <em>QuizBrain</em> class which requires a list of questions. So, we're passing the <code>question_bank</code> to it. </p>
<p>After that, we're creating an object <code>quiz_ui</code> of the <em>QuizInterface</em> class which requires an object of the QuizBrain class, so we have passed the newly created <code>quiz</code> object to it.</p>
<p>Now that everything is ready, we are ready to run the application.</p>
<pre><code class="lang-bash">$ python main.py
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Congrats on making it to the end! This was a basic tutorial on how you can build a GUI Quiz application using Tkinter. You can add more features and make the UI more attractive if you want to.</p>
<p>Here's the code repository: <a target="_blank" href="https://github.com/ashutoshkrris/GUI-Quiz-Tkinter">https://github.com/ashutoshkrris/GUI-Quiz-Tkinter</a></p>
<p>For Windows, you can download the executable application from <a target="_blank" href="https://github.com/ashutoshkrris/GUI-Quiz-Tkinter/raw/master/quiz.exe">here</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learn How to Use Tkinter to Create GUIs in Python ]]>
                </title>
                <description>
                    <![CDATA[ Do you want to create a graphic user interface for your Python program? You should learn how to use Tkinter! Tkinter is the most common way to add GUIs to Python programs. Tkinter provides an object-oriented interface to the Tk GUI toolkit that is bu... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-how-to-use-tkinter-to-create-guis-in-python/</link>
                <guid isPermaLink="false">66b2048ea8b92c9329236494</guid>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tkinter ]]>
                    </category>
                
                    <category>
                        <![CDATA[ youtube ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Beau Carnes ]]>
                </dc:creator>
                <pubDate>Tue, 19 Nov 2019 15:04:18 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/11/tkinter.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Do you want to create a graphic user interface for your Python program? You should learn how to use Tkinter! Tkinter is the most common way to add GUIs to Python programs.</p>
<p>Tkinter provides an object-oriented interface to the Tk GUI toolkit that is built-in to Python. You don't even have to install anything extra to use Tkinter.</p>
<p>Tkinter makes it simple to create a GUI which handles user input and output. A GUI uses a form of object oriented programming called "event-driven." This means that the program responds to events, which are actions that a user takes.</p>
<p><a target="_blank" href="https://twitter.com/flatplanet">John Elder</a> from <a target="_blank" href="https://codemy.com">Codemy.com</a> created a 5.5 hour long comprehensive course about how to use Tkinter. We have released the full course for free on the freeCodeCamp.org YouTube channel.</p>
<p>Here is what the course covers:</p>
<ul>
<li>What is Tkinter?</li>
<li>Positioning with Tkinter's Grid System</li>
<li>Creating Buttons</li>
<li>Creating Input Fields</li>
<li>Building a Simple Calculator App</li>
<li>Using Icons, Images, and Exit Buttons</li>
<li>Building an Image Viewer App</li>
<li>Adding a Status Bar</li>
<li>Adding Frames</li>
<li>Using Radio Buttons</li>
<li>Adding Message Boxes</li>
<li>Creating New Windows</li>
<li>Opening Files Dialog Boxes</li>
<li>Using Sliders</li>
<li>Using Checkboxes</li>
<li>Using Dropdown Menus</li>
<li>Using Databases</li>
<li>Building a GUI for a Database App</li>
<li>Deleting a Record From a Database</li>
<li>Updating a Record with SQLite</li>
<li>Building a Weather App</li>
<li>Using Matplotlib Charts</li>
</ul>
<p>Watch the course below or on the <a target="_blank" href="https://www.youtube.com/watch?v=YXPyB4XeYLA">freeCodeCamp.org YouTube channel</a> (5.5 hour watch).</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/YXPyB4XeYLA" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
