Creating Tic-Tac-Toe With an AI Player & Shortcuts for Python Decorators | Real Python Podcast #132
Key Takeaways
Creating a Tic-Tac-Toe game with an AI player using Python and implementing shortcuts for Python decorators, with discussions on doc tests, unit tests, and various Python tools and libraries.
Full Transcript
welcome to the real python podcast this is episode 132. how do you create a computer opponent for a simple game within python would you also like to learn how to adapt the game to run in a web browser or graphical user interface this week on the show Christopher Trudeau is here bringing another batch of Pi coders weekly articles and projects Christopher shares a recent real python step-by-step project for creating a tic-tac-toe game engine he talks about how to build the game engine and adapt it for different front ends the tutorial also shows how to implement an unbeatable computer player using the Minimax algorithm we discussed an article about how to avoid repeating yourself when creating decorators with multiple parameters we talk about how you can stop copying and pasting code several times by assigning The Decorator to a new variable we share several other articles and projects from the python Community including a news Roundup a deep dive into python stock test several python command line tricks type annotations via automated refactoring a new way to draw boxes in the terminal a collection of projects for beginners with source code a minimalist PDF creation library and a tool for sensible logging within python this episode is sponsored by influxdb influxdb time series platform is built to handle the massive volumes of Time series data produced by sensors apps and systems are you building real-time applications check it out at influxdata.com all right let's get started [Music] the real python podcast is a weekly conversation about using python in the real world my name is Christopher Bailey your host each week we feature interviews with experts in the community and discussions about the topics articles and courses found at realpython.com after the podcast join us and learn real world python skills with a community of experts at realpython.com hey Christopher welcome back ah good to be here again we have a couple little news tidbits here so I thought maybe we could hit them first you want to start with them sure right off the top so the first one is that you know in case you were tired of all that python 311 news we're on the python 312 already yeah Alpha One is out so if you're wanting to play with some of the new stuff it's there and the other one is just a quick reminder that the call for proposals for pycon us 2023 is still open and will be for a week or two so if you're interested at speaking there then you should check that out yeah definitely um there's some internal conversations going on inside real python of people thinking about how they want to do different talks and garon has done several over the years he did a lightning talk I think last time and are you planning on coming uh probably not probably not okay oh all right we'll figure out a way to drag you out of there let's stay bunkered down in my Canadian Fortress of Solitude for for a little longer sure that's fine all right well diving into articles and topics this week I'm going to start with a real python one and it's from our favorite lay it on esposo Ramos it's a recent article he did basically a tutorial diving really deep as he likes to do into Python's doc test and the subtitle is document and test your code at once and so the idea here as we've talked about doc test for a few episodes uh I think episode 118 we talked about an article from Martin Boyce which was getting into MK docs and generating documentation using doc strings and how that can be used and that kind of nice twofold factor and MK docs kind of just finding that information and building out your documentation from it which is really nice this covers a whole bunch of stuff it covers the fundamentals of writing doc tests in your codes documentation and putting them inside the doc strings and then understanding how the doc tests actually work internally and then exploring some of the limitations like where it kind of falls down and I thought you had some input we were going to kind of talk a little bit about you're like well I don't know if I would use it for everything and this definitely covers some of that and then there's also a security implication that you might not think of right away especially if you're looking at other people's code or code that you're not familiar with and how maybe running the doc test might not be as secure and then the last thing he gets into is a couple real deep dive things and strategies that I was not familiar with inside of playing inside there but it starts out and he gives links to pep 257 which talks about doc stream conventions how the most common way that I've seen doc tests use is to write it in that triple quoted doc string area and what's interesting about them if you need a little refresher on Doc test is that you write them in this sort of special format that looks like you're running commands from the terminal and so you have that triple greater than symbol and as you're going through that as you see that prompt like you would in a rebel you'd type out your test so maybe it's something like adding and so you have you know called the function add parentheses four comma two and then right below that you'd have the line where the result was six and in that this is showing not only somebody who's reading your documentation what should happen but you can then run a command from the command line to run the doc test across this and that would be like you know python-m the command is Doc test no spaces and and then the name of the file and it goes through and runs it and then there's a way to run it with a dash V flag that would give you a verbose output that actually tells you you know normally if you just run it and nothing happens yay nothing failed and so you're all good but if you want a more verbose thing where it actually shows you it'll say like trying and it'll show each line trying expecting and then okay and so it goes through all that showing you the output he talks about what sort of matches are expected and actual test output some other kind of corner cases that you might run into there he talks about how you could use it for catching exceptions and how you would write that and how that looks a little different inside there and then as you go to build something a little more elaborate it gets it kind of start to hit the limitations of what what you can do in there but I think one of my favorite things that I learned about by reading this is that you can create the doc tests as Standalone files if you want also which might be you know handy depending on how you're deploying the code or if you feel like the doc tests are potentially cluttering up the documentation you can put the doc test inside of a just a text file or a markdown file so you can run them independently of that he shows that as he goes along he talks about a few more sort of security limitations and things you might run into because it is running eval um which you've probably heard us even talk about that you may not want to run eval directly on code that you're not that familiar with because it's just you know literally running inside your machine so it's a risky method that could allow execution of you know just arbitrary code so something to keep in mind and then he covers a little bit about test driven development and how you could do that with Doc test and then really dives into like okay well the next level is pi test or unit test where the differences are there and what you would get into diving into the next level of that sort of stuff so he covers how you can use unit test and Pi test to run your existing doc tests and how to kind of integrate it but one of the limitations that doc test has is it doesn't have the ability to you know use something like fixtures or set up and tear down mechanisms it really is very specific about sort of exact matching for many many of the things that you would be checking for so it doesn't have a lot of flexibility if you will because it's really just sort of text strings that you're sort of checking about it and the funny thing that he mentioned we had that article that was covering Ellipsis recently there's actually a way to use an ellipsis and using this technique inside of Doc test where you can sort of add like these little directives to say hey in this particular case here's some potential flexibility I might be looking for and you could say you know maybe it's looking for an object ID number or a memory location or something like that you could actually have like a 0x dot dot dot and so that kind of like a wild card allowing other options there but again this article really Dives deep into this stuff I think you may if you're new to the subject the first half of it really is going to get you going and working with it and then as late as likes to do he goes much deeper into all the corner cases and lots of other kinds of areas to kind of give you much more background and understanding on that I'm a fan especially for smaller projects I think it's a good way to set up tests and kind of get going on it and I was going to ask you you had said to me that you're not a huge fan of it I'm not guessing it's just depending on the types of projects something like Django where you're going to maybe need fixtures or you need to kind of talk to databases this really isn't going to work kind of the way that you want is that kind of your feelings so I you know I like start from having some tests is better than not having some tests okay so if you're in a place where this gets you to write some tests quickly go for it um what I find is it doesn't take long before you start running into those Edge conditions and uh so I wasn't aware of the the addition of that Ellipsis uh thing but even with it you're not fully testing it then you're sort of saying output kind of looks like this right right and and so you I find it doesn't it doesn't take much until you end up having to go into a unit test yeah and once you're there there's little advantage to keeping both you're already there and I don't find that the unit tests are that much more complicated the doc tests are definitely easier to read so for someone who's new to the language or you don't want to troll through a whole bunch of unit tests it's very obvious what you want and I don't remember how we got on the topic but months and months back we talked about I have used it in the outside file format before okay so yeah so when we uh when we build courses I've got a little engine that shows the rebel on the screen and I'm not actually showing the rebel in real time I'm showing a little recorded thing and the file that I keep that in just looks like a repo session and so I am able to use doc test on that to make sure that it actually operates correctly so I haven't screwed something up when I copy and paste it into it so one of my open source libraries is something called torquamada and it does a few things and one of the things it does in addition to like black and a few others is it goes through and reads those Rebel files and runs them through doc test okay so so I've used it but it I did like I said I tend to I have found most of the times that I've used it I'm the constraints you start hitting the constraint too quickly okay start bumping your head against it yeah yeah I just really like that that tie-in with the documentation part of it again it depends on the complexity of what you're trying to show off and so forth but that idea of uh writing out and having it kind of create the markdown files and stuff like that that kind of reinvigorated my desire to like well this might be a really great way to go but again you're going to eventually maybe hit hit a point where you're like okay well it's not going to be able to like kind of get you much past that as you start to get into much more elaborate types of setups and and things where unit test and Pi test and so forth kind of make more sense yeah and I kind of wonder whether there's some clever way of doing something to get around some of this stuff like whether somebody could write a library that you always use a function and because the function is doing the checking or whatever it from the doc test point of view it's correct uh some way of sort of mixing in the idea of an assert from the unit test or something like that that there might be a way I if you could get around things you know the one I always run into and it's a pain with tests is things like dates right so you're you're digging okay you know and you need to mock something up or you need to explicitly say okay the date is today or you're operating with this date and if you make any call that goes and checks what data it is then in Doc test you're you're stuffed because it'll go off and figure out what date it is and it's no longer matching what's in the file right yeah it doesn't help for variability like that it just doesn't like that kind of stuff right so so if there were some tools out there that could handle some of those cases I'd be all for it because it definitely is easier to read because it like I said it's just like looking at a rebel session and and you know that's kind of where we all start right you're you you're used to experimenting in the rebels so yeah it just needs that extra thing before it convinces me that's fine so you had your first one was going to be a real python one also right it is yeah so this is a bartash zazinski article and it's called build a tic-tac-toe game engine with an AI player in Python so I've heard Tales of a chicken in New York City that plays tic-tac-toe so in case you don't have one of those chickens you can write some code to be your own electronic chicken right and that sounds like a 70s funk band and now coming to the stage see Bailey and the electronic chickens where was I oh yeah python tic-tac-toe crap anyways so the article uses tic-tac-toe to teach a couple of Concepts one it uses a sort of a library based structure so that your front end and the game engine are separated and this kind of architecture allows you to build different front ends and say one for the web or one for TK enter or something like that and it keeps the game engine separate and so it's neat that he sort of walks you through the design concept and why you might do that as Beyond just the hey tic-tac-toe right and then second it does a little bit of introductory AI algorithm stuff showing you something called min max evaluation this is a way to get your computer to look into all possible Futures within the context of Tic-tac-toe and choose the move that will have the best outcome for it and this is how a lot of computer game AIS work so this is a an interesting little intro to that so to get going the article outlines project structure explains the design decisions behind it the structure separates the front and back ends like I said and within the engine it separates the game structure from the logic processing so it you know and it includes the typical project Tamil and virtual M stuff as well so if you're new to these kinds of mid-sized projects rather than say writing your first just a simple script it walks you through all that stuff and although tic-tac-toe is a relatively simple game by the time you're done you'll have touched a lot of modules uh you'll need some familiarity with object-oriented coding data classes regexes and recursion and so he helpfully provides a bunch of links to other articles in case you need to brush up on any of those topics with the base structure in place you start by writing code that describes the state of a game and this includes an enum containing the X and O's that's knots for British listeners along with encoding the positions in the board there's a little bit of regex use here to make sure that the board data only contains those X's and O's as well as some empty spaces and then once you've got a board the next step is to define a move so you're going to need this in order to have the AI look into all the possible future moves as well as determine if a player is allowed to do an action so you have to codeify all of this a game State object tracks all the possible states of the game you know not started ongoing and then the three possible finishing States tie X wins o wins and the game state code includes data about those winning boards and what they look like and then the same idea is applied to valid and invalid board States so you shouldn't have a board with say nine X's for example the article walks you through how to take the this logic and refactor it out into a place where it's more reusable so because it's step by step you're starting with like a little thing and you practice a bit and you get it and you test it and then you oh wait maybe this should live somewhere else so it's very much like how well at least how I code actually I shouldn't speak for everybody but this is a common practice right you rethink things as you go along now that you know whether a state is valid the next step is to figure out what are the allowed next steps in the game so given any in-progress board State what are the legal next steps and being able to answer this is the first thing you need for that future prediction thing that I keep making references to so once you've got the data models in place you start putting all this together through a rough scaffold for the game and that includes things like different renderers so that you can have like a command line versus a GUI renderer and now we get to the interesting stuff which is actually playing so you build out your first little renderer and that's based on ANSI escapes sequence that clear the screen and control where things are printed in the terminals you got your little XO board going on and then it adds a bit of Randomness and allows the computer to play itself and the computer at this point is isn't playing smartly it's just randomly making valid moves and then the last step the article dives into is the AI so greetings Professor Falcon shall we play a game uh esoteric 80s movie reference that probably only you and I will get the min max algorithm is a common AI tool for computer games so how this works is it uses a tree representation of subsequent game States so you start with the current state and then imagine all the possible next States and those are put as leaves in the tree underneath that current state each of those leaves then does the same thing and you keep going and building this tree and eventually you're going to get to some leaves that you can't get past because they're end States and then you find all of those and you mark those with one minus ones and zeros for winning losing and tying and then you walk those backwards through the tree annotating each of the branches to score the outcomes so this allows you at the state you're in to say oh I should take this Branch or I shouldn't take this Branch maximizing the chance of winning and minimizing the chance of your opponent doing so so basic like things like chess engines and things like that do this use this algorithm to play against computer users the difference is tic-tac-toe the board space is so small that the computer can see all the possible States something like chess or go the number of positions is huge and so they can't see completely into the future and so then they start adding other algorithms to try and you know make guesswork but for Tic-tac-toe python can just you know basically see the entire future which means you really can't beat the chicken I mean computer and the article caps it off uh with writing a nice little wrapper that takes command line arguments to determine whether you're playing against another person or the random computer or the min max based one and like I said there's no option for chickens but you know whatever that's uh so deep article lots of nifty little stuff here far more information than you would ever expect out of tic-tac-toe yeah it there's actually a I don't know the percentage of article that's covering you know the setup and getting it to be graphically created and so forth and making a random one and then adding the AI is actually on the smaller side of the article as far as like diving into it and maybe that's partly because of the fact that it's like you said there's not as many potential choices for it to go through to kind of try everything out but it's neat he really Dove deep into this that's cool well and as much as this kind of you know min max is is a strategy that gets labeled as AI it's one of those things though you can code it in very few lines like it really is you're just walking a tree and looking for some conditions so in a game like tic-tac-toe where there aren't a lot of conditions the AI here doesn't really have to be particularly smart but I also I I distinctly remember one of my profs who was in the AI space saying that eventually all algorithms that are that solve a problem get removed from the AI space so this was considered like Cutting Edge stuff when they came up with it in the 80s or 90s and right and now it's like oh yeah we'll just apply it no problem then then now it's like I'm not sure that even counts as AI anymore right so yeah when you're talking to your computer and it's answering back to you uh you know a simple Branch mechanism seems uh Antiquated yeah I mean this is like the types of algorithms that would have been in early in computer games as far as like yeah you know just creating movement and you know so yeah and they're still and they're still used yeah they're still used awesome [Music] time series data runs almost every technology the building real-time apps in Legacy databases can be a nightmare to manage at influx data creator of the time series data platform in fluxdb they built their time series platform with tools so developers don't have to make wholesale changes to their product or application just to use influxdb influx DB is optimized for developer productivity so developers can build iot analytics and Cloud applications quickly and at scale check it out and start for free today at influxdata.com that's influx d-a-t-a.com foreign that takes us into my next one which this one's a little shorter it's diving into a set of command line tools that you might not be familiar with that are actually running python but just straight from the command line and not requiring you to create a whole script and and so forth It's a medium article it's by Martin Heinz who we've heard from a few times before he starts out the article the title of it is python CLI tricks command line interface tricks that don't require any code whatsoever I'll reference a few of these things uh and the first one he gets into is time it which I think we've talked about you know on a handful of different times getting into sort of a version of profiling or code and benchmarking how it is running time it is a very popular tool for that the command line would look like basically python-m time it and then you'd run your code and then you can set a whole bunch of different flags to choose like how many Loops you wanted to go and which sometimes you need to be careful of because it might just keep going on forever and there are examples where it will automatically run a certain number of Loops to just get an idea of like how many you know everything from microseconds that the loop takes to run and so forth but it's a nice tool again just kind of get going with it the next one he talks about is pi perf which is a little more advanced in some of the stuff that it can do one thing that I I haven't run it very often but one of the things that it can do is a histogram which I thought was kind of interesting and can kind of show you the results and in sort of bins to indicate different performance characteristics as it was running through so that might be a handier one depending on the type of code you're trying to run through it and then he talks about C profile which gets into you know a little more elaborate kind of stuff as far as like you know actually more truly profiling your code and looking at the individual modules that are running as it goes he gives some links for diving deeper into python profiling and we had a whole article recently our whole uh podcast recently about memory profilers and some of those other kinds of tools and there's definitely those types of routes where you might run into from there the next one that he covers actually we had talked about in episode 97 with Adam Johnson where he was helping kind of improve your Django python developer experience and he had mentioned the ability that you can run a server inside of Python and the way that we were talking about running it was that you can set up documentation and run a server pointed at this folder and then you're running potentially all the documentation like maybe locally on your computer and being able to access it the way that it would normally be able to get to it on online and it's just again python-m in this case HTTP dash dot server and then what port you want it to run on and then you know what kind of directory that you're pointing it to very handy tool yeah I use this one a lot my corporate website is a static generated site based on Django a Django project called distill that takes a Django site and turns it into a static site and when I'm testing them to make a change the easiest thing to do is just point this web server at the directory and then use it in the browser it's fantastic yeah yeah again just you know the idea that you can just kind of stand something up and then kind of poke at it and that it's one of those batteries included these are ones that we hope we keep so have you used this next one the FTP no thing I had never been filler familiar with it I have my FTP I haven't touched FTP in quite some time yeah well I I use it occasionally again talking about uh simple websites or static websites that occasionally I have to help with other family members that have really simple sites that they want me to update and so forth and so FTP is still my simple way to get in and out of updating things but I thought it was interesting that you can set up an FTP server really quickly and then access it and I didn't try it out but that one sounds kind of interesting he also has a reference to the library Twisted to do something like that Twisted FTP is another one uh then he gets into debugging with pdb which again from the command line might be a handy way to kind of approach it the one that I I have seen you use that I thought was very interesting is this one where you can do parsing of Json again something built into the python standard library is the Json module and so you can use this Json dot tool Json in its raw form is rather ugly and hard to parse and so there's a way to have it printed out and I had seen you do this in a handful of the video tutorials where you were discussing in most recently the ninja API setup that you can do Django Ninja yeah I think I used it in the drf course as well yeah any any time where you're getting you know Json back from something through say curl uh this is a quick and easy way to do a nice little pretty print on it yeah so it's just again python M and then whatever commands you're pulling in in json.tool to look at the output there can be able to be handy the last two key covers are compressing and packaging he covers doing gzip which would be like individual files that you want to zip up or the more advanced one is Zip app and then he actually calls out a real python article in there from La Adonis it's a neat tool where you can actually build executable zip zipped up applications with Zip app and so instead of having to provide somebody like you know this entire directory structure and so forth you can provide them just the single file and then it can actually you know be a standalone python app in in a way which is pretty cool so I'll include the link to that article also and then I think the last one is you have to have this set up in your terminal but you could launch a web browser so you could like have it call out and have it you know actually start up Chrome or what have you I feel like this is a whole path like if you're a very very terminal focused and do a lot of work inside there's a lot of great tools that you just might not be aware of that are low hanging fruit for you to get a little more handy stuff happening inside your terminal yeah the um the debug one that you mentioned I'd only learned about this one recently uh from one of uh Gerard's articles actually and uh it's the dash I parameter to Python and it's not specifically for debugging what it does is it runs your script and then kicks you into a rebel in context of the script and in the article he goes and then Imports pdb in order to start doing things in the debugger but you can do other things with it as well so if you're just trying to let's say you've got some functions in your script and you want to play with them interactively if you do Dash I and the script only has the functions because there's no double underscore main it won't it won't do anything it just loads the functions into the context and then if you're you have it inside of your Rebel space and then in the rebel you can call the function and play with the function yeah so it's a neat little you know play with your code experiment kind of thing without even needing the pdb side yeah I'm sorry I didn't call that one out but that definitely is one of the handier things he had talked to me about it a long time ago um he was using it with other rebel tools to kind of do that sort of interactivity stuff before yeah yeah cool so what's your your next one uh so this is something called type annotation via automated refactoring by Jimmy Lai and if you're not a first time listener uh you may recall I'm not a huge fan of type annotation so you might be wondering what why am I talking about this so although the article is nominally about type annotations it's really not about type annotations Jimmy works at Carta which is a company with over 2 million lines of python code and they decided they wanted to start using type annotations this article talks about the automated tools they built to help them do this so the fact that they're trying to add the type annotations is almost secondary uh how they go about doing it and the process they have and all the things they have to think about is quite deeply covered in the article they started out by investigating their current state so they have more than 100 python repos of the company and so they picked one of their more active ones it has 200 people working on it at any given time and it turned out that they only had about 14 of the 120 000 functions inside of it were fully typed and this they wanted to do something about this they figured they were if they were able to add about 30 annotations per day that would be 10 years worth of work assuming no one else added any code in the meantime so this is why they were going down the automation path um they had done a similar process uh in the past uh trying to make their code compliant with the black code formats and one of the things that they learned through that was if the automation tools opened up too many pull requests that were too large a chaos ensued so they found that the through that project that PRS of one to 200 lines of code were sort of a good range and they also figured out how to use some of the metadata from GitHub to try to make the pr impact only a single team at a time if possible and all of this again was just trying to reduce that whole ensuing chaos thing and it could warn that group here comes the change exactly that's exactly right so so once they had a commit strategy in place they identified some low-hanging fruit and they came up with three things one was Dunder init statements should return none makes sense built-in functions so things like Dunder string and under hash have well-known return types so Dunder string returns a string Under hash returns an INT Etc and then some of their functions doing sort of a basic code scanning thing have obvious return types so if all the function is always returning true or false then you know add the mapping to Bool Jimmy goes into great detail about how they used a package called git python to manage the commits and their Pipeline and they even included notifying the code owners via slack that hey you know change like you said changes are coming and as a person has to actually accept the pr they also did a little gamification thing to make sure that the coders were actually taking in the requested changes that were coming from the tool so in a little over a year they went from 14 compliance to almost 70 compliance and they're hoping to hit 100 by the end of 2022 so this is an ongoing thing so whether or not you're a mypai guy or gal the article does a great job of sort of walking you through what it's like to make automated changes to a large code base and so I found there was a lot to learn here even independent of whether or not you want to do the typing thing and when you're dealing with two million lines of code this is exactly where you should be doing typing you want this kind of rigidity when you've got a larger code base because you want the extra checks so yeah and getting all those teams to agree on you know what what's coming in and out of the code yeah yep awesome so we had a couple short ones that we both wanted to mention and mine is from will mcgugan of rich and textual Fame he was a guest on episode 80 we talked a lot about working and creating these two e's and his article is just a short and sweet one it was a new question mark way of drawing boxes in the terminal and he was noting that as he's drawing these you know pretty common box shapes that he's using ASCII or other additional types of characters and often the ones that have lines and then to you can make these shapes to create a box the lines were like in the middle of a square and so if that square is shaded it means that there's going to be shading on the top that align and then on the bottom or whatever is on the outside and he's like man this is kind of ugly that there's always going to be this background color kind of outside of the lines and so he started to think about it a little bit more and said well there are boxes that have vertical and horizontal lines that are on the edge so like you could think of like a top box that has a line that's just at the top and then the color or whatever the background is below it and the same with the bottom would be something above and then just a line on the bottom and then one's on the left and the right sides and he thought to himself well wait maybe I can just flip this thing and so by flipping the box that normally would be considered a Top Line in making it be one that has a line just on the bottom it allows them to create these box shapes that don't have that weird kind of outer shading and uh he jokingly called the magugan boxes which I thought was pretty funny so he's looking at the I guess this must have just came out then the next release the textual came out on October 24th if everything went smoothly there and anyway so he's looking at some new ways to create these boxes and kind of remove some of the additional clutter and and so forth so if you are we've talked about the release of python 311 how they were doing a little more of this I was calling it ASCII art but these lines and boxes and underlining and so forth so this is a a common technique if you're doing terminal output and here's another way that you could maybe make it look a little more attractive yeah they're sticking to Pure ASCII art though they're using dashes and pluses it looks very 1980s yeah yeah and underscores but hey you could yeah so uh what's your little shorty yeah so this is a post called decorator shortcuts from NED batchelder it's a simple little thing that kind of made me go of course you can do that why didn't I know this and what the post talks about is Ned sort of reminds us that decorators are just functions which means you can call them and that seems obvious but why would you want to do this outside of the context well it uh it turns out that this can save you some typing and it can enable reuse in certain cases so a common case here is let's say you're using pi tests which uses decorators to manage test functions some of these decorators have a large number of arguments associated with them for example if you set a test to fail automatically if a certain version of python is used doing so requires a test condition as well as an error message if you wanted to wrap that decorator around many tests you'd be typing that out a lot or copying and pasting it and if you want to go in and change the python version now you've got to go and change it all right so you're doing this repeat yourself thing so this little trick is to get around that so instead of doing the copy and paste thing you call The Decorator as if it's a normal function with all those arguments and store the result in a variable so in that example I just gave you might call that variable conditional python version and then you use this variable as The Decorator so my test would now have at conditional python version over the top of a function instead of at pystest.mark.xfail parentheses and then all those parameters so like I said it's not something that I'd ever thought to do but now that I've seen it I've sort of like oh of course and like most brilliant stuff it you know that that's always great when you see this kind of thing so it's a neat little another tool for the tool bag really is what it comes down to yeah it's kind of wild you know that you know it goes back to the idea everything being an object and the idea that you can you know yep create you know it's not quite a factory but you know in a way you're creating a an object that is this other function and then you can use that as a decorator so yeah there's you know decorators and generators and async await are all these like it's executing but it's not executing sort of magic and uh and and and this leans right into it because you're not really calling the thing that's being called you can wrap it and go right so it works yeah [Music] this week I want to shine a spotlight on another real python video course it's about a topic we touch on this week and new students to python can often find a bit confusing it's titled python decorators 101 the course is based on real python guide my previous guest on the podcast Gerardo yella it's a course created by yours truly and I take you through how functions are first class objects in Python how to return a function from a function how to create simple decorators creating some syntactic sugar when using decorators how to decorate functions with arguments and you'll practice creating several real world examples including code for timing your functions debugging code slowing code down and a plug-in registering system I think it's a worthy investment of your time to learn how to use decorators in Python and to recognize how decorators are being used in all the code you encounter along your python Journey real python video courses are broken into easily consumable sections and where needed include code examples for the technique shown all lessons have a transcript including closed captions check out the video course you can find a link in the show notes or you can find it using the enhanced Search tool on realpython.com [Music] we decided to do something kind of different this week about our discussion topic we found this article from Amman carwall it's actually from a little while ago but it's I guess sort of bubbled up it's 190 python projects with source code for each of the projects if you were to click on one it goes to a small web page that has a description of what you're going to create the python code the output and then like a whole comment section and so forth on Beyond it so it's a very elaborate kind of setup that Iman has created here and I think it's actually pretty genius as far as SEO and getting attention and so forth but a lot of the projects I think the he mentions them as like python projects for beginners one of the dividing lines and then the other one is a advanced python projects I almost think of like three or four different ways you could kind of approach this article as a resource for again for like a beginner is it could be one of these things where okay I want to practice my python skills and you could see something like this as number seven count number of words in a column or uh print emojis using python or correct spellings or find a missing number or some of these games and stuff like that and you could try to create your own unique version of that and then compare your answer yeah it's kind of like having the answers in the back of the textbook right like you read the sentence you go I'm gonna go try this and then go see okay how did the teacher do it yeah right right yeah and then I thought of it as a maybe like you could look at what Amman created and maybe think of well I could improve on this or I could think of another way to do this so as like kind of a refactoring type of thing because there are some examples where I'm like well I could see some improvements or some other maybe ways that we could think of as you kind of learn more about the library and you go there might be other ways to do this and then the other Most Fascinating thing about it as I went through them is that often the solution was use this third-party Library yeah and I was like oh well I didn't even know that was available so like there's one that's removing uh was it cuss words yep and better profanity yeah there's a library that's just in you know pip install Better underscore profanity and you know it pretty much does the work for you and you might not have known that that was available and so this is kind of a neat exploration of some of these third-party tools that are out there and so I wanted to you know kind of discuss some of these uh we're not going to go through all 190 but there were a handful that were kind of interesting as a way for you to kind of get into them and then that might be a whole side journey into those libraries and seeing what's made of them you know and kind of digging into their code and well how did they solve this if it's just as simple as you know installing it and using it I'm not saying that you need to re-write the wheel each time but you know if you're going to use this as an educational tool that might be one yeah and and because he uses the third party libraries for a lot of it very few of these are more than like a dozen lines of code so that they're right so you're they're all it's it's not like you're deep diving into oh go read a thousand lines of code and try to understand how it is they're all like little snacky bits of oh there's recipes for doing things right so you know similar to the better profanity one the one of the ones I liked that I'm going to file away is Lang detect and it uh you feed it some text and it spits back its best guessed as to what language it's in so spoken language not programming language so right yeah so and there was another one which I thought again was kind of cute and cool which is python Emoji yeah yeah that one too I thought was cool and it uses the colon Name colon format that's very common in the tools like slack where you can you know say colon ta-da colon and it turns it into the little party uh thing and python Emoji essentially does the same thing right I have haven't dug into the library yet but I suspect it's just doing the Unicode lookup name right I'm hoping so because otherwise somebody has spent a lot of their time typing all that stuff in yeah I thought about this one the the scrape IMDb and like oh whoa what's that gonna be and IMDb has the library yep you literally can pip install IMDb and then from there you can get specific movies or you know look at the different fields that are in it's very much a database you know kind of API connection so but pretty slick yeah and the other thing I found too was there's because a bunch of them are either using standard libraries or popular libraries yeah again that sort of recipe thing it was a neat way of sort of oh how would I do X right so the there's there's a short one in here about removing stop words and these are words that you can skip if you're doing semantic processing so the nltk library does this with you know it's a couple lines of code and but if you were new to this space or you know you're sort of trying to Google how would I do this you know this is right there this is exactly how to do it kind of thing you know you mentioned the the text columns thing his approach is to use pandas and uh you know if you were if you say did it and didn't know pandas existed you you go off and you write you know whatever it is couple dozen lines of python and then you look at his and it's like oh pip install and then call that function okay that makes it much easier right so right right and it's similar and there's things like that even within the standard library is found as well right so you know one of the recipes is removing Unicode characters from a string and that's that that's not even in a module that's straight off part of the string library but it's a encode and decode using the right parameters and you can pull all that stuff and put it back into asking land so again neat little sort of recipe lots of tricks and tips yeah just kind of hiding in there yeah yeah and you know and there's all you know a real variety of things like building a music player GUI graphical user interface and he's using to kinter in this case and then and actually using pi game which has a lot of built-in functionality as far as like creating you know a mixer and other ways to kind of play the music and control that sort of stuff it's a fun place to kind of like go in and just look through it there's enough there that it could keep you busy for sure trying to be inspired to like try out some new things or uh you know there was enough of them that I clicked on like oh yeah that would be fun and and for our uh younger listeners there's some homework cheats in here as well so yeah totally the interview type questions yeah pretty standard computer science type things like cues and diapers algorithm and Fizz Buzz which is a common interview question you know quick sort some of that kind of stuff so there's uh yeah it's quite a mix it's a it's worth uh sort of trolling through and seeing what Peaks your fancy yeah so that gets us into projects I I'm the resident PDF guy always talking about PDFs and creating them it's partly my background of creating stuff for small businesses I think and little tools and things like that I had Mike Driscoll on way back in episode 20 and he had mentioned a particular library that he said well it's kind of dead and not really happening it was this thing called it was based on a PHP Library called free PDF and that one was called Pi fpdf well it's been sort of resurrected and updated and modernized and one persons who was involved previously I believe in this case is Mariano reingard and there's a ton of additional other contributors on this project so I don't know who gets all the credit there but it is known as fpdf2 it's a library with low-level Primitives to easily generate PDF documents it has a lot of similarity in episode 20 we talked about report lab Mike was working on a book about that at the time and the idea of having cells and flowables things that can kind of span across multiple rows and pages and tables and this Library does a lot of that stuff too it has hooks that can tie into letting you to do like subclasses of like headers and Footers and stuff like that again this whole thing was developed a long time ago in the PHP language and then it was sort of a free alternative to these super proprietary C libraries and I had the creator of borb on and he's also another person who created a very powerful Library that's got a lot of similarities here uh this one the tutorials are good they can kind of get you up and running really quickly if you want to just create something simple I'll include some links for some additional documentation and then other ports and directions and stuff that people have taken it but fpdf2 it's a nice project to do as their subtitle is minimalist PDF creation Library so what's yours what's your project this week so usually we pull the project stuff out of the pie Cutters projects section which yeah kind of makes sense this this week I didn't actually this is uh from a article but it really is just an article about a library so same difference and it's called Simple sane and sensible logging in Python and it's by Pete feisen and it's a quick overview of a library called log 2D and I have a love hate relationship with python logging uh it's very comprehensive and fairly close to how logging setup Works in other languages which is great trying to do something simple always feels painful and I I don't know about you but I tend to start with print statements and then add blogging when I need to industrialize a program because I just don't want to have to think about it and in fact I've got logging helpers in a couple of my libraries that are wrappers to common things that I do in Python logging and I'm going to stop using them because log 2D does it so much better so someone else can maintain it right yeah so the 2D in log 2D is the idea of configuring multiple loggers each for its own classification of message so rather than sticking to just sort of debug and warning and critical you can classify with things like say successes and failure messages and timing or instrumentation
Original Description
How do you create a computer opponent for a simple game within Python? Would you also like to learn how to adapt the game to run in a web browser or Graphical User Interface (GUI)? This week on the show, Christopher Trudeau is here, bringing another batch of PyCoder's Weekly articles and projects.
👉 Links from the show: https://realpython.com/podcasts/rpp/132/
Christopher shares a recent Real Python step-by-step project for creating a Tic-Tac-Toe game engine. He talks about how to build the game engine and adapt it for different front ends. The tutorial also shows how to implement an unbeatable computer player using the minimax algorithm.
We discuss an article about how to avoid repeating yourself when creating decorators with multiple parameters. We talk about how you can stop copying and pasting code several times by assigning the decorator to a new variable.
We share several other articles and projects from the Python community, including a news roundup, a deep dive into Python's doctest, several Python command line tricks, type annotations via automated refactoring, a new way to draw boxes in the terminal, a collection of projects for beginners with source code, a minimalist PDF creation library, and a tool for sensible logging in Python.
Topics:
- 00:00:00 -- Introduction
- 00:02:25 -- Python 3.12.0 Alpha 1 Released
- 00:02:45 -- PyCon US 2023 Call for Proposals
- 00:03:27 -- Python's doctest: Document and Test Your Code at Once
- 00:13:59 -- Build a Tic-Tac-Toe Game Engine With an AI Player in Python
- 00:22:12 -- Sponsor: InfluxDB
- 00:22:59 -- Python Command Line Tricks
- 00:30:50 -- Type Annotation via Automated Refactoring
- 00:34:29 -- A New (?) Way of Drawing Boxes in the Terminal
- 00:37:10 -- Decorator Shortcuts
- 00:39:36 -- Video Course Spotlight
- 00:41:02 -- 190 Python Projects With Source Code
- 00:47:58 -- fpdf2: Minimalist PDF Creation Library
- 00:50:04 -- Simple, Sane, and Sensible Logging in Python
- 00:53:05 -- Thanks and goodbye
👉
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
Playlist
Uploads from Real Python · Real Python · 0 of 60
← Previous
Next →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
A better Python REPL – bpython vs python interpreter
Real Python
Introducing large-type.com – A Utility Website
Real Python
Reading Hacker News Without Wasting Tons of Time
Real Python
Forward References and Python 3 Type Hints
Real Python
Using Sublime Text as your Git Editor
Real Python
Python Code Linting and Auto-Complete for Sublime Text
Real Python
Make your Python Code More Readable with Custom Exceptions
Real Python
Write Better Tests with Sublime Text's Split Layout Feature
Real Python
How to Use Sublime Text from the Command Line
Real Python
Rename Variables with Multiple Selection in Sublime Text
Real Python
Sublime Text Settings for Writing PEP 8 Python
Real Python
Write Cleaner Python with Sublime Text's Indent Guides
Real Python
Sublime Text Whitespace Settings for Python Development
Real Python
Function Argument Unpacking in Python
Real Python
Python Code Review: Debugging and Refactoring "Conway's Game of Life" + Automated Tests
Real Python
Using "get()" to Return a Default Value from a Python Dict
Real Python
A Python Shorthand for Swapping Two Variables
Real Python
Python Code Review: Refactoring a Web Scraper, PEP 8 Style Guide Compliance, requirements.txt
Real Python
Click & Jump to Test Failures from the Command Line (iTerm2)
Real Python
Setting up Sublime Text for Python Developers
Real Python
Sublime Text + Python Guide Overview
Real Python
Python Code Review: Adding Pytest Tests to an Existing Python Web Scraper
Real Python
Type-Checking Python Programs With Type Hints and mypy
Real Python
A Shorthand for Merging Dictionaries in Python 3.5+
Real Python
Python Code Review Flask Web Security Tutorial + Virtualenvs, requirements.txt
Real Python
My Python Code Looks Ugly and Confusing – Help!
Real Python
Setting Up a Programmer Portfolio/Developer Blog – How To Get Started
Real Python
Do I Need a GitHub/GitLab/Bitbucket Profile as a Developer?
Real Python
Programmer Portfolio – Example and Walkthrough
Real Python
How to Get Your 1st Speaking Gig at a Tech Conference
Real Python
How to Build Your Public Speaking Skills as a Developer
Real Python
The Object-oriented Version of "Spaghetti Code" is "Lasagna Code" ?!
Real Python
Setting up Sublime Text for Python Developers – Lesson #1
Real Python
Cool New Features in Python 3.6
Real Python
"is" vs "==" in Python – What's the Difference? (And When to Use Each)
Real Python
Emulating switch/case Statements in Python with Dictionaries
Real Python
Python Function Argument Unpacking Tutorial (* and ** Operators)
Real Python
What Code Should I Put On My GitHub/GitLab/BitBucket Profile?
Real Python
A Crazy Python Dictionary Expression ?!
Real Python
String Conversion in Python: When to Use __repr__ vs __str__
Real Python
Method Types in Python OOP: @classmethod, @staticmethod, and Instance Methods
Real Python
Optional Arguments in Python With *args and **kwargs
Real Python
Python Context Managers and the "with" Statement (__enter__ & __exit__)
Real Python
Installing Python Packages with pip and virtualenv / venv
Real Python
"For Each" Loops in Python with enumerate() and range()
Real Python
Python Code Review: LibreOffice Automation and the Python Standard Library
Real Python
Managing Python Dependencies With Pip and Virtual Environments – Lesson #1
Real Python
Python Tutorial: List Comprehensions Step-By-Step
Real Python
Leveraging Python's Implicit "return None" Statements
Real Python
What's the meaning of underscores (_ & __) in Python variable names?
Real Python
Python Data Structures: Sets, Frozensets, and Multisets (Bags)
Real Python
Writing automated tests for Python command-line apps and scripts
Real Python
How to find great Python packages on PyPI, the Python Package Repository
Real Python
Immutable vs Mutable Objects in Python
Real Python
PyPI vs Warehouse, the Next-Generation Python Package Repository
Real Python
pep8.org — The Prettiest Way to View the PEP 8 Python Style Guide
Real Python
My Experience at PyCon 2017 in Portland
Real Python
Pylint Tutorial – How to Write Clean Python
Real Python
"Reverse a List in Python" Tutorial: Three Methods & How-to Demos
Real Python
Python Refactoring: "while True" Infinite Loops & The "input" Function
Real Python
More on: Prompt Craft
View skill →Related Reads
📰
📰
📰
📰
When Tradition Meets Artificial Intelligence: The Future of Japanese Work Culture
Medium · AI
Crypto Market Navigates Institutional Inflows and Innovation Amidst Rising AI Scam Threats and Valuation Deb Concerns
Dev.to AI
IQE bets on AI data-centre demand to drive 20% sales growth in 2026
The Next Web AI
Judge signs off on Anthropic’s $1.5bn book piracy settlement, the biggest in US copyright history
The Next Web AI
🎓
Tutor Explanation
DeepCamp AI