Planet Python
Talk Python to Me: #476: Unified Python packaging with uv
PyCoder’s Weekly: Issue #645 (Sept. 3, 2024)
#645 – SEPTEMBER 3, 2024
View in Browser »
This course covers two problems from introductory astronomy to help you play with some Python libraries. You’ll use NumPy, Matplotlib, and pandas to find planet conjunctions, and graph the best viewing times for a star.
REAL PYTHON course
Talk Python to Me interviews Seth Michael Larson and they talk about this year’s Python Language Summit. Learn all about what happened at the closed door session for core developers inside PyCon.
KENNEDY & LARSON podcast
With CodeRabbit, solve your indentation issues and security concerns. CodeRabbit doesn’t just point out issues; it suggests fixes and explains the reasoning behind the suggestion. Elevate code quality with AI-powered, context-aware reviews and 1-click fixes. Sign up for free today →
CODERABBIT sponsor
This is a plain language guide to every built-in function in Python, paired with a simple example that shows each function in action.
MATT LAYMAN
In this video course, you’ll learn how to sort Python dictionaries. By the end, you’ll be able to sort by key, value, or even nested attributes. But you won’t stop there—you’ll also measure the performance of variations when sorting and compare different key-value data structures.
REAL PYTHON course
The Template Method Pattern is when a base class is used to implement a series of steps, and subclasses can override one or more of those steps to customize the process. This article shows an example usage in Python and why you might want to implement it.
LANCE GOYKE
Experience the power of Edge AI—delivering lightning-fast, real-time processing where it matters. Optimize your applications with low latency, high efficiency, and unparalleled accuracy. Push performance beyond limits with Intel’s OpenVINO toolkit.
INTEL CORPORATION sponsor
The asyncio.gather() function allows you to run multiple co-routines concurrently. There are times when you want to control just how much concurrency you have though and this post shows you how to use a semaphore to do just that.
JASON BROWNLEE
Spreadsheets are a fascinating tool: you can both store and structure data, and include formulas that run computations on the contents of a sheet. James has written a spreadsheet engine, and this post talks about how it is done.
JAMES G
In version 24.2, pip learns to use system certificates by default, receives a handful of optimizations, and deprecates legacy (setup.py develop) editable installations. This article covers the changes and why they’ve been made.
RICHARD SI
Nate has been working on the CPython compiler, applying memory hardening guidelines recommended by OpenSSF’s Memory Safety Special Interest Group. This blog post talks about what was applied and how it should improve CPython.
NATE OHLSON
This is a comparison chart of the most common host providers that support Python serverless functions. It compares what features are supported, pricing, runtime limits, and more.
HAROLD MARTIN
A weird historical first in baseball recently reminded James about how often as programmers we map our data assuming a one-to-one relationship, and how often that’s a bad choice.
JAMES BENNETT
It has been a year since Mike joined the PSF as the Safety & Security Engineer for PyPI. This blog post talks about all the things he’s been involved with.
MIKE FIELDER
Official Python Developers Survey 2023 Results by Python Software Foundation and JetBrains: more than 25k responses from almost 200 countries.
JETBRAINS.COM
This article covers some of the lesser used parts of the Python standard library, including Deque, defaultdict, UserDict, and more.
TRICKSTER DEV
PYPI.ORG • Shared by Alex Towell
anacondacode: Execute Python Directly From Excel pare: Deploy Python Lambdas Alongside Your Web App django-admin-action-forms: Forms for Django Admin PromptMage Simplifies Managing LLM WorkflowsPROMPTMAGE.IO • Shared by Tobias Sterbak
Events EARL 2024 September 4 to September 6, 2024
DATACOVE.CO.UK
September 4, 2024
REALPYTHON.COM
September 5 to September 7, 2024
PYCON.EE
September 5, 2024
MEETUP.COM
September 5, 2024
SYPY.ORG
September 7, 2024
MEETUP.COM
Happy Pythoning!
This was PyCoder’s Weekly Issue #645.
View in Browser »
[ Subscribe to 🐍 PyCoder’s Weekly 💌 – Get the best Python news, articles, and tutorials delivered to your inbox once a week >> Click here to learn more ]
Mike Driscoll: ANN: JupyterLab 101 Kickstarter
My latest Python book is now available for pre-order on Kickstarter.
JupyterLab 101 mockupJupyterLab, the latest iteration of the Jupyter Notebook, is a versatile tool for sharing code in an easily understandable format.
Hundreds of thousands of people around the world use Jupyter Notebooks or variations of the Notebook architecture for any or all of the following:
- teaching
- presentations
- learning a computer language
- numerical simulations
- statistical modeling
- data visualization
- machine learning
- and much more!
Jupyter Notebooks can be emailed, put on GitHub, or run online. You may also add HTML, images, Markdown, videos, LaTeX, and custom MIME types to your Notebooks. Finally, Jupyter Notebooks support big data integration.
JupyterLab 101 will get you up to speed on the newest user interface for Jupyter Notebooks and the other tools that JupyterLab supports. You now have a tabbed interface that you can use to edit multiple Notebooks, open terminals in your browser, create a Python REPL, and more. JupyterLab also includes a debugger utility to help you figure out your coding issues.
Rest assured, JupyterLab supports all the same programming languages as Jupyter Notebook. The main difference lies in the user interface, which this guide will help you navigate effectively and efficiently.
After reading JupyterLab 101, you will be an expert in JupyterLab and produce quality Notebooks quickly!
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 ANN: JupyterLab 101 Kickstarter appeared first on Mouse Vs Python.
Real Python: Using Pydantic to Simplify Python Data Validation
Pydantic is a powerful data validation and settings management library for Python, engineered to enhance the robustness and reliability of your codebase. From basic tasks, such as checking whether a variable is an integer, to more complex tasks, like ensuring highly-nested dictionary keys and values have the correct data types, Pydantic can handle just about any data validation scenario with minimal boilerplate code.
In this video course, you’ll learn how to:
- Work with data schemas with Pydantic’s BaseModel
- Write custom validators for complex use cases
- Validate function arguments with Pydantic’s @validate_call
- Manage settings and configure applications with pydantic-settings
[ 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 ]
Django Weblog: Django security releases issued: 5.1.1, 5.0.9, and 4.2.16
In accordance with our security release policy, the Django team is issuing releases for Django 5.1.1, Django 5.0.9, and Django 4.2.16. These releases address the security issues detailed below. We encourage all users of Django to upgrade as soon as possible.
CVE-2024-45230: Potential denial-of-service vulnerability in django.utils.html.urlize()urlize and urlizetrunc were subject to a potential denial-of-service attack via very large inputs with a specific sequence of characters.
Thanks to MProgrammer for the report.
This issue has severity "moderate" according to the Django security policy.
CVE-2024-45231: Potential user email enumeration via response status on password resetDue to unhandled email sending failures, the django.contrib.auth.forms.PasswordResetForm class allowed remote attackers to enumerate user emails by issuing password reset requests and observing the outcomes.
To mitigate this risk, exceptions occurring during password reset email sending are now handled and logged using the django.contrib.auth logger.
Thanks to Thibaut Spriet for the report.
This issue has severity "low" according to the Django security policy.
Affected supported versions- Django main branch
- Django 5.1
- Django 5.0
- Django 4.2
Patches to resolve the issue have been applied to Django's main, 5.1, 5.0, and 4.2 branches. The patches may be obtained from the following changesets.
CVE-2024-45230: Potential denial-of-service vulnerability in django.utils.html.urlize()- On the main branch
- On the 5.1 branch
- On the 5.0 branch
- On the 4.2 branch
- On the main branch
- On the 5.1 branch
- On the 5.0 branch
- On the 4.2 branch
- Django 5.1.1 (download Django 5.1.1 | 5.1.1 checksums)
- Django 5.0.9 (download Django 5.0.9 | 5.0.9 checksums)
- Django 4.2.16 (download Django 4.2.16 | 4.2.16 checksums)
The PGP key ID used for this release is Natalia Bidart: 2EE82A8D9470983E
General notes regarding security reportingAs always, we ask that potential security issues be reported via private email to security@djangoproject.com, and not via Django's Trac instance, nor via the Django Forum, nor via the django-developers list. Please see our security policies for further information.
Python Bytes: #399 C will watch you in silence
Armin Ronacher: Progress
As I'm getting older a lot of my social circles are becoming ever more conservative. The focus shifts from building with ambition to fiercly protecting what one has achieved. Shifting the mind on protectionism makes one consider all that can cause damage. It puts the focus on the negative, it makes those negative thoughts feel much more significant than they are and one dwells on the past, instead of envisioning of what opportunity might lie ahead.
Yet, when we look back at history, it becomes clear that progress and fresh ideas tend to prevail over time. Not every new idea will succeed, but the overall trend is undeniable.
I believe that every day presents us with a choice: to step forward with courage and optimism or to cling to the status quo, even as it becomes increasingly untenable. Embracing new ideas carries inherent risks, but so does the refusal to explore them.
Right now we find ourselves slowly sliding down from our local maximum and some people try to pull you back up to where we were standing. On the other hand if you dare to run you will find a bigger and more impressive hill to scale. One that offers a better vantage point and when water rises undoubtedly the better place to be.
In today's political environment, the rhetoric is dominated by a yearning for the past. Some politicians will promote a return to fossil fuels and conservative social norms. They play into your fears of others and promote individualism at cost of the collective. The will uphold every bad news as a reason to fortify borders and strengthen nation-states.
But as time marches on, future generations will likely look back at these regressive inclinations and wonder how we could have been so short-sighted.
Hynek Schlawack: How to Ditch Codecov for Python Projects
Codecov’s unreliability breaking CI on my open source projects has been a constant source of frustration for me for years. I have found a way to enforce coverage over a whole GitHub Actions build matrix that doesn’t rely on third-party services.
Real Python: Generate Images With DALL·E and the OpenAI API
Describe any image, then let a computer create it for you. What sounded futuristic only a few years ago has become reality with advances in neural networks and latent diffusion models (LDM). DALL·E by OpenAI has made a splash through the amazing generative art and realistic images that people create with it.
OpenAI allows access to DALL·E through their API, which means that you can incorporate its functionality into your Python applications.
In this tutorial, you’ll:
- Get started using the OpenAI Python library
- Explore API calls related to image generation
- Create images from text prompts
- Create variations of your generated image
- Convert Base64 JSON responses to PNG image files
You’ll need some experience with Python, JSON, and file operations to breeze through this tutorial. You can also study up on these topics while you go along, as you’ll find relevant links throughout the text.
Get Your Code: Click here to download the free sample code that you’ll use to generate stunning images with DALL·E and the OpenAI API.
Take the Quiz: Test your knowledge with our interactive “Generate Images With DALL·E and the OpenAI API” quiz. You’ll receive a score upon completion to help you track your learning progress:
Interactive Quiz
Generate Images With DALL·E and the OpenAI APIIn this quiz, you'll test your understanding of generating images with DALL·E by OpenAI using Python. You'll revisit concepts such as using the OpenAI Python library, making API calls for image generation, creating images from text prompts, and converting Base64 strings to PNG image files.
Complete the Setup RequirementsIf you’ve seen what DALL·E can do and you’re eager to make its functionality part of your Python applications, then you’re in the right spot! In this first section, you’ll quickly walk through what you need to do to get started using DALL·E’s image creation capabilities in your own code.
Install the OpenAI Python LibraryConfirm that you’re running Python version 3.7.1 or higher, create and activate a virtual environment, and install the OpenAI Python library:
Windows PowerShell PS> python --version Python 3.12.5 PS> python -m venv venv PS> .\venv\Scripts\activate (venv) PS> python -m pip install openai Copied! Shell $ python --version Python 3.12.5 $ python -m venv venv $ source venv/bin/activate (venv) $ python -m pip install openai Copied!The openai package gives you access to the full OpenAI API. In this tutorial, you’ll focus on image generation, which lets you interact with DALL·E models to create and edit images from text prompts.
Get Your OpenAI API KeyYou need an API key to make successful API calls. Sign up with OpenAI and create a new project API key by clicking on the Dashboard menu and then API keys on the bottom left of the navigation menu:
On this page, you can create and manage your API keys, which allow you to access the service that OpenAI offers through their API. You can create and delete secret keys.
Click on Create new secret key to create a new API key, and copy the value shown in the pop-up window.
Note: OpenAI assigns your API usage through unique key values, so make sure to keep your API key private. The company calculates the pricing of requests to generate images on a per-image basis that depends on the model you use and the resolution of the output image.
Keep in mind that OpenAI’s API services and pricing policies may change. Be sure to check their website for up-to-date information about pricing and offers.
Always keep this key secret! Copy the value of this key so you can later use it in your project. You’ll only see the key value once.
Save Your API Key as an Environment VariableA quick way to save your API key and make it available to your Python scripts is to save it as an environment variable. Select your operating system to learn how:
Windows PowerShell (venv) PS> $ENV:OPENAI_API_KEY = "<your-key-value-here>" Copied! Shell (venv) $ export OPENAI_API_KEY="<your-key-value-here>" Copied! Read the full article at https://realpython.com/generate-images-with-dalle-openai-api/ »[ 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: How to Use Conditional Expressions With NumPy where()
In this quiz, you’ll test your understanding of How to Use Conditional Expressions With NumPy where().
By working through the questions, you’ll consolidate the knowledge you gained from the tutorial and take yourself beyond what you learned.
To answer some of the questions, you’ll need to do some research outside of the tutorial itself. Embrace this challenge because exploration can take you on a valuable learning journey.
[ 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: Generate Images With DALL·E and the OpenAI API
In this quiz, you’ll test your understanding of generating images with DALL·E by OpenAI API using Python.
By working through this quiz, you’ll revisit how to use the OpenAI Python library, make API calls related to image generation, create images from text prompts, create variations of an image, and convert Base64 strings to PNG image files.
[ 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 ]
Zato Blog: Airport integrations in Python
Did you know you can use Python as an integration platform for your airport systems? It's Open Source too.
From AODB, transportation, business operations and partner networks, to IoT, cloud and hybrid deployments, you can now use Python to build flexible, scalable and future-proof architectures that integrate your airport systems and support your master plan.
➤ Read here about what is possible and learn more why Python and Open Source are the right choice.
More blog posts➤Quansight Labs Blog: Towards Inclusive Documentation: the PyData Sphinx Theme, Before and After Accessibility Fixes
Tryton News: Newsletter August 2024
In the last month we focused on fixing bugs, improving the behaviour of things, speeding-up performance issues - building on the changes from our last release. We also added some new features which we would like to introduce to you in this newsletter.
For an in depth overview of the Tryton issues please take a look at our issue tracker or see the issues and merge requests filtered by label.
Changes for the User Sales, Purchases and ProjectsNow Tryton warns the user when submitting another complaint for the same origin.
Accounting, Invoicing and PaymentsNow Tryton allows to copy account moves from closed periods. When copy a move from a closed period we now set the period of the duplicate to the current period and the date to the actual date, while informing the user about the changes.
Stock, Production and ShipmentsOur sendcloud integration now adds package weight and warehouse as shipping method criteria.
User InterfaceNow we add a searcher for summary fields, which searches the whole description.
We’ve now merged the HTML edit and translate buttons into a single button that asks for the language before opening, with the current language pre-selected.
System Data and ConfigurationNow you can configure the license key for TinyMCE.
Now Tryton supports the UTR (United Kingdom Unique Taxpayer Reference) identifier.
New Documentation We've created or updated the following documentations:- Server Modules (ir, res, report): look-up changes…
- account_es_sii: look-up changes…
- account_invoice_correction: look-up changes…
- account_invoice_history: look-up changes…
- account_invoice_line_standalone: look-up changes…
- account_invoice_secondary_unit: look-up changes…
- account_payment_braintree: look-up changes…
- account_payment_sepa_cfonb: look-up changes…
- account_statement_coda: look-up changes…
We released bug fixes for the currently maintained long term support series
7.0 and 6.0, and for the penultimate series 7.2.
1 post - 1 participant
Carl Trachte: Scalable Vector Graphics Followup
A quick follow up to the last post:
1) I spelled scalable wrong in the title; hopefully it's fixed.
2) The svg partial logo that rendered in Blogger did not render on the Planet Python feed.
3) The logo svg is too big for Blogger. I need to find a way to make a smaller (file size) one.
One more try with svg in Blogger. The png DAG Hamilton logo first:
And one more attempt:
Carl Trachte: Scaleable Vector Graphics (svg) - Decomposing and Scaling Elements for Blogger
Last post I lamented the failure of any the svg graphs I had for DAG Hamilton workflows to render in Blogger. I set out to rectify this and have had some initial success.
My first attempt to get svg to show up in Blogger has the DAG Hamilton logo as its subject. My approach was to bring the svg elements down to the most basic primitives I could manage, then scale and translate their individual coordinates to bring them into the view.Fortunately, I was able to find an example from someone who had successfully rendered svg in Blogger. The subject blog post is eleven years old. It appears svg never totally caught on for some platforms. Nonetheless, I used this as a template, and, after some initial success, managed to render the Hamilton logo.
The post will step through the individual path components of the Hamilton logo (7) and show the code used to transform the coordinates to make the svg elements render at an appropriate location and size. The individual path elements that make up the logo are a large number of 3 coordinate bezier curves. The manner in which the curves listed is very format specific to the platform that created them. Unfortunately, I cannot recall which online png to svg converter I used to create the svg. Portable Inkscape kept crashing on the large png file, so I brute forced the issue by using an online converter.
The first element of the logo is basically a purple background for the whole logo. A gap or divit can be seen just left of center on the upper part. I'll cover the manual "fixing" of this further on.
Second path (orange)
Third path (deep purple)
Fourth path (yellow top point)
Fifth path (light orangey left leg were the star to face out from the screen)
Sixth path (medium purple little triangle in the center)
Seventh path (light orangey little triangle to the right of center)
Fixing that niggling divit on the top half of the logo (the thin subvertical line).
Final product. This is the one svg inline drawing I was able to show (content size limitations of Blogger?)
The full logo refuses to render (although I swear it did before). Well, at least there is an svg element showing up on the page (a purple star). <sigh> Another png . . .
The code. I'm not strong on HTML, but it was necessary to edit this post inline. As part of that exercise, I included the post outline generation as part of the script.
# python 3.12
# blog_post_make_outline.py
"""
Attempt to scale, translate, and inline svg
elements for display in Blogger.
"""
import re
import pprint
import sys
import copy
import xml.etree.ElementTree as ET
# REGEX patterns.
PATHPAT = r'[<]path[ ]d[=]["]'
MPAT = r'M([-]*[0-9]+[.]*[0-9]*)[ ]([-]*[0-9]+[.]*[0-9]*)[ ]'
# first bezier curve coord
BEZPAT = (r'C([-]*[0-9]+[.]*[0-9]*)[ ]([-]*[0-9]+[.]*[0-9]*)[ ]'
# second bezier curve coord
r'([-]*[0-9]+[.]*[0-9]*)[ ]([-]*[0-9]+[.]*[0-9]*)[ ]'
# third bezier curve coord
r'([-]*[0-9]+[.]*[0-9]*)[ ]([-]*[0-9]+[.]*[0-9]*)[ ]')
ZPAT = r'Z[ ]'
FILLPAT = (r'["] fill[=]["]([#][A-F0-9][A-F0-9][A-F0-9]'
r'[A-F0-9][A-F0-9][A-F0-9])["][ ]')
# transform="translate(4756.96875,109.12890625)"
# transform="translate(5619,4112)"/>
TRANSFORMPAT = (r'transform[=]["]translate[(]'
r'([-]*[0-9]+[.]*[0-9]*)[,]([-]*[0-9]+[.]*[0-9]*)[)]["]')
# Output formats/constants.
BEZFMT = ('C{0:.7f} {1:.7f} '
'{2:.7f} {3:.7f} '
'{4:.7f} {5:.7f} ')
PATHFMT_OPEN = '<path d="'
PATHFMT_1 = 'M{mstartx:.5f} {mstarty:.5f} {path:s} Z '
PATHFMT_2 = '" fill="{fill:s}" transform="translate({translatex:.7f},{translatey:.7f})"'
PATHFMT_CLOSE = ' />'
SVG_TAG_OPEN = ('<svg xmlns="http://www.w3.org/2000/svg" '
'xmlns:xlink="http://www.w3.org/1999/xlink" '
"width='500px' height='500px'>")
SVG_TAG_CLOSE = '</svg>'
def parse_path(pathstring):
"""
Capture path elements in a dictionary.
pathstring is the svg string for the path (one line).
For a path comprised entirely of bezier curves
in the format (all one line):
<ns0:path d="M0 0 C2.54601018 1.57157072 5.09846344 3.13131386 7.65625 4.68359375 C39.179 . . . 0 0 Z M-690.96875 4007.87109375 C-707.702 . . . Z " fill="#C3368C" transform="translate(4756.96875,109.12890625)" />
Returns dictionary.
"""
retval = {}
patpath = re.compile(PATHPAT)
match = patpath.match(pathstring)
startindex = match.span()[1]
mpat = re.compile(MPAT)
# MPAT
match = mpat.match(pathstring[startindex:])
mpatgroups = match.groups()
retval['mpatgroups'] = []
retval['mpatgroups'].append(mpatgroups)
startindex += match.span()[1]
bezpat = re.compile(BEZPAT)
zpat = re.compile(ZPAT)
retval['paths'] = []
while match:
pathpoints = []
# BEZPAT
match = bezpat.match(pathstring[startindex:])
while match:
# Sentinel.
if not match:
continue
pathpoints.append(match.groups())
startindex += match.span()[1]
match = bezpat.match(pathstring[startindex:])
retval['paths'].append(pathpoints)
# ZPAT
match = zpat.match(pathstring[startindex:])
startindex += match.span()[1]
# Then look for MPAT
# MPAT
match = mpat.match(pathstring[startindex:])
# If MPAT not there, work on color and transform.
if not match:
continue
startindex += match.span()[1]
retval['mpatgroups'].append(mpatgroups)
fillpat = re.compile(FILLPAT)
match = fillpat.match(pathstring[startindex:])
startindex += match.span()[1]
print('adding fill . . .')
fill = match.groups()[0]
retval['fill'] = fill
transformpat = re.compile(TRANSFORMPAT)
match = transformpat.match(pathstring[startindex:])
transform = match.groups()
print('adding transform . . .')
retval['transform'] = transform
return retval
def parse_all_paths(svgfilepath):
"""
Finds and parses all svg paths
within an svg file (very format
specific - bezier curves only).
Returns list of dictionaries, one
for each path line of the svg file.
"""
# Do all paths in Hamilton logo.
# Make list of dictionaries.
patpath = re.compile(PATHPAT)
with open(svgfilepath, 'r') as f:
paths = []
# Line one.
next(f)
# Line two.
next(f)
for linex in f:
print(PATHPAT)
print(linex[:30])
match = patpath.match(linex)
if not match:
break
paths.append(parse_path(linex))
return paths
def work_paths(paths, fcn):
"""
Apply an operation to all coordinates in
the bezier curve paths represented in
paths.
Also covers translate and fill.
paths is a list of dictionaries. Each
dictionary represents one line of an
svg file with a path made up of
bezier curves.
"""
# Return value.
newpaths = []
# M - start of path segment.
for pthx in paths:
newmpatgroups = []
for coordsx in pthx['mpatgroups']:
newmpatgroups.append([fcn(x) for x in coordsx])
newpaths.append({'mpatgroups':newmpatgroups})
# to Z - end of path segment.
# List of path dictionaries (paths).
for pthx, newpath in zip(paths, newpaths):
newpath['paths'] = []
# Each M to Z path segment.
for path in pthx['paths']:
curvegroup = []
for curve in path:
newcurve = [fcn(x) for x in curve]
curvegroup.append(newcurve)
newpath['paths'].append(curvegroup)
# transform and fill.
for pthx, newpath in zip(paths, newpaths):
newpath['transform'] = [fcn(x) for x in pthx['transform']]
newpath['fill'] = pthx['fill']
return newpaths
def translate_paths(paths, translation):
"""
From a two tuple of x, y translation,
adjust dictionary values for x, y
translation in each path in path
list accordingly.
Returns new dictionary
"""
# TRANSLATE
# ['mpatgroups', 'paths', 'fill', 'translate']
translated_paths = copy.deepcopy(paths)
for pathx in translated_paths:
pathx['transform'][0] += translation[0]
pathx['transform'][1] += translation[1]
return translated_paths
def get_path_strings(paths):
"""
From a list of path dictionaries,
builds one line strings for insertion
into svg file.
Returns list
"""
pathdict_2 = {'fill':None,
'translatex':None,
'translatey':None}
path_segment_dict = {'mstartx':None,
'mstarty':None,
'path':None}
pathstrings = []
for pathx in paths:
# Copy and initialize fill/translate dictionary.
fill_translate = copy.deepcopy(pathdict_2)
fill_translate['fill'] = pathx['fill']
fill_translate['translatex'] = pathx['transform'][0]
fill_translate['translatey'] = pathx['transform'][1]
# Zip together M and path segments.
path_segs = zip(pathx['mpatgroups'], pathx['paths'])
# For each path segment.
path_strings = []
for M, path_seg in path_segs:
seg_dict = copy.deepcopy(path_segment_dict)
seg_dict['mstartx'] = M[0]
seg_dict['mstarty'] = M[1]
# Build path segment string.
path_seg_strings = [BEZFMT.format(*coords) for coords in path_seg]
path = ''.join(path_seg_strings)
seg_dict['path'] = path
# Make final segment string with M (PATHFMT_1)
path_with_M = PATHFMT_1.format(**seg_dict)
path_strings.append(path_with_M)
path_all_together = ''.join(path_strings)
# Tack on fill/translate at end and beginning with d path flag.
# Add to pathstrings.
pathstrings.append(PATHFMT_OPEN +
path_all_together +
PATHFMT_2.format(**fill_translate) +
PATHFMT_CLOSE)
return pathstrings
paths = parse_all_paths('hamilton_logo_large.svg')
print('len(paths) = {0:d}'.format(len(paths)))
pprint.pprint([x for x in paths[0]])
paths = work_paths(paths, float)
scale = 0.035
scaleit = lambda x: scale * x
paths = work_paths(paths, scaleit)
# pprint.pprint(paths[0]['paths'][0])
paths = translate_paths(paths, (125, 0))
pathstrings = get_path_strings(paths)
# with open('test_paths.txt', 'w') as f:
# for pathx in pathstrings:
# print(pathx, file=f)
# print('\n\n', file=f)
GAP_FIX = "<polygon points='265 90.25, 245 143.75, 268 144.1, 295 90.25' style='fill: black;' />"
GAP_FIX_PROPER_COLOR = "<polygon points='265 90.25, 245 143.75, 268 144.1, 295 90.25' style='fill: #C3368C;' />"
TEXT = '<p>{0:s}</p>'
CODE = """
<p> </p><pre style="background: rgb(238, 238, 238); border-bottom-color: initial; border-bottom-style: initial; border-image: initial; border-left-color: initial; border-left-style: initial; border-radius: 10px; border-right-color: initial; border-right-style: initial; border-top-color: rgb(221, 221, 221); border-top-style: solid; border-width: 5px 0px 0px; color: #444444; font-family: "Courier New", Courier, monospace; font-stretch: inherit; font-variant-east-asian: inherit; font-variant-numeric: inherit; line-height: inherit; margin-bottom: 1.5em; margin-top: 0px; overflow-wrap: normal; overflow: auto; padding: 12px; vertical-align: baseline;"><span style="font-size: 13px;">{0:s}</span></pre>
"""
textlist = ['blah blah blah',
'blah blah blah again',
'blah blah blah a third time',
'blah blah blah a fourth time',
'blah blah blah a fifth time',
'blah blah blah a sixth time',
'blah blah blah a seventh time',
'fix divit',
'final product']
fixed_divit = copy.deepcopy(pathstrings)
fixed_divit.insert(1, GAP_FIX_PROPER_COLOR)
svglist = [pathstrings[0:1],
pathstrings[0:2],
pathstrings[0:3],
pathstrings[0:4],
pathstrings[0:5],
pathstrings[0:6],
pathstrings[0:],
pathstrings[0:] + [GAP_FIX],
fixed_divit]
with open('blogpost.html', 'w') as f:
for blah, svgels in zip(textlist, svglist):
print(TEXT.format(blah), file=f)
print(SVG_TAG_OPEN, file=f)
for svgelement in svgels:
print(svgelement, file=f)
print(SVG_TAG_CLOSE, file=f)
print(TEXT.format('More blah about code'), file=f)
print(CODE.format('>>> import this'), file=f)
print('Done')
Notes:
1) I had had good intentions of including a code box (the CODE string constant in the Python code) and I hit a bit of a wall. Not only is my code a mixed bag (this blog was always intended as a learning experience and a place for trying things out), it doesn't look good. We deal.
Which brings me to the point: you hear titles like front end developer, designer, website marketer etc. and think, "Well, it's kind of like art, kind of like coding . . . sort of creative." I now know, it's coding and it's thinking and it's grinding. All respect.
2) Steven Lott recently published a book that I bought (pdf). I have found it helpful. It's very pragmatic. I'm only about 15% of the way into it, but his treatment of regular expressions as just another tool not be scared of made me less tentative in my REGEX use (even if my REGEXes are far from elegant). Group capture with parens was really helpful for this exercise.
3) Our chief geology database administrator commented that the colors of the DAG Hamilton logo are those of the Spanish shawl nudibranch. There is a resemblance.
Photo courtesy of iNaturalist.
Thanks for stopping by.
Python Morsels: Functions and Methods in Python
Methods are functions that live on objects.
Table of contents
- Operators
- Some functions included with Python
- Calling functions
- Function arguments
- Functions either return a value or perform an action
- Methods are a special type of functions
- Functions are everywhere in Python
Python includes operators, like the plus operator (+) and the minus operator (-):
>>> n = 9 >>> language = "Python" >>> language + " is fun" 'Python is fun' >>> n - 4 5 Some functions included with PythonBut Python also includes many …
Read the full article: https://www.pythonmorsels.com/functions-and-methods/CodersLegacy: Understanding the Switch Case Statement in Python 3.10
Python is known for its simplicity and readability, but one feature it has historically lacked is a native switch case statement, commonly found in other programming languages like C, C++, and Java. Instead, Python developers often relied on a series of if-elif-else statements or dictionaries to emulate switch-case behavior.
However, with the release of Python 3.10, a new feature known as “Structural Pattern Matching” was introduced, which effectively brings a form of switch-case functionality to Python.
In this tutorial, we’ll explore how to use the switch case statement, Python’s new approach to handling multiple conditions in a more readable and efficient way.
The match statement in Python 3.10 allows for pattern matching, which is more powerful and flexible than the traditional switch-case statements found in other languages. Pattern matching checks a given value against a series of patterns and executes the corresponding block of code when a match is found.
Here’s a basic structure of how a match statement works:
Pythondef example(value): match value: case pattern1: # Code block for pattern1 case pattern2: # Code block for pattern2 case _: # Default case (similar to 'default' in switch-case) Key Components:- match statement: The equivalent of the switch keyword in other languages.
- case clauses: These represent the individual cases you want to check against, similar to case in switch-case.
- Wildcard (_): Acts as the default case, covering any values that don’t match the specified patterns.
Let’s start with a simple example of using match to simulate a switch-case statement that handles different types of user inputs.
Pythondef process_command(command): match command: case "start": return "Starting the system..." case "stop": return "Stopping the system..." case "restart": return "Restarting the system..." case _: return "Unknown command." # Testing the function print(process_command("start")) # Output: Starting the system... print(process_command("pause")) # Output: Unknown command.In this example:
- The match statement checks the value of command.
- Depending on the matched value, the corresponding message is returned.
- The wildcard (_) case handles any input that doesn’t match the predefined commands, acting as a fallback or default case.
The match statement in Python 3.10 is not limited to simple value matching. It supports more complex patterns, including:
1. Matching Data StructuresYou can use pattern matching with lists, tuples, and dictionaries.
Pythondef analyze_shape(shape): match shape: case ("circle", radius): return f"Circle with radius {radius}" case ("rectangle", width, height): return f"Rectangle with width {width} and height {height}" case ("square", side): return f"Square with side {side}" case _: return "Unknown shape" # Testing the function print(analyze_shape(("circle", 5))) # Output: Circle with radius 5 print(analyze_shape(("rectangle", 4, 6))) # Output: Rectangle with width 4 and height 6You can add conditions to cases using if statements, known as “guards”.
Python 0: return "Negative number" case n if n == 0: return "Zero" case n if n > 0: return "Positive number" # Testing the function print(categorize_number(-5)) # Output: Negative number print(categorize_number(0)) # Output: Zero print(categorize_number(10)) # Output: Positive number" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button">def categorize_number(number): match number: case n if n < 0: return "Negative number" case n if n == 0: return "Zero" case n if n > 0: return "Positive number" # Testing the function print(categorize_number(-5)) # Output: Negative number print(categorize_number(0)) # Output: Zero print(categorize_number(10)) # Output: Positive numberYou can also combine multiple patterns in a single case using the | (or) operator.
Pythondef get_day_type(day): match day: case "Saturday" | "Sunday": return "Weekend" case "Monday" | "Tuesday" | "Wednesday" | "Thursday" | "Friday": return "Weekday" case _: return "Invalid day" # Testing the function print(get_day_type("Sunday")) # Output: Weekend print(get_day_type("Monday")) # Output: Weekday print(get_day_type("Funday")) # Output: Invalid dayWhile you can still use if-elif-else statements, match provides a cleaner and more readable alternative when dealing with multiple conditions. It’s especially useful when:
- You have a large number of conditions to check.
- You want to match complex data structures.
- You need to execute different code blocks based on the structure of data, not just its value.
By mastering this new feature, you can write cleaner, more maintainable code that can easily adapt to complex logic scenarios.
As you start integrating match into your code, you’ll likely find many situations where it simplifies your conditional logic, making your Python code not only more efficient but also more Pythonic.
The post Understanding the Switch Case Statement in Python 3.10 appeared first on CodersLegacy.