Qua

Reader

A list of all postings of all blogs on Qua where the author has configured the blog to publish on this page.

from Rolistologie

Apparemment, il reste certaines confusions entre univers du jeu, système de jeu et système de joueurs. Les distinctions ne sont pas suffisamment claires, et tout le monde ne serait pas capable d'y classer les différentes règles rencontrées.

Je vais donc rappeler des définitions, donner des astuces et lister des exemples afin que ça devienne limpide pour tout le monde.

Définitions

Le premier rappel concerne la diégèse. Les éléments diégétiques appartiennent à la fiction. Ils existent dans l'univers. Et ils ne dépendent pas du media utilisé pour générer cette fiction (littérature, JdR, cinéma…)

Les règles qui existent dans le monde, comme les lois physiques, mais aussi sociologiques (les règles d'étiquette, les interdits moraux…) appartiennent à l'univers. Elles ne font pas partie du système de jeu, ni celui de joueurs.

Les règles extra-diégétiques qui régissent l'univers appartiennent au système de jeu. Elles ne font aucunement référence à des joueurs.

Les règles qui impliquent des joueurs sont évidemment extra-diégétiques. Elles forment le système de joueurs.

Astuces

Si vous avez du mal à séparer ces 3 notions, posez-vous les questions suivantes :

Est-ce qu'un personnage pourrait discuter de ces règles avec un autre personnage ? Est-ce que ces règles pourraient apparaître dans un film adaptant la fiction ? Si oui on a affaire à des règles de l'univers, diégétiques, et donc hors système.

Si la règle est extra-diégétique, est-ce qu'une personne seule pourrait l'utiliser ? Est-ce qu'elle ne comporte bien aucune référence à un joueur ? Si oui elle appartient au système de jeu.

Est-ce que la règle fait référence à un ou plusieurs joueurs ? Est-ce qu'elle concerne la façon de jouer ? Si oui elle fait partie du système de joueurs.

Exemples

Avant de rentrer dans des cas précis, quelques exemples en vrac.

Règles propres à l'univers : cette race extra-terrestre mesure en moyenne 1m30. Chez les amazones, les combattants sont toutes des femmes. Ce personnage gagne 100€ par mois. À 18 ans tout le monde sombre dans le coma. Les personnages ont 6 clones.

Règles relevant du système de jeu : cette race extra-terrestre a 20 points de vie. Il y a une classe de personnage, “Amazone”, réservée aux persos féminins. Ce personnage a Ressources à 2. Les persos de plus de 18 ans ont 3 points de connaissance supplémentaires. Avoir une voix mélodieuse donne un bonus de +2 aux discussions.

Règles appartenant au système de joueurs : au début de la séance, on détermine qui interprète le personnage du Roi. Quand un PJ meure, son joueur déchire la feuille de perso. On joue dans le noir. Quand un perso communique par télépathie, le joueur doit chuchoter. C'est le MJ qui décide des pauses. On joue en temps réel. Les scènes jouées ne font intervenir que 2 personnages.

Maintenant, quelques exemples qui ont été soulevés.

Dans la plupart des univers, le temps est diégétique. Il existe dans la fiction, il est régit par les lois physiques. Par contre, une règle qui déclare “un personnage peut faire 2 actions par round” est extra-diégétique est appartient au système de jeu. Déjà, on est manifestement dans un cas de simplification mécanique, car dans la fiction, toutes les actions n'ont pas l'exacte même durée, tous les personnages n'ont pas la même vitesse d'exécution. Par ailleurs, jamais un personnage ne prononcera cette phrase. Et ensuite, si on change l'unité du round en le divisant par deux (l'auteur du système en a parfaitement le droit), on obtient “un personnage peut faire 1 action par round”, alors que l'univers n'a évidemment pas été modifié.

La gravité, si elle est présente dans un univers, est diégétique. Les personnages la ressentent. Encore une fois, elle est régit par les lois physiques de l'univers donc appartient à l'univers. Un écrivain peut mettre en scène un protagoniste qui chute. Un personnage peut affirmer “généralement, si on tombe d'un étage, on se casse un membre”. Par contre toute règle qui traduirait des dégâts de chute en point de blessure, en perte de point de vie, ou tout autre référence extra-diégétique est, par conséquence, également extra-diégétique. On bascule donc dans le système de jeu. De la même façon, si dans l'univers les lois physiques démontrent que la gravité est variable, affirmer qu'elle est constante, en contradiction avec le monde, rentre dans le cadre du système de jeu où ce genre d'approximation est commun.

