🚲 Tanguy Ortolo a écrit 12091 commentaires

  • [^] # Re: Utile?

    Posté par  (site web personnel) . En réponse au journal L'indice de réparabilité. Évalué à 5.

    Ça m'est arrivé de casser 3 rayons en me gamellant, par exemple.

    Ah, en effet. Mais disons qu'après une chute qui aura suffis à casser des rayons, je m'attendrais à ce que la jante soit voilée, voire fêlée, au point de ne plus pouvoir être utilisée en toute sécurité. À remplacer, donc en pratique, la roue entière.

    Mais même sans casser de rayons, dévoiler une roue c'est quand même chaud, et ça ça va arriver assez régulièrement.

    Pas plus compliqué que ça. Il faut de la patience, c'est tout, mais ce n'est vraiment pas compliqué. On vérifie que l'étrier de frein est centré, vélo à l'envers, on fait tourner la roue, quand ça frotte d'un côté on agit sur les rayons qui entourent l'endroit concerné : on desserre les rayons du côté où ça frotte et on resserre les rayons de l'autre côté.

    L'autre exemple qui m'est arrivé c'est pour un dérailleur nexus défaillant. Tu peux acheter le Nexus tout seul ou déja monté sur une roue, bah bon courage pour monter les rayons et dévoiler la roue.

    Oui, alors ça c'est vraiment l'exemple du truc casse-pied à remplacer en effet. J'ai déjà fait l'inverse, à savoir changer la jante d'une roue équipée d'une dynamo de moyeu. Dans ce sens-là, c'est long, mais pas excessivement compliqué. Dans l'autre sens, il faut remettre tous les rayons, autrement dit remonter complètement une roue, ce qui doit être le sommet de la technique de mécanique vélo.

  • [^] # Re: Utile?

    Posté par  (site web personnel) . En réponse au journal L'indice de réparabilité. Évalué à 6.

    Il y aurait bien un plan pour éviter le surcoût des composants séparés : acheter deux vélos au départ. Un pour rouler dessus, l'autre pour servir de pièces détachées…

  • [^] # Re: Utile?

    Posté par  (site web personnel) . En réponse au journal L'indice de réparabilité. Évalué à 10. Dernière modification le 05 janvier 2023 à 11:40.

    La comparaison est intéressante, en effet. Mais on est d'accord qu'il y a des différences majeures entre les gadgets électroniques et les vélos?

    Pas tant que ça. Je me souviens de mon premier ordinateur fixe. Disque dur PATA de 6 Go, lecteur de CD PATA également. Un ou deux ans plus tard, les 6 Go commençant à être un peu petits, j'achète et j'installe un nouveau DD. Puis arrivent les DVD : j'achète et j'installe un lecteur de DVD. Pas possible de les lire, carte graphique pas assez puissante. Pas de problème, je change la CG. Quelques années plus tard, le processeur et la mémoire commencent à être insuffisants, je remplace carte mère, processeur et mémoire.

    Finalement, je remplace aussi le boîtier, j'achète un graveur de DVD, je me débarrasse du lecteur de CD. Il ne reste alors plus que le lecteur de disquettes et la carte son d'origine, il me semble.

    J'ai continué comme ça assez longtemps, et je suis récemment passé au reconditionné, parce qu'une chose a changé : un PC de cinq ans me convient largement.

  • [^] # Re: Utile?

    Posté par  (site web personnel) . En réponse au journal L'indice de réparabilité. Évalué à 10.

    J'imagine que tu as remplacé les pièces toi-même et que tu n'as pas compté le temps passé dans ton calcul de coût, ça change quand même pas mal de choses.

    Oui, ça coûte encore plus cher si on le fait faire par un pro évidemment.

    Je ne suis pas certain que le changement des galets du dérailleur ou de la chaîne soit à la portée de tout le monde, il faut être un minimum bricoleur, avoir un local, un certain outillage, etc.

    Oui pour tout, sauf pour le local. Le seul besoin est de pouvoir stocker son vélo, ce qui est indépendant du fait qu'on le répare sois-même, et de stocker les outils. Faire sa réparation dans un local, c'est inutile, n'importe quel endroit pas trop gênant sur le voie publique convient. J'ai effectué des réparation sur une place de stationnement auto, sur un bout de trottoir, dans un jardin public…

    Par exemple, je suis incapable de remonter et dévoiler une roue, par exemple. C'est quelque chose que je dois faire faire par un pro; le budget est conséquent et peut impliquer l'achat d'une roue neuve plutôt que le changement de quelques rayons.

    Mauvais exemple à mon avis : à moins d'avoir une pratique très particulière, quand on en arrive à casser des rayons par usure naturelle, inutile de chercher à les changer, les autres vont suivre. C'est justement le moment de changer la roue entière. On pourrait changer tous les rayons en gardant la jante, mais quand on est arrivé à user les rayons jusqu'à la rupture, la jante ne doit pas être dans un très bel état.

    Comme tu n'indiques pas vraiment tes critères, c'est compliqué d'être en désaccord avec toi. Tu dis que ça t'a coûté plus cher qu'un vélo neuf, donc ton critère n'est pas financier.

    Si si. En vérifiant mon vélo, je m'aperçois que la chaîne a atteint le point d'usure où il serait raisonnable de la changer avant qu'elle n'attaque trop les pignons. Je ne vais pas changer de vélo, il est bien plus intéressant de changer la chaîne seule ! Six mois plus tard, un pneu commence à craqueler un peu. Pas étonnant, je ne l'ai pas changé depuis trois ans. Je ne vais pas racheter un vélo, ça coûte moins cher de changer seulement le pneu. Un an plus tard, j'ai un levier de dérailleur qui commence à déconner, pas étonnant, il est d'origine et j'ai quand même roulé presque 50.000 kilomètres avec. Je ne vais pas racheter un vélo entier pour si peu, ça coûte moins cher de changer seulement le levier.

    Et ainsi de suite. Les composants d'un vélo ne tombent pas en panne en même temps, c'est progressif.

  • # Fairphone 3

    Posté par  (site web personnel) . En réponse au message Cherche modèle de téléphone. Évalué à 8.

    Le Fairphone 3 serait un bon candidat, évidemment. Je le connais bien, puisque j'en ai un en fait. Un peu encombrant, mais au moins on sait pourquoi, et c'est un modèle de réparabilité.

    Sauf que ce n'est pas pour moi, et que le Fairphone 3 est un peu trop encombrant au goût du destinataire de cet appareil.

  • # Vélo !

    Posté par  (site web personnel) . En réponse au journal L'indice de réparabilité. Évalué à 4.

    Dommage qu'il n'y ait pas les vélos dans cette liste. On aurait un indice de réparabilité de 20/20 pour l'immense majorité des modèles !

    Et sinon, ce serait bien que ce soit obligatoire pour les automobiles, d'ailleurs.

  • [^] # Re: Utile?

    Posté par  (site web personnel) . En réponse au journal L'indice de réparabilité. Évalué à 10.

    En particulier, même pour les gens qui font attention, le dernier item devient incontournable après 5 ou 6 ans, puisque tu vas récupérer gratuitement les téléphones de ton entourage, plus performants que le tien, qui autrement iraient à la poubelle.

    Et dont tu vas devoir changer la batterie, à mon avis le point le plus important.

    Pouvoir changer l'écran, c'est bien, mais c'est cher et ça ne s'use pas vraiment naturellement, ça se casse en faisant tomber le téléphone. Dommage. Mais la batterie, ça s'use vraiment pour le coup, et pouvoir la changer sans effort n'est pas un luxe, c'est juste la base. L'écran, à côté, c'est secondaire.

    Si au bout de 10 ans tu as remplacé toutes les parties de ton téléphone, c'est pareil que d'avoir acheté un nouveau smartphone (voire pire, puisqu'il n'y a eu aucune économie d'échelle sur le transport, le stockage, l'emballage des pièces, etc., et que les coûts écologiques du marché des pièces détachées ne sont pas petits (comme la surproduction des pièces de rechange qui peuvent partir à la déchetterie par cartons entier à la fin de la vie du produit).

    Tu fais pareil avec ta bicyclette ? Ce n'est pas un exemple anodin, la bicyclette est à mon avis le meilleur exemple actuel de machine parfaitement réparable pièce par pièce. Perso, quand j'ai une pièce usée ou cassée, je ne change que ça, pas le vélo entier. Au bout de dix ans, j'ai presque tout remplacé :
    - cintre (bon, pas parce qu'il était usé mais parce que je n'aimais pas sa forme),
    - roues,
    - pneus (plusieurs fois),
    - chaîne (plusieurs fois), pignons (plusieurs fois) et plateaux,
    - galets de dérailleur,
    - pédales,
    - câbles et gaines de dérailleur et de frein,
    - leviers de dérailleur et de frein,
    - patins de frein,
    - sonnette et feux (bon, seulement parce que j'ai trouvé plus performant que ceux d'origine),
    - selle,
    - porte-bagage,
    - garde-boues.

    Il ne reste d'origine que le cadre, les manivelles, les dérailleurs, le moyeu-dynamo de roue avant, la fourche, la tige et le chariot de selle, si je ne m'abuse. Les pièces détachées ne sont pas spécialement données, donc ces remplacements successifs m'ont sans aucun doute coûté plus cher que le vélo neuf, pourtant je ne regrette pas d'avoir procédé ainsi. Et j'aimerais pouvoir faire de même avec mon téléphone.

  • [^] # Re: Trop pour moi

    Posté par  (site web personnel) . En réponse au message Avent du Code, jour 22. Évalué à 5.

    C'est amusant, l'AoC regorge d'exemples de choses qui sont évidentes pour un humain, mais assez ou très difficiles à mettre en algorithme, qui sera d'ailleurs fort différent de la pensée humaine.

    Deux beaux exemples cette année :

    • Comment trouver les trous dans une pierre ponce (ou un emmental, ou une éponge) ? Facile, ça se voit ! Et en algorithme ? Euh, inondation depuis l'extérieur, ça ne remplit pas les trous, qu'on peut déterminer ensuite par différence, par exemple.
    • Comment relier et orienter les faces d'un patron de cube ? Facile, on découpe et on plie ! Et comme algorithme ? Euh, c'est compliqué !
  • # Trop pour moi

    Posté par  (site web personnel) . En réponse au message Avent du Code, jour 22. Évalué à 5.

    Bon, aucun problème pour la première partie, en revanche pour la seconde, j'y renonce… pour le moment.

    L'intérêt de Avent du Code est entre autres, pour moi, dans la satisfaction d'avoir implémenté des algorithmes originaux, astucieux, élégants, etc. Dans ce cas, en particulier, coder en dur la disposition particulière de mes données d'entrée serait très insatisfaisant. Quant à coder un algorithme qui implémente la modélisation des faces d'un cube à partir d'un patron arbitraire, je n'ai trouvé pour cela aucun moyen qui ne soit pas très, très fastidieux à écrire.

    Donc, pour le moment, je laisse tomber. J'y reviendrai peut-être plus tard dans l'année.

  • [^] # Re: Modélisation trop longue à débugger

    Posté par  (site web personnel) . En réponse au message Avent du Code, jour 19. Évalué à 4.

    On limite le nombre de robot de chaque type au coût maximal d'un robot pour ce type de ressources.

    Ce n'est pas empirique ça, c'est prouvable. Comme on ne peut construire qu'un robot par tour, récolter plus d'unités de n'importe quelle ressource que la quantité qu'on peut en dépenser ne sert à rien.

  • # Python, fait maison

    Posté par  (site web personnel) . En réponse au message Avent du Code, jour 21. Évalué à 4.

    Bon, fait maison, c'est à dire sans eval ni bibliothèque externe. On construit un arbre, pour la première partie on calcule récursivement la valeur du singe racine. Pour la deuxième partie, on force la valeur du singe racine, ce qui force récursivement la valeur des singes en-dessous, jusqu'à forcer la valeur de l'humain.

    from __future__ import annotations
    
    import re
    
    from collections import defaultdict
    from enum import Enum
    from typing import Callable, Dict, Iterable, Optional, Sequence, Set, Tuple
    
    
    class Operation(Enum):
        ADD = '+'
        SUB = '-'
        MUL = '*'
        DIV = '/'
    
        @property
        def op(self) -> Callable[[int, int], int]:
            if self is self.ADD:
                return int.__add__
            if self is self.SUB:
                return int.__sub__
            if self is self.MUL:
                return int.__mul__
            if self is self.DIV:
                return int.__floordiv__
            assert False  # we covered all cases
    
        @property
        def rev1(self) -> Callable[[int, int], int]:
            """Given a and b, return x so self.op(x, a) = b"""
            if self is self.ADD:
                return int.__sub__
            if self is self.SUB:
                return int.__add__
            if self is self.MUL:
                return int.__floordiv__
            if self is self.DIV:
                return int.__mul__
            assert False  # we covered all cases
    
        @property
        def rev2(self) -> Callable[[int, int], int]:
            """Given a and b, return x so self.op(a, x) = b"""
            if self is self.ADD:
                return int.__sub__
            if self is self.SUB:
                return lambda v, a: a - v
            if self is self.MUL:
                return int.__floordiv__
            if self is self.DIV:
                return lambda v, a: a // v
            assert False  # we covered all cases
    
    
    class Monkey:
        monkeys: Dict[str, Monkey] = {}
    
        def __init__(self, name: str,
                     value: Optional[int] = None,
                     others: Optional[Sequence[str]] = None,
                     operation: Optional[Operation] = None) -> None:
            if (others is None) != (operation is None):
                raise ValueError(
                        "others and operation must be both None or both defined")
            if (value is None) == (others is None):
                raise ValueError(
                        "value xor (others and operation) must be defined")
            self.name = name
            self._value = value
            self.others = others
            self.operation = operation
            # Register self in class directory
            self.monkeys[name] = self
    
        @property
        def value(self) -> int:
            if self._value is not None:
                return self._value
            if self.others is None or self.operation is None:
                raise ValueError(
                        "cannot compute value of a monkey w/o others or operation")
            return self.operation.op(
                    *[self.monkeys[other].value for other in self.others])
    
        @value.setter
        def value(self, v: int) -> None:
            if self._value is not None:
                # This monkey has a fixed value
                raise ValueError("cannot change value of a valued monkey")
            if self.others is None or self.operation is None:
                # This monkey has a free value, we just have to set it
                self._value = v
                return
            # The free monkey is somewhere under self
            a: Optional[int] = None  # value of first sub-monkey
            b: Optional[int] = None  # value of second sub-monkey
            try:
                a = self.monkeys[self.others[0]].value
            except ValueError:
                # This failed because the value-free monkey is here, not a problem
                pass
            try:
                b = self.monkeys[self.others[1]].value
            except ValueError:
                # This failed because the value-free monkey is here, not a problem
                pass
            if a is None and b is not None:
                a = self.operation.rev1(v, b)
                self.monkeys[self.others[0]].value = a
                return
            if a is not None and b is None:
                b = self.operation.rev2(v, a)
                self.monkeys[self.others[1]].value = b
                return
            # We do not expect to have two or no value-free monkey under us
            assert False
    
        _monkey_re = re.compile(r"^(\w+): (.*)\n?$")
        _operation_re = re.compile(r"^(\w+) ([-+/*]) (\w+)\n?$")
    
        @classmethod
        def import_line(class_, line: str) -> Monkey:
            match = class_._monkey_re.match(line)
            if match is None:
                raise ValueError("invalid monkey description '{}'".format(line))
            name = match.group(1)
            line = match.group(2)
            if line.isdigit():
                value = int(line)
                return class_(name, value=value)
            match = class_._operation_re.match(line)
            if match is None:
                raise ValueError("invalid monkey operation '{}'".format(line))
            others = (match.group(1), match.group(3))
            op = Operation(match.group(2))
            return class_(name, others=others, operation=op)
    
    
    def solve_both(lines: Iterable[str]) -> Tuple[int, int]:
        """Solve both parts of today's puzzle"""
        for line in lines:
            _ = Monkey.import_line(line)
        root = Monkey.monkeys['root']
        humn = Monkey.monkeys['humn']
        # Get original root monkey value
        result1 = root.value
        # Correct root monkey operation
        root.operation = Operation.SUB
        # Unset our own value so it becomes the free one
        humn._value = None
        # Force root monkey value: this will cascade to eventually set
        # our value
        root.value = 0
        result2 = humn.value
        return result1, result2
  • [^] # Re: N'importe quoi...

    Posté par  (site web personnel) . En réponse au journal L'entreprise est-elle responsable des fuites de données dans le cadre du télétravail ?. Évalué à 9.

    a) Tu n'as en rien la maitrise de ton système. Tu crois l'avoir, cela s'arrète là

    À ce compte-là, personne ne maîtrise rien. Sérieusement, je pense qu'un utilisateur averti d'un système libre maîtrise justement beaucoup mieux ce qui se passe sur son ordinateur, que l'entreprise ne maîtrise ce qui se passe sur ses ordinateurs.

  • [^] # Re: Un bug que j'ai résolu sans jamais le trouver.

    Posté par  (site web personnel) . En réponse au message Avent du Code, jour 20. Évalué à 4.

    Joli, du coup j'ai honte de montrer ma solution avec liste chaînée maison. Mais je la montre quand même, allez :

    from __future__ import annotations
    
    import io
    
    from typing import Iterable, Iterator, Optional
    
    
    class Chain:
        def __init__(self, *elts: Element) -> None:
            self._len = len(elts)
            self.first = elts[0]
            last = elts[-1]
            prev: Optional[Element] = None
            for elt in elts:
                if prev is not None:
                    prev.attach(elt)
                prev = elt
            last.attach(self.first)
    
        def __len__(self):
            return self._len
    
        def __getitem__(self, index: int) -> Element:
            index = index % len(self)
            current = self.first
            for _ in range(index):
                current = current.next
            return current
    
        def get_elt(self, base_elt: Element, index: int) -> Element:
            index = index % len(self)
            current = base_elt
            for _ in range(index):
                current = current.next
            return current
    
        def __iter__(self) -> Iterator[Element]:
            current = self.first
            for _ in range(self._len):
                yield current
                current = current.next
    
        def extract(self, index: int) -> Element:
            elt = self[index]
            elt.detach()
            self._len -= 1
            return elt
    
        def extract_elt(self, elt: Element) -> None:
            # WARNING: not checking that elt is part of self
            elt.detach()
            self._len -= 1
    
        def insert(self, index: int, elt: Element) -> None:
            prev = self[index]
            next_ = prev.next
            # Attach (prev and elt) and (elt and next_)
            prev.attach(elt)
            elt.attach(next_)
            self._len += 1
    
        def insert_elt(self, base: Element,
                       shift: int, elt: Element) -> None:
            # WARNING: not checking that elt is part of self
            shift %= self._len
            prev = base
            for _ in range(shift):
                prev = prev.next
            next_ = prev.next
            # Attach (prev and elt) and (elt and next_)
            prev.attach(elt)
            elt.attach(next_)
            self._len += 1
    
        def __str__(self):
            result = io.StringIO()
            result.write('(')
            for elt in self:
                result.write('{}, '.format(elt.value))
            result.write(')')
            return result.getvalue()
    
    
    class Element:
        def __init__(self, value: int) -> None:
            self.value = value
            self.prev = self
            self.next = self
    
        def attach(self, other: Element) -> None:
            self.next = other
            other.prev = self
    
        def detach(self) -> None:
            prev = self.prev
            next_ = self.next
            # Detach self
            self.prev = self
            self.next_ = self
            # Attach prev and next_
            prev.attach(next_)
    
    
    def solve1(lines: Iterable[str]) -> int:
        """Solve part 1 of today's puzzle"""
        elts = [Element(int(line)) for line in lines]
        seq = Chain(*elts)
        zero: Optional[elt] = None
        for elt in elts:
            if zero is None and elt.value == 0:
                zero = elt
            prev = elt.prev
            seq.extract_elt(elt)
            seq.insert_elt(prev, elt.value, elt)
        if zero is None:
            raise ValueError("invalid input without a zero value")
        return (seq.get_elt(zero, 1000).value
                + seq.get_elt(zero, 2000).value
                + seq.get_elt(zero, 3000).value)
    
    
    def solve2(lines: Iterable[str]) -> int:
        """Solve part 2 of today's puzzle"""
        key = 811589153
        elts = [Element(key * int(line)) for line in lines]
        seq = Chain(*elts)
        zero: Optional[elt] = None
        for _ in range(10):
            for elt in elts:
                if zero is None and elt.value == 0:
                    zero = elt
                prev = elt.prev
                seq.extract_elt(elt)
                seq.insert_elt(prev, elt.value, elt)
        if zero is None:
            raise ValueError("invalid input without a zero value")
        return (seq.get_elt(zero, 1000).value
                + seq.get_elt(zero, 2000).value
                + seq.get_elt(zero, 3000).value)

    À noter que c'est pas mal plus lent qu'avec des listes Python en fait… :-(

  • [^] # Re: SNCF Connect & transilien

    Posté par  (site web personnel) . En réponse au journal Utiliser l'Identité numérique la Poste sans Google Play. Évalué à 5.

    Au temps pour moi, il me semblait que l'utilisation de la marque Android pour décrire un système d'exploitation impliquait d'y inclure des trucs comme les Google Play Services, mais en fait non.

    LineageOS et compagnie sont bien des sytèmes Android, et il serait faux de prétendre que l'Identité Numérique La Poste fonctionne bien « sous Android ». Ça fonctionne sous certaines distributions Android répondant à leurs critères, pour le reste on doit bidouiller.

  • [^] # Re: Tetris style

    Posté par  (site web personnel) . En réponse au message Avent du Code, jour 17. Évalué à 4.

    Je n'ai pas encore commencé, mais vu l'énoncé de la première partie, je dirais que l'incrément de hauteur doit se répéter au bout du PPCM du nombre de formes et du nombre de d'instructions de direction du vent.

    Avec la première série de tant de blocs qui doit monter un petit peu plus haut puisqu'elle est posée sur un sol plat et non sur une tour qui sommet irrégulier.

  • [^] # Re: Attention

    Posté par  (site web personnel) . En réponse au journal Piéger les démarcheurs abusifs. Évalué à 10. Dernière modification le 17 décembre 2022 à 16:31.

    Bon, alors effectivement, mon titre était un peu trompeur : ce n'est pas le démarcheur lui-même que je cherche à piéger, mais son commanditaire en fait.

    La boîte de rénovation qui me fait appeler a bien une existence en France, et si je peux contribuer à les mettre en difficulté, ce sera toujours une bonne action de faite, au profit de leurs concurrents plus honnêtes. Pareil pour les boîtes de formation professionnelle.

    En fait, quand on se montre intéressé, on nous passe rapidement quelqu'un qui n'est plus un démarcheur mais un conseiller de la boîte malhonnête.

  • [^] # Re: Attention

    Posté par  (site web personnel) . En réponse au journal Piéger les démarcheurs abusifs. Évalué à 6. Dernière modification le 17 décembre 2022 à 12:20.

    En tout cas, des boulots dans des secteurs qui recrutent, ça n'est pas difficile à trouver : employé dans la restauration, aide-soignante, infirmière, conducteur d'autobus ou de train…

    Certains demandent de la formation, mais la pénurie de main d'œuvre est telle que les employeurs peuvent aller jusqu'à la prendre en charge.

    Ce sont des métiers contraignants, mais aujourd'hui, pour travailler à faire des trucs pénibles, nuisibles et illicites à longueur de journée, il faut le vouloir.

  • [^] # Re: SNCF Connect & transilien

    Posté par  (site web personnel) . En réponse au journal Utiliser l'Identité numérique la Poste sans Google Play. Évalué à 10.

    Pour tous ces logiciels, c'est assez paradoxal, mais le meilleur moyen de les faire fonctionner dans qu'ils détectent que votre téléphone utilise un système non Android, c'est de le rooter avec Magisk, d'activer Zygisk, d'installer Universal SafetuNet Fix et de les ajouter à la liste d'exclusion.

    Avec un peu d'explication :
    - Magisk, c'est un /bin/su et des possibilités techniques de changer des tas de trucs à ce que vient les logiciels qu'on lance ;
    - Zygisk, c'est une option de Magisk, plus liée à l'intérieur des processus applicatifs eux-mêmes si j'ai bien compris, et c'est nécessaire pour…
    - Universal SafetyNet Fix (USF), in module Magisk qui permet de passer la validation SafetyNet malgré un système non Android et rooté ;
    - la liste d'exclusion, c'est un réglage de Magisk, qui indique à quels logiciels la présence de /bin/su doit être masquée, et qui est aussi utilisée par USF.

    Bilan tout de même, grâce à ces contraintes de « sécurité », pour utiliser ces logiciels, on passe d'un système normal mais juste pas Android, à un système rooté et bidouillé pour mentir à gogo… On n'arrête pas le progrès.

  • [^] # Re: Attention

    Posté par  (site web personnel) . En réponse au journal Piéger les démarcheurs abusifs. Évalué à 5.

    Un peu désolé, ou pas en fait. Des boulots de merde, il y en a d'autres aussi, qui ont l'avantage de ne pas considérer à commettre des infractions en série.

  • [^] # Re: Et avec le téléphone de quelqu'un d'autre ?

    Posté par  (site web personnel) . En réponse au journal Utiliser l'Identité numérique la Poste sans Google Play. Évalué à 4.

    À un moment il faut donner un numéro de téléphone, mais ça ne change rien si c'est celui de quelqu'un d'autre.

  • [^] # Re: python, on a RAMé

    Posté par  (site web personnel) . En réponse au message Avent du Code jour 15. Évalué à 4. Dernière modification le 16 décembre 2022 à 09:15.

    Tiens, je n'avais pas pensé à Pypy. Pour info, ma solution termine la seconde partie – ligne par ligne, avec calcul d'unions d'intervalles – en 2,7 s sous Pypy.

  • [^] # Re: Une solution brillante

    Posté par  (site web personnel) . En réponse au message Avent du Code jour 15. Évalué à 4. Dernière modification le 16 décembre 2022 à 09:14.

    J'y ai réfléchi cette nuit, on peut faire encore mieux. Premièrement parce qu'il n'est pas vraiment nécessaire de considérer les intersections de droites, mais seulement celles des segments qui délimitent les zones de chaque capteur (enfin, les segments juste un point plus loin en fait).

    Mais surtout parce que le point cherché est soit :

    • dans un coin du terrain et sur un segment ;
    • sur un bord du terrain et à l'intersection de deux segments ;
    • n'importe où ailleurs, mais à l'intersection de quatre segments.

    Bref, in n'a plus qu'à tester si un coin ne se trouverait pas sur un segment, et sinon, si on construit la liste des intersections, on n'a plus qu'à chercher si on ne trouve pas dedans :

    • un point qui serait sur un bord ;
    • un point qui s'y trouverait quatre fois.
  • [^] # Re: Que de temps perdu !

    Posté par  (site web personnel) . En réponse au journal Piéger les démarcheurs abusifs. Évalué à 4.

    Je ne réponds pas à un numéro qui n'est pas dans mon annuaire perso (même si c'est un livreur, un commerçant ou un artisan qui m'appelle pour un truc important, figurez-vous qu'il va me laisser un mot sur le répondeur !!! dingue non ?)

    Quand on a une messagerie vocale, oui. J'ai volontairement désactivé la mienne, et les fournisseurs divers risqueraient de moyennement apprécier le fait que je leur demande de laisser un SMS sans possibilité de laisser un message vocal…

  • [^] # Re: encore faut il leur laisser la possibilité de nous faire sonner ;)

    Posté par  (site web personnel) . En réponse au journal Piéger les démarcheurs abusifs. Évalué à 4.

    Ça, c'est bien quand on supporte les messages vocaux. Personnellement, je déteste ça, et après des années d'hésitation, j'ai finalement désactivé ma messagerie vocale. J'ai juste un message d'absence qui invite à laisser un SMS. Le genre de truc qu'un démarcheur ne fera jamais depuis son poste fixe d'ailleurs.

  • [^] # Re: Exemple : démarchage au CPF

    Posté par  (site web personnel) . En réponse au journal Piéger les démarcheurs abusifs. Évalué à 4.

    Il me semble que c'est un brin plus nuancé. Je ne suis pas certain qu'il soit illégal d'enregistrer un appel qu'on reçoit dans le consentement de l'interlocuteur. Mais même si ça l'était, s'il ne l'apprend jamais il ne pourra pas s'en plaindre, en attendant c'est bien pratique pour vérifier le nom qu'à donné le démarcheur par exemple.

    Rendre public cet enregistrement, ça pourrait peut-être bien être risqué en revanche. Et ça pourrait bien ne pas être recevable comme preuve en effet.