<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sylvain Saurel</title>
    <description>The latest articles on DEV Community by Sylvain Saurel (@ssaurel).</description>
    <link>https://dev.to/ssaurel</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F201909%2Febcefee4-c549-4a5f-b685-cc4a4b6e1b65.jpg</url>
      <title>DEV Community: Sylvain Saurel</title>
      <link>https://dev.to/ssaurel</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ssaurel"/>
    <language>en</language>
    <item>
      <title>Revive Some Nostalgia: Recreating the Snake Game Using HTML5's Canvas API and JavaScript</title>
      <dc:creator>Sylvain Saurel</dc:creator>
      <pubDate>Tue, 23 Jan 2024 10:29:50 +0000</pubDate>
      <link>https://dev.to/ssaurel/revive-some-nostalgia-recreating-the-snake-game-using-html5s-canvas-api-and-javascript-cee</link>
      <guid>https://dev.to/ssaurel/revive-some-nostalgia-recreating-the-snake-game-using-html5s-canvas-api-and-javascript-cee</guid>
      <description>&lt;p&gt;If you’ve never played the famous Snake game, raise your hand!&lt;/p&gt;

&lt;p&gt;I say that, but I suppose that nowadays, the new generation may never have heard of this game, which may seem a bit old-fashioned given the possibilities offered by today’s computers and the Web.&lt;/p&gt;

&lt;p&gt;And yet, there was a time when the Snake game was a game that all cell phone owners spent an inordinate amount of time playing. Yes, back then, we weren’t talking about smartphones, just telephones.&lt;/p&gt;

&lt;p&gt;It was a good time, as the saying goes, and Nokia popularized the game through its mobile devices, which were also a benchmark. Today, not much remains of Nokia’s domination of the mobile world and the Snake game.&lt;/p&gt;

&lt;p&gt;For those who are nostalgic for this game – and I’m one of them, I must admit – this tutorial will teach you how to recreate it for the Web. To do so, I’ll be using HTML5’s Canvas API and JavaScript.&lt;/p&gt;

&lt;p&gt;It’s also an opportunity to learn how to use classes in Javascript and to create an effective game loop for Web games.&lt;/p&gt;




&lt;h2&gt;
  
  
  Creating the Web page for our Snake game
&lt;/h2&gt;

&lt;p&gt;To begin with, we’re going to create the Web page that will enable us to play the Snake game we’ll be developing in this tutorial. You’ll soon see that this Web page presents no difficulties whatsoever. Two divs, one for the page title and another to display the area where the snake will move.&lt;/p&gt;

&lt;p&gt;To this, I’ll add a little CSS to center these divs by applying a fixed width to them:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;





&lt;h2&gt;
  
  
  Design of the Snake class
&lt;/h2&gt;

&lt;p&gt;As I explained in the introduction to this tutorial, I’m going to use a dedicated Snake class to model the game. This will also allow you to discover how to manipulate classes in JavaScript.&lt;/p&gt;

&lt;p&gt;Our Snake will have the following properties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;bw and bh to represent board size in width and height respectively.&lt;/li&gt;
&lt;li&gt;nbx and nby represent the number of cells available for the board.&lt;/li&gt;
&lt;li&gt;eltw and elth to represent the size of a snake element in width and height.&lt;/li&gt;
&lt;li&gt;dirx and diry which represent the snake’s displacement vector.&lt;/li&gt;
&lt;li&gt;marginx and marginy add a small margin to the width and height of snake elements so that the player can see the demarcation between each snake element.&lt;/li&gt;
&lt;li&gt;keyup, keydown, keyleft, keyright which store the state of the moving arrows at a given moment.&lt;/li&gt;
&lt;li&gt;startftps stores the number of frames per second required to move the snake at the start of the game.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At the end of the constructor, an init method is called to initialize the snake at the start of the game. When a new game is to be started, simply call this init method again.&lt;/p&gt;

&lt;p&gt;This gives us the following code for our Snake class:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;In the init method, you can define other snake properties, such as a pointer to its head and a pointer to tail. The elements array will store all the snake’s elements at a given moment. The points property is used to store points for the current game, while the level property is used to define how many points are accumulated to increase the game’s fps. The higher the number of fps, the faster the snake will move.&lt;/p&gt;

&lt;p&gt;Since the fps property represents the number of frames per second, we need to have a fpsinterval property valued at the result of dividing 1 second (or 1,000 milliseconds) by the desired number of fps.&lt;/p&gt;




&lt;h2&gt;
  
  
  The principle of the Snake game
&lt;/h2&gt;

&lt;p&gt;The principle of the Snake game is simple: you have to guide the snake using the 4 directional arrows so that it eats the maximum number of apples that appear on the board. Each time you eat an apple, the snake grows by one element. As the snake grows, you’ll find it difficult to avoid touching its own tail. If you don’t, you’ll lose and the score will start again from zero. Of course, every time you eat an apple, you score a point.&lt;/p&gt;

&lt;p&gt;It’s worth pointing out that the version of Snake we’re going to implement is the one where touching the edges of the board doesn’t make you lose. It just makes you tip over to the opposite side. The second versions of the Snake game were implemented in this way by Nokia.&lt;/p&gt;

&lt;p&gt;Since the snake has to eat an apple, we need to display this apple on the board in a random fashion, taking care not to generate an apple directly on an element of the snake.&lt;/p&gt;

&lt;p&gt;This gives us the following generatefood method for our Snake class:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;





