fa
Feedback

فریب کلاهبرداران را نخورید! تل‌متریو این کانال‌ها را شناسایی و برچسب‌گذاری می‌کند 👉 برای مشاهده برچسب، اشتراک تهیه کنید

Coding Learn

Coding Learn

رفتن به کانال در Telegram

Canal de partage de contenus sur la programmation et sur l'informatique 📬 Pour suggérer venez sur @codingsupport_bot

نمایش بیشتر
5 104
مشترکین
اطلاعاتی وجود ندارد24 ساعت
+187 روز
+1730 روز
آرشیو پست ها
⚡ ASTUCE Go — ERRORS.IS & ERRORS.AS : LE CHAINAGE D'ERREURS MODERNE 1️⃣ L'ancien problème : la perte de contexte

// ❌ fmt.Errorf avec %v perd le type de l'erreur
if err != nil {
  return fmt.Errorf("failed to open file: %v", err)
}

// Impossible de savoir si c'est os.ErrNotExist plus tard
if errors.Is(err, os.ErrNotExist) {
  // toujours false, on a perdu l'info
}
2️⃣ La solution : fmt.Errorf avec %w (Go 1.13+)

// ✅ %w wrappe l'erreur, garde son identité
if err != nil {
  return fmt.Errorf("failed to open file: %w", err)
}

// Maintenant errors.Is fonctionne !
if errors.Is(err, os.ErrNotExist) {
  return c.SendStatus(404)
}

// errors.As permet d'extraire le type
var pathErr *os.PathError
if errors.As(err, &pathErr) {
  log.Printf("path: %s, op: %s", pathErr.Path, pathErr.Op)
}
3️⃣ Bonus : créer ses propres erreurs wrappables

type ValidationError struct {
  Field string
  Reason string
}

func (e *ValidationError) Error() string {
  return fmt.Sprintf("%s: %s", e.Field, e.Reason)
}

// Dans le caller
var verr *ValidationError
if errors.As(err, &verr) {
  return JSON{"field": verr.Field, "issue": verr.Reason}
}
✅ Contexte préservé, debugging simplifié, gestion d'erreurs propre. 💾 Enregistre ce post pour ne pas l'oublier. #Go #Go #Golang #WebDev #DevTips #MetaCodeLearn

⚡ ASTUCE React — USEDEFERREDVALUE : INPUT FLUIDE SUR GROSSE LISTE 1️⃣ Le problème : input qui lag sur du gros volume

function SearchList({ query }) {
  // ❌ À chaque frappe, re-filtrage bloquant de 10k items
  const filtered = hugeList.filter(item =>
    item.name.includes(query)
  );
  return filtered.map(renderItem);
}
2️⃣ La solution : useDeferredValue (React 18+)

import { useDeferredValue, useMemo } from 'react';

function SearchList({ query }) {
  const deferredQuery = useDeferredValue(query);

  // ✅ Le filtrage passe en priorité basse
  const filtered = useMemo(
    () => hugeList.filter(item =>
      item.name.includes(deferredQuery)
    ),
    [deferredQuery]
  );

  const isStale = query !== deferredQuery;
  return (
    <ul style={{ opacity: isStale ? 0.7 : 1 }}>
      {filtered.map(renderItem)}
    </ul>
  );
}
3️⃣ Bonus : useTransition pour les états plus larges

import { useTransition } from 'react';

function App() {
  const [isPending, startTransition] = useTransition();
  const [query, setQuery] = useState('');

  return (
    <>
      <input
        value={query}
        onChange={(e) => {
          setQuery(e.target.value);  // urgent : la frappe
          startTransition(() => {
            setExpensiveFilter(e.target.value);  // peut attendre
          });
        }}
      />
      {isPending && <Spinner />}
    </>
  );
}
✅ Input toujours réactif, liste filtrée sans bloquer l'UI. 💾 Enregistre ce post pour ne pas l'oublier. #React #React #WebDev #DevTips #MetaCodeLearn

⚡ ASTUCE SQL — CTE RÉCURSIVES : TRAVERSER DES ARBRES EN SQL 1️⃣ Le problème : récupérer toute une hiérarchie d'un coup
-- Sans récursion : impossible en une seule requête
-- Tu faisais du Python + plusieurs SELECT ? C'était ton cas ?
2️⃣ La solution : WITH RECURSIVE

-- Parcourt un arbre parent → enfants
WITH RECURSIVE org_tree AS (
  -- Ancrage : les racines
  SELECT id, name, parent_id, 1 as level
  FROM employees
  WHERE parent_id IS NULL

  UNION ALL

  -- Récursion : les enfants
  SELECT e.id, e.name, e.parent_id, t.level + 1
  FROM employees e
  INNER JOIN org_tree t ON e.parent_id = t.id
)
SELECT * FROM org_tree ORDER BY level, name;
3️⃣ Bonus : générer des séries de nombres à la volée

-- Génère 1..100 sans table temporaire
WITH RECURSIVE nums AS (
  SELECT 1 as n
  UNION ALL
  SELECT n + 1 FROM nums WHERE n < 100
)
SELECT n FROM nums;

-- MySQL nécessite SET cte_max_recursion_depth = 1000;
-- PostgreSQL et SQLite gèrent par défaut
Note : pense à limiter la récursion sur MySQL. Requête unique, zéro code applicatif, performances SQL natives. 💾 Enregistre ce post pour ne pas l'oublier. #SQL #PostgreSQL #WebDev #DevTips #MetaCodeLearn

⚡ ASTUCE JavaScript — STRUCTUREDCLONE : COPIER PROFOND EN 1 LIGNE 1️⃣ Le piège classique : la fausse copie

// ❌ Référence partagée, pas une copie
const original = { user: { name: 'Aliou', score: 10 } };
const copy = { ...original };

copy.user.score = 99;
console.log(original.user.score); // 99 ! mutation inattendue
2️⃣ La solution native : structuredClone() (Node 17+, tous navigateurs modernes)

// ✅ Copie profonde native, zéro dépendance
const original = { user: { name: 'Aliou', score: 10 } };
const copy = structuredClone(original);

copy.user.score = 99;
console.log(original.user.score); // 10 ✅ intact
console.log(copy.user.score);     // 99 ✅ vraiment copié

# Supporte : Date, Map, Set, ArrayBuffer, RegExp...
const data = structuredClone({
  date: new Date(),
  tags: new Set(['js', 'web']),
  items: [1, 2, 3]
});
3️⃣ Bonus : l'astuce de l'objet gelé pour forcer l'immutabilité

const state = Object.freeze({
  user: Object.freeze({ name: 'Aliou' })
};

// Lance TypeError en mode strict, échoue en sloppy
state.user.name = 'Bob'; // silencieux en sloppy, erreur en strict
✅ Native, rapide, et plus safe que JSON.parse(JSON.stringify() qui perd les Dates et les undefined. 💾 Enregistre ce post pour ne pas l'oublier. #JavaScript #JavaScript #WebDev #DevTips #MetaCodeLearn

⚡ ASTUCE Python — WALRUS OPERATOR := : ASSIGNER SANS POLLUER 1️⃣ Le pattern classique : assigner puis tester

# ❌ On duplique l'appel coûteux
data = fetch_data()
if data:
    process(data)
2️⃣ La solution propre : := (Python 3.8+)

# ✅ Assignation dans l'expression
if data := fetch_data():
    process(data)

# Encore plus lisible dans une boucle
while (line := file.readline().strip()):
    process_line(line)
3️⃣ Bonus : dans les list comprehensions

# Avant : deux passes sur la liste
results = [compute(x) for x in items if compute(x) is not None]

# Avec walrus : une seule passe
results = [y for x in items if (y := compute(x)) is not None]

# Lecture de fichier ligne par ligne
total = 0
with open('data.txt') as f:
    [total := total + int(n) for line in f if (n := line.strip()).isdigit()]
✅ Moins de répétitions, moins d'appels redondants, code plus expressif. 💾 Enregistre ce post pour ne pas l'oublier. #Python #Python #WebDev #DevTips #MetaCodeLearn

⚡ ASTUCE TypeScript — SATISFIES : L'OPÉRATEUR QUI CHANGE LA DONNE 1️⃣ Le problème classique : typage strict vs inférence

// ❌ On perd l'inférence des littéraux
type Config = {
  api: string;
  debug: boolean;
  features: string[];
};
const config: Config = {
  api: 'https://api.example.com',
  debug: false,
  features: ['auth', 'cache']
};
config.features.map(f => f.toUpperCase());  // OK mais features est string[]
2️⃣ La solution : satisfies (TS 4.9+)

// ✅ On valide la forme, on garde l'inférence
const config = {
  api: 'https://api.example.com',
  debug: false,
  features: ['auth', 'cache']
} satisfies Config;

config.features.map(f => f.toUpperCase()); // ✅ features reste ('auth' | 'cache')[]
// Erreur immédiate si une prop est manquante
3️⃣ Bonus : as const vs satisfies

// as const : fige tout en readonly literal
const a = { x: 1, y: 'hello' } as const;
// type : { readonly x: 1, readonly y: 'hello' }

// satisfies : valide sans transformer
const b = { x: 1, y: 'hello' } satisfies { x: number, y: string };
// type : { x: number, y: string } — toujours flexible
✅ Validates without losing the original type. Best of both worlds. 💾 Enregistre ce post pour ne pas l'oublier. #TypeScript #TypeScript #WebDev #DevTips #MetaCodeLearn

⚡ ASTUCE CSS — CONTAINER QUERIES : LE RESPONSIVE ENFIN LOGIQUE 1️⃣ Le problème des media queries classiques

/* On se base sur la taille de l'écran */
/* Mais le composant est peut-être dans une sidebar */
.card {
  display: flex;
  flex-direction: column;
}
@media (min-width: 768px) {
  .card { flex-direction: row; }
}
2️⃣ La révolution : @container (CSS Containment Level 3)

.card-wrapper {
  container-type: inline-size;
  container-name: card;
}

@container card (min-width: 400px) {
  .card { flex-direction: row; }
}

@container card (min-width: 600px) {
  .card { font-size: 1.2rem; }
}
3️⃣ Bonus : style queries (Chrome 111+, Safari 18+)

@container card style(--theme: dark) {
  .card { background: #1a1a1a; color: #fff; }
}

/* On peut même lier un custom property */
.card-wrapper { --theme: light; }
.dark-mode .card-wrapper { --theme: dark; }
✅ Les composants s'adaptent à leur conteneur, pas à l'écran. Design systems enfin réutilisables. 💾 Enregistre ce post pour ne pas l'oublier. #CSS #CSS #Frontend #WebDev #DevTips #MetaCodeLearn

⚡ ASTUCE JavaScript — ARRAY.FROM : LE COUTEAU SUISSE OUBLIÉ 1️⃣ Transformer un objet en array proprement

// Le piège : length-only ne suffit pas
const obj = { 0: 'a', 1: 'b', length: 2 };
[...obj];  // ❌ TypeError: object is not iterable

// La solution : Array.from avec mapping direct
const arr = Array.from(obj, (v, i) => `item-{i}:{v}`);
// ['item-0:a', 'item-1:b']
2️⃣ Générer une séquence numérique (remplace les boucles)

// 0..4 en une ligne
const range = Array.from({ length: 5 }, (_, i) => i);
// [0, 1, 2, 3, 4]

// Avec une fonction
const squares = Array.from({ length: 5 }, (_, i) => i * i);
// [0, 1, 4, 9, 16]
3️⃣ Bonus : Array.fromAsync pour itérer sur des promesses

const urls = ['/api/users', '/api/posts', '/api/comments'];
const results = await Promise.all(
  urls.map(url => fetch(url).then(r => r.json()))
);

// Ou plus élégant avec Array.fromAsync (ES2024)
const responses = await Array.fromAsync(
  urls.map(url => fetch(url).then(r => r.json()))
);
✅ Plus concis que les boucles, plus lisible que les hacks. Un outil à toujours avoir sous la main. 💾 Enregistre ce post pour ne pas l'oublier. #JavaScript #JavaScript #WebDev #DevTips #MetaCodeLearn

⚡ ASTUCE Rust — OWNERSHIP : LA RÈGLE QUI SAUVE DES VIES 1️⃣ Le principe fondamental : une seule variable possède la donnée

let s1 = String::from("hello");
let s2 = s1;  // s1 est "moved" vers s2
println!("{}", s1); // ❌ Erreur : s1 n'est plus valide
2️⃣ Pour dupliquer vraiment : clone()

let s1 = String::from("hello");
let s2 = s1.clone();  // copie profonde
println!("{} {}", s1, s2); // ✅ les deux valides
3️⃣ Le borrow checker en action — références immuables vs mutables

fn longest(a: &str, b: &str) -> &str {
    if a.len() > b.len() { a } else { b }
}

let r1 = &mut String::from("hi");
let r2 = &r1;        // ❌ une mutable + une immuable = interdit
println!("{} {}", r1, r2);

// OK : plusieurs immuables OU une seule mutable
let r1 = &String::from("hi");
let r2 = &r1;        // ✅ plusieurs & partagées
✅ Pas de garbage collector, pas de data races à la compilation. Le compilateur est ton meilleur QA. 💾 Enregistre ce post pour ne pas l'oublier. #Rust #RustLang #WebDev #DevTips #MetaCodeLearn

⚡ ASTUCE Go — SLICES VS ARRAYS : LA DIFFÉRENCE QUI COMPTE 1️⃣ Le piège classique : passer un array à une fonction

// En Go, [3]int et []int sont DEUX types différents
func sum(arr [3]int) int {
    total := 0
    for _, v := range arr { total += v }
    return total
}

nums := [3]int{1, 2, 3}
sum(nums)    // ✅ OK
nums2 := []int{1, 2, 3}
sum(nums2)   // ❌ Erreur de compilation
2️⃣ La bonne pratique : toujours passer un slice

func sumSlice(nums []int) int {
    total := 0
    for _, v := range nums { total += v }
    return total
}

sumSlice([]int{1, 2, 3})  // ✅
sumSlice(nums[:])          // ✅ conversion array → slice
3️⃣ Bonus : slices internes — attention au partage mémoire

// a et b partagent le même backing array !
a := []int{1, 2, 3, 4, 5}
b := a[:3]
b[0] = 999
fmt.Println(a) // [999 2 3 4 5] — a aussi modifié !

// Solution : copy()
c := make([]int, len(a[:3]))
copy(c, a[:3])
c[0] = 999
fmt.Println(a) // [1 2 3 4 5] — intact
✅ Slices flexibles pour les fonctions, arrays pour les tailles fixes connues. Toujours copy() si tu veux isoler. 💾 Enregistre ce post pour ne pas l'oublier. #Go #Golang #WebDev #DevTips #MetaCodeLearn

⚡ ASTUCE Python — LE WALRUS OPERATOR POUR DES LOOPS PLUS PROPRES 1️⃣ Le problème : lire un fichier ligne par ligne avec un compteur

# Classique : on appelle .readline() deux fois
line = f.readline()
while line:
    print(f"Ligne {n}: {line.strip()}")
    n += 1
    line = f.readline()
2️⃣ Avec le walrus operator := (Python 3.8+)

while (line := f.readline()):
    print(f"Ligne {n}: {line.strip()}")
    n += 1
3️⃣ Bonus : pattern matching pour parser du JSON imbriqué

# Match + walrus = combo gagnant
match data:
    case {"users": users} if (n := len(users)) > 10:
        print(f"Trop d'utilisateurs : {n}")
    case {"users": users}:
        print(f"OK : {len(users)} users")
✅ Plus concis, plus lisible, une seule source de vérité pour la condition. 💾 Enregistre ce post pour ne pas l'oublier. #Python #PythonTips #WebDev #DevTips #MetaCodeLearn

💡 LE SAVIEZ-VOUS — Le premier "bug" informatique Le 9 septembre 1947, Grace Hopper et son équipe trouvent un papillon de nuit coincé dans le relais électromécanique du Mark II à Harvard. L'insecte est soigneusement collé dans le carnet de bord avec la note : "First actual case of bug being found." Le terme "bug" (bestiole) existait déjà chez Edison en 1878 pour désigner un défaut technique — mais c'est ce papillon qui a popularisé le mot dans l'informatique. Et son opposé ? Le "debug" : littéralement retirer les bestioles du programme. 🦋 ✅ Leçon : même les machines les plus sérieuses ont commencé par un accident poisseux. 💾 Enregistre ce post pour ne pas l'oublier. #DevHistory #DevFacts #Programming #MetaCodeLearn

⚡ ASTUCE WEB — Un nom de domaine en emojis Oui, un nom de domaine peut être composé d'emojis. Ça marche depuis 2001 (IDN) et c'est de plus en plus utilisé par les marques pour se démarquer. 1️⃣ Comment ça marche techniquement
🌍.example  →  Punycode: xn--7vg.example
❤️.example  →  xn--g6h.example
🔥.io       →  xn--wp3a.io
2️⃣ Convertir en JS
const emoji = "🔥";
const puny = emoji.codePointAt(0)
  .toString(16)
  .replace(/^/, "xn--");
console.log(puny); // xn--wp3a
3️⃣ Enregistreur compatible
# Quelques bureaux qui acceptent
- porkbun.com
- namecheap.com
- dynadot.com

# Vérifier la dispo :
nslookup xn--g6h.com
✅ En interne (navigateur, app), l'utilisateur voit 🌟. En externe (DNS, SSL), c'est du ASCII. C'est la magie du Punycode. 💾 Enregistre ce post pour ne pas l'oublier. #WebDev #Domains #IDN #Punycode #MetaCodeLearn

⚡ ASTUCE RUST — match, if let & ? Trois outils pour gérer les Option<T> et Result<T, E> sans paniquer. Le compilateur t'oblige à traiter tous les cas — et c'est une bonne chose. 1️⃣ match exhaustif
match user {
    Some(u) => println!("salut {}", u.name),
    None => println!("invité"),
}
2️⃣ if let : un seul cas qui t'intéresse
if let Some(u) = get_user(id) {
    send_email(&u.email);
}
// pas de else obligatoire
3️⃣ ? : propager l'erreur sans if partout
fn read_file() -> Result<String, io::Error> {
    let data = fs::read_to_string("a.txt")?;
    Ok(data.to_uppercase())
}
✅ ? convertit l'erreur via From — c'est ce qui rend les fonctions Rust lisibles malgré la gestion d'erreur stricte. 💾 Enregistre ce post pour ne pas l'oublier. #Rust #RustLang #SystemsProgramming #DevTips #MetaCodeLearn

⚡ ASTUCE GO — Goroutines & select Go exécute des milliers de goroutines sur quelques OS threads. Le pattern select te permet de gérer plusieurs channels comme un switch non-bloquant. 1️⃣ Lancer une goroutine en une ligne
go func() {
    fmt.Println("async")
}()
2️⃣ select : attendre le plus rapide de plusieurs channels
select {
case msg := <-ch1:
    fmt.Println("reçu:", msg)
case <-time.After(2*time.Second):
    fmt.Println("timeout")
case <-ctx.Done():
    fmt.Println("annulé")
}
3️⃣ Quit pattern : channel de signal
quit := make(chan os.Signal, 1)
signal.Notify(quit, os.Interrupt)
<-quit // bloque jusqu'à Ctrl+C
✅ select avec default rend l'opération non-bloquante — utile pour les workers sans blocage. 💾 Enregistre ce post pour ne pas l'oublier. #Go #Golang #Concurrency #DevTips #MetaCodeLearn

⚡ ASTUCE BASH — ${} vs $() Beaucoup de devs confondent les deux. L'un exécute une commande, l'autre lit une variable. Voici la différence clé : 1️⃣ $(commande) — substitution de commande
date=$(date +%Y-%m-%d)
echo $date
# → 2026-08-26

users=$(who | wc -l)
echo "$users utilisateurs connectés"
2️⃣ ${var} — expansion de variable
name="Aliou"
echo "Salut ${name}!"
# → Salut Aliou!

# Utile pour les valeurs par défaut
echo "${HOME:-/tmp}"
3️⃣ Combiner les deux : nom de variable dynamique
key="PORT"
echo "${!key}"
# → 8080  (lit la variable dont le nom est dans $key)
✅ Toujours mettre les guillemets autour de $(...) pour éviter le word splitting sur les espaces. 💾 Enregistre ce post pour ne pas l'oublier. #Bash #Shell #Linux #DevOps #MetaCodeLearn

🎨 ASTUCE CSS — :has() Le sélecteur :has() te permet de styliser un parent en fonction de ses enfants. Avant, c'était impossible sans JavaScript. 1️⃣ Mettre en évidence une carte avec image
.card:has(img) {
  border: 2px solid #c8a96a;
}
2️⃣ Désactiver un bouton si formulaire invalide
form:has(input:invalid) button[type="submit"] {
  opacity: 0.4;
  pointer-events: none;
}
3️⃣ Highlight d'une ligne au hover
tr:has(td:hover) {
  background: rgba(200, 169, 106, 0.1);
}
✅ Supporté par tous les navigateurs modernes depuis fin 2023. 💾 Enregistre ce post pour ne pas l'oublier. #CSS #WebDev #Frontend #MetaCodeLearn

📝 Gemini AI Plus va être gratuit pour les étudiants (pendant 12 mois) ! ➥ Une bonne nouvelle pour les étudiants, qui n'ont e
📝 Gemini AI Plus va être gratuit pour les étudiants (pendant 12 mois) ! ➥ Une bonne nouvelle pour les étudiants, qui n'ont en général pas d'argent. Le plan Gemini entrée de gamme va en effet être gratuit pour eux pendant un an. ➥ Lire l'article ⌕ #clubic #hightech #tech - @crunchtech

📝 La toute dernière arme du Web contre les robots IA d'extraction est « ShieldFont », une police conçue pour corrompre les d
📝 La toute dernière arme du Web contre les robots IA d'extraction est « ShieldFont », une police conçue pour corrompre les données d'entraînement sans rendre les pages illisibles pour les humains ➥ La toute dernière arme du Web contre les robots IA d'extraction est « ShieldFont », une police conçue pour corrompre les données d'entraînement sans rendre les pages illisibles pour les humainsLa nouvelle police de caractères « ShieldFont » a été conçue pour empêcher l'exploration des sites Web p... ➥ Lire l'article ⌕ #programmation #actualite - @metacodelearn