D'autres exemples détaillés :

À Vampire, le sang est diégétique. Un personnage sait qu'il en consomme une certaine quantité sur un humain, sur un animal, il sait qu'il est limité par une contenance maximale, il sait qu'il peut utiliser ce sang pour augmenter sa force, sa vitesse, ou utiliser ses disciplines. Par contre les points de sangs sont extra-diégétique. Il ne dira pas “j'ai perdu 5 points de sang” alors qu'on pourra par contre entendre “j'ai perdu la moitié de ma réserve”, ou “il faut que je tue 4 chiens pour compenser”.

À INS/MV, les Points d'Administration (souvent considérés comme équivalent à l'XP) sont diégétiques, mais les Points de Pouvoir ne le sont pas. Un personnage peut dire “j'ai gagné 3PA lors de ma dernière mission”, mais pas “et ça m'a permis de gagner 3PP”. La notion de Pouvoir est diégétique (en effet, plus un perso a de PP max, plus son aura est foncée), mais pas son découpage en PP. C'est souvent un test facile à faire : que se passe-t-il si on change d'échelle, à part la correction des valeurs utilisées dans le système de jeu ? Si l'univers n'est pas modifié, on est souvent dans du système de jeu (comme ici pour les PP). Si par contre l'univers est affecté, c'est que c'est diégétique (“J'ai gagné 3PA” “Avant ou après la dévaluation ?”)

#JdR #rolistologie #théorieJdR

 
Lire la suite...

from Être Divin

  • Clés collectives

“Il y a donc, pour vous tous, de par ce Trousseau, de par sa Forme et sa Musique, de par la qualité de chacune des Clés qui le composent : l’ouverture, l’accès à votre Plénitude la plus absolue, à votre Unité la plus entière, la plus simple, la plus parfaite, la plus véritable. Il y a accès à votre Joie la plus pure et la plus véritable également, dans toutes ses facettes, ses manifestations, ses vérités. Il y a également accès à tout Partage, non seulement entre vous, mais entre vous et Tout Ce qui est.”

https://voixdelumiere.fr/2012/02/sehelam-anna-n5-cles-collectives/ #SehelamAnna

 
Lire la suite...

from Être Divin

  • Clés collectives

“Et d’ailleurs vous êtes effectivement – comme il vous l’a été dit tout récemment, en particulier par Marie-Isis, par Ashtir : interdimensionnels au sens où vous pouvez naviguer entre ce que vous vivez encore dans votre ancien niveau -qui est toujours présent là où il est- ainsi que dans la Dimension autre, plus élevée, moins visible, moins mentalisable, non matérielle (en grande partie du moins), à laquelle vous avez accès, en toute facilité je le précise – et j’insiste sur cette information.”

https://voixdelumiere.fr/2012/02/sehelam-anna-n5-cles-collectives/ #SehelamAnna

 
Lire la suite...

from Être Divin

  • Exploration de deux formes directionnelles pour changer de couche vibratoire.

“Partant donc de cet Alignement Telouq, vous pouvez intégrer avec votre cerveau, et vos capacités plus étendues, le fait que vous pouvez vous déplacer en arc dans différentes orientations. Le principe de l’arc vous permet de changer de couche vibratoire beaucoup plus aisément qu’un déplacement linéaire sur une ligne droite -ainsi bien évidemment qu’un déplacement un peu anarchique.”

https://voixdelumiere.fr/2012/01/sehelam-anna-n4/ #SehelamAnna

 
Lire la suite...

from Isso me fez pensar...

Esta semana, após uma reunião interessante, reservei um tempinho para rememorar meu início como “professor universitário”, nos idos de 2002 (sempre tive vontade de escrever isso).