&lt;h2&gt;
  
  
  Snake on-screen rendering
&lt;/h2&gt;

&lt;p&gt;Our Snake class is progressing, and we now need to create a method for rendering the snake on the screen. We’ll also need to display the player’s number of points at a given time, and finally, display the apple to be eaten. The apple’s position is stored in the Snake class’s food property.&lt;/p&gt;

&lt;p&gt;To render the Snake on the screen, I’m using HTML5’s Canvas API.&lt;/p&gt;

&lt;p&gt;I’ll use this API’s drawing primitives to draw rectangles representing the various elements of the snake, as well as the apple to be eaten. I’ll apply a different color to the apple and the snake so that the player can distinguish between them.&lt;/p&gt;

&lt;p&gt;This gives the following code for the draw method of our Snake class:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;





&lt;h2&gt;
  
  
  Moving the Snake
&lt;/h2&gt;

&lt;p&gt;We now have a snake that we can display on screen. This is all very well, but we need to add support for the snake’s movement. As explained above, the snake moves along the coordinate vector (dirx, diry). So, each time we call the move method I’m going to define here, the snake will move by the same amount.&lt;/p&gt;

&lt;p&gt;In this move method, we check that the coordinates of the snake’s head correspond to those of the apple to be eaten. If so, the snake has just eaten the apple. The player scores a point, but more importantly, we need to take four actions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add an element to the snake’s elements. This element becomes the new tail.&lt;/li&gt;
&lt;li&gt;Generate a new apple by calling generatefood.&lt;/li&gt;
&lt;li&gt;Add a point to the player.&lt;/li&gt;
&lt;li&gt;If the player passes a level, then we update the number of frames per seconds to be displayed to speed up the Snake’s movement.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Still, in the move method, we need to check that the player hasn’t made the mistake of touching an element of the snake with the head. If this is the case, the game is lost, and we start afresh! To do this, we call the init method of the Snake class presented above.&lt;/p&gt;

&lt;p&gt;Now we need to complete the move method by actually moving the snake. To do this, we add dirx and diry to the snake’s head coordinates. This gives us a new head to add. You’ll also notice that moving the snake is done intelligently by removing the tail each time and adding a new head. This avoids having to update the position of all the snake’s elements.&lt;/p&gt;

&lt;p&gt;Finish by remembering to update the new head. Incidentally, you’ll also have noticed that when the snake’s head crosses a board boundary, we make it move to the opposite side of the board. This applies to both width and length.&lt;/p&gt;

&lt;p&gt;This gives us the following code for the move method:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;





&lt;h2&gt;
  
  
  The GameLoop of our Snake Game
&lt;/h2&gt;

&lt;p&gt;Our Snake can be displayed on screen. Our Snake can be moved by calling its move method. What are we missing?&lt;/p&gt;

&lt;p&gt;We’re missing the implementation of our game’s GameLoop!&lt;/p&gt;

&lt;p&gt;Without this GameLoop, which will call the move and draw methods at regular intervals, the Snake won’t be able to move. In what follows, we’ll show you how to implement a GameLoop the right way in JavaScript, leaving it up to the browser to call it when it sees fit, so as not to block the rendering thread of the game’s web page.&lt;/p&gt;

&lt;p&gt;To do this, we’ll use the requestAnimationFrame method of the standard JavaScript object window. The browser will then adapt the maximum fps it can support to the computer or smartphone on which the web page will be used.&lt;/p&gt;

&lt;p&gt;Within our gameloop method, we’ll then decorrelate the number of fps supported by the browser from the number of fps we want to move our snake. We’ll only call the move and draw methods when we’re within the fps range defined earlier.&lt;/p&gt;

&lt;p&gt;It’s important to update the coordinates of the snake’s movement vector according to the state of the 4 directional keys up, down, left, and right.&lt;/p&gt;

&lt;p&gt;Finally, we call the GameLoop, delegating to the browser the task of choosing the best moment to do so. This gives us the following code for the GameLoop:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;





&lt;h2&gt;
  
  
  Handling user interaction with the Snake
&lt;/h2&gt;

&lt;p&gt;To enable the Snake to be moved according to the directional keys pressed by the player, we use the keydown and keyup events. For each of these events, we’ll call a method of the Snake class. Logically, this will be pressdown for the keydown event and pressup for the keyup event.&lt;/p&gt;

&lt;p&gt;We update the value of the linked Snake class properties according to what the player does with these keys. As you can see, we don’t block the game by updating the snake’s position directly. Instead, we update the state in the gameloop method, which is called at regular intervals.&lt;/p&gt;




&lt;h2&gt;
  
  
  Assembling the various Snake components
&lt;/h2&gt;

&lt;p&gt;To complete this Snake game, we need to assemble the various elements. We retrieve the Canvas object via its id. Then, we obtain the 2D context linked to this Canvas. Apply the desired dimensions. We create a Snake object, passing the various expected values as parameters, including the number of cells on the board.&lt;/p&gt;

&lt;p&gt;Add the event listeners for the keydown and keyup events.&lt;/p&gt;

&lt;p&gt;Finally, all that’s left to do is call our Snake’s gameloop once to start the game. This gives us the following complete code for the famous Snake game made with the Canvas API and the infernal HTML5/JavaScript Web couple:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;





&lt;h2&gt;
  
  
  Our Snake Game in Action
&lt;/h2&gt;

