One thing that Rust is great for is using the type system to encode states. With the (relatively) new sealed classes in Dart, it's possible to build something similar, relying on the type system to prevent any misuse of the API.
As an example, I'll create a robust HTTP response interface. This approach enforces valid state transitions while providing a clear and concise API for constructing HTTP responses. The implementation ensures the correct order of operations when setting the HTTP status code (which must be first), adding headers (from zero to any number, after the HTTP status, but before the response body), and defining the body of the response (which is the last thing allowed to do with the response).
Implementation
Here is the code, without syntax highlighting. Sorry about that, but you can actually copy-paste it to DartPad to make it pretty and run it! I also assume you have a window that is more than 80 characters wide, so I've longer lines here.
/// Represents the base class for HTTP response states.
sealed class HttpResponse {
const HttpResponse();
}
/// Represents the initial state of an HTTP response.
class HttpResponseInitial extends HttpResponse {
const HttpResponseInitial();
/// Sets the status code and transitions to the next state.
HttpResponseAfterStatus status(int code, String message) => HttpResponseAfterStatus(code, message, this);
}
/// Represents the state of an HTTP response after a status code has been set.
class HttpResponseAfterStatus extends HttpResponse {
/// The HTTP status code.
final int statusCode;
/// The HTTP status message.
final String statusMessage;
/// The list of headers associated with the response.
final List<Map<String, String>> headers;
/// Creates an instance of [HttpResponseAfterStatus].
HttpResponseAfterStatus(this.statusCode, this.statusMessage, HttpResponse previous) : headers = previous is HttpResponseAfterStatus ? previous.headers : [];
/// Adds a header to the response, creating a new object.
HttpResponseAfterStatus header(String key, String value) => HttpResponseAfterStatus(statusCode, statusMessage, this)..headers.add({key: value});
/// Adds a header to the response, mutating the current object.
HttpResponseAfterStatus header2(String key, String value) => this..headers.add({key: value});
/// Sets the body of the response and finalizes it.
void body(String text) {
print('Response: $statusCode $statusMessage');
headers.forEach((header) => header.forEach((key, value) => print('$key: $value')));
print('Body: $text');
}
}
void main() {
// Example of a valid response
HttpResponseInitial()
.status(200, "OK")
.header("X-Unexpected", "Spanish-Inquisition")
.header2("Content-Length", "6")
.body("Hello!");
// Example of an invalid response (uncommenting will cause a compile-time error)
/*
HttpResponseInitial()
.header("X-Unexpected", "Spanish-Inquisition"); // Error: statusCode not called
HttpResponseInitial()
.statusCode(200, "OK")
.body("Hello!")
.header("X-Unexpected", "Spanish-Inquisition"); // Error: header called after body
*/
}
Explanation
In this implementation, a sealed class HttpResponse
serves as the base for two subclasses: HttpResponseInitial
and HttpResponseAfterStatus
. The HttpResponseInitial
class represents the initial state of the response, while HttpResponseAfterStatus
captures the state after the HTTP status code has been set. The status
method transitions from the initial state to the after-status state, allowing us to set the HTTP status code and message.
The header
method creates a new instance of HttpResponseAfterStatus
while adding a new header to the existing list of headers. This ensures that headers are not duplicated. Additionally, the header2
method allows for mutating the current instance by directly adding a header to the existing list. The two approaches are functionally identical, but there might be a runtime performance of recreating a new object for each header.
Finally, the body
method finalizes the response by printing the status, headers, and body content.
This design enforces the correct order of operations, preventing invalid states such as adding headers before setting the status code or after defining the body.
Variation: State Type Parameter
Instead of having separate classes for each state, the state can be modeled as a type parameter for a single generic class. This approach reduces boilerplate and enhances flexibility, but it may be more complex to understand initially.
Consider the HTTP response example again. Here's how it can be modeled it using a state type parameter, using extension
s to define operations that are valid only in specific states.
/// Represents the base class for HTTP response states.
sealed class ResponseState {}
/// Represents the initial state of an HTTP response.
class Start implements ResponseState {}
/// Represents the state of an HTTP response after headers have been set.
class Headers implements ResponseState {}
/// Represents the HTTP response with a state type parameter.
class HttpResponse<S extends ResponseState> {
final int? statusCode;
final String? statusMessage;
final List<Map<String, String>> headers;
HttpResponse({this.statusCode, this.statusMessage, List<Map<String, String>>? headers}) : headers = headers ?? [];
/// Creates a new response in the Start state.
static HttpResponse<Start> create() => HttpResponse<Start>();
}
/// Operations valid only in Start state.
extension StartOperations on HttpResponse<Start> {
HttpResponse<Headers> status(int code, String message) => HttpResponse<Headers>(statusCode: code, statusMessage: message);
}
/// Operations valid only in Headers state.
extension HeadersOperations on HttpResponse<Headers> {
/// Adds a header to the response, creating a new object.
HttpResponse<Headers> header(String key, String value) => HttpResponse<Headers>(statusCode: statusCode, statusMessage: statusMessage, headers: headers..add({key: value}));
/// Adds a header to the response, mutating the current object.
HttpResponse<Headers> header2(String key, String value) => this..headers.add({key: value});
void body(String text) {
print('Response: $statusCode $statusMessage');
headers.forEach((header) => header.forEach((key, value) => print('$key: $value')));
print('Body: $text');
}
}
void main() {
// Example of a valid response
HttpResponse.create() // Should even be directly using `status()` to create the object.
.status(200, "OK") // This will return HttpResponse<Headers>
.header("X-Unexpected", "Spanish-Inquisition")
.header2("Content-Length", "6")
.body("Hello!");
// Example of an invalid response (uncommenting will cause a compile-time error)
/*
HttpResponse.create()
.header("X-Unexpected", "Spanish-Inquisition"); // Error: status not called
HttpResponse.create()
.status(200, "OK")
.body("Hello!")
.header("X-Unexpected", "Spanish-Inquisition"); // Error: header called after body
*/
}
Using state type parameters provides several advantages:
- Conciseness: It reduces the number of classes needed to represent different states, making the codebase cleaner and easier to maintain.
- Single Documentation: All operations for the
HttpResponse
class are documented in one place, making it easier for users to understand the available methods and their valid contexts. - Flexibility: Adding new operations that are valid in specific states or across multiple states becomes straightforward. For example, we can define operations that are valid in any state without needing to modify the existing structure:
/// Operations available in any state. extension CommonOperations<S extends ResponseState> on HttpResponse<S> { int? get statusCode => this.statusCode; }
Unfortunately, I could not find a way to make the response creation as const
.
Variation: state types that contain actual state
I tried to twist my code in a way to also implement the Variation: state types that contain actual state section of the article linked below, but without luck. I might be missing something.
Source
Inspiration drawn from The Typestate Pattern in Rust - Cliffle which is about Rust instead.
Pourquoi LFI et le Parti Communiste Français sont seulement de gauche (et non d'extrême-gauche) alors que le Rassemblement National est bien d'extrême droite.
C'est pas moi qui le dit, c'est le Conseil d'État, institution publique indépendante chargée de conseiller le gouvernement français.
Et oui, bonne question ! Faire d'avoir une langue (presque) complément logique comme l'espéranto, on peut au moins rafistoler ce qu'on utilise quotidiennement !
Un TriCount/Splitwise/CoSpend/SettleUp, mais sans devoir avoir une app ni un compte.
Peut être à tester. Au moins à garder sous le coude pour le pas oublier le nom "Ergo-L" :)
As far as I know, there is no way to put a gradient along a path using Inkscape. Here is a convoluted workaround that can be used, considering a linear gradient with only two stops:
- Create the path you want
- Create a closed path that will be repeatedly copied for the full path length (which means we are somehow discretizing the path)
- Copy this second path to the clipboard
- Select the first path, and open the Path Effects window (menu Path → Path effects)
- Choose the effect "Pattern along path"
- Configure the pattern copies to "Repeated, steched"
- Tune the parameters so the paterns trustfully follow your path the way you want
- In the dropdown menu next to the
👁️
and🗑️
icons, select "Flatten": it will apply the effect to the path (meaning that the path won't exist anymore, and the object copies will be created in your document for real) - Group all the copies together
- In menu Extensions, select "Style" → "Interpolate attribute in a Group"
- Set "Attribute to interpolate" to "Fill", and choose your "Start Value" and "End Value" to the colors you want.
And you are done!
EDIT: Similar approach but different:
https://m.youtube.com/watch?v=RoIEZBXO0eQ
In short, create as many shapes (circles) as gradient stops, convert them to paths, colorize them, select them and use the "Interpolate" extension, group them all, and use the "Bend" path effect to apply the gradient of circles along the path.
Oh, ça semble intéressant pour une gestion de jardin
Pour avoir une trace d'exécution de script bash ou zsh, il est intéressant d'afficher les commandes exécutées. Cela se fait avec set -x
. Chaque ligne exécutée sera affichée, préfixée par un +
.
C'est intéressant, mais il est possible de personnaliser le PS4 (le préfixe +
) pour afficher en couleur la fonction actuelle et le numéro de ligne concerné :
# Zsh
export PS4=$'\033[0;33m($0:${LINENO}):+ \033[0m'
C'est dans la même veine que les modifications de prompt PS1
Voici un script bash (ou zsh) d'une ligne qui permet de faire de l'OCR sur tous les fichiers PDF du dossier courant:
for file in *.pdf; do ocrmypdf --output="pdfa" "$file" "${file%.*}_ocrmypdf.${file##*.}"; done
Version alias à mettre dans votre .bashrc
ou .zshrc
:
alias ocr='for file in *.pdf; do ocrmypdf --output="pdfa" "$file" "${file%.*}_ocrmypdf.${file##*.}"; done'
Un guide open-source pour le (pain au) levain !
J'ai bricolé vite fait une spécifications Vega-Lite des amendes liées au RGPD.
Les données viennent directement en https://enforcementtracker.com mais avec des en-têtes qui bloquent la requête (CORS). Il faut donc ruser et demander au navigateur d'ignorer ça, grâce par exemple à CORS Everywhere.
Je me suis amusé à faire en sorte que la visualisation s'adapte au thème clair/sombre du système. Les plus curieux remarqueront que cette pas n'est stockée sur aucun serveur : tout est encodé dans l'URL.
Il y aurait beaucoup d'autres analyses à faire (histogrammes, tendencies, groupements par catégories, etc.), mais je n'ai pas le temps de creuser.
- Quelle est l'audience ? Pourquoi devrait-elle être intéressée ?
- Pourquoi j'en parle ? Pourquoi faire cette présentation est important pour moi ?
- Comment transformer l'audience, plutôt que simplement l'informer ?
- Avant la présentation :
1. Qu'est ce que l'audience sait ?
2. Qu'est ce que l'audience croît ?
3. Qu'est ce que l'audience ressent ?
4. Qu'est ce que l'audience fait ?
- Après la présentation, dans l'ordre inverse :
1. Qu'est ce que l'audience fera ?
2. Qu'est ce que l'audience ressentira ?
3. Qu'est ce que l'audience croira ?
4. Qu'est ce que l'audience saura ? - Trouver des éléments pour chaque points, et les arranger de manière à raconter une histoire.
Joli outil pour faire du reverse engineering de fichiers.
Une explication très détaillée, et illustrée de manière grandiose, du fonctionnement interne des montres mécaniques.
Privilege Checklist
These checklists aren't exhaustive, but they did help our consultants to get started thinking about their privileges. We crafted these specifically for our center, so many of the items on the checklists are especially relevant because of our university's location, demographics, and politics. We encourage you to use these lists and also add items that are particularly pertinent to your center.
Class Privilege
- I have usually had access to healthcare.
- I can afford to visit a healthcare professional multiple times per year.
- I have access to transportation that will get me where I need to go.
- New products are designed and marketed with my social class in mind.
- I have knowledge of and access to community resources.
- I can swear or commit a crime without people attributing it to the low morals of my class.
- I can update my wardrobe with new clothes to match current styles and trends.
- People do not assume that I am unintelligent or lazy based on the dialect I grew up speaking.
- Regardless of the season, I can count on my home remaining a comfortable temperature.
- I know that I will be able to go to the grocery store when I need to and will be able to buy healthy foods that I want.
- Whenever I've moved out of my home it has been voluntary, and I had another home to move into.
- I can plan on getting a raise at my job.
- My decision to go or not to go to college wasn't based entirely on financial determinants.
- I have a safe and reliable place where I can study.
White Race, Ethnicity, and Culture Privilege
- I can expect that I'll receive days off from work for holidays that matter to me.
- People know how to pronounce my name; I am never mocked or perceived as a threat because of my name.
- I know that the police and other state authorities are there to protect me.
- People of my race widely represented in media, positively as well as negatively.
- When I am told about our national heritage or about civilization, I am shown that people of my color made it what it is.
- I can expect to see many students and professors of my race on campus.
- I do not often have to think about my race or ethnicity--in fact, I don't really notice it.
- I do not have to worry about incarceration unless I commit a very serious crime.
- People do not assume that I am unintelligent or lazy based on my race.
- There have never been attempts to scientifically or socially eliminate people of my race or ethnicity.
- Other people attribute my successes to my personal merit.
- My race or ethnicity will not make people around me uncomfortable.
- I do not have to worry about being chosen last for a job or housing due to my race or ethnicity.
- I can move into a new neighborhood, start a new job, or enter a new school or class and know that the people around me will generally respect and feel safe around me.
- I can go to a store or spend money knowing that no one will be suspicious of me.
- I am seen as an individual; I am never held personally responsible for the actions of other people of my race or ethnicity.
Citizenship Privilege
- If I apply for a job, I do not have to worry about what to write under "Social Security Number."
- I know that I will be paid at least minimum wage at a job and that labor laws will protect me.
- If I am mistreated or a crime is committed against me, I have some hope of being able to access legal recourse.
- Most of the time I am able to surround myself with people who share a common or collective history, who speak the same language that I do, and who understand my culture.
- I am not worried on a daily basis about being "discovered" and deported along with, or away from my family; I don't have to worry that a small misstep could lead to my deportation, even if I currently have legal papers to be in the U.S.
- I can go into any bank and set up a checking account without fear of discrimination, thus knowing my money is safer than on my person or elsewhere.
- If a police officer pulls me over, I can be sure I haven't been singled out because of my perceived immigration status.
- I can be reasonably sure that if I need legal or medical advice, my citizenship status will not be a consideration.
- I can vote in any election on policies or for people who will make laws affecting my way of life and my community.
- I may consider running for political office to serve my community.
- I, or a member of my family, can apply for scholarship aid to the institutions of higher education that are supported by my family's tax dollars.
- No one ever tells me to speak a particular language or to get out of their country.
- I do not have to worry that my citizenship status will make people around me uncomfortable.
Cisgender Privilege
- I can use public facilities like restrooms and locker rooms without fear of verbal abuse, assault, or arrest.
- People know what to call me and how to refer to me without asking.
- I do not have to worry that my gender expression will make people around me uncomfortable.
- Strangers don't ask me what my genitals look like and how I have sex.
- My validity as a man/woman/human is not based on how much surgery I've had or how well I "pass" as a particular gender.
- I have the ability to walk through the world and generally blend-in, not being constantly stared or gawked at, whispered about, pointed at, or laughed at because of my gender expression.
- Acquaintances use the name I provide, and don't insist on calling me by my "real name" [birth name].
- I can reasonably assume that my ability to work, rent an apartment, or secure a loan will not be denied on the basis of my gender identity/expression.
- I can flirt, engage in courtship, or form a relationship and not fear that my biological status may be cause for rejection or attack, nor will it cause my partner to question their sexual orientation.
- If I end up in the emergency room, I do not have to worry that my gender will keep me from receiving appropriate treatment, or that all of my medical issues will be seen as a result of my gender.
- My identity is not considered a mental pathology ("gender identity disorder" in the DSM IV) by the psychological and medical establishment.
- I will not be placed in a sex-segregated detention center, holding facility, jail or prison that is incongruent with my identity.
- I am not required to undergo an extensive psychological evaluation in order to receive basic medical care.
- When I do receive health care, professionals know how to provide me with needed treatments and respect.
- If a crime is committed against me, my gender expression will not be used as a justification ("gay panic") nor as a reason not to punish the perpetrators.
- I can easily find role models and mentors to emulate who share my identity.
- Hollywood depicts people of my gender in films and television, and representations are more nuanced than having my identity be either the focus of a dramatic storyline or the punchline for a joke.
- I can assume that everyone I encounter will understand my identity, and not think I'm confused or hell-bound when I reveal it to them.
- I am able to purchase clothes, shoes, and other products that I like without being refused service/mocked by staff, questioned about my genitals, or having to order special or custom made sizes.
- Official documents like my certificate and driver's license show the name I go by and the gender I identify as.
- No stranger checking my identification or driver's license will ever question me because I do not fit gender expression they have assigned to me.
- I can reasonably assume that I will not be denied services at a hospital, bank, or other institution because the staff does not believe the gender marker on my ID card to match my gender identity or because they simply do not like me.
- My gender is an option on legal forms.
- No one will disagree with my stated gender or accuse me of lying.
- I do not fear interactions with police or security officers due to my gender identity.
- I am able to go to new places knowing there will be bathrooms there I can use and people there who will respect me.
- I don't have to convince my family, friends, and coworkers of my true gender, earn their love and respect all over again, or constantly remind them to use proper gender pronouns and my name.
- I know that I can date someone and that they aren't just looking to satisfy a curiosity or kink pertaining to my gender identity.
Sexuality Privilege
- I will have immediate access to my loved one in case of accident or emergency.
- I will receive public recognition and support for an intimate relationship (e.g., congratulations for an engagement).
- I may express affection in most social situations and not expect hostile or violent reactions from others.
- I can openly live with my partner.
- When a relationship ends from death or separation, I will receive support from others.
- When my partner dies, I will receive paid leave to grieve.
- Neighbors, colleagues, and good friends will find me socially acceptable.
- Learning about romance and relationships from fiction movies and television.
- I have access to role models of my sexual orientation and accurate media images of people with whom I can identify.
- I can assume I am around others of my sexuality most of the time, and I do not have to worry about being the only one of my sexuality in a class, on a job, or in a social situation.
- I will not be fired from my job for my sexuality.
- I can talk openly about my relationship, vacations, and family planning.
- I can easily find a neighborhood in which residents will accept my household.
- If I raise, adopt, or teach children, no one will assume that I will molest them or somehow force them into my sexuality.
- If I work in a field not traditionally dominated by members of my gender, it will not be presumed a reflection of my sexuality.
- Strangers don't ask me how I have sex.
- When I do receive health care, professionals know how to provide me with needed treatments and respect.
- I can love, act, speak, and dress as I choose without being treated as a representative of my sexuality or being prosecuted for breaking the law.
- I have access to basic civil rights that will not be denied or outlawed because some people disapprove of my sexuality.
- I will not be mistreated by the police or victimized by the criminal justice system because of my sexuality.
- I have never had to conceal or reveal my sexuality to the people around me.
Male/Masculine Privilege
- I can expect to receive promotions as frequently and be paid the same amount as my equally qualified colleagues.
- I can express frustration, passion, assertiveness, etc. without being called a bitch, someone attributing my ideas to 'my time of the month', or being similarly dismissed.
- I can mess something up without it being seen as an indictment of my entire gender.
- People don't attribute my successes and positions simply to my gender; my personal merits are never called into question.
- I can enter public spaces without being sexually harassed.
- At work, I don't often have to worry about harassment from customers, coworkers, or bosses.
- I feel comfortable going somewhere alone or going on a date with someone new; I don't have to fear violence.
- I know that people will believe me when I report a crime against me.
- I don't have to worry about people perceiving me as sexual because of my clothes or body.
- People do not often make unsolicited comments about my body.
- I am not expected to spend a great deal of time and money on my appearance, and I are not shamed when I choose not to spend my time and money on my appearance.
- The decision to hire me will not be based on assumptions about whether or not I might choose to have a family.
- People do not call my personal and family life into question in context of my career.
- I do not often have to fear sexual violence.
- People of my gender who I can identify with appear frequently in media and popular culture.
- When I speak up, my opinions are heard and respected equally with others'.
Ability Privilege
- I can go to new places knowing that I will be able to move through the space.
- When I feel unwell or unable to do something, people do not often say that I'm faking it or tell me to just suck it up.
- Language and slang are not predicated on the assumption that I am bad because of my conditions and abilities (i.e. retarded, lame, stupid, crazy, psycho, crippled, blind meaning ignorant, etc.)
- I will not be rejected when applying for health insurance due to physical or cognitive disability or mental illness.
- People do not suspect that I got a job or got into a certain school due to my disability status.
- I do not have to worry about making the people around me uncomfortable because of my disability.
- People do not treat me like a child by crouching down to me, using a 'baby voice', or offering unsolicited help for trivial tasks.
- I can excel in challenging situations without other people being surprised by my success.
- My success is not presented as a guilt trip for others who do not have my disability ("If she can do it despite her disability, what's your excuse?"
- People believe that my ailments actually exist, even if they can't see them.
- I see people with my physical and cognitive disabilities and/or mental illnesses in media and popular culture presented accurately and positively.
- I can assume that people will be willing and able to communicate with me; they will understand my body language and social cues, etc.
- If I have a medical problem, I don't have to worry that doctors will dismiss it as part of a pre-existing ability-related condition.
- There are not scientific efforts to eradicate people with my DNA.
- People do not pity me or call my quality of life into question.
- I do not expect isolation rooms, restraints, and psychotropic drugs forced upon me during my educational and medical experiences.
- People who have power over my education will not decide that I need to be removed from classes with my peers and/or taught an entirely different set of non-academic skills.
- I can go to any class, job, or website and assume that the materials presented to me will be understandable.
- If I need an accommodation (such as an interpreter, extra time for a text, or an extension), I will receive it.
- People don't think I'm lazy or stupid when I need to try something again.
- I am able to enter new situations without fear of debilitating anxiety, embarrassment, harassment, or violence.
- No one assumes that any partner attracted to me must be a predator or pedophile, even though I am an adult.
- I am never told that I should not have children lest I pass on the genes that cause my neurological type.
- People do not assume that living in the same household as me is inherently "tragic" or "devastating," or that my family, friends and partner will need a support group to deal with living with me.
- If I am unhappy, people do not assume my unhappiness is a character trait; my emotions are acknowledged and respected rather than dismissed.
Linguistic Privilege
- People do not make assumptions about my intelligence based on my language ability.
- I can go anywhere and assume that I will be able to understand the things around me and communicate with the people around me.
- People do not talk to me like a child or otherwise treat me like a child; they do not speak too loudly and slowly to me.
- I do not have to worry about making people uncomfortable because of my native language, accent, or skill level in their native language.
- People will usually be willing to repeat and restate things for me.
- I do not have to worry that I will be chosen last for housing and jobs because of my language use.
- If I speak multiple languages, people view it as a unique talent rather than a detriment.
- Customers, coworkers, bosses, professors, and peers are not likely to give me negative performance reviews or assessments due to my language use.
- People do not mock my accent, dialect, and/or language.
- People do not fetishize my accent, dialect, and/or language.
- People do not ask to learn bad words in my language or share the few words they do know in my language.
- I speak my native language because it is part of my family's heritage, not because it was forced onto my ancestors by others.
- People do not view me as an invader or threat due to my native language or dialect.
- People might not correct me when I make a minor mistake in grammar or pronunciation.
- People don't assume they can understand my entire culture based on my native language or dialect.
- I can readily find people and media around me that can communicate with me in my native language or dialect.
De l'autoconstruction de maison à pas cher, ça fait très low-tech 🤩
C'est mal, mais je vais citer uniquement le dernier paragraphe de la conclusion :
Pour finir, si vous avez peur de mal dormir avant d’aller vous coucher, inquiétez-vous des paramètres qui ont vraiment une influence sur votre sommeil (le tabac, l’alcool, le café ou le thé, le fait d’avoir une activité sportive tardive, l’exposition aux écrans le soir, un environnement de sommeil inadapté ou votre niveau d’anxiété) plutôt que des phases de la Lune.
Si vous avez acheté des bundles de jeu sur itch.io et que vous êtes perdus dans quoi choisir, voici un site qui permet de se guider en les filtrant selon différents criètres, et avec possibilité de les trier.
Un logiciel (libre) de statistiques. Sous le coude, des fois que ça me serve à l'avenir. (SOFA est pédagogique dans son approche, mais sa stabilité et utilisabilité est questionnable)