Comecei ministrando aulas de informática no curso de licenciatura em Matemática. Após alguns semestres, passei a lecionar informática básica, também, nos cursos de Serviço Social, Nutrição, Educação Física e Pedagogia. Passado tanto tempo — mais de duas décadas —, vejo-me lecionando, ainda, informática básica no curso de Licenciatura de Matemática.

Nos anos 2000, Marc Prensky “agitou” o meio acadêmico com a sua teoria sobre os nativos digitais. Prensky os definiu como jovens nascidos na era da internet (após anos 80/90) que cresceram imersos na tecnologia, aprendendo de forma rápida, multitarefa e interativa (por favor, me perdoem por não trazer a definição como uma citação).

Desde então, o computador tornou-se significativamente mais acessível, a internet popularizou-se e a informação passou a estar disponível em diversos dispositivos e a qualquer momento. Atualmente, diante de um desafio técnico desconhecido, basta consultar portais globais — independentemente do idioma, graças à tradução simultânea — ou recorrer a uma vasta gama de tutoriais em vídeo. Os smartphones, antes simples aparelhos de telefonia celular, consolidaram-se como autênticos computadores de bolso.

Apesar disso tudo, ainda preciso ensinar a usar um “editor de texto”.

Lembro-me que, naquela época, eu usava o StarOffice e argumentava com meus alunos que não fazia sentido pagar por uma suíte de escritório, existindo uma opção gratuita e com tanta qualidade. Eles contra-argumentavam, dizendo que não pagavam, pois usavam uma cópia pirata.

Passadas duas décadas, ainda utilizo os mesmos argumentos com meus alunos e eles, curiosamente, também.

Olhando todo este tempo, fico pensando: podíamos ter avançado um pouco mais. Não precisava muito. Eu poderia, por exemplo, estar ensinando a utilizar estilos para a edição dos textos.

#EducaçãoMatemática #TecnologiaNaEducação #DocênciaSuperior

 
Leia mais...

from clognz

...Ainsi, les différents registres communicationnels peuvent être définis comme étant : un spectre bidirectionnel, clôturé de chaque coté par une polarité complémentaire et antagoniste.

Or, la polarité spectrale déploie une influence apparentée au magnétisme. C'est cela qui détermine les interactions de champ, et non pas le croisement aléatoire des unités isolées navigant à la dérive dans un vide sidéral.

 
Lire la suite...

from clognz

Si l'idée est l'étoile qui indique la direction à suivre, l'idéologie se veut l'unique chemin possible pour essayer de l'atteindre. Mais, tandis que l'étoile reste lointaine à mesure qu'on avance, l'idéologie, elle, opère le mouvement inverse. Elle devient à la fois la voie et la destination promise. En cela, elle n'est qu'usurpation et imposture.

 
Lire la suite...

from 工人小记

同事YQ:我买一件衣服居然是从鸡屁股那块发货的,我说怎么路上走第三天了还没到手呢。 我:现在是不是还在四川? Y:!你怎么知道? 我:因为“蜀道难,难于上青天”

 
阅读更多

from veer66

I recently wanted to learn about MCP (Model Context Protocol). As someone whose default programming language is Common Lisp, I naturally decided to build an MCP server using Lisp.

Thanks to the creators of 40ants-mcp, the library provides a nice pattern and code structure that I really like. However, I struggled significantly with installation and getting started. What should have taken minutes ended up taking days.

I'm sharing my experience here so that others who want to build MCP servers in Common Lisp can get started in minutes, not days like I did.

Prerequisites

Before you begin, make sure you have the following installed:

  • SBCL – A high-performance Common Lisp compiler
  • Roswell – A Common Lisp implementation manager and script runner
  • Quicklisp – The de facto package manager for Common Lisp
  • Ultralisp – A community-driven distribution of Common Lisp libraries

Installing Ultralisp

In SBCL with Quicklisp, you can enable Ultralisp by:

(ql-dist:install-dist "http://dist.ultralisp.org/" :prompt nil)

(How to install SBCL and Quicklisp is in the appendix.)

The Gotcha: Loading 40ants-mcp

Here's the issue that cost me days: when you try to load 40ants-mcp with:

(ql:quickload :40ants-mcp)

You might encounter errors. The solution is simple but not obvious—load jsonrpc first:

(ql:quickload :jsonrpc)
(ql:quickload :40ants-mcp)

This dependency isn't automatically resolved, which was the source of my frustration.

Creating Your MCP Server

Here's a minimal example from my mcp-exper package:

(in-package :mcp-exper)

(openrpc-server:define-api (mi-tools :title "mi-tools"))

(40ants-mcp/tools:define-tool (mi-tools add) (a b)
  (:summary "just add")
  (:param a integer "a")
  (:param b integer "b")
  (:result text-content)
  (make-instance 'text-content :text (format nil "~a" (+ a b))))

(defun start-server ()
  (40ants-mcp/server/definition:start-server mi-tools))

Key points:

  1. Use openrpc-server:define-api to define your API
  2. Use 40ants-mcp/tools:define-tool to define tools
  3. Return text-content instances for text results (MCP requires specific content types)

Running the Server

Create a Roswell script (mi-mcp-server.ros):

#!/bin/sh
#|-*- mode:lisp -*-|#
exec ros -Q -- $0 "$@"
|#
(progn
  (ros:ensure-asdf)
  #+quicklisp(ql:quickload '(:mcp-exper) :silent t))

(defun main (&rest argv)
  (declare (ignorable argv))
  (mcp-exper:start-server))

Quick Test

Run directly with Roswell:

ros mi-mcp-server.ros

Production Installation

Build and install as an executable:

ros build mi-mcp-server.ros
install -m 0755 mi-mcp-server $HOME/.local/bin/

Make sure $HOME/.local/bin is in your PATH.

Integrating with Opencode

To enable your MCP server in opencode, add this to ~/.config/opencode/opencode.json:

{
    "mcp": {
        "mi-tools": {
            "type": "local",
            "command": ["mi-mcp-server"],
            "enabled": true
        }
    }
}

Conclusion

Building MCP servers with Common Lisp is straightforward once you know the tricks. The 40ants-mcp library is well-designed, and the OpenRPC integration works smoothly.

I hope this guide saves you the days of frustration I experienced. Happy hacking!


The full source code for this example is available at mcp-exper.

Appendix: Installing SBCL

macOS

brew install sbcl

Debian/Ubuntu

apt install sbcl

Arch Linux

pacman -S sbcl

Appendix: Installing Quicklisp

Download and install Quicklisp:

wget https://beta.quicklisp.org/quicklisp.lisp
sbcl --load quicklisp.lisp \
        --eval '(quicklisp-quickstart:install)' \
        --eval '(ql-util:without-prompting (ql:add-to-init-file))' \
        --quit
 
Read more...

from veer66

I recently wanted to learn about MCP (Model Context Protocol). As someone whose default programming language is Common Lisp, I naturally decided to build an MCP server using Lisp.

Thanks to the creators of 40ants-mcp, the library provides a nice pattern and code structure that I really like. However, I struggled significantly with installation and getting started. What should have taken minutes ended up taking days.

I'm sharing my experience here so that others who want to build MCP servers in Common Lisp can get started in minutes, not days like I did.

Prerequisites

Before you begin, make sure you have the following installed:

  • SBCL – A high-performance Common Lisp compiler
  • Roswell – A Common Lisp implementation manager and script runner
  • Quicklisp – The de facto package manager for Common Lisp
  • Ultralisp – A community-driven distribution of Common Lisp libraries

Installing Ultralisp

In SBCL with Quicklisp, you can enable Ultralisp by:

(ql-dist:install-dist "http://dist.ultralisp.org/" :prompt nil)

(How to install SBCL and Quicklisp is in the appendix.)

The Gotcha: Loading 40ants-mcp

Here's the issue that cost me days: when you try to load 40ants-mcp with:

(ql:quickload :40ants-mcp)

You might encounter errors. The solution is simple but not obvious—load jsonrpc first:

(ql:quickload :jsonrpc)
(ql:quickload :40ants-mcp)

This dependency isn't automatically resolved, which was the source of my frustration.

Creating Your MCP Server

Here's a minimal example from my mcp-exper package:

(in-package :mcp-exper)

(openrpc-server:define-api (mi-tools :title "mi-tools"))

(40ants-mcp/tools:define-tool (mi-tools add) (a b)
  (:summary "just add")
  (:param a integer "a")
  (:param b integer "b")
  (:result text-content)
  (make-instance 'text-content :text (format nil "~a" (+ a b))))

(defun start-server ()
  (40ants-mcp/server/definition:start-server mi-tools))

Key points:

  1. Use openrpc-server:define-api to define your API
  2. Use 40ants-mcp/tools:define-tool to define tools
  3. Return text-content instances for text results (MCP requires specific content types)

Running the Server

Create a Roswell script (mi-mcp-server.ros):

#!/bin/sh
#|-*- mode:lisp -*-|#
exec ros -Q -- $0 "$@"
|#
(progn
  (ros:ensure-asdf)
  #+quicklisp(ql:quickload '(:mcp-exper) :silent t))

(defun main (&rest argv)
  (declare (ignorable argv))
  (mcp-exper:start-server))

Quick Test

Run directly with Roswell:

ros mi-mcp-server.ros

Production Installation

Build and install as an executable:

ros build mi-mcp-server.ros
install -m 0755 mi-mcp-server $HOME/.local/bin/

Make sure $HOME/.local/bin is in your PATH.

Integrating with Opencode

To enable your MCP server in opencode, add this to ~/.config/opencode/opencode.json:

{
    "mcp": {
        "mi-tools": {
            "type": "local",
            "command": ["mi-mcp-server"],
            "enabled": true
        }
    }
}

Conclusion

Building MCP servers with Common Lisp is straightforward once you know the tricks. The 40ants-mcp library is well-designed, and the OpenRPC integration works smoothly.

I hope this guide saves you the days of frustration I experienced. Happy hacking!


The full source code for this example is available at mcp-exper.

Appendix: Installing SBCL

macOS

brew install sbcl

Debian/Ubuntu

apt install sbcl

Arch Linux

pacman -S sbcl

Appendix: Installing Quicklisp

Download and install Quicklisp:

wget https://beta.quicklisp.org/quicklisp.lisp
sbcl --load quicklisp.lisp \
        --eval '(quicklisp-quickstart:install)' \
        --eval '(ql-util:without-prompting (ql:add-to-init-file))' \
        --quit
 
Read more...

from mattesilver

A set of workshop tools

I've been looking for a tool to manage development tools like linters, test runners, etc. The tools are typically development tools, so for example pipx would qualify.

A tool manager should make the environment reproducible and portable. The installed tools should work not only on my machine as well as on machine of everyone else who works on the same project, and they should not conflict with other tools anyone has installed on their systems.

Ideally the tool would have a declarative configuration, so it's clear what's used and easy to upgrade.

The problem with task managers (that aren't also tool managers) is that they don't control the tools, so a task that works on one system may fail on another. Worse, a task that works at one point in time may fail at another, because of a new tool version. So task manager should be either also a tool manager or it should be used with one.

On the other hand, managing tools is also a big subject, it's pretty much a package manager, needing some sort of a descriptor for a lot of tools in various languages, that need to be installable on various systems and architectures.

In short, the requirements boil down to:

  • declarative tool SBOM
  • tool isolation (but with access to project dependencies)
  • task management

Installing tools directly in the system

The old way, where the user installs tools following the project readme. Not declarative, not reproducible, definitely not isolated.

❌ declarative ❌ isolated ❌ task management

Declarative package managers – Nix, Guix

Environments are reproducible, declarative (both use functional languages). Rather difficult to use and very intrusive – you pretty much install another operating system in your operating system. I don't see any technical obstacle from making them single-user application, but they chose against it. Unless you already use one of them, it's a total overkill.

Maybe they work better with dev containers, but even then there are alternatives.

✅ declarative ✅ isolated ❌ task management

pipx

pip for executable packages. Supports installation of multiple versions of the same tool, but there's no way to activate the required versions for a given project. And it only works for python tools (and those with a python wrapper).

❌ declarative ❌ isolated (tools are isolated from each other, but shared across projects) ❌ task management

uvx, npx, pnpx, etc

Set of tools that let you run their respective languages projects as programs. Each works only with tools in its language, but it's not the biggest problem, since typically the tools are written in the same language, or have wrappers.

They arent really designed to manage a toolbox, rather for one-off execution. There's no declarative versioning.

uvx is a part of uv, which is a package manager, and also python version manager, but somehow tool manager is out of scope 🤷.

❌ declarative ✅ isolated ❌ task management

Tools as dev dependencies

It's really not what dev dependencies are meant for: everything is installed in a shared environment (venv, nodemodules). In the nodejs environment this should be fine, every package maintains its own dependencies, even if versions differ – that's why you end up with huge nodemodules. In python you might end up with conflicting dependencies (this somehow doesn't stop poetry project to use dev dependency group this way). Again, they only work for tools written in the same language as the project.

✅ declarative ❌ isolated ❓ task management (not in python, package.json has scripts)

pre-commit

Technically ticks many boxes, but not really intended as a dev tool manager.

Uses git repositories as a distributed source of packages, keeps them isolated and cached per project. Versions are fully declarative – you can even pin full SHA hashes.

This is all great, but it's literal git's pre-commit utility, which means it's designed for fast and predictable execution. It's not intended as a general purpose tool manager – it doesn't provide the tools with full project environment (it doesn't include dependencies), it doesn't support test runners (also because testing is too slow for a pre-commit hook) and even support for some linters (see pythons mypy) is suboptimal (again, mypy works best with access to dependencies).

✅ declarative ✅ isolated (actually too isolated for my purpose) ❌ task management

Mise

Works both as a package manager (tools) and task manager (replacement for package.json scripts, rather than for make). The only tool with the express goal of being a tool and task manager.

It doesn't handle tools with plugins well (e.g. pydantic.mypy) – it uses a shared directory for installs, but only tool name and version are used for tools “identity”. which means if you have two projects, both using mypy, one using pydantic with mypy plugin, there's a conflict (there's a workaround to this, but not good for collaboration).

It also does funny things to $PATH so it doesn't work great with other tools, like IDEs or pre-commit.

✅ declarative ❌ isolated (buggy) ✅ task management

Dev containers

This isn't even a tool, it's simply a container (docker, podman, you name it) that has your tools installed and has access to your project directory.

It's great for isolation and reproducibility, as long your installs are versioned. The isolation makes curl | sudo sh - a bit more acceptable.

I haven't worked with it, but the concept seems very reasonable, especially for occasional build of applications that you only use (but not develop).

Conclusion

I don't see here a perfect tool, and I'm not even looking for a polyglot multi-project / monorepo manager.

Mise comes very close, and I'm currently using it but it has a problem with isolation and it doesn't seem interested in fixing it, so I wouldn't recommend it on it's own in a collaborative environment.

I'll take a closer look at mise in a dev container. Dev containers would provide the isolation and mise covers declarative tool and task management quite well.

 
Read more...

from veer66

In the context of programming in the 1980s, “global variables” likely brings to mind languages like MBASIC. However, using MBASIC as an example today would be challenging, as it is now rarely used or known. Instead, GNU Bash, which is the default shell scripting language for many systems—will be used to illustrate what global variables were traditionally like. Anyway, some might think of Fortran II, but I'm not familiar with it.

Bash Example

I wrote a Bash script consisting of four files:

a.bash

a.bash orchestrates everything. “Orchestration” might be too grand a word for these toy scripts, but I want to convey that it performs a role similar to Apache Airflow.

#!/bin/bash

. ./b.bash
. ./c.bash
. ./d.bash

init
print_count
inc
print_count

b.bash

b.bash contains only one function, inc, which increments the counter, which is the global variable in this example.

inc() {
    counter=$((counter + 1))
}

c.bash

c.bash contains print_count, which simply displays the value of the global variable counter.

print_count() {
    echo $counter
}

d.bash

In Bash, counter can be initialized globally from within a function by default.

init() {
    counter=1
}

Python Example

The following section shows the result of porting the Bash script above to Python, highlighting the key differences.

a.py

This is the orchestration part. Note the use of namespaces or module names.

import c, b, d

d.init()
c.print_count()
b.inc()
c.print_count()

b.py

In the Python version, inc must refer to the module d to access the variable. Alternatively, counter could be explicitly imported.

import d

def inc():
    d.counter += 1

c.py

Similarly, print_count in Python must also refer to module d.

import d

def print_count():
    print(d.counter)

d.py

Unlike in Bash, initializing a global variable from within a function—even in the same module—requires an explicit global declaration.

def init():
    global counter
    counter = 1

Key Differences

As you can see, a global variable in Bash is truly global across files. In Python, however, a global variable is only global within its module, i.e., file. Furthermore, mutating a global variable in Bash requires no special syntax, whereas in Python a function must explicitly declare global to modify a module-level variable.

Consequently, although both are called “global variables,” Python's are scoped to the module. This means they won’t interfere with variables in other modules unless we deliberately make them do so. For developers who use one class per module, a Python global variable behaves much like a class variable. Additionally, variable assignment inside a Python function is local by default, preventing accidental modification of global state unless explicitly intended.

In short, many traditional precautions about global variables in languages like Bash or MBASIC no longer apply in Python. Therefore, we might reconsider automatically rejecting global variables based on past advice and instead evaluate their use case thoughtfully.

 
Read more...

from veer66

I was impressed by pkgsrc because it is a powerful package management system that defines packages using a common tool like a Makefile. I later discovered that the PKGBUILD file is even more impressive, as its purpose is immediately clear. I initially attributed this to my greater familiarity with Bash scripting compared to Makefiles, but I now believe the true reason is PKGBUILD's level of abstraction.

It retains explicit calls to configure and make, preserving the transparency of a manual installation. This demonstrates that while increased abstraction can make code shorter, it can also hinder understanding.

Another potential advantage of greater abstraction is the ability to change the configure command for every package by modifying just one location. However, since GNU Autotools has continued to use the configure command for decades, it may not be worth sacrificing clarity for this particular benefit.

 
Read more...

from mattesilver

I'm developing a small package for writing typed Web API clients, similar to Uplink, only compatible with OpenAPI (lapidary). I use these clients mostly in Web servers, so I decided to make it async. So far I've settled on HTTPX, but I want to keep tabs on available python packages.

urllib.request

See also The Requests package is recommended for a higher-level HTTP client interface.

It accepts request headers only as a dict, and I've decided that it doesn't count as support for HTTP

❌ HTTP/1.1 ❌ HTTP/2 ❌ HTTP/3 ❌ asyncio

urllib3

Fast and robust, slowly acquiring HTTP/2 support, but only sync.

✅ HTTP/1.1 ❌ HTTP/2 ❌ HTTP/3 ❌ asyncio

requests

This the one every python example tells you to use. It's under a feature freeze since forever – HTTP moves on but requests is as perfect as possible. It also “broke the internet” when it moved to urllib3 2.0.0, which dropped support for older TLS algorithms, in a minor version release. As long as the API doesn't change in an incompatible way, right?

✅ HTTP/1.1 ❌ HTTP/2 ❌ HTTP/3 ❌ asyncio

pycURL

It's super fast, since it's super thin wrapper over libcURL.

Also a great showcase of how not to write python wrappers. Might as well use ctypes.

✅ HTTP/1.1 ✅ HTTP/2 ✅ HTTP/3 (I think it's supported, libcURL says it's experimental) ❌ asyncio but non-blocking, since it's a native code.

HTTPX

The most popular async HTTP client package for python. Supports HTTP/2 but claims it's “not as robust” as 1.1. Both sync and async.

API is mostly compatible with requests (it's not a feature). Depending on usage pattern, it's slightly slower or much slower than aiohttp.

✅ HTTP/1.1 ✅ HTTP/2 (discouraged, opt-in) ❌ HTTP/3 ✅ sync & async

aiohttp

API is close to the protocol, so a bit more complex than alternatives, but I like it. One of the fastest packages in python.

The community seems more focused on the server side (more features and plugins).

✅ HTTP/1.1 ❌ HTTP/2 ❌ HTTP/3 ✅ asyncio-only

Aiosonic

Looks and feels like HTTPX.

Depending on usage pattern, it's either a bit slower or a bit faster than aiohttp. Probably there's something wrong with it, because nobody seems to be using it. Definitely worth a closer look.

✅ HTTP/1.1 ✅ HTTP/2 – beta ❌ HTTP/3 ✅ sync & asyncio

Aioquic

Really low level HTTP/3 & QUIC package. Only for genuine H3 users. Could use better examples – example client has 600+ lines. Or maybe it's that hard to use...

❌ HTTP/1.1 ❌ HTTP/2 ✅ HTTP/3 ✅ asyncio-only

Niquests

Async fork of requests with HTTP/2 and 3. Fast, full featured but not user-friendly.

It uses a forked urllib3 (by the same author) that shadows it, so if you happen to have a transitive dependency on the original, it will mess up your environment. The author is fine with it. I recommend against using it.

✅ HTTP/1.1 ✅ HTTP/2 ✅ HTTP/3 ✅ sync & asyncio

Reqwest wrappers

This makes a lot of sense – Rust is a popular language, reqwest is a popular rust package, keep it DRY. None of the wrappers are widely popular, but some projects are live and definitely worth watching. – gufo-http – I think it's the oldest and still maintained – pyreqwesthttpr

Found a few more, just search reqwest in pypi.

✅ HTTP/1.1 ✅ HTTP/2 ❌ HTTP/3 – maybe, it's still experimental in reqwest ✅ sync and asyncio

Conclusion

Honestly, the clients for the protocol that makes the Web makes me wonder is Python still alive? There isn't a single popular and stable package with HTTP/2 (2015!) or HTTP/3 (2022) either sync or async. Is Python only for Django and LLM? Have everyone else switch to Rust and/or Deno?

 
Read more...

from mattesilver

Based on the Litestar Fullstack Inertia showcase project.

Prerequisites

For social authorization to work, you first need to register your application with the identity provider (e.g., GitHub).

Implementation

Frontend

You need a login or registration page with a button/link that sends the browser to a backend route which starts the OAuth2 flow. For social login, it doesn’t matter whether you call it “login” or “registration”, as the first login typically creates the user.

Implementation details: – In the showcase project it’s implemented in partials: – Login formRegistration form – Both partials use the same button, which handles clicks with router.post(route("github.register")). – route() is an Inertia.js helper function which simply resolves handler names to paths. – A plain link and HTTP GET would also work here, since no data is sent at this stage.

Login/Register handler (backend)

Create a route that redirects to the provider’s authorization URL and includes a callback pointing to your completion handler. For production you should generate OAuth2 state and PKCE code verifier, and store them in the session.

Implementation details: – See the authorization controller – You can use httpx_oauth to get auth-related URLs for popular OAuth2 providers.

Authorization callback handler (backend)

Your callback (named “github.complete” in the showcase) should:

  1. Validate the store OAuth2 state (required for security; missing in the showcase)
  2. Exchange the authorization code for an access token
  3. Create a user object in the local database and store the user Id in the session
  4. Redirect to a post-login page (e.g., dashboard)

Optionally: – Fetch user details (e.g., email) from the provider
– Provide user data to the frontend

Implementation details: – The showcase doesn't use OAuth2 state or PKCE – GitHubOAuth2.get_access_token is used to exchange the auth code for a token (wrapped as a Litestar dependency, to facilitate re-use) – GitHubOAuth2.get_id_email is used to retrieve users email – Inertia’s share() is used to pass user details to the frontend

© 2025 Matte Silver

 
Read more...

from Jéssica Maryellen

Jogo da memória - Números - Nível 3

Tema: Números e Quantidades – Maternal II

Este jogo da memória foi especialmente desenvolvido para os alunos do Maternal II, com o objetivo de auxiliar no processo de reconhecimento dos números de 1 ao 9 e na associação entre número e quantidade.

O jogo é composto por seis pares de cartas, com cada par sendo formado por:

  • Uma carta com o número escrito.
  • Uma carta com a quantidade correspondente em figuras.

De forma lúdica e interativa, as crianças são incentivadas a observar, contar e associar, desenvolvendo habilidades como:

  • Reconhecimento visual dos números.
  • Noção de quantidade.
  • Atenção e memória.
Nível 1 -:-:-:– Nível 2 -:-:-:– Nível 3
 
Leia mais...