&lt;p&gt;Our Snake complete, it’s time to test it in a Web browser to see if the Snake magic works again, as it did when Nokia outrageously dominated the mobile world:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcigknzauz39vbypiqq79.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcigknzauz39vbypiqq79.jpg" alt="Our Snake Game in Action" width="800" height="734"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From this Snake game, you can imagine several possible enhancements. For example, you could add a sound each time the snake eats the apple. You could use HTML5’s Web Storage API to store a player’s local high score. This way, when a player beats his high score, you can display a congratulatory message. The possibilities are endless and your only limit, as ever in programming, is your imagination.&lt;/p&gt;




&lt;h2&gt;
  
  
  Watch this tutorial on YouTube
&lt;/h2&gt;

&lt;p&gt;This tutorial can also be watched on YouTube on the SSaurel channel:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/0uSfTEq2JMo"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>html</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>Learn How to Create an Interactive Map of India Using HTML5/JavaScript and SVG</title>
      <dc:creator>Sylvain Saurel</dc:creator>
      <pubDate>Mon, 08 Jan 2024 09:32:57 +0000</pubDate>
      <link>https://dev.to/ssaurel/learn-how-to-create-an-interactive-map-of-india-using-html5javascript-and-svg-4bok</link>
      <guid>https://dev.to/ssaurel/learn-how-to-create-an-interactive-map-of-india-using-html5javascript-and-svg-4bok</guid>
      <description>&lt;p&gt;Ever heard of SVG? This acronym may not mean anything to you, but it’s an essential format to master if you want to use vector graphics on Web pages. SVG stands for Scalable Vector Graphics. SVG is an XML-based ASCII data format designed to describe vector graphics.&lt;/p&gt;

&lt;p&gt;SVG is specified by the World Wide Consortium and has been around since 1998. Even if you’re not familiar with SVG, it’s widely used in the world of cartography and cell phones.&lt;/p&gt;

&lt;p&gt;To learn how to use some of the immense potential of the SVG format, we’re going to focus on the field of cartography. In this step-by-step tutorial, I’ll show you how to create an interactive map of India using the infernal Web couple HTML5 and JavaScript, but also the SVG format.&lt;/p&gt;

&lt;p&gt;How will our map of India be interactive?&lt;/p&gt;

&lt;p&gt;Our map of India will have two main functionalities. The first will be to display each region of India in a different color according to its population. The second will respond to the user’s mouse hover to display the name of the region in question.&lt;/p&gt;

&lt;p&gt;Please note that this tutorial can be applied to any other country in the world.&lt;/p&gt;

&lt;p&gt;All you need is an SVG representation of the country or continent you wish to display to users. You can create your maps in SVG format using software such as Inkscape, or you can simply find SVG maps on the Internet with a simple Google search.&lt;/p&gt;

&lt;p&gt;As the aim of this tutorial is not to create a map in SVG format ourselves, but rather to use it, I’ve limited myself to downloading such a map.&lt;/p&gt;

&lt;h2&gt;
  
  
  Displaying the SVG map in an HTML page
&lt;/h2&gt;

&lt;p&gt;The first step is to integrate our SVG map of India into an HTML page. You could import it using the object tag, but then you wouldn’t be able to apply CSS styles to it from your HTML page.&lt;/p&gt;

&lt;p&gt;The best thing to do here is to integrate the SVG directly into our HTML page, which gives us the following code:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;You can test this code in your favorite browser and get the result below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Vy_ed86Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ivh8ynypvgaz5schy0ud.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Vy_ed86Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ivh8ynypvgaz5schy0ud.png" alt="India Map Step 1 Result" width="800" height="887"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nothing extraordinary here, since the map is displayed in black only. But the magic of SVG is that we can then apply styles to the various SVG paths we’ve placed on our Web page.&lt;/p&gt;

&lt;p&gt;Enhancing the SVG of our Web page with other geometric shapes&lt;br&gt;
We’re now going to enhance our SVG by adding a title and legend for the population data. We’re going to classify the population by regions of India according to 6 major classes: &amp;gt; 200M, 100-200M, 50-100M, 10-50M, 1-10M, &amp;lt; 1M.&lt;/p&gt;

&lt;p&gt;This legend will also show you how to use some of the graphic primitives of the SVG format to draw a rectangle or write text.&lt;/p&gt;

&lt;p&gt;This gives us the following code:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;As you can see, I’ve taken care to add some CSS to give a better graphic rendering to the regions of India. Applying CSS styles to elements in your SVG is done in the same way as with elements in an HTML page. You define an id on your SVG elements and apply your styles. Simple, practical, and efficient… that’s why we love the SVG format so much.&lt;/p&gt;

&lt;p&gt;You will get the following result on your browser:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mnX6oPvZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qutzjjc59lazk38jm0f5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mnX6oPvZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qutzjjc59lazk38jm0f5.png" alt="India Map Step 2 Result" width="800" height="628"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Rather nice, isn’t it?&lt;/p&gt;

&lt;h2&gt;
  
  
  Add interactivity to our map of India in SVG format using JavaScript
&lt;/h2&gt;

&lt;p&gt;The next step is to add interactivity to our map of India in SVG format. Interactivity on the Web means JavaScript. So I’m going to do two essential things in this part of the tutorial.&lt;/p&gt;

&lt;p&gt;The first will be to apply the right colors to each region of India according to the number of inhabitants in those regions. To be able to manipulate each path associated with a region of India in our SVG, I’m going to use the ids defined.&lt;/p&gt;

&lt;p&gt;This is classic if you’re developing on the Internet.&lt;/p&gt;

&lt;p&gt;The second thing to do will be to react to the user’s mouse-over on a region of India. To do this, I’ll iterate over each SVG path and add mousemove and mouseout event listeners. When the mouse is moved, I’ll display a tooltip that I’ll hide when the mouse leaves the region.&lt;/p&gt;

&lt;p&gt;As you can see, I need to update my SVG by adding a rectangle and a text element, which will initially be hidden. Their visibility will only be activated when the user’s mouse hovers over a path in our SVG.&lt;/p&gt;

&lt;p&gt;This gives us the following complete code for our Web page displaying an interactive SVG map of India:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;This gives us the following result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ICUuYTvW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x5xwjhag4oz4a24h2opi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ICUuYTvW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x5xwjhag4oz4a24h2opi.png" alt="India Map Step 3 Result" width="800" height="628"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let’s see what happens when we move the mouse over India’s most densely populated region: Uttar Pradesh.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_mYyV74j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xcdlc6dpyxyjwcnlnoyv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_mYyV74j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xcdlc6dpyxyjwcnlnoyv.png" alt="India Map Step 4 Result" width="800" height="628"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The key part of the code of our HTML page to display this tooltip is located here:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;When our SVG is loaded, the init method is called. This init method retrieves the SVG objects tooltip and tooltip_bg. Next, we iterate over all the regions of India using their id. For each region, we can set up a listener as explained above. We then call the showTooltip method, which displays the region name on the Web page:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Our tutorial on how to display an interactive map of India using the infernal couple of Web HTML5/JavaScript and SVG is now complete. You can also watch this tutorial on YouTube on SSaurel’s channel:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/bmEzq12pjC4"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>html</category>
      <category>programming</category>
    </item>
    <item>
      <title>Creating the Classical Pong Game in Python with a Tkinter UI</title>
      <dc:creator>Sylvain Saurel</dc:creator>
      <pubDate>Thu, 04 Jan 2024 17:02:24 +0000</pubDate>
      <link>https://dev.to/ssaurel/creating-the-classical-pong-game-in-python-with-a-tkinter-ui-1djl</link>
      <guid>https://dev.to/ssaurel/creating-the-classical-pong-game-in-python-with-a-tkinter-ui-1djl</guid>
      <description>&lt;p&gt;To kick off the year 2024 on SSaurel’s Blog, what better way than to code the classic game of Pong in Python?&lt;/p&gt;

&lt;p&gt;That’s what I suggest you do in this step-by-step tutorial, using the Tkinter library for the user interface. This will show you how to program a simple game in Python and manage user interaction.&lt;/p&gt;




&lt;h2&gt;
  
  
  Let’s start by designing the Ball
&lt;/h2&gt;

&lt;p&gt;To design our ball, we need to define its position and velocity. We’ll then need to define a method for modifying the position of the rectangle representing this ball as its coordinates change.&lt;/p&gt;

&lt;p&gt;When the ball touches one of the two horizontal edges, we’ll need to restart the ball from the center of the screen. This will be done in a restart method, and we’ll use the random method in Python’s Random library to randomly choose an x and y direction.&lt;/p&gt;

&lt;p&gt;Finally, the bulk of the work remains to be done in the ball’s move method.&lt;/p&gt;

&lt;p&gt;We’ll have to deal with several scenarios. The first is when the ball touches the outer edges at height. In this case, we’ll need to reverse the direction of the ball in ordinate. This is done by multiplying the current y velocity of the ball by -1.&lt;/p&gt;

&lt;p&gt;The second is when the ball comes into contact with the right or left paddles. In this case, you need to invert the current velocity on the x-axis. This is done by multiplying the velocity at x by -1.&lt;/p&gt;

&lt;p&gt;In the third and fourth cases, points are scored for the player on the left and the player on the right. If the ball touches the edge on the left, the player on the right scores 1 point. If the ball touches the edge on the right, the player on the left scores 1 point.&lt;/p&gt;

&lt;p&gt;Finally, we play the x and y positions of the ball, adding the current velocity.&lt;/p&gt;

&lt;p&gt;This gives us the following for the Ball object:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;





&lt;h2&gt;
  
  
  Let’s move on to designing the Paddle
&lt;/h2&gt;

&lt;p&gt;To model a paddle, we define a Paddle object.&lt;/p&gt;

&lt;p&gt;This Paddle object will have x and y coordinates, as well as a width and height. Each paddle is assigned a score initialized to 0. We also initially create the rectangle representing the paddle and store its id returned by the Tkinter library’s create_rectangle method. This id will then be used to modify the paddle’s coordinates.&lt;/p&gt;

&lt;p&gt;The draw method is used to modify the paddle’s coordinates using this id.&lt;/p&gt;

&lt;p&gt;The top and down methods move the paddle up and down respectively. The VELOCITY constant is used for displacement. This constant will also be used whenever ball positions are modified.&lt;/p&gt;

&lt;p&gt;Finally, we use the collideright and collideleft methods to test whether the paddle and ball collide to the right and left respectively. In the event of a collision, we return True, which will then be used in the Pong class we’ll define for the Pong game.&lt;/p&gt;

&lt;p&gt;This gives us the following code for our Paddle object:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;





&lt;h2&gt;
  
  
  Time to design the Pong Game using Ball and Paddle objects
&lt;/h2&gt;

&lt;p&gt;With our two objects modeled above, we can move on to modeling the Pong object.&lt;/p&gt;

&lt;p&gt;The Pong object will store the scores of the two Paddles, as well as the objects drawn on the canvas to represent these scores. These will be deleted before each rewrite when the scores are updated. This avoids having to delete the entire canvas each time the scores are updated.&lt;/p&gt;

&lt;p&gt;A Boolean is set to True when the game is rendering.&lt;/p&gt;

&lt;p&gt;Four Booleans are used to define whether the up/down keys chosen for each player are pressed or not. If they are pressed, the paddles are activated. The Paddle and Ball objects are created in the Pong object constructor. We call the canvas’s pack method and then call the drawmiddlelines, drawbord, and move methods respectively to start the game.&lt;/p&gt;

&lt;p&gt;The drawmiddlelines method draws the mid-screen line vertically.&lt;/p&gt;

&lt;p&gt;The drawboard method draws all game elements. Note the small workaround used with the _exit method of the os library to ensure that the application stops when the Tkinter game window is closed.&lt;/p&gt;

&lt;p&gt;The drawpoints method is used to draw the scores of two players on the screen.&lt;/p&gt;

&lt;p&gt;The move method will be called every X milliseconds to update the state of our Pong game. We’ll use a Timer object from Python’s Threading library to handle this repetitive call. In the method, we check whether it’s necessary to move the paddles. If so, we act accordingly.&lt;/p&gt;

&lt;p&gt;After calling the ball’s move method, we retrieve the returned state. If the state is True, this means that the ball must be restarted from the center of the board. To do this, we call the restart method of the Pong object, within which we call only the restart method of the Ball object. So why a separate method? To improve the game in the future and add more behaviors to restart. You could choose to emit a sound at this point…&lt;/p&gt;

&lt;p&gt;As for the keypress and keyrelease methods, they are associated with the keyboard events  and . This makes it possible to manage several keyboard keys at the same time. We choose the z / s keys for the left paddle and the o / l keys for the right paddle.&lt;/p&gt;

&lt;p&gt;Finally, the killtimer method will be used to end the rendering phase and cancel the timer if it’s running.&lt;/p&gt;

&lt;p&gt;This gives us the following code for the Pong object:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;





&lt;h2&gt;
  
  
  Assembling objects for the Pong Game
&lt;/h2&gt;

&lt;p&gt;The final part of the program simply consists of creating the root of the UI by calling the TK method of the tk object. The instance of the Pong game is created by passing the board size and margin as parameters. These are defined as constants at the start of the program.&lt;/p&gt;

&lt;p&gt;We then bind the  and  events to the UI root and call the keypress and keyrelease methods of our Pong object instance respectively. Finally, don’t forget to listen for the WM_DELETE_WINDOW event to react to the click on the cross in our Tkinter window. This ensures that the timer is properly killed and that the process associated with our Pong game is stopped.&lt;/p&gt;

&lt;p&gt;This gives us the following complete code for our Pong game in Python with a Tkinter UI:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;





&lt;p&gt;You can see the result of our Pong Game below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3_PCDFWf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rabckpm9xnpkda7gg765.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3_PCDFWf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rabckpm9xnpkda7gg765.jpg" alt="Our Pong Game in Python in Action" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;You can also watch this tutorial on YouTube on the SSaurel channel here:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/LfrCWu5-I5A"&gt;
&lt;/iframe&gt;
&lt;/p&gt;




&lt;p&gt;At the end of the program code on Github, I’ve also suggested some ideas for improvements, such as defining a limit at which the game is over. You can also define an AI for the second paddle. Finally, there’s inevitably some work to be done to improve the dependencies between each of the objects. This will allow you to code your own Python Pong game.&lt;/p&gt;

&lt;p&gt;It’s up to you to code.&lt;/p&gt;

</description>
      <category>python</category>
      <category>gamedev</category>
      <category>programming</category>
      <category>pong</category>
    </item>
    <item>
      <title>Creating a Flipping Bits Game in Python With Tkinter</title>
      <dc:creator>Sylvain Saurel</dc:creator>
      <pubDate>Mon, 08 May 2023 20:14:52 +0000</pubDate>
      <link>https://dev.to/ssaurel/creating-a-flipping-bits-game-in-python-with-tkinter-47eb</link>
      <guid>https://dev.to/ssaurel/creating-a-flipping-bits-game-in-python-with-tkinter-47eb</guid>
      <description>&lt;p&gt;After having proposed a tutorial showing you how to develop a program to create a Sitemap generator in Python, I continue my comeback to the Python language with the creation of a little game.&lt;/p&gt;

&lt;p&gt;The goal here is to show you how to use the Tkinter GUI library that comes standard with Python. The game I have chosen is not revolutionary, but it is interesting enough to allow you to play it a little once you have finished the program we are going to develop.&lt;/p&gt;

&lt;p&gt;This game is called Flipping Bits.&lt;/p&gt;

&lt;p&gt;If you are a programmer, I assume that you have already developed it at least once in your career, but if you haven’t, this is your chance to fill that gap.&lt;/p&gt;

&lt;p&gt;From a square grid (in 2 dimensions) composed of 0 and 1 randomly generated, the goal is to obtain a target grid by performing operations of two types:&lt;/p&gt;

&lt;p&gt;A click on a column reverses all the 0’s and 1’s of the column. This operation is called flipping a column.&lt;br&gt;
A click on a row reverses all the 0s and 1s in the row. This operation is called flipping a row.&lt;br&gt;
You solve this puzzle when you get the target grid.&lt;/p&gt;

&lt;p&gt;Concretely, here is an initial grid of dimension 3×3:&lt;/p&gt;

&lt;p&gt;0 1 0&lt;br&gt;
1 0 0&lt;br&gt;
1 1 1&lt;/p&gt;

&lt;p&gt;Here is the grid you want to obtain:&lt;/p&gt;

&lt;p&gt;1 0 1&lt;br&gt;
0 1 1&lt;br&gt;
0 0 1&lt;/p&gt;

&lt;p&gt;Let’s say you click on column 1 of the initial grid, you would have the following configuration:&lt;/p&gt;

&lt;p&gt;1 1 0&lt;br&gt;
0 0 0&lt;br&gt;
0 1 1&lt;/p&gt;

&lt;p&gt;And so on.&lt;/p&gt;


&lt;h2&gt;
  
  
  Modeling the program
&lt;/h2&gt;

&lt;p&gt;Our program will be divided into two classes.&lt;/p&gt;

&lt;p&gt;The first one will be a FlippingBitsGame class which will model the game itself with methods to flip a column and a row, but also to generate a new grid.&lt;/p&gt;

&lt;p&gt;The second class will be called FlippingBitsGUI. It will model the graphical part of the game by managing the graphical part but also the interactions with the user. I think here in particular of the click on a column and a row, as well as the message telling the player that he has won.&lt;/p&gt;

&lt;p&gt;To materialize a 0, we will use the yellow color. The blue color will be reserved for the number 1.&lt;/p&gt;

&lt;p&gt;When displaying the squares of the grid, a small square with the target color for that square should be placed in the upper left corner. This will allow the player to know the goal to be reached to solve the Flipping Bits Game.&lt;/p&gt;


&lt;h2&gt;
  
  
  Creating the FlippingBitsGame class
&lt;/h2&gt;

&lt;p&gt;In the constructor of the FlippingBitsGame class, we define level as a data member. This corresponds to the size of our square grid. Then, we define two two-dimensional arrays to store respectively the grid to be reached and the current grid.&lt;/p&gt;

&lt;p&gt;We define a boolean solved which will indicate if the grid is solved or not. Finally, we call a method newgame which will be defined later. It will allow to create a new game.&lt;/p&gt;

&lt;p&gt;We then define a flipcol method and a fliprow method.&lt;/p&gt;

&lt;p&gt;The flipcol method will invert all the values of the cells of a column within the grid to be solved. The fliprow method will do the same job for the values of the cells in a row of the grid.&lt;/p&gt;

&lt;p&gt;When these methods are called, the 0’s become 1’s, and the 1’s become 0’s.&lt;/p&gt;

&lt;p&gt;This gives us the following code for these two methods:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;In order to create a different grid between the target and the one from which the player will play, we define a shuffle method that will perform different flipping operations randomly on the rows and columns.&lt;/p&gt;

&lt;p&gt;This gives the following code:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The newgame method can then be defined. A new game can only be created if the grid is marked as resolved. To do this, we check the value of the data member solved.&lt;/p&gt;

&lt;p&gt;Then, we will iterate to create a target grid to reach different from the current one. For this, it will be necessary to call the shuffle method and to copy the current grid into the target grid.&lt;/p&gt;

&lt;p&gt;If the current grid is not already solved, then the work is finished. Otherwise, the iteration continues. It would be a pity to propose to the player a grid already solved …&lt;/p&gt;

&lt;p&gt;It remains to finish the code of this class FlippingBitsGame with the method issolved which will check if the current grid corresponds to the grid to be reached.&lt;/p&gt;

&lt;p&gt;This gives us the following code for the FlippingBitsGame class:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;





&lt;h2&gt;
  
  
  Creating the FlippingBitsGUI class
&lt;/h2&gt;

&lt;p&gt;With our FlippingBitsGame class finished, it’s time to move on to the FlippingBitsGUI class which will display to the user the state of the grid to be solved, but also manage the interactions.&lt;/p&gt;

&lt;p&gt;When I talk about interaction, I mean the click to flip a column or a row to solve the grid to reach the target grid, which will be displayed as the small squares in the upper left corner.&lt;/p&gt;

&lt;p&gt;In the constructor of the FlippingBitsGUI class, we create an instance of the game by using the FlippingBitsGame class.&lt;/p&gt;

&lt;p&gt;As input parameter we get the root of the GUI which will allow us to create the Canvas in which the game will be rendered. We finish by calling a drawboard method which displays the grid on the screen.&lt;/p&gt;

&lt;p&gt;Within this drawboard method, we reset the canvas via the call to the delete method of the canvas object.&lt;/p&gt;

&lt;p&gt;We calculate the size of a square in relation to the number of boxes to display for the square. We also take the opportunity to calculate the size of the small square that will be displayed in the upper left corner.&lt;/p&gt;

&lt;p&gt;Then, it is necessary to iterate on each cell of the table allowing to store the grid. For each cell, we will draw a rectangle filled with the color yellow if the value of the cell is 0 and blue otherwise.&lt;/p&gt;

&lt;p&gt;At the end of the method, we check if the game has been solved by the user by calling the issolved method of the FlippingBitsGame object. If the game has been solved, then we display a message to the user telling him that he only has to click to generate a new game.&lt;/p&gt;

&lt;p&gt;This gives us the following code for the drawboard method:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;We still have to manage the user’s click to flip the columns. Nothing very difficult, but we must be careful to transform a click into a column or row number.&lt;/p&gt;

&lt;p&gt;Obviously, before anything else, we will check that the grid is not already solved. If it is, then this click means that a new set must be generated.&lt;/p&gt;

&lt;p&gt;Then we get the coordinates of the user click. We check that these coordinates are outside the grid. If the click is on the right or left side of the grid, then we get the line to flip. Then we call the fliprow method on the FlippingBitsGame instance.&lt;/p&gt;

&lt;p&gt;If the click is located at the top or bottom of the grid, then we get the column to flip. Then we call the flipcol method on the FlippingBitsGame instance.&lt;/p&gt;

&lt;p&gt;Once these operations are done, we have to call the drawboard method to draw the GUI again.&lt;/p&gt;

&lt;p&gt;This gives us the following code for the onclick method:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;





&lt;h2&gt;
  
  
  Assembling the classes
&lt;/h2&gt;

&lt;p&gt;Finally, we have to assemble our classes to launch the game. We create the root via the call to the Tk method of the tk object from Tkinter. We create a FlippingBitsGUI with a level set to 5. We link the left mouse button to the onclick method of the FlippingBitsGUI object. We launch the application by calling the mainloop method on the Tkinter root.&lt;/p&gt;

&lt;p&gt;This gives us the following complete code for our game:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;





&lt;h2&gt;
  
  
  Our Flipping Bits Game in Action
&lt;/h2&gt;

&lt;p&gt;The best part of the tutorial is here as we can put our Flipping Bits Game into action.&lt;/p&gt;

&lt;p&gt;Here is the first display that awaits us:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--W9vwlW9G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o16449lj52ep3h6flobx.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--W9vwlW9G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o16449lj52ep3h6flobx.jpg" alt="Flipping Bits Game Initial" width="800" height="581"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The only thing left to do is to find the solution. After a few clicks, more or less according to your sense of logical reasoning (:P), you will obtain the following solved grid:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ORJG_X8W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ydz22hmq6iin52ht9tbc.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ORJG_X8W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ydz22hmq6iin52ht9tbc.jpg" alt="Flipping Bits Game Solved" width="800" height="581"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Watch this tutorial on YouTube
&lt;/h2&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/mPZOLy9wui0"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>python</category>
      <category>programming</category>
      <category>tkinter</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>Learn to Create a Sitemap File Generator in Python</title>
      <dc:creator>Sylvain Saurel</dc:creator>
      <pubDate>Tue, 02 May 2023 09:18:52 +0000</pubDate>
      <link>https://dev.to/ssaurel/learn-to-create-a-sitemap-file-generator-in-python-417h</link>
      <guid>https://dev.to/ssaurel/learn-to-create-a-sitemap-file-generator-in-python-417h</guid>
      <description>&lt;p&gt;I’ve been wanting to get back into Python for a while now, but I couldn’t find any ideas for small projects to get back into the language.&lt;/p&gt;

&lt;p&gt;I used to develop frequently in Python more than 15 years ago, but as time went by, I abandoned this language in my projects.&lt;/p&gt;

&lt;p&gt;So to put an end to this regret, I decided to get back into it.&lt;/p&gt;

&lt;p&gt;After thinking about an idea for a small project that could get me back into Python, but also interest you, I thought I would develop a Sitemap file Generator.&lt;/p&gt;

&lt;p&gt;If you don’t know what a Sitemap is, I’ll use the definition given by Wikipedia:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“A Sitemap is a representation of the architecture of a website that lists the resources offered, usually in hierarchical form.&lt;br&gt;
It is most often a web page that allows the user to quickly access all the pages offered for reading, and facilitates the work of indexing robots.&lt;br&gt;
Google proposed a protocol called Sitemaps in 2005. This protocol establishes rules to represent the map of sites in text or XML for the exclusive use of search engines.&lt;br&gt;
A Sitemap is very important for the natural referencing of websites.&lt;br&gt;
The Sitemap allows webmasters to include additional information on each URL, such as: the frequency of updates, the time of the last update and the level of importance of the pages.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To discover all the details about the Sitemaps format, I suggest you visit the official website of the format: &lt;a href="https://www.sitemaps.org/protocol.html"&gt;https://www.sitemaps.org/protocol.html&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You will see that the format is quite simple:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I3he3pNK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qfy0ainnn99zkhi39lhr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I3he3pNK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qfy0ainnn99zkhi39lhr.png" alt="Sitemaps Format" width="800" height="767"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This simple format is perfect for a small project in Python.&lt;/p&gt;

&lt;p&gt;Since the goal here is to have fun, I’ll just include the mandatory tags in the sitemap.xml file that my Python program will produce. You won’t see a last modification date right away for example, as that would require storing the crawled URLs in a database. But this could be something you could implement on your side to go further, or I could do it in a future article.&lt;/p&gt;




&lt;h2&gt;
  
  
  What should our Sitemap File Generator program do?
&lt;/h2&gt;

&lt;p&gt;First of all, we need to define what our Sitemap generation program will do.&lt;/p&gt;

&lt;p&gt;As you can imagine, the program will take as input the URL of a Web site whose Sitemap we want to generate.&lt;/p&gt;

&lt;p&gt;The program will then have to retrieve the content of the source page and then parse this content looking for all the HTML links found in the document. Each link will then be explored by incrementing the depth level of the visited page about the root page.&lt;/p&gt;

&lt;p&gt;When all the Web pages of the root site and its descendants have been crawled, it will be time to generate the sitemap.xml file.&lt;/p&gt;

&lt;p&gt;The most interesting part here is to calculate the priority of each page from the depth level compared to the root.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exploration of the Website for which we want to generate the Sitemap
&lt;/h2&gt;

&lt;p&gt;Requests is a popular open-source HTTP library that simplifies working with HTTP requests. We will use it to call the web page.&lt;/p&gt;

&lt;p&gt;The call is done as follows:&lt;/p&gt;

&lt;p&gt;page = requests.get(url)&lt;/p&gt;

&lt;p&gt;Nothing special.&lt;/p&gt;

&lt;p&gt;Next, we will test the status of the result of the HTTP request. In case the return is OK (HTTP code = 200), then we can proceed to the parsing of the page obtained.&lt;/p&gt;

&lt;p&gt;For parsing, I decided to use BeautifulSoup which I usually use in other languages. This will simplify the use within the program.&lt;/p&gt;

&lt;p&gt;From the content of the page, the instantiation of the HTML parser is done as follows:&lt;/p&gt;

&lt;p&gt;soup = BeautifulSoup(page.content, “html.parser”)&lt;/p&gt;

&lt;p&gt;Then we have to recover all the HTML links of the page which are materialized by a tag a. We then iterate on it to recover the content of the href attribute which corresponds to the new page which will be explored then.&lt;/p&gt;

&lt;p&gt;We take care to manage the case whether the page points to a page of the same domain or not. If it is not the same domain, we do nothing because our goal is to limit ourselves to the URLs of the root’s site, not to go see beyond the Web.&lt;/p&gt;

&lt;p&gt;We can go and launch the exploration of the Web page found via a recursive call to our exploration method.&lt;/p&gt;

&lt;p&gt;This gives us a crawl method within a SitemapGenerator class:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The small subtlety of this code is that we add the page at the first pass within a dictionary which is a member of the SitemapGenerator class and if the page is already present in the dictionary, we take care to check that the exploration level is not less than the previous one.&lt;/p&gt;

&lt;p&gt;The goal is to have for each URL of the Website the closest level of exploration to the root.&lt;/p&gt;




&lt;h2&gt;
  
  
  Generating the XML Sitemap file
&lt;/h2&gt;

&lt;p&gt;Once all the URLs of the root’s Website are stored within our class after the crawling, we must move on to the generation of the Sitemap.&lt;/p&gt;

&lt;p&gt;This will be done within a generatefile method.&lt;/p&gt;

&lt;p&gt;In this method, we will iterate on the items of the previously filled dictionary to store the URLs found by depth level within a map of lists. The final goal is to have a Sitemap file with page locations ranked with a priority between 1.0 and 0. Of course, we have no interest in telling search engines that a page has a priority of 0. We will have to take care to limit the lowest priority listed in the Sitemap file.&lt;/p&gt;

&lt;p&gt;For the generation of the XML file, I use the ElementTree library which does the job, which is the main thing. There may be better, but for my needs, it will be sufficient.&lt;/p&gt;

&lt;p&gt;I create the root object, then I will iterate on the elements of the list map.&lt;/p&gt;

&lt;p&gt;For each level of depth, I will then iterate on the list of stored URLs and add to the XML root a new URL with the mandatory elements loc and priority.&lt;/p&gt;

&lt;p&gt;At the end of the iteration loop, we just have to call the write method on the ElementTree object created from the root to create the sitemap.xml file.&lt;/p&gt;

&lt;p&gt;This gives us the following code for the generatefile method of the SitemapGenerator class:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;





&lt;h2&gt;
  
  
  Using our SitemapGenerator class to generate the Sitemap of a Web site
&lt;/h2&gt;

&lt;p&gt;We will now use our SitemapGenerator class to generate the Sitemap of a Web site.&lt;/p&gt;

&lt;p&gt;We instantiate a SitemapGenerator object by passing in parameters the Web site whose Sitemap we want to generate and the name of the Sitemap file produced as output.&lt;/p&gt;

&lt;p&gt;Then, it remains to call the crawl methods by launching with the root URL and the initial depth level which is set to 0 for the root. This will allow it to have a priority of 1 afterward.&lt;/p&gt;

&lt;p&gt;Finally, we have to call the generatefile method.&lt;/p&gt;

&lt;p&gt;This gives the following complete code for our program to generate a Sitemap file in Python:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;





&lt;h2&gt;
  
  
  Our Sitemap File Generator in Action
&lt;/h2&gt;

&lt;p&gt;The best part is here since we are going to put our program into action. For that, I use the runner within Eclipse. After some time of waiting, I get the sitemap.xml file, of which there is a part of the content below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Lf_4z15L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dhqw0yh5cqgw1ygrv66m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Lf_4z15L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dhqw0yh5cqgw1ygrv66m.png" alt="Sitemap generation result" width="800" height="630"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our Sitemap is correctly generated.&lt;/p&gt;

&lt;p&gt;Feel free to get the source code and test the program on your side and even make it evolve by adding new features.&lt;/p&gt;




&lt;h2&gt;
  
  
  Watch this tutorial on YouTube
&lt;/h2&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/mPbhr--wg8A"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>python</category>
      <category>tutorial</category>
      <category>web</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
