Planet Python
Python⇒Speed: Beyond multi-core parallelism: faster Mandelbrot with SIMD
What do you do when computation is too expensive?
Recently I’ve had a brilliant business idea: Mandelbrot-as-a-Service! Instead of companies calculating their own fractals, I will do it for them, freshly calculated in the cloud, with no work on their part. And by using cloud computing, I will be able to scale to the no-doubt vast number of customers who will be paying for my ingenious new service.
I have two goals:
- Speeding up results: The faster I can return fractals, the happier my customers will be.
- Reducing costs: If I can pay my cloud provider less for computing, my profits will go up!
Unfortunately, since I will only be selling freshly calculated and warm-from-the-CPU Mandelbrots, I can’t rely on caching.
What would you do in this situation?
One obvious approach is parallelism: threading or multiprocessing. This will speed up results, so it’s definitely worth doing, but it won’t reduce my costs. If we use 10 cores instead of 1 core, the service will return results ten times faster, but we’ll have to pay approximately 10× as much, since we’ll be using 10× larger instances.
However, if we can figure out how to speed up calculations on a single core, this will contribute to both our goals. We’ll both get faster results, compounded by any multi-core processing, and reduce compute costs.
In this article we will:
- Quickly go over a standard Mandelbrot implementation, written in Rust.
- Discuss why it can be tricky to optimize the Mandelbrot algorithm on a single CPU core.
- Demonstrate how you can in fact do so, by using masked SIMD operations.
- Trivially add on multi-core parallelism, using Rust’s Rayon library.
- PROFIT!
Mike C. Fletcher: Interesting Memory Leak with Python 3.12 for PyOpenGL-accelerate
So I'm currently trying to figure out why the PyOpenGL 3.12 test suite is failing. There's a particular test that looks for VBO memory leakage and it looks loosely like this:
for i in range(100):
create_a_vbo_and_delete_it()
calculate_total_process_memory()
assert_no_leak()
which shouldn't ever lose more than a few bytes (limit is set to 200 for this test, but it doesn't lose even one normally). This passes fine on python2.7 through 3.11, but on 3.12 the first 75 iterations leak nothing, then on the 76th iteration (always the 76th) iteration there is a substantial memory leak (100s of KB) and then memory usage goes flat again.
My first guess is that there's something in the 3.12 JIT compiler that looks for e.g. 75 iterations, then does lots of analysis and caching and uses the 100s of KBs of RAM to track the behaviour. I can "fix" the test by reducing the iterations below 75, but that doesn't really address the underlying issue of the test, which is that it's using whole-system memory as a proxy for "did this local function leak RAM". Guess I need to find a better "does some RAM leak" test.
Update: always 75th iteration observation is *only* when run with just the single test. When run in the main test suite, the JIT seems to kick in much earlier (likely because of other tests exercising the same paths). That means it's likely to start failing as more tests are added, which reinforces the need to find a better test method.
The Python Coding Blog: The Python Coding Stack’s New Look
The Python Coding Stack has a new look. Here it is:
The Stack has been growing steadily as a standalone publication, separate from The Python Coding Book and The Python Coding Place, and now it has its own identity.
It offers a very different and unique perspective on Python programming, often with a narrative style.
If you’ve not read articles on The Stack yet, have a look at some of the most recent ones, or the top 5.
The post The Python Coding Stack’s New Look appeared first on The Python Coding Book.
Ned Batchelder: Changelog philosophy
I playfully quipped about changelogs, and Sumana Harihareswara thoughtfully responded with Changelogs and Release Notes. I agree with her on some things, and disagree on others.
My point with the meme was that people should put effort into a hand-crafted description of what has changed in each release of their product. It should be focused on what users need to know, and not include internal changes, which can be found in the git commits or pull requests. It’s easy to publish a list of commits or pull requests and call it a changelog, but it’s not that helpful to your users trying to understand what has changed for them. That was the point of the meme.
But Sumana raised the stakes, explaining why projects should produce two hand-crafted descriptions. The first is a changelog which mentions every non-trivial change. The second are release notes which should be user-focused with more details.
I liked the reasons Sumana gave:
- Release notes can include project-level information that doesn’t correspond to a particular change in a release. Maybe you started a new discussion forum, or there’s a shift in maintainer attention, plans for upcoming work, and so on.
- If the release notes are user-focused, then the changelog can be more comprehensive, giving people a fuller picture of the work that goes into producing the project. This can pull back the curtain, helping people understand the inner workings of the project and perhaps find a way to help out.
My problem with separating the changelog and release notes is that I have limited energy to produce them, and perhaps more importantly, people have limited attention to read them. For my projects, I opt instead for a middle ground: my changelogs lean more toward Sumana’s ideal of release notes. They are hand-written, focused on what users of the project need to know, and do not include things like build changes and refactorings.
For large projects like Python and Linux, there are many maintainers and many types of information, so it makes sense to have multiple views of “what’s changed.” For single-maintainer projects, it feels like too much. I applaud people who can do it, but I don’t think I can, and I won’t expect it from others.
Ultimately, each project has to decide for themselves how to balance the effort and the benefit. They know their audience(s), and what resources they have to do the work. Open source is already difficult, the last thing I want to do is add a giant SHOULD to a project.
There’s an inexact nested ratio at work in projects: Most users (say 90%) will only consume, you will never hear from them. You hear from the remaining 10%, but only 10% of those will do something you consider a contribution. For widely used projects like coverage.py, I think the ratio might be more like 1% of 1% instead of 10% of 10%. How does this affect your communication approach? You could look at it two ways: either write for the audience you have (focus on the 90%), or write for the audience you want (focus on the 10%).
In my changelogs now, for fixes I try to describe the bad thing that used to happen and any important changes in behavior. For features, I link to the new docs. I include links to issues and pull requests, and I name the contributors who helped.
So I guess my approach is to write changelogs for the 90%. But I like Sumana’s idea of making the full picture of maintainence more visible to people, so I’m thinking about how to add that without changing the essential character of my changelog. Perhaps something at the end summarizing the changes that aren’t yet mentioned, with a link to the git history? I’m not sure I can automate collecting that information, but I’ll have to play with it.
Real Python: Quiz: Syntactic Sugar: Why Python Is Sweet and Pythonic
Test your understanding of Python’s most common pieces of syntactic sugar and how they make your code more Pythonic and readable.
Take this quiz after reading our Syntactic Sugar: Why Python is Sweet and Pythonic tutorial.
[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]
Real Python: Quiz: Python 3.13: Cool New Features for You to Try
In this quiz, you’ll test your understanding of Python 3.13: Cool New Features for You to Try. By working through this quiz, you’ll review the key updates and improvements in this version of Python.
[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]
Kushal Das: Updated blog theme after many years
One of the major reason of using static blogging for me is to less worry about how the site will look like. Instead the focus was to just write (which of course I did not do well this year). I did not change my blog's theme for many many years.
But, I noticed Oskar Wickström created a monospace based site and kindly released it under MIT license. I liked the theme, so decided to start using it. I still don't know HTML/CSS but managed to change the template for my website.
You can let me know over mastodon what do you think :)
Zero to Mastery: Python Monthly Newsletter 💻🐍
Python Morsels: The string split method in Python
Strings can be split by a substring separator. Usually the string split is called without any arguments, which splits on any whitespace.
Table of contents
- Breaking apart a string by a separator
- Splitting a specific number of times
- Splitting from the end of a string
- The string split method versus regular expressions
If you need to break a string into smaller strings based on a separator, you can use the string split method:
>>> time = "1:19:48" >>> time.split(":") ['1', '19', '48']The separator you split by can be any string. It doesn't need to be just one character:
>>> graph = "A->B->C->D" >>> graph.split("->") ['A', 'B', 'C', 'D']Note that it's a little bit unusual to call the string split method on a single space character:
>>> langston = "Does it dry up\nlike a raisin in the sun?\n" >>> langston.split(" ") ['Does', 'it', 'dry', 'up\nlike', 'a', 'raisin', 'in', 'the', 'sun?\n']It's usually preferable to call split without any arguments at all:
>>> langston = "Does it dry up\nlike a raisin in the sun?\n" >>> langston.split() ['Does', 'it', 'dry', 'up', 'like', 'a', 'raisin', 'in', 'the', 'sun?']Calling the split with no arguments will split on any consecutive whitespace characters. So we're even splitting on a new line here in between up and like (up\nlike).
Also note that the split method without any arguments removes leading and trailing whitespace (note that the last element in the list is sun? rather than sun?\n).
There's one more split feature that's often overlooked: maxsplit.
Splitting a specific number of timesWhen calling split with a …
Read the full article: https://www.pythonmorsels.com/string-split-method/Carl Trachte: DAG Hamilton Graph Presented as SVG in Blogger
Through the kindness of the DAG Hamilton project team, I was able to secure an official svg version of the DAG Hamilton logo. It looks significantly better than the one I had generated with an online image to svg converter and is much smaller and easy to work with (4 kilobytes versus 200 kb). The DAG Hamilton graphviz graph now shows up in Blogger; it is unlikely to show up on the planet(python) feed. Blogger is not liking the code and svg I have included (complaints of malformed html). In the interest of preserving the rendering of the graph(s), I am constraining the text here to a few paragraphs
The first graph has the code provided. This graph is from a previous post.
The second graph represents the DAG Hamilton workflow for the production of the first graph. This is in keeping with the "Eat your own dogfood" mantra. I happen to like the DAG Hamilton dogfood as I've mentioned in previous posts. It allows me to visualize my workflows and track complexity and areas for improvement in the code.
The third one I did with a scaled down version of the code presented (no logos). I hand pasted the DAG Hamilton official logo into the third one. It is not subtle (the logo is huge), but it provides an idea of what one can do creatively with the logo or any svg element. Also, it shows the DAG Hamilton workflow for the graph with the respective two logos.
All the code is a work in progress. Ideally I would like to keep reducing this to the most simple svg implementation possible to get it to show up or "work." Realistically, I'm afraid to sneeze for fear Blogger will protest. For now, I'm leaving good enough alone. Links and thoughts on svg (there is at least one python library (orsinium-labs/svg.py) out there that is way more elegant in its treatment of the medium than my rough regular expressions / text processing) will have to wait for another post.
Thanks for stopping by.
run.py code
""" Hamilton wrapper. """ # run.py import sys import pprint from hamilton import driver import dag_hamilton_to_blogger as dhtb dr = driver.Builder().with_modules(dhtb).build() dr.display_all_functions('dhtb.svg', deduplicate_inputs=True, keep_dot=True, orient='BR') results = dr.execute(['defluffed_lines', 'scale_and_translation', 'logo_positions', 'captured_values', 'scaled_elements', 'translated_elements', 'hamilton_logo_data', 'scale_and_translation_hamilton_logo', 'fauxcompany_logo_data', 'scale_and_translation_fauxcompany_logo', 'svg_ready_doc', 'written_svg'], inputs={'svg_file':'web_scraping_functions_highlighted.svg', 'outputfile':'test_output.svg', 'hamiltonlogofile':'hamilton_official_stripped.svg', 'hamiltonlogo_coords':{'min_x':-0.001, 'max_x':4353.846, 'min_y':-0.0006, 'max_y':4177.257}, 'fauxcompanylogofile':'fauxcompanylogo_stripped_down.svg', 'fauxcompanylogo_coords':{'min_x':11.542786063261742, 'max_x':705.10684, 'min_y':4.9643821, 'max_y':74.47416391682819}})Main DAG Hamilton functions (dag_hamilton_to_blogger.py)
# python 3.12 """ Make DAG Hamilton graph show up in Blogger. """ import re import sys import pprint import math import copy import reusedfunctions as rf VIEWBOX_PAT = (r'[ ]viewBox[=]["][-]?[0-9]+[.]?[0-9]*[ ][-]?[0-9]+[.]?[0-9]*[ ]' r'([0-9]+[.]?[0-9]*)[ ]([0-9]+[.]?[0-9]*)') # 5 coordinates. POLYGON_PAT = (r'[]polygon' r'.*([ ]points[=]["])([-]?[0-9]+[.]?[0-9]*)[,]' r'([-]?[0-9]+[.]?[0-9]*)[ ]' r'([-]?[0-9]+[.]?[0-9]*)[,]' r'([-]?[0-9]+[.]?[0-9]*)[ ]' r'([-]?[0-9]+[.]?[0-9]*)[,]' r'([-]?[0-9]+[.]?[0-9]*)[ ]' r'([-]?[0-9]+[.]?[0-9]*)[,]' r'([-]?[0-9]+[.]?[0-9]*)[ ]' r'([-]?[0-9]+[.]?[0-9]*)[,]' r'([-]?[0-9]+[.]?[0-9]*)["]') # 4 coordinates instead of 5. POLYGON_PAT_4 = (r'[]polygon' r'.*([ ]points[=]["])([-]?[0-9]+[.]?[0-9]*)[,]' r'([-]?[0-9]+[.]?[0-9]*)[ ]' r'([-]?[0-9]+[.]?[0-9]*)[,]' r'([-]?[0-9]+[.]?[0-9]*)[ ]' r'([-]?[0-9]+[.]?[0-9]*)[,]' r'([-]?[0-9]+[.]?[0-9]*)[ ]' r'([-]?[0-9]+[.]?[0-9]*)[,]' r'([-]?[0-9]+[.]?[0-9]*)["]') # x, y TEXTPAT = (r']text[ ].*' r'([ ]font[-]size[=])' r'["]([0-9]+[.]?[0-9]*)["]') # initial bezier curve notation PATHPAT = (r'[]path[ ].*' r'([ ]d[=]["]M)([-]?[0-9]+[.]?[0-9]*)[,]' r'([-]?[0-9]+[.]?[0-9]*)C') X_SIZE = 600 NEW_FIRST_LINE = '') IMAGE_FLAG = '') # 4 coords (arrow head). POLYGON_STR_4 = (r' points="{0:.3f},{1:.3f} {2:.3f},{3:.3f} ' r'{4:.3f},{5:.3f} {6:.3f},{7:.3f}"/>') PATH_START_STR = r' d="M{0:.3f},{1:.3f}C' PATH_STR_SEGMENT = ' {0:.3f},{1:.3f}' PATH_STR = r' {0:s}"/>' TEXT_STR = r' x="{0:.3f}" y="{1:.3f}"' TEXT_STR_FONT = r' font-size="{0:.3f}"' HAMILTON_LOGO_DIMENSIONS_PAT = (r'.*width[=]["]([0-9]+[.]?[0-9]*)px["][ ]' r'height[=]["]([0-9]+[.]?[0-9]*)px["][>]') FAUXCOMPANY_LOGO_DIMENSIONS_PAT = (r'[ ]width[=]["]([0-9]+[.]?[0-9]*)["][ ]' r'height[=]["]([0-9]+[.]?[0-9]*)["][ ][>]') # The official Hamilton logo splits the path into multiple # lines with the last one having the absolute location # ("C") of a bezier curve. HAMILTON_CHANGE_LINE_PAT = r'.*C[-]?[0-9]+[.]?[0-9]*' HAMILTON_TRANSFORM_FMT = (' transform="scale({scale:f}) ' 'translate({translate_x:f},{translate_y:f})" />') # One line of paths in Inkscape generated file. FAUXCOMPANY_CHANGE_LINE_PAT = r'.*d[=]["]m[ ]' # Inkscape put the closing tag /> on the following line. FAUXCOMPANY_TRANSFORM_FMT = (' transform="scale({scale:f}) ' 'translate({translate_x:f},{translate_y:f})"') # * - get rid of first 6 lines. # * - get rid of any line starting with: # # "Terri Oda: Best practices in practice: Black, the Python code formatter
I’m starting a little mini-series about some of the “best practices” I’ve tried out in my real-life open source software development. These can be specific tools, checklists, workflows, whatever. Some of these have been great, some of them have been not so great, but I’ve learned a lot. I wanted to talk a bit about the usability and assumptions made in various tools and procedures, especially relative to the wider conversations we need to have about open source maintainer burnout, mentoring new contributors, and improving the security and quality of software.
So let’s start with a tool that I love: Black.
Black’s tagline is “the uncompromising Python code formatter” and it pretty much is what it says on the tin: it can be used to automatically format Python code, and it’s reasonably opinionated about how it’s done with very few options to change. It starts with pep8 compliance (that’s the python style guide for those of you don’t need to memorize such things) and takes it further. I’m not going to talk about the design decisions they made but the black style guide is actually an interesting read if you’re into this kind of thing.
I’m probably a bit more excited about style guides than the average person because I spent several years reading and marking student code, including being a teaching assistant for a course on Perl, a language that is famously hard to read. (Though I’ve got to tell you, the first year undergraduates’ Java programs were absolutely worse to read than Perl.) And then in case mounds of beginner code wasn’t enough of a challenge, I also was involved in a fairly well-known open source project (GNU Mailman) with a decade of code to its name even when I joined so I was learning a lot about the experience of integrating code from many contributors into a single code base. Both of these are… kind of exhausting? I was young enough to not be completely set in my ways, but especially with the beginner Java code, it became really clear that debugging was harder when the formatting was adding a layer of obfuscation to the code. I’d have loved to have an autoformatter for Java because so many students could find their bugs easier once I showed them how to fix their indents or braces.
And then I spent years as an open source project maintainer rather than just a contributor, so it was my job to enforce style as part of code reviews. And… I kind of hated that part of it? It’s frustrating to have the same conversation with people over and over about style and be constantly leaving the same code review comments, and then on top of that sometimes people don’t *agree* with the style and want to argue about it, or people can’t be bothered to come back and fix it themselves so I either have to leave a potentially good bug fix on the floor or I have to fix it myself. Formatting code elegantly can be fun once in a while, but doing it over and over and over and over quickly got old for me.
So when I first heard about Black, I knew it was a thing I wanted for my projects.
Now when someone submits a thing to my code base, Black runs alongside the other tests, and they get feedback right away if their code doesn’t meet our coding standards. It hardly any time to run so sometimes people get feedback very fast. Many new contributors even notice failing required test and go do some reading and fix it before I even see it, and for those that don’t fix issues before I get there I get a much easier conversation that amounts to “run black on your files and update the pull request.” I don’t have to explain what they got wrong and why it matters — they don’t even need to understand what happens when the auto-formatter runs. It just cleans things up and we move on with life.
I feel like the workflow might actually be better if Black was run in our continuous integration system and automatically updated the submitted code, but there’s some challenges there around security and permissions that we haven’t gotten around to solving. And honestly, it’s kind of nice to have an easy low-stress “train the new contributors to use the tools we use” or “share a link to the contributors doc” opening conversation, so I haven’t been as motivated as I might be to fix things. I could probably have a bot leave those comments and maybe one of those days we’ll do that, but I’m going to have to look at the code for code review anyhow so I usually just add it in to the code review comments.
The other thing that Black itself calls out in their docs is that by conforming to a standard auto-format, we really reduce the differences between existing code and new code. It’s pretty obvious when the first attempt has a pile of random extra lines and is failing the Black check. We get a number of contributors using different integrated development environments (IDEs) that are pretty opinionated themselves, and it’s been freeing to not to deal with whitespace nonsense in pull requests or have people try to tell me on the glory if their IDE of choice when I ask them to fix it. Some python IDEs actually support Black so sometimes I can just tell them to flip a switch or whatever and then they never have to think about it again either. Win for us all!
So here’s the highlights about why I use Black:
As a contributor:
- Black lets me not think about style; it’s easy to fix before I put together a pull request or patch.
- It saves me from the often confusing messages you get from other style checkers.
- Because I got into the habit of running it before I even run my code or tests, it serves as a quick mistake checkers.
- Some of the style choices, like forcing trailing commas in lists, make editing existing code easier and I suspect increase code quality overall because certain types of bug are more obvious.
As a an open source maintainer:
- Black lets me not think about style.
- It makes basic code quality conversations easier. I used to have a *lot* of conversations about style and people get really passionate about it, but it wasted a lot of time when the end result was usually going to be “conform to our style if you want to contribute to this project”
- Fixing bad style is fast, either for the contributor or for me as needed.
- It makes code review easier because there aren’t obfuscating style issues.
- It allows for very quick feedback for users even if all our maintainers are busy. Since I regularly work with people in other time zones, this can potentially save days of back and forth before code can be used.
- It provides a gateway for users to learn about code quality tools. I work with a lot of new contributors through Google Summer of Code and Hacktoberfest, so they may have no existing framework for professional development. But also even a lot of experienced devs haven’t used tools like Black before!
- It provides a starting point for mentoring users about pre-commit checks, continuous integration tests, and how to run things locally. We’ve got other starting points but Black is fast and easy and it helps reduce resistance to the harder ones.
- It reduces “bike shedding” about style. Bikeshedding can be a real contributor to burnout of both maintainers and contributors, and this reduces one place where I’ve seen it occur regularly.
- It decreases the cognitive overhead of reading and maintainin a full code base which includes a bunch of code from different contributors or even from the same contributor years later. If you’ve spent any time with code that’s been around for decades, you know what I’m talking about.
- In short: it helps me reduce maintainer burnout for me and my co-maintainers.
So yeah, that’s Black. It improves my experience as an open source maintainer and as a mentor for new contributors. I love it, and maybe you would too? I highly recommend trying it out on your own code and new projects. (and it’s good for existing projects, even big established ones, but choosing to apply it to an existing code base gets into bikeshedding territory so proceed with caution!)
It’s only for Python, but if you have similar auto-formatters for other languages that you love, let me know! I’d love to have some to recommend to my colleagues at work who focus on other languages.
comments
Real Python: The Real Python Podcast – Episode #222: Using Virtual Environments in Docker & Comparing Python Dev Tools
Should you use a Python virtual environment in a Docker container? What are the advantages of using the same development practices locally and inside a container? Christopher Trudeau is back on the show this week, bringing another batch of PyCoder's Weekly articles and projects.
[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]
Python GUIs: Introduction to the QGraphics framework — Creating vector interfaces using the QGraphics View framework
The Qt Graphics View Framework allows you to develop fast and efficient 2D vector graphic scenes. Scenes can contain millions of items, each with their own features and behaviors. By using the Graphics View via PySide6 you get access to this highly performant graphics layer in Python. Whether you're integrating vector graphics views into an existing PySide6 application, or simply want a powerful vector graphics interface for Python, Qt's Graphics View is what you're looking for.
Some common uses of the Graphics View include data visualization, mapping applications, 2D design tools, modern data dashboards and even 2D games.
In this tutorial we'll take our first steps looking at the Qt Graphics View framework, building a scene with some simple vector items. This will allow us to familiarize ourselves with the API and coordinate system, which we'll use later to build more complex examples.
Table of Contents- The Graphics View Framework
- A simple scene
- Another way to create objects.
- Building a more complex scene
- Adding graphics views to Qt layouts
The Graphics View framework consists of 3 main parts QGraphicsView, QGraphicsScene, and QGraphicsItem, each with different responsibilities.
The framework can be interpreted using the Model-View paradigm, with the QGraphicsScene as the Model and the QGraphicsView as the View. Each scene can have multiple views. The QGraphicsItems within the scene can be considered as items within the model, holding the visual data that the scene combines to define the complete image.
QGraphicsScene is the central component that glues everything together. It acts as a whiteboard on which all items are drawn (circles, rectangles, lines, pixmaps, etc). The QGraphicsView has the responsibility of rendering a given scene -- or part of it, with some transformation (scaling, rotating, shearing) -- to display it to the user. The view is a standard Qt widget and can be placed inside any Qt layout.
QGraphicsScene provides some important functionalities out of the box, so we can use them to develop advanced applications without struggling with low-level details. For example --
- Collision Detection, detect a graphics item is collided with another item.
- Item Selection, gives us the ability to deal with multiple items at the same time, for example, the user can select multiple items, and when pressing delete, a function asks the scene to give the list for all selected items, and then delete them.
- Items discovery, the scene can tell us what items are present (or part of them) at a specific point or inside some defined region, for example, if the user adds an item that intersects with a forbidden area, the program will detect them and give them another (mostly red) color.
- Events Propagation, the scene receives the events and then propagates them to items.
To define a QGraphicsScene you define it's boundaries or sceneRect which defines the x & y origins and dimensions of the scene. If you don't provide a sceneRect it will default to the minimum bounding rectangle for all child items -- updating as items are added, moved or removed. This is flexible but less efficient.
Items in the scene are represented by QGraphicsItem objects. These are the basic building block of any 2D scene, representing a shape, pixmap or SVG image to be displayed in the scene. Each item has a relative position inside the sceneRect and can have different transformation effects (scale, translate, rotate, shear).
Finally, the QGraphicsView is the renderer of the scene, taking the scene and displaying it -- either wholly or in part -- to the user. The view itself can have transformations (scale, translate, rotate and shear) applied to modify the display without affecting the underlying scene. By default the view will forward mouse and keyboard events to the scene allowing for user interaction. This can be disabled by calling view.setInteractive(False).
A simple sceneLet's start by creating a simple scene. The following code creates QGraphicsScene, defining a 400 x 200 scene, and then displays it in a QGraphicsView.
python import sys from PySide6.QtWidgets import QGraphicsScene, QGraphicsView, QApplication app = QApplication(sys.argv) # Defining a scene rect of 400x200, with it's origin at 0,0. # If we don't set this on creation, we can set it later with .setSceneRect scene = QGraphicsScene(0, 0, 400, 200) view = QGraphicsView(scene) view.show() app.exec()If you run this example you'll see an empty window.
The empty graphics scene, shown in a QGraphicsView window.
Not very exciting yet -- but this is our QGraphicsView displaying our empty scene.
As mentioned earlier, QGraphicsView is a widget. In Qt any widgets without a parent display as windows. This is why our QGraphicsView appears as a window on the desktop.
Adding itemsLet's start adding some items to the scene. There are a number of built-in graphics items which you can customize and add to your scene. In the example below we use QGraphicsRectItem which draws a rectangle. We create the item passing in it's dimensions, and then set it's position pen and brush before adding it to the scene.
python import sys from PySide6.QtWidgets import QGraphicsScene, QGraphicsView, QGraphicsRectItem, QApplication from PySide6.QtGui import QBrush, QPen from PySide6.QtCore import Qt app = QApplication(sys.argv) # Defining a scene rect of 400x200, with it's origin at 0,0. # If we don't set this on creation, we can set it later with .setSceneRect scene = QGraphicsScene(0, 0, 400, 200) # Draw a rectangle item, setting the dimensions. rect = QGraphicsRectItem(0, 0, 200, 50) # Set the origin (position) of the rectangle in the scene. rect.setPos(50, 20) # Define the brush (fill). brush = QBrush(Qt.red) rect.setBrush(brush) # Define the pen (line) pen = QPen(Qt.cyan) pen.setWidth(10) rect.setPen(pen) scene.addItem(rect) view = QGraphicsView(scene) view.show() app.exec()Running the above you'll see a single, rather ugly colored, rectangle in the scene.
A single rectangle in the scene
Adding more items is simply a case of creating the objects, customizing them and then adding them to the scene. In the example below we add an circle, using QGraphicsEllipseItem -- a circle is just an ellipse with equal height and width.
python import sys from PySide6.QtWidgets import QGraphicsScene, QGraphicsView, QGraphicsRectItem, QGraphicsEllipseItem, QApplication from PySide6.QtGui import QBrush, QPen from PySide6.QtCore import Qt app = QApplication(sys.argv) # Defining a scene rect of 400x200, with it's origin at 0,0. # If we don't set this on creation, we can set it later with .setSceneRect scene = QGraphicsScene(0, 0, 400, 200) # Draw a rectangle item, setting the dimensions. rect = QGraphicsRectItem(0, 0, 200, 50) # Set the origin (position) of the rectangle in the scene. rect.setPos(50, 20) # Define the brush (fill). brush = QBrush(Qt.red) rect.setBrush(brush) # Define the pen (line) pen = QPen(Qt.cyan) pen.setWidth(10) rect.setPen(pen) ellipse = QGraphicsEllipseItem(0, 0, 100, 100) ellipse.setPos(75, 30) brush = QBrush(Qt.blue) ellipse.setBrush(brush) pen = QPen(Qt.green) pen.setWidth(5) ellipse.setPen(pen) # Add the items to the scene. Items are stacked in the order they are added. scene.addItem(ellipse) scene.addItem(rect) view = QGraphicsView(scene) view.show() app.exec()The above code will give the following result.
A scene with two items
The order you add items affects the stacking order in the scene -- items added later will always appear on top of items added first. However, if you need more control you can set the stacking order using .setZValue.
python ellipse.setZValue(500) rect.setZValue(200)Now the circle (ellipse) appears above the rectangle.
Using Zvalue to order items in the scene
Try experimenting with setting the Z value of the two items -- you can set it before or after the items are in the scene, and can change it at any time.
Z in this context refers to the Z coordinate. The X & Y coordinates are the horizontal and vertical position in the scene respectively. The Z coordinate determines the relative position of items toward the front and back of the scene -- coming "out" of the screen towards the viewer.
There are also the convenience methods .stackBefore() and .stackAfter() which allow you to stack your QGraphicsItem behind, or in front of another item in the scene.
python ellipse.stackAfter(rect) Making items moveableOur two QGraphicsItem objects are currently fixed in position where we place them, but they don't have to be! As already mentioned Qt's Graphics View framework allows items to respond to user input, for example allowing them to be dragged and dropped around the scene at will. Simple functionality like is actually already built in, you just need to enable it on each QGraphicsItem. To do that we need to set the flag QGraphicsItem.GraphicsItemFlags.ItemIsMoveable on the item.
The full list of graphics item flags is available here.
python import sys from PySide6.QtWidgets import QGraphicsScene, QGraphicsView, QGraphicsItem, QGraphicsRectItem, QGraphicsEllipseItem, QApplication from PySide6.QtGui import QBrush, QPen from PySide6.QtCore import Qt app = QApplication(sys.argv) # Defining a scene rect of 400x200, with it's origin at 0,0. # If we don't set this on creation, we can set it later with .setSceneRect scene = QGraphicsScene(0, 0, 400, 200) # Draw a rectangle item, setting the dimensions. rect = QGraphicsRectItem(0, 0, 200, 50) # Set the origin (position) of the rectangle in the scene. rect.setPos(50, 20) # Define the brush (fill). brush = QBrush(Qt.red) rect.setBrush(brush) # Define the pen (line) pen = QPen(Qt.cyan) pen.setWidth(10) rect.setPen(pen) ellipse = QGraphicsEllipseItem(0, 0, 100, 100) ellipse.setPos(75, 30) brush = QBrush(Qt.blue) ellipse.setBrush(brush) pen = QPen(Qt.green) pen.setWidth(5) ellipse.setPen(pen) # Add the items to the scene. Items are stacked in the order they are added. scene.addItem(ellipse) scene.addItem(rect) ellipse.setFlag(QGraphicsItem.ItemIsMovable) view = QGraphicsView(scene) view.show() app.exec()In the above example we've set ItemIsMovable on the ellipse only. You can drag the ellipse around the scene -- including behind the rectangle -- but the rectangle itself will remain locked in place. Experiment with adding more items and configuring the moveable status.
If you want an item to be selectable you can enable this by setting the ItemIsSelectable flag, for example here using .setFlags() to set multiple flags at the same time.
python ellipse.setFlags(QGraphicsItem.ItemIsMovable | QGraphicsItem.ItemIsSelectable)If you click on the ellipse you'll now see it surrounded by a dashed line to indicate that it is selected. We'll look at how to use item selection in more detail in a later tutorial.
A selected item in the scene, highlighted with dashed lines
Another way to create objects.So far we've been creating items by creating the objects and then adding them to the scene. But you can also create an object in the scene directly by calling one of the helper methods on the scene itself, e.g. scene.addEllipse(). This creates the object and returns it so you can modify it as before.
python import sys from PySide6.QtWidgets import QGraphicsScene, QGraphicsView, QGraphicsRectItem, QApplication from PySide6.QtGui import QBrush, QPen from PySide6.QtCore import Qt app = QApplication(sys.argv) scene = QGraphicsScene(0, 0, 400, 200) rect = scene.addRect(0, 0, 200, 50) rect.setPos(50, 20) # Define the brush (fill). brush = QBrush(Qt.red) rect.setBrush(brush) # Define the pen (line) pen = QPen(Qt.cyan) pen.setWidth(10) rect.setPen(pen) view = QGraphicsView(scene) view.show() app.exec()Feel free to use whichever form you find most comfortable in your code.
You can only use this approach for the built-in QGraphicsItem object types.
Building a more complex sceneSo far we've built a simple scene using the basic QGraphicsRectItem and QGraphicsEllipseItem shapes. Now let's use some other QGraphicsItem objects to build a more complex scene, including lines, text and QPixmap (images).
python from PySide6.QtCore import QPointF, Qt from PySide6.QtWidgets import QGraphicsRectItem, QGraphicsScene, QGraphicsView, QApplication from PySide6.QtGui import QBrush, QPainter, QPen, QPixmap, QPolygonF import sys app = QApplication(sys.argv) scene = QGraphicsScene(0, 0, 400, 200) rectitem = QGraphicsRectItem(0, 0, 360, 20) rectitem.setPos(20, 20) rectitem.setBrush(QBrush(Qt.red)) rectitem.setPen(QPen(Qt.cyan)) scene.addItem(rectitem) textitem = scene.addText("QGraphics is fun!") textitem.setPos(100, 100) scene.addPolygon( QPolygonF( [ QPointF(30, 60), QPointF(270, 40), QPointF(400, 200), QPointF(20, 150), ]), QPen(Qt.darkGreen), ) pixmap = QPixmap("cat.jpg") pixmapitem = scene.addPixmap(pixmap) pixmapitem.setPos(250, 70) view = QGraphicsView(scene) view.setRenderHint(QPainter.Antialiasing) view.show() app.exec()If you run the example above you'll see the following scene.
Scene with multiple items including a rectangle, polygon, text and a pixmap.
Let's step through the code looking at the interesting bits.
Polygons are defined using a series of QPointF objects which give the coordinates relative to the items position. So, for example if you create a polygon object with a point at 30, 20 and then move this polygon object X & Y coordinates 50, 40 then the point will be displayed at 80, 60 in the scene.
Points inside an item are always relative to the item itself, and item coordinates are always relative to the scene -- or the item's parent, if it has one. We'll take a closer look at the Graphics View coordinate system in the next tutorial.
To add an image to the scene we can open it from a file using QPixmap(). This creates a QPixmap object, which can then in turn add to the scene using scene.addPixmap(pixmap). This returns a QGraphicsPixmapItem which is the QGraphicsItem type for the pixmap -- a wrapper than handles displaying the pixmap in the scene. You can use this object to perform any changes to item in the scene.
The multiple layers of objects can get confusing, so it's important to choose sensible variable names which make clear the distinction between, e.g. the pixmap itself and the pixmap item that contains it.
Finally, we set the flag RenderHint,Antialiasing on the view to smooth the edges of diagonal lines. You almost always want to enable this on your views as otherwise any rotated objects will look very ugly indeed. Below is our scene without antialiasing enabled, you can see the jagged lines on the polygon.
Scene with antialiasing disabled.
Antialiasing has a (small) performance impact however, so if you are building scenes with millions of rotated items it may in some cases make sense to turn it off.
Adding graphics views to Qt layoutsThe QGraphicsView is subclassed from QWidget, meaning it can be placed in layouts just like any other widget. In the following example we add the view to a simple interface, with buttons which perform a basic effect on the view -- raising and lowering selected item's ZValue. This has the effect of allowing us to move items in front and behind other objects.
The full code is given below.
python import sys from PySide6.QtCore import Qt from PySide6.QtGui import QBrush, QPainter, QPen from PySide6.QtWidgets import ( QApplication, QGraphicsEllipseItem, QGraphicsItem, QGraphicsRectItem, QGraphicsScene, QGraphicsView, QHBoxLayout, QPushButton, QSlider, QVBoxLayout, QWidget, ) class Window(QWidget): def __init__(self): super().__init__() # Defining a scene rect of 400x200, with it's origin at 0,0. # If we don't set this on creation, we can set it later with .setSceneRect self.scene = QGraphicsScene(0, 0, 400, 200) # Draw a rectangle item, setting the dimensions. rect = QGraphicsRectItem(0, 0, 200, 50) rect.setPos(50, 20) brush = QBrush(Qt.red) rect.setBrush(brush) # Define the pen (line) pen = QPen(Qt.cyan) pen.setWidth(10) rect.setPen(pen) ellipse = QGraphicsEllipseItem(0, 0, 100, 100) ellipse.setPos(75, 30) brush = QBrush(Qt.blue) ellipse.setBrush(brush) pen = QPen(Qt.green) pen.setWidth(5) ellipse.setPen(pen) # Add the items to the scene. Items are stacked in the order they are added. self.scene.addItem(ellipse) self.scene.addItem(rect) # Set all items as moveable and selectable. for item in self.scene.items(): item.setFlag(QGraphicsItem.ItemIsMovable) item.setFlag(QGraphicsItem.ItemIsSelectable) # Define our layout. vbox = QVBoxLayout() up = QPushButton("Up") up.clicked.connect(self.up) vbox.addWidget(up) down = QPushButton("Down") down.clicked.connect(self.down) vbox.addWidget(down) rotate = QSlider() rotate.setRange(0, 360) rotate.valueChanged.connect(self.rotate) vbox.addWidget(rotate) view = QGraphicsView(self.scene) view.setRenderHint(QPainter.Antialiasing) hbox = QHBoxLayout(self) hbox.addLayout(vbox) hbox.addWidget(view) self.setLayout(hbox) def up(self): """ Iterate all selected items in the view, moving them forward. """ items = self.scene.selectedItems() for item in items: z = item.zValue() item.setZValue(z + 1) def down(self): """ Iterate all selected items in the view, moving them backward. """ items = self.scene.selectedItems() for item in items: z = item.zValue() item.setZValue(z - 1) def rotate(self, value): """ Rotate the object by the received number of degrees """ items = self.scene.selectedItems() for item in items: item.setRotation(value) app = QApplication(sys.argv) w = Window() w.show() app.exec()If you run this, you will get a window like that shown below. By selecting an item in the graphics view and then clicking either the "Up" or "Down" button you can move items up and down within the scene -- behind and in front of one another. The items are all moveable, so you can drag them around too. Clicking on the slider will rotate the currently selected items by the set number of degrees.
A graphics scene with some custom controls
The raising and lowering is handled by our custom methods up and down, which work by iterating over the currently selected items in the scene -- retrieved using scene.selectedItems() and then getting the items z value and increasing or decreasing it respectively.
python def up(self): """ Iterate all selected items in the view, moving them forward. """ items = self.scene.selectedItems() for item in items: z = item.zValue() item.setZValue(z + 1)While rotation is handled using the item.setRotation method. This receives the current angle from the QSlider and again, applies it to any currently selected items in the scene.
python def rotate(self, value): """ Rotate the object by the received number of degrees. """ items = self.scene.selectedItems() for item in items: item.setRotation(value)Take a look at the QGraphicsItem documentation for some other properties you can control with widgets and try extending the interface to allow you to change them dynamically.
Hopefully this quick introduction to the Qt Graphics View framework has given you some ideas of what you can do with it. In the next tutorials we'll look at how events and user interaction can be handled on items and how to create custom & compound items for your own scenes.
Matt Layman: Postgres to SQLite - Building SaaS #204
PyCharm: Django Project Ideas
Ready to get started on your Django project? Whether you want to build a personal project, improve your portfolio, or just experiment with a new technology, Django provides the perfect foundation.
We’ve compiled a list of Django project ideas that will help you expand your competence, whether you’re new to the framework or looking to advance your existing skills.
In this guide, we’ll explore a range of Django project ideas to help you get hands-on experience, ranging from simple apps to more advanced, full-stack applications.
When should I use Django?Known as the “web framework for perfectionists with deadlines”, Django is a great choice for building robust, production-ready websites, apps, or services.
It’s an open-source and highly versatile Python web framework that can be used for everything from blogs and social media platforms to e-commerce sites, content management systems, and fitness trackers.
First released in 2005, Django continues to receive regular updates and enjoys a considerable following. Its “batteries included” design means you get what you need to build a full-stack web app right out of the box. You can also pair Django with a front-end JavaScript framework for projects that demand richly interactive user interfaces.
- Learn more about Django in our blog, including its key components and benefits.
- Still trying to figure out whether Django is the right framework for you? Read our comparison of Django and Flask – the two most popular Python web frameworks.
Working on a real-world project is one of the best ways to get to grips with Django. You can start with something simple and extend it as you learn more about the framework. In the process, you’ll develop your skills and build a portfolio of work showcasing your abilities.
Stuck for ideas? Previous projects (both professional and personal), forums, dev meetups and hackathons, as well as platforms like GitHub, can all provide sources of inspiration.
GitHub is also useful for hosting and collaborating on open-source projects – this is where the source code or design documents are made publicly available for anyone to access, modify, and distribute. You can use and build upon various software, making them a great jumping-off point for a Django project.
Some GitHub open-source Django projects include:
- Django packages: a directory of reusable apps, sites, tools, and more for your Django projects.
- Django project: source code for djangoproject.com.
- Django social: code for a social network or community site built using Django.
Are you unfamiliar with a particular area, such as routing or database design? You could choose to design a project that addresses this knowledge gap while learning Django simultaneously.
Django project ideas for beginnersIf this is your first time building with Django, look no further. We’ve compiled a list of project ideas that are ideal for anyone using Django for the first time. These will help you find your feet as you explore what Django offers.
Before you start, reading this Django tutorial for beginners is useful. It walks through building a simple but non-trivial project by starting with a single file. The tutorial is an excellent starting point for anyone new to Django, as it introduces core concepts and helps you build a functional project from the ground up.
Once you’re familiar with Django’s principal elements and are comfortable building within the framework, you can get going with these more dynamic yet straightforward projects.
Air temperature appThis tutorial will walk you through creating a simple Django app using PyCharm that displays the current air temperature at your location. The app also allows users to explore weather conditions at random locations to add interactivity.
By following this guide, you’ll learn to:
- Set up a Django project.
- Develop models, views, and templates.
- Make and process API calls.
- Connect to and populate databases.
This hands-on task will give you practical experience with core Django concepts and show how PyCharm can help you develop more efficiently while working with Django. It’s a great place to begin building web applications and sets you up for further starter projects.
Follow the step-by-step tutorial BlogRequired tech stack:
- Django admin: for managing blog posts.
- Django templates: for rendering HTML pages.
- TinyMCE or CKEditor (optional): for rich text editing.
Building your own blogging platform with Django is a great way to cover the basics of create, read, update, and delete (CRUD), setting up routes, and serving a site locally. To keep things simple, use the Django Admin site to add and update blog posts. To explore further, extend the basic blog functionality by implementing tags and filters, adding a search option, or enabling comments.
We highly recommend the Django Girls Tutorial for beginners, which takes you through creating a small blog.
To-do list appRequired tech stack:
- Django templates: for rendering the UI.
- Single-page applications (SPA)/JavaScript: for updating the status of pages and components without reloading the page.
A simple task list with an option to check items off when complete is an excellent way to learn the basics of developing with Django. You’ll need a UI to add tasks and update their status and a simple database to record each entry. You can also add the ability to record due dates or set priorities.
Recipe organizerRequired tech stack:
- Django templates: for rendering the frontend.
- Django ORM: for database interactions.
- JavaScript (optional): for additional security.
Familiarize yourself with Django’s ORM (object-relational mapper) and database support by building an app to keep track of your favorite recipes. Add a web-based frontend with options to filter recipes by category, ingredients, and user ratings so you can easily browse for inspiration.
Quiz appRequired tech stack:
- Django templates: for rendering the UI.
- Django ORM: for managing the question bank and user scores.
- JavaScript: for interactive quiz elements.
Create a quiz app or website to familiarize yourself with each layer of Django’s architecture. Build a question bank, give players a simple UI to select their answer, and calculate the score. Enhance the functionality by sorting questions into categories and adding options to choose topics or change the number of questions asked. You could also add a leaderboard to celebrate your highest scorers.
Authentication systemRequired tech stack:
- Django built-in authentication: for handling login, registration, and password resetting.
- Email service: for email validation and password reset (e.g. SMTP server).
Login systems are a feature of most websites and apps. Fortunately, adding authentication and authorization to a web app is easier with Django’s built-in authentication system. Creating one as a practice project helps familiarize yourself with the functionality and provides a reusable pattern for future projects. Don’t forget to include key features such as email validation and a password reset option.
URL shortenerRequired tech stack:
- Django templates: for the frontend.
- Django ORM: for storing URLs.
- Bitly API (optional): if using an external shortening service.
You can approach this project in a couple of ways, depending on your interests. One option is to build a simple app that sends requests to an existing URL-shortening service, such as Bitly’s API. Alternatively, create your own service by generating shortened URLs, storing the URLs in a database, and defining routing logic to match incoming requests to the appropriate URL. Add a simple frontend so you can generate new shortened URLs on demand.
Expense trackerRequired tech stack:
- Django templates: for the UI.
- Django ORM: for managing expense data.
- Chart.js or D3.js: for visualizing expense trends.
Expense management apps provide an opportunity to define different data models for expenses, such as invoices, payroll, and cash expenditures. As well as creating forms for users to enter the costs, you might have existing data to import. Consider creating graphs to show expense trends in each category.
Simple social networkRequired tech stack:
- Django templates: for rendering the UI.
- Django ORM: for managing user data and posts.
- Media storage: for images and videos (e.g. Amazon S3 or local storage).
- JavaScript: For interactive elements.
Use Django to create your version of Instagram or Facebook and learn about user account management, security, and privacy along the way. Users will need to be able to manage connections, share images and videos, and view each other’s posts.
Personal portfolioRequired tech stack:
- Django templates: for the frontend.
- Django ORM: for managing project data.
- Deployment tools: for deploying the website (e.g. Heroku, AWS, or DigitalOcean).
Sharing personal projects on your website enables you to showcase your skills as a developer. Create an engaging website for users to browse your work and view the source code. This project will also allow you to try deploying Django to a production web server.
Learn how to build a personal portfolio using Django with this helpful guide.
Event calendarRequired tech stack:
- Django templates: for rendering the frontend.
- JavaScript libraries: for interactive calendar functionalities (e.g. FullCalendar).
- Django ORM: for storing event data.
An enjoyable beginner project with a frontend focus, building an event calendar gives you a reason to work with Django’s built-in templates or Jinja2. You can also combine Django with JavaScript libraries to make your calendar interactive.
Survey toolRequired tech stack:
- Django templates: for the frontend.
- Django forms: for creating and submitting surveys.
- Django ORM: for storing survey data.
- Chart.js or D3.js: for visualizing survey results.
An online survey tool requires UIs for building and responding to surveys, storage of the responses, and logic to aggregate answers. This project is an ideal opportunity to try out Django forms. If you want to extend it, add user authentication and/or visualizations for the survey data.
Advanced Django projectsIf you’re familiar with Django or looking for more advanced project ideas, the following suggestions are for you. Get ideas to help you use more of Django’s rich capabilities and grow your developer skills.
Multi-user classifieds siteBuild a site where multiple users can post classified ads. You’ll need to create pages for listing, creating, and editing ads. Since the site supports multiple users, you’ll also need to create and manage user accounts, manage permissions so only the ad owner can edit their ads, and create paginated ad listings to avoid overloading the browser.
For the full experience, include a self-sign-up page and password reset management. For additional practice, consider adding an API to the site and/or using a frontend library like HTMX or Vue.js to make your pages more dynamic.
The book “Django In Action” guides you through building a musicians’ classified ad site called RiffMates. It also covers deeper topics such as testing, management commands, and Django power tools.
Chat appBuilding a messaging app is an excellent way to explore real-time two-way communication using WebSockets and Django Channels.
You’ll also need to create and manage user accounts, add contacts, and view message history. You can model the functionality on existing chat platforms like WhatsApp, X, or Telegram. Adding support for audio messages helps to extend your project further.
This tutorial on Django Channels will help you create your chat app, going beyond the basics for a more comprehensive application. For an extra challenge, consider incorporating WebRTC and webcam video chat.
E-commerce storeBuilding an online retail site is a sizable project that demonstrates various skills. In addition to a database of products and a website that lets customers browse and search, you’ll need to handle user accounts, shopping carts, payments, and order updates.
There is plenty to consider, from generating product image thumbnails to managing abandoned checkout processes. This project will help you understand advanced Django features like signals, middleware, and caching.
Medical records systemThis project requires you to consider user authentication and authorization to ensure only those with the correct permissions can view a patient’s records.
When defining your templates, ensure you present the data reverse chronologically (most recent first). You will also need to provide forms for authorized users to add new patients and update patients’ records.
You may even connect to another system to import test results and associate them with the right patient, integrating third-party APIs for extended functionality.
Financial dashboardDashboards make fantastic projects for combining Django with a frontend JavaScript framework. You can pull in data from an API or add an option to import data manually from .csv files. For real-time data, use Django Channels.
Leverage Django to manipulate the data in different ways and JavaScript to create visually appealing UIs. This project can also integrate with data visualization libraries such as D3.js or Chart.js for dynamic, interactive charts.
Property management systemBuilding a system to keep track of rented properties, record rent payments, and manage maintenance tasks and inspections is ideal for Django.
This project gives you a chance to work with multiple data sources, implement complex business logic, and handle common functionality such as user authentication and notifications. Consider using the Django REST framework to create APIs that mobile apps or other systems can consume.
Interactive dashboardsDeveloping an interactive dashboard with Django is perfect for visualizing data from various sources. It also allows you to handle large datasets, perform real-time data updates, and integrate frontend visualization libraries with Django.
Use libraries like Plotly or Bokeh to create dynamic charts and graphs. Implement data filtering, time range selection, and report exporting. Add user authentication to provide personalized dashboards based on roles and permissions.
Stock exchange analysisBuild a stock market analysis platform using Django, a project that combines data science, machine learning, and the Django REST framework. It also offers more practical experience in handling lots of real-time data.
Import historical stock prices, run technical analyses, and generate predictions using machine learning. Create RESTful APIs for data retrieval and analysis results, and integrate external APIs for real-time market data. Implement visualization tools to display trends, predictions, and alerts.
Processing large volumes of dataUse Django with Celery and Redis to process large datasets. This project will involve setting up task queues with Celery and managing them with Redis, helping you understand task scheduling and big data processing.
Implement features to handle server failures and ensure data integrity throughout the pipeline. Demonstrate how to scale the system by running Redis in cluster mode and balancing loads across multiple servers. Create dashboards to monitor task progress and performance metrics.
Generative AI RAG-based applicationDjango projects are a great way to gain practical experience working with language models. This project involves natural language processing and AI, helping to deepen your understanding.
Build a Django application for advanced AI-driven solutions using retrieval-augmented generation (RAG) techniques. Integrate pre-trained language models like GPT-3 or GPT-4 with a retrieval system to fetch relevant documents. Develop features for generating contextual responses, automated content creation, and personalized recommendations. Implement a feedback loop to continuously improve the system’s accuracy.
AIOps for server scalingTake on this assignment to help enhance your skills in AI, cloud computing, and automation.
Develop an AI-based system for predicting traffic and scaling servers automatically. Use machine learning models to analyze historical traffic data and forecast future loads. Integrate this system with cloud platforms like AWS or GCP to automatically provision and de-provision servers based on the predictions. Implement features for monitoring system performance, generating alerts, and providing dashboards for administrators.
Customized dashboard for MLOps pipelineCreate a dashboard to manage and monitor machine learning pipelines, integrating tools like TensorFlow or PyTorch with Django.
Allow users to track experiments, visualize training progress, and compare model performance. Implement features for managing datasets, configuring training parameters, and deploying models to production. Provide tools for monitoring model drift and triggering re-training when necessary.
By the end of the project, you should understand the end-to-end machine learning lifecycle and how to operationalize ML models using Django.
Location-based food recommendationLevel up your skills in recommendation systems, geolocation services, and user personalization. This task involves using machine learning algorithms to recommend food options based on user location and preferences.
Integrate with mapping services like Google Maps or OpenStreetMap to provide location-based search and routing. Implement user profiles to store preferences, dietary restrictions, and past interactions. Use collaborative filtering or content-based filtering techniques to generate recommendations. Provide a user-friendly interface to browse and rate food options.
Langchain-based projectsBuild applications utilizing Langchain for advanced natural language processing tasks.
Create use cases such as automated summarization, question answering, or text generation. Integrate with Django to provide a web-based interface for users to interact with the system. Implement features for fine-tuning models on specific domains, evaluating model performance, and giving real-time predictions.
Building these apps will help you explore the capabilities of state-of-the-art language models and how to integrate them with web applications.
Birthday message reminderDeveloping a birthday message reminder is a fantastic project for helping to understand chatbot development and automating workflows with Django. You will implement a system using ChatGPT to generate unique birthday messages and send them to employees via Slack.
Integrate with Slack’s API to send or direct messages to the appropriate channels. Use Django’s scheduling features to automate the message-sending process. Allow administrators to configure message templates, personalize messages based on employee data, and track message delivery.
Cloud server managementDeveloping cloud servers is an ideal way to build your skills in cloud computing, infrastructure as code, and DevOps practices. You could begin by creating and managing cloud servers using Django and Pulumi.
Allow users to provision and configure infrastructure as code, including virtual machines, databases, and networking resources. Implement features for monitoring resource usage, scaling infrastructure based on demand, and generating cost reports. Provide a web-based interface for administrators to manage cloud resources and view infrastructure status.
Ready to get started?We hope these project ideas have provided some inspiration to help you start building web apps with Django. Whatever your experience level, using an IDE optimized for your chosen language and framework makes software development more accessible and enjoyable.
PyCharm Professional is a Python IDE with built-in support for Django, Flask, FastAPI, and more. Intelligent coding assistance, streamlined navigation, and powerful debugging are just some of the features that PyCharm offers to help you code faster and smarter.
Using PyCharm, you will also benefit from:
- Advanced database management (including PostgreSQL, SQLite, Redis, and more).
- Frontend support for various languages and frameworks (such as JavaScript, React, Node.js, Tailwind CSS, and more).
- A built-in HTTP Client – essential for developing Django web applications.
- The Endpoints tool window – to visualize and navigate through your application’s endpoints.
Use PyCharm’s full-stack development features and database tools to help you build powerful Django projects.
Get started with PyCharm now More tutorials and guidesMike Driscoll: Textual – The New MaskedInput Widget
Textual v0.80.0 was released today, and it included the brand-new MaskedInput widget. If you have used other GUI toolkits, such as wxPython, you might already be familiar with a masked input widget. These widgets allow you to control the user’s input based on a mask string that the developer provides when instantiating the widget.
Let’s spend a few brief moments learning how this new widget works.
Getting the Latest TextualBefore you can use the MaskedInput widget, you must ensure you have version 0.80.0 or greater. If you have an older version, then you’ll need to upgrade by running the following command in your terminal:
python -m pip install textual --upgradeNow that you have a 0.80.0 or greater, you can use this great widget!
Using the MaskedInput WidgetThe Textual documentation has a credit card masked string for their demo application. Let’s start by looking at that example:
from textual.app import App, ComposeResult from textual.widgets import Label, MaskedInput class MaskedInputApp(App): # (1)! CSS = """ MaskedInput.-valid { border: tall $success 60%; } MaskedInput.-valid:focus { border: tall $success; } MaskedInput { margin: 1 1; } Label { margin: 1 2; } """ def compose(self) -> ComposeResult: yield Label("Enter a valid credit card number.") yield MaskedInput( template="9999-9999-9999-9999;0", # (2)! ) if __name__ == "__main__": app = MaskedInputApp() app.run()The template in this code says that you want four groups of four digits. The template automatically adds a dash after each four digits except the last one.
When you run this code, you will see something like this:
Note that when the widget is empty or not completely filled out, there is a red outline around it. The widget will ignore all keys except for number keys. So if you press A-Z or any special characters like semi-colon or question mark, the MasketInput widget will ignore them and nothing appears in the widget.
When you have entered four groups of four integers though, you will see the red outline turn green. Here’s an example:
Note that this code does NOT actually validate that these are working credit card numbers. It only validates that there four groups of four integers.
A more common mask would be to create something to accept phone numbers. Let’s take the code above and rewrite the mask and the label text accordingly:
from textual.app import App, ComposeResult from textual.widgets import Label, MaskedInput class MaskedInputApp(App): # (1)! CSS = """ MaskedInput.-valid { border: tall $success 60%; } MaskedInput.-valid:focus { border: tall $success; } MaskedInput { margin: 1 1; } Label { margin: 1 2; } """ def compose(self) -> ComposeResult: yield Label("Enter a valid phone number.") yield MaskedInput( template="(999)-999-9999;0", ) if __name__ == "__main__": app = MaskedInputApp() app.run()If you runt his code, the output it a little different, but the concept is the same:
The MaskedInput widget is using regular expressions to mask characters. If you look at the documentation you can see how it works. Following are a few examples from the documentation:
A [A-Za-z] Yes a [A-Za-z] No N [A-Za-z0-9] Yes n [A-Za-z0-9] No X [^ ] Yes x [^ ] No 9 [0-9] YesThis widget may get additional updates to include more refined regular expressions, so it is definitely best to review the documentation for the latest information on the masked templates and how they work.
Wrapping UpThe MaskedInput widget is a great addition to the Textual TUI toolkit. There are lots of great widgets included with Textual now. While there may not be as many as wxPython or PyQt, those projects have been around for a couple of decades and have had much more time to mature. You can create really amazing and neat applications in your terminal with Python and Textual. You should try it out today!
The post Textual – The New MaskedInput Widget appeared first on Mouse Vs Python.
Django Weblog: 2025 DSF Board Nominations
Nominations are open for the 2025 Django Software Foundation Board of Directors.
In 2023 we introduced a staggered term for directors. Of our 7 directors, there are 4 positions currently open, with each position serving for two years.
Decisions around the 2025 officer roles will be made during the meeting of the new board. You don’t need to specify which position you are nominating for.
As you know, the Board guides the direction of the marketing, governance and outreach activities of the Django community. We provide funding, resources, and guidance to Django events on a global level. Further we provide support to the Django community with an established Code of Conduct and make decisions and enforcement recommendations for violations. We work with our corporate and individual members to raise funds to help support our great community.
In order for our community to continue to grow and advance the Django Web framework, we need your help. The Board of Directors consists of seven volunteers who are elected to two year terms. This is an excellent opportunity to help advance Django. We can’t do it without volunteers, such as yourself. Anyone including current Board members, DSF Members, or the public at large can apply to the Board. It is open to all.
2025 DSF Board Nomination Form
If you are interested in helping to support the development of Django we’d enjoy receiving your application for the Board of Directors. Please fill out the 2025 DSF Board Nomination form by October 25, 2024 Anywhere on Earth to be considered.
If you have any questions about applying, the work, or the process in general please don’t hesitate to reach out via email to foundation@djangoproject.com.
Thank you for your time and we look forward to working with you in 2025.
The 2024 DSF Board of Directors.
Real Python: Python 3.13 Preview: A Modern REPL
One of Python’s strong points is its interactive capabilities. By running python you start the interactive interpreter, or REPL, which allows you to perform quick calculations or explore and experiment with your code. In Python 3.13, the interactive interpreter has been completely redesigned with new modern features.
Python’s REPL has remained largely unchanged for decades. Instead, alternative interpreters like IPython, bpython, and ptpython have addressed some of the built-in REPL’s shortcomings, providing more convenient interactive workflows for developers. As you’re about to learn, Python 3.13 brings many significant improvements to the interactive interpreter.
In this tutorial, you’ll:
- Run Python 3.13 and explore the new REPL
- Browse through the help system
- Work with multiline statements
- Paste code into your REPL session
- Navigate through your interpreter history
The upgraded REPL is just one of the new features coming in Python 3.13. You can read about all the changes in the what’s new section of Python’s changelog. Additionally, you can dig deeper into the work done on free threading and a Just-In-Time compiler.
Get Your Code: Click here to download the free sample code that shows you how to use some of the new features in Python 3.13.
A New Interactive Interpreter (REPL) in Python 3.13To try out the new REPL for yourself, you need to get your hands on a version of Python 3.13. Before the official release in October 2024, you can install a pre-release version. After October 2024, you should be able to install Python 3.13 through any of the regular channels.
A REPL, or a Read-Eval-Print Loop, is a program that allows you to work with code interactively. The REPL reads your input, evaluates it, and prints the result before looping back and doing the same thing again.
Note: To learn about the built-in REPL in Python and how it works in general, check out The Python Standard REPL: Try Out Code and Ideas Quickly.
In any version of Python, you can start this interactive shell by typing the name of your Python executable in your terminal. Typically, this will be python, but depending on your operating system and your setup, you may have to use something like py or python3 instead.
Once you start the REPL in Python 3.13, you’ll see a small but noticeable difference. The familiar Python interactive shell prompt, consisting of three right angle brackets (>>>), is now colored differently from the rest of the text:
The color difference indicates that the shell now supports color. In the new shell, color is mainly used to highlight output in tracebacks. If your terminal doesn’t display color, then the new REPL will automatically detect this and fall back to its plain, colorless display.
If you prefer to keep your interpreter free of color even when it’s supported, you can disable this new feature. One option is to set the new environment variable PYTHON_COLORS to 0:
Shell $ PYTHON_COLORS=0 python Python 3.13.0rc2 (main, Sep 13 2024, 17:09:27) [GCC 9.4.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> Copied!Setting PYTHON_COLORS=0 disables color in the REPL. If you set the environment variable to 1, you’ll get the colored prompt and output. However, since it’s the default, this is rarely necessary.
Before going any further, you’ll exit the REPL. As you may know, the old REPL, that you’ve used on Python 3.12 and earlier, has been widely commented on for the following idiosyncrasy:
Python >>> exit Use exit() or Ctrl-D (i.e. EOF) to exit Copied!The shell clearly understands your intention to end the session. Still, it makes you jump through hoops and add parentheses to your command. In Python 3.13, the REPL now understands special commands that you can write without any parentheses:
- exit or quit: Exit the interpreter
- help or F1: Access the help system
- clear: Clear the screen
Having these commands more easily available is a small thing, but it removes some friction when using the interactive interpreter. You can still use parentheses and type something like exit() if you prefer. These commands are not reserved though. That means that you could shadow them with variable assignments:
Python >>> exit = True >>> exit True >>> exit() Traceback (most recent call last): ... TypeError: 'bool' object is not callable >>> del exit >>> exit Copied!Here you create a variable named exit, effectively disabling the exit command. To end your REPL session, you can either delete the exit variable or use one of the alternative ways to exit the interpreter.
Note: Even with the new improvements, the built-in REPL is not as powerful as some of the third-party alternatives. If you’re already using any of these, there’s no immediate reason to revert back to the standard interactive interpreter.
The main advantage of the new REPL is that it’s installed together with Python. In other words, it’ll always be available for you. This is great if you find yourself in a situation where you can’t or don’t want to install a third-party library.
You can learn more about the alternative interactive interpreters in the following tutorials:
- Unlock IPython’s Magical Toolbox for Your Coding Journey
- Discover bpython: A Python REPL With IDE-Like Features
- Boost Your Coding Productivity With Ptpython
You can also read more about alternative REPLs in the guide to the standard REPL.
Read the full article at https://realpython.com/python313-repl/ »[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]
Mike Driscoll: JupyterLab 101 Kickstarter Stretch Goal
My Kickstarter for my latest Python book is still going on for another eight days. Now is a great time to pre-order the book as well as get my other Python books.
The project is fully funded, and I added a stretch goal.
Stretch GoalThe stretch goal is $5000 or 350 backers. If we reach either of those, I will create a video course version of the book and release it to all backers. I think being able to show JupyterLab in a video format may be an even better medium for teaching this type of topic, although the book may be better for quick browsing.
What You’ll LearnIn this book, you will learn how about the following:
- Installation and setup of JupyterLab
- The JupyterLab user interface
- Creating a Notebook
- Markdown in Notebooks
- Menus in JupyterLab
- Launching Other Applications (console, terminal, text files, etc)
- Distributing and Exporting Notebooks
- Debugging in JupyterLab
- Testing your notebooks
As a backer of this Kickstarter, you have some choices to make. You can receive one or more of the following, depending on which level you choose when backing the project:
- An early copy of JupyterLab 101 + all updates including the final version (ALL BACKERS)
- A signed paperback copy (If you choose the appropriate perk)
- Get all by Python courses hosted on Teach Me Python or another site (If you choose the appropriate perk)
- T-shirt with the book cover (If you choose the appropriate perk)
Get the book on Kickstarter today!
The post JupyterLab 101 Kickstarter Stretch Goal appeared first on Mouse Vs Python.