Python >> Tutoriel Python >  >> Python

Restez simple, stupide ! Minimalisme dans la programmation :comment la complexité nuit à votre productivité

Cet article est basé sur un chapitre de mon prochain livre "From One to Zero :A Minimalistic Approach to Programming" .

Mes étudiants en programmation écrivent souvent avec leurs difficultés et leurs échecs. De nombreux étudiants finissent par surmonter leurs difficultés, mais un grand pourcentage d'entre eux abandonnent leurs ambitions de programmation après avoir réalisé à quel point il peut être difficile de créer un logiciel. Ces étudiants ont commencé avec l'objectif de devenir des codeurs professionnels, mais, finalement, ils ont raté cet objectif.

Après des milliers de conversations personnelles avec ces étudiants, il est devenu évident que de nombreux nouveaux codeurs n'échouent pas parce qu'ils ne connaissent pas l'une ou l'autre fonctionnalité de Python ou parce qu'ils manquent de compétences techniques, d'intelligence ou même de talent.

Ce ne sont pas les raisons sous-jacentes pourquoi ils échouent.

Au lieu de cela, ils échouent parce qu'ils sont submergés par la complexité qui se cache partout dans la programmation . La complexité les pousse à jeter l'éponge. C'est dommage car il existe de nombreuses façons d'atténuer les effets néfastes de la complexité de la programmation. Dans le chapitre précédent, vous avez déjà appris quelques stratégies sur le principe 80/20 (Concentrez-vous sur les quelques éléments vitaux et sacrifiez les plus insignifiants !).

Dans ce chapitre, nous allons avoir un aperçu complet de ce sujet important et très peu exploré. Qu'est-ce que la complexité ? Où se produit-il ? À quoi ça ressemble ?

Commençons par un bref aperçu :il est très difficile de sélectionner le bon

  • langage de programmation parmi des dizaines de langages populaires,
  • projet de codage sur lequel travailler, parmi des milliers de projets open source et des myriades de problèmes,
  • bibliothèques au sein d'un langage (scikit-learn vs NumPy vs TensorFlow),
  • des technologies émergentes sur lesquelles "parier" :applications Alexa, applications pour smartphone, applications Web basées sur un navigateur, applications Facebook ou WeChat intégrées, applications de réalité virtuelle, et
  • éditeur de codage tel que PyCharm, IDLE et Atom.

Compte tenu de la grande confusion causée par ces sources de complexité, il n'est pas surprenant que"Comment commencer ?" est l'une des questions les plus fréquemment posées par les débutants en programmation.

Pour répondre tout de suite à la question, la meilleure façon de commencer n'est pas en choisissant un livre de programmation et en lisant toutes les caractéristiques syntaxiques du langage de programmation. Étonnamment, ces livres de codage se vendent bien - même moi, je suis un vendeur de ces livres. Cependant, en interagissant personnellement avec des milliers d'étudiants en programmation, j'ai réalisé que de nombreux étudiants ambitieux achètent des livres de programmation comme un dispositif d'engagement pour mettre la tâche d'apprentissage sur leurs listes de tâches - s'ils ont dépensé de l'argent pour le livre, ils feraient mieux de le lire ou l'investissement sera être perdu. Mais comme tant d'autres tâches sur leurs listes de tâches, la lecture d'un livre de programmation est rarement une tâche à accomplir.

De nombreux étudiants achètent ces didacticiels de programmation, mais très peu les lisent réellement.

Alors, quelle est la meilleure façon de commencer à apprendre à programmer ? À mon avis, la meilleure façon de commencer est de choisir un projet de code pratique - simple si vous êtes débutant - et de le pousser jusqu'à son terme.

  • Ne lisez pas de livres de codage avant de faire cela.
  • Ne lisez pas de didacticiels au hasard sur le Web.
  • Ne faites pas défiler les flux interminables sur StackOverflow.

Configurez simplement le projet et commencez à coder avec les compétences limitées dont vous disposez et votre bon sens.

Ce n'est pas grave si vous ne comprenez pas ce que vous faites, vous augmenterez progressivement votre compréhension. Vous lisez des livres et des articles uniquement pour progresser sur le projet qui vous attend. En plongeant dans le processus de finition de votre premier projet, vous devez résoudre un certain nombre de problèmes très pertinents :

  • Quel éditeur de code devez-vous utiliser ?
  • Comment installer Python ?
  • Comment lire les entrées d'un fichier ?
  • Comment stocker l'entrée dans votre programme pour une utilisation ultérieure ?
  • Comment manipuler l'entrée pour obtenir la sortie souhaitée ?

En répondant à ces questions, vous construisez progressivement un ensemble de compétences bien équilibré d'un praticien. Au fil du temps, vous répondrez de mieux en mieux à ces questions. Votre vitesse et votre habileté à résoudre ces problèmes augmenteront. Vous serez en mesure de résoudre des problèmes similaires beaucoup plus importants et vous créerez votre base de données interne de modèles de programmation et d'idées conceptuelles. Même les codeurs avancés apprennent et s'améliorent avec exactement le même processus. Seuls les projets de codage sont devenus beaucoup plus gros et plus compliqués.

Supposons que vous adoptiez cette approche d'apprentissage par projet. Vous vous concentrez sur un seul projet et y travaillez pendant un temps considérable. Quel est votre plus grand ennemi maintenant ? Vous l'avez deviné :complexité .

Vous aurez du mal avec la complexité dans :

  • trouver des bogues dans des bases de code en croissance constante,
  • comprendre les composants du code et leur interaction,
  • choisir la bonne fonctionnalité à implémenter ensuite,
  • comprendre les bases mathématiques et conceptuelles du code.

La complexité est partout , à chaque étape d'un projet qui prend vie. Et les coûts cachés de cette complexité sont bien tangibles :les codeurs qui débutent jettent l'éponge et les projets ne voient jamais le jour. Le débutant argumente :"coder est trop difficile pour moi" et il y croit vraiment, même si rien ne peut être plus éloigné de la vérité.

La racine du problème est une complexité écrasante et un manque de concentration. Alors, la question se pose :

Comment résoudre la complexité et le manque de concentration ?

La réponse est simple, et je l'ai déjà souligné à plusieurs reprises dans ce livre :minimalisme . Recherchez la simplicité et la concentration - à chaque étape du cycle de codage. Je veux que vous retiriez ce concept du livre :adoptez une position radicalement minimaliste dans tous les domaines que vous rencontrerez dans l'espace de programmation. Si ce livre peut vous convaincre de prendre des mesures plus extrêmes pour augmenter votre concentration, il a rempli sa mission !

Approfondissons le concept de complexité pour développer une compréhension de l'un des grands ennemis de votre productivité de codage.

Qu'est-ce que la complexité ?

Dans différents domaines, le terme complexité a différentes significations. Parfois, il est strictement défini, comme dans la complexité de calcul d'un programme informatique qui fournit un moyen d'analyser une fonction de code donnée pour des entrées variables. D'autres fois, il est vaguement défini comme la quantité ou la structure des interactions entre les composants du système. Mais dans ce livre, nous allons l'utiliser de manière plus générique.

Le dictionnaire Merriam Webster définit la complexité comme "quelque chose de complexe" . Le terme complexe est défini comme "un tout composé de […] parties compliquées" . Si vous résolvez le terme compliqué—"difficile à analyser, comprendre ou expliquer" — vous vous retrouvez avec la définition approximative suivante :

Complexité :"un tout, composé de parties, difficile à analyser, à comprendre ou à expliquer" .

C'est ainsi que nous utilisons le terme complexité dans ce livre. La complexité décrit un système entier ou une entité. C'est difficile à expliquer ou à décrire. En raison de sa difficulté, la complexité provoque lutte et confusion. Lorsqu'ils sont confrontés à la complexité, les gens se retrouvent cognitivement incapables de comprendre le sens profond, les implications ou les effets de "l'ensemble".

Ils ne peuvent pas voir la situation dans son ensemble - la complexité est l'ennemie de la clarté, de la clôture et de la prévisibilité, car un système complexe se comporte de manière hautement imprévisible. Où trouvez-vous la complexité ? Vous le trouverez partout, car les systèmes du monde réel sont désordonnés :un réseau de causes et d'effets hautement interdépendants qui obscurcit le comportement d'un système réel, et qui est impossible à décoder pour les individus qui sont eux-mêmes pris dans ce réseau complexe. Comme une équation différentielle, la sortie d'un système alimente l'entrée d'un autre système qui, à son tour, réinjecte dans le premier système en tant qu'entrée. Des exemples de systèmes très complexes sont le marché boursier, les tendances sociales, les points de vue politiques émergents et les gros programmes informatiques avec des centaines de milliers de lignes de code, comme le système d'exploitation Windows.

Si vous êtes un codeur, vous êtes particulièrement sujet à une complexité écrasante. Plongeons-nous dans différentes sources de complexité dans le domaine de la programmation :

  • Complexité dans le cycle de vie d'un projet
  • Complexité des logiciels et théorie algorithmique
  • Complexité dans l'apprentissage
  • Complexité des processus
  • Complexité des réseaux sociaux
  • La complexité dans votre vie quotidienne
  • Complexité dans le cycle de vie d'un projet

La meilleure façon d'apprendre et de créer une valeur durable est de participer ou d'initier un projet réel. Mais à quoi cela ressemble-t-il lorsqu'un projet du monde réel prend vie ? Plongeons-nous dans les différentes étapes du cycle de vie d'un projet :planification, définition, conception, création, test et déploiement (voir la figure 1).

Figure 1  :Un projet logiciel prend vie - le cycle de vie du projet se compose de six phases conceptuelles :planification, définition, conception, construction, test, déploiement.

La figure 1 montre le cycle de vie du développement logiciel composé de six phases. Même si vous travaillez sur un très petit projet logiciel, vous traversez probablement les six phases du cycle de vie du développement logiciel. Ensuite, vous découvrirez rapidement les six phases et l'impact significatif de la complexité sur chacune d'entre elles.

Planification

La première étape du cycle de vie du développement logiciel est la phase de planification. D'après la littérature sur le génie logiciel, vous connaissez peut-être cela sous le nom d'analyse des exigences . Le but de cette phase est de déterminer à quoi ressemblera le produit final. Une phase de planification réussie conduit à un ensemble strictement défini de fonctionnalités requises à fournir au client ou à l'utilisateur final.

La phase de planification résout un problème multidimensionnel où différents départements et fonctions doivent collaborer pour déterminer l'ensemble optimal de fonctionnalités du logiciel. Un certain nombre de facteurs doivent être pris en considération :les coûts de construction d'une fonctionnalité, le risque de ne pas réussir à implémenter la fonctionnalité, la valeur attendue pour l'utilisateur final, les implications marketing et commerciales, la maintenabilité, l'évolutivité, les restrictions légales et bien d'autres. plus.

Cette phase est cruciale car elle peut vous éviter des gaspillages massifs d'énergie en aval dans les phases suivantes. Les propriétaires d'entreprise savent que l'allocation de capital (ou de manière générale :allocation des ressources ) est la fonction la plus importante d'un PDG. La phase de planification est celle où l'effet de levier joue à son maximum :les erreurs de planification peuvent entraîner un gaspillage de ressources d'une valeur de plusieurs millions de dollars. D'autre part, une planification minutieuse a le pouvoir de préparer l'entreprise à un grand succès dans les années à venir. La phase de planification est un excellent point de levier où vous pouvez appliquer votre compétence nouvellement acquise de réflexion 80/20.

Cependant, la phase de planification est également très difficile à réaliser correctement.

Pourquoi? A cause de notre ennemi majeur qui rôde partout :la complexité . Il est compliqué d'évaluer correctement les risques à l'avance. Il est tout aussi compliqué de déterminer l'orientation stratégique d'une entreprise ou d'une organisation. Il est compliqué de deviner les réponses des clients à un projet logiciel. Il est compliqué de peser l'impact positif des différentes fonctionnalités candidates - les fonctionnalités qui sont envisagées pour l'inclusion. Et il est compliqué de déterminer les implications juridiques d'une fonctionnalité logicielle donnée. Dans l'ensemble, la complexité de la résolution de ce problème multidimensionnel nous tue.

Définir

Par rapport à la phase précédente, cette phase est relativement simple. La phase de définition consiste à traduire les résultats de la phase précédente (exigences) en exigences logicielles correctement spécifiées. En d'autres termes, il formalise le résultat de la phase précédente pour obtenir l'approbation ou les commentaires des clients et des utilisateurs finaux qui utiliseront le produit ultérieurement.

Conception

L'objectif de la phase de conception est de rédiger l'architecture du système , décidez des modules et composants qui fournissent les fonctionnalités définies et conçoivent l'interface utilisateur – en gardant à l'esprit les exigences qui ont été élaborées au cours des deux phases précédentes. L'étalon-or de la phase de conception est de créer une image parfaitement claire de l'apparence du produit logiciel final et de la manière dont il est construit.

Mais le diable se cache dans les détails ! Un grand concepteur de système doit connaître les avantages et les inconvénients de divers outils logiciels pour construire le système de la manière la plus efficace. Par exemple, certaines bibliothèques peuvent être très faciles à utiliser par le programmeur mais lentes en vitesse d'exécution. Construire ses propres bibliothèques est plus difficile pour les programmeurs, mais peut entraîner une vitesse beaucoup plus élevée et, par conséquent, une meilleure convivialité du produit logiciel final. La phase de conception doit fixer ces variables afin que le rapport avantages/coûts soit maximisé, pour les définitions spécifiques des coûts et des avantages dans votre organisation.

En gros, vous voulez en avoir pour votre argent.

Bâtiment

C'est là que de nombreux codeurs veulent passer tout leur temps. La phase de construction est l'endroit où la transformation de l'ébauche architecturale au produit logiciel se produit . Ici, vos idées se transforment en résultats tangibles. Il est satisfaisant de voir votre idée prendre vie.

Grâce à une bonne préparation dans les phases précédentes, une grande partie de la complexité a déjà été éliminée. Par exemple, les constructeurs savent quelles fonctionnalités implémenter parmi toutes les fonctionnalités possibles. Ils savent à quoi ressemblent les fonctionnalités et quels outils utiliser pour les mettre en œuvre.

Pourtant, la phase de construction est toujours pleine de problèmes nouveaux et émergents . Des événements inattendus se produisent et ralentissent la progression, tels que des bogues dans des bibliothèques externes, des problèmes de performances, des données corrompues, des erreurs humaines et bien d'autres. Construire un produit logiciel est une entreprise très compliquée. Pour écrire un bon logiciel, vous devez utiliser un langage artificiel et expliquer correctement aux machines stupides ce qu'il faut faire dans toutes les circonstances possibles. Une petite faute d'orthographe (=bug) peut décider de l'exactitude et de la viabilité de l'ensemble du produit logiciel.

Test

Félicitations, vous avez implémenté toutes les fonctionnalités demandées et le programme semble fonctionner.

As tu fini? Pas assez!

Vous devez toujours tester le comportement de votre produit logiciel pour différentes entrées utilisateur et modèles d'utilisation . Cela semble être un détail mineur, mais cette phase est souvent la plus importante de toutes !

En fait, c'est tellement important que de nombreux praticiens préconisent désormais l'utilisation du développement piloté par les tests où vous ne commencez même pas à implémenter (dans la phase précédente) sans avoir écrit tous les tests. Bien que vous puissiez contester ce point de vue - je n'ai pas vu de moyen de déployer rigoureusement le développement piloté par les tests dans la pratique - c'est généralement une bonne idée de passer beaucoup de temps à réfléchir à différentes façons de tester votre produit en créant des cas de test et vérifier si le logiciel fournit le bon résultat pour ces cas de test.

Par exemple, si vous implémentez une voiture autonome, vous devez écrire des tests dits unitaires pour vérifier si chaque petite fonction (une unité) de votre code génère la sortie souhaitée pour une entrée donnée. Cela découvrira généralement certaines fonctions défectueuses qui se comportent étrangement sous certaines entrées (extrêmes). Mais même si tous vos tests unitaires réussissent, vous n'avez pas encore terminé la phase de test. Vous devez tester l'interaction correcte des unités car elles construisent un plus grand ensemble. Vous devez concevoir des tests dans le monde réel, conduire la voiture sur des milliers voire des dizaines de milliers de kilomètres pour découvrir des comportements étranges dans des situations étranges et imprévisibles.

  • Que se passe-t-il si votre voiture roule sur une petite route sans signalisation ?
  • Et si la voiture devant vous s'arrête brusquement ?
  • Et si plusieurs voitures s'attendaient à un carrefour ?
  • Que se passe-t-il si le conducteur se dirige soudainement vers un trafic qui approche ?

Il y a tellement de tests à prendre en compte - la complexité est si élevée que beaucoup de gens jettent l'éponge ici. Ce qui semblait bien en théorie, même après votre première mise en œuvre, échoue souvent en pratique après l'application de différents niveaux de tests logiciels tels que des tests unitaires ou des tests d'utilisation dans le monde réel.

Déploiement

Votre logiciel a passé la phase de test rigoureux. Il est maintenant temps de le publier et de le lancer sur le marché .

Cette phase vous oblige à lancer le produit, à créer des campagnes marketing, à parler aux premiers utilisateurs du produit, à corriger de nouveaux bogues qui apparaîtront sûrement après avoir été exposés aux utilisateurs, à orchestrer le déploiement du logiciel sur différents systèmes d'exploitation, à assurer le support et le dépannage différents types de problèmes, et maintenir la base de code pour s'adapter et s'améliorer au fil du temps. Inutile de dire que cette phase peut devenir assez compliquée, compte tenu de la complexité et de l'interdépendance des différents choix de conception de votre produit (comme les bibliothèques logicielles utilisées, la puissance de calcul requise, les modèles d'utilisation supposés).

Êtes-vous déjà découragé ? Bien - maintenant vous connaissez l'ennemi. Mais restez avec nous car il y a une solution dans ce livre !

Complexité des logiciels et théorie algorithmique

Bien qu'il y ait une complexité importante dans l'ensemble du processus de développement de logiciels, il y a autant de complexité dans un logiciel donné. La complexité des logiciels :comment la définit-on ? Vous avez peut-être déjà une intuition concernant la complexité des produits logiciels (« Waouh – comment ont-ils implémenté cette fonctionnalité de détection de visage ! Cela a dû être vraiment compliqué ! » ).

Mais il existe de nombreuses métriques en génie logiciel qui mesurent la complexité des logiciels de manière plus formelle .

Par exemple, il y a le terme précisément défini de complexité algorithmique. Cela n'a rien à voir avec l'intuition quant à la facilité avec laquelle vous pouvez comprendre un morceau de code donné. Au lieu de cela, la complexité algorithmique parle des besoins en ressources des différents algorithmes. Il vous permet de comparer différents algorithmes qui résolvent le même problème. Par exemple, supposons que vous ayez implémenté une application de jeu avec un système de notation des meilleurs scores. Vous voulez que les joueurs avec le score le plus élevé apparaissent en haut de la liste et les joueurs avec le score le plus bas en bas.

En d'autres termes, vous devez trier la liste. Trier une liste est plus compliqué pour 1 000 000 que pour 100 joueurs. Il existe des milliers d'algorithmes pour trier une liste. Certains algorithmes évoluent mieux avec une taille croissante de l'entrée de la liste ; d'autres évoluent plus mal. Tant que votre application sert quelques centaines d'utilisateurs, peu importe l'algorithme que vous choisissez. Mais à mesure que votre base d'utilisateurs augmente, la complexité d'exécution de la liste augmente de manière super linéaire. Bientôt, vos utilisateurs devront attendre de plus en plus longtemps pour que la liste soit triée. Ils commencent à se plaindre :vous avez besoin de meilleurs algorithmes !

La figure 2 illustre la complexité algorithmique de deux algorithmes schématiques. Sur l'axe des abscisses, il indique la taille de la liste à trier. L'axe des ordonnées montre le temps d'exécution de l'algorithme (en unités de temps). L'algorithme 1 est beaucoup plus lent que l'algorithme 2. En fait, l'inefficacité de l'algorithme 1 devient de plus en plus apparente, plus il faut trier d'éléments de liste. En conséquence, votre application de jeu devient de plus en plus lente, plus les utilisateurs jouent avec.

Illustration 2 :Complexité algorithmique de deux algorithmes de tri différents.

C'est pourquoi la complexité algorithmique est un domaine de recherche approfondie avec des décennies de progrès et des myriades d'informaticiens qui réduisent continuellement la complexité algorithmique des algorithmes pour résoudre les mêmes problèmes de plus en plus vite. À mon avis, les algorithmes produits au cours de décennies de recherche en informatique sont parmi les actifs technologiques les plus précieux de l'humanité . Ces algorithmes nous permettent de résoudre les mêmes problèmes avec moins de ressources, pas une fois, mais encore et encore. Nous nous tenons vraiment sur les épaules de géants.

Fait intéressant, la complexité algorithmique n'est pas la seule métrique qui mesure la complexité du code. Il existe également des mesures pratiques telles que la complexité cyclomatique, une métrique développée par Thomas McCabe en 1976 qui décrit le nombre de chemins linéairement indépendants à travers votre code :le nombre de chemins qui ont au moins un bord qui n'est pas dans un autre chemin. Par exemple, un code avec une instruction if entraînerait deux chemins indépendants dans votre code, il aurait donc une complexité cyclomatique plus élevée qu'un code plat sans instruction if. La complexité cyclomatique est une mesure solide de la complexité cognitive de nombreuses bases de code.

Cependant, cette mesure de complexité ignore la complexité cognitive qui vient, par exemple, de l'imbrication de boucles for différentes par rapport à une boucle for plate. Il existe d'autres mesures qui améliorent cela (comme la complexité NPath). L'important à retenir, cependant, est que la complexité est un facteur si important à la fois dans la théorie algorithmique et dans la pratique de la mise en œuvre qu'elle a fait l'objet de recherches approfondies pendant des décennies par des centaines de milliers de chercheurs. L'objectif de tous ces efforts est de réduire la complexité pour atténuer ses effets néfastes sur la productivité et l'utilisation des ressources des humains et des machines.

Complexité dans l'apprentissage

L'information mondiale peut être modélisée comme un énorme réseau de morceaux d'information interdépendants — et aucun morceau d'information n'est indépendant des autres morceaux.

En 2012, Google a annoncé le remplissage d'une structure de données appelée "Knowledge Graph" avec des informations. Le graphe de connaissances représente les informations dans une structure semblable à un réseau qui, au lieu de stocker des faits stupides et indépendants, a maintenu une relation entre différents faits et éléments d'information.

Le moteur de recherche Google a ensuite utilisé cette interdépendance des faits pour enrichir les résultats de recherche avec des connaissances de plus haut niveau et créer de nombreuses réponses de manière autonome.

Exemple :une petite partie du graphe des connaissances concerne peut-être le célèbre informaticien Alan Turing. Dans le graphe des connaissances, le concept d'Alan Turing est relié à différentes informations telles que son année de naissance (1912), son domaine d'études (informatique, philosophie, théorie du langage) et son directeur de thèse (Alonzo Church). Chacune de ces informations est également liée à d'autres faits (par exemple, le domaine d'étude d'Alonzo Church était également l'informatique), formant un vaste réseau de faits interdépendants. Vous pouvez utiliser ce réseau pour acquérir de nouvelles informations et répondre aux requêtes des utilisateurs par programmation. Par exemple, une requête sur le "domaine d'études du père médecin de Turing" entraînerait la réponse déduite "informatique". Bien que cela puisse vous sembler trivial, la génération de nouveaux factoïdes comme ceux-ci conduit à une percée dans la recherche d'informations et la pertinence des moteurs de recherche. Vous conviendrez probablement qu'il est beaucoup plus efficace d'apprendre par association qu'en se souvenant de faits sans rapport. Vous pouvez facilement vous souvenir d'une histoire, mais vous avez du mal à vous souvenir du numéro de téléphone de votre mère !

Tout domaine d'étude explore et essaie d'étendre le graphe des connaissances de l'humanité avec plus de faits et d'observations . Mais n'importe quel domaine d'étude se concentre uniquement sur une petite partie du graphique, chacun composé de myriades de factoïdes interdépendants. Vous ne pouvez pas vraiment dire que vous avez compris un fait, si vous n'avez pas déjà compris tous les faits connexes. Comment pouvez-vous connaître Alan Turing sans connaître les croyances, les philosophies et les caractéristiques de son conseiller de doctorat Church ? Et comment comprendre Church sans comprendre aussi Turing ?

Si vous étudiez n'importe quel domaine, vous devez accumuler des connaissances sur un grand nombre de faits interdépendants . Au fil du temps, vous comprendrez plus que vous ne compreniez auparavant, mais vous ne comprendrez jamais tout. La connaissance est beaucoup trop complexe. Il y a trop de dépendances et de faits dans le graphique. Vous pouvez en apprendre plus mais plus vous apprenez, plus vous prenez conscience des limites de vos connaissances. Il est évident que la complexité pose les limites les plus fondamentales à vos ambitions d'apprendre. Apprentissage et complexité sont les deux faces d'une même médaille :la complexité est à la limite des connaissances que vous avez déjà acquises. Pour en savoir plus, il faut d'abord savoir maîtriser la complexité.

Nous obtenons une sorte de résumé ici, alors prenons un exemple pratique ! Supposons que vous souhaitiez programmer un robot de trading qui achète et vend des actifs selon un ensemble de règles sophistiquées. Il y a beaucoup de connaissances utiles que vous pourriez apprendre avant de commencer votre projet. Vous pourrez en apprendre davantage sur des concepts tels que les bases de la programmation, les systèmes distribués, les bases de données, les interfaces de programmation d'applications (API), les services Web, l'apprentissage automatique, la science des données, les mathématiques et bien d'autres.

Vous pouvez en apprendre davantage sur des outils pratiques tels que Python, NumPy, Scikit-learn, CCXT, TensorFlow et Flask. Vous pourriez en apprendre davantage sur les stratégies de négociation et les philosophies boursières. Et, en fait, beaucoup de gens abordent ces problèmes avec un tel état d'esprit. Ils n'arrêtent jamais d'apprendre. Ils ne se sentent jamais prêts à démarrer le projet. Ils continuent d'apprendre parce que plus ils apprennent, moins ils se sentent compétents. Chacune des catégories mentionnées exigera des milliers d'heures d'étude pour la maîtriser. Vous n'atteindrez jamais une maîtrise suffisante dans tous ces domaines pour vraiment satisfaire votre désir de vous sentir préparé. Frustré et submergé par la complexité de l'ensemble de l'entreprise, vous avez envie de jeter l'éponge et de laisser le champ à des codeurs plus intelligents. La complexité est sur le point de faire sa prochaine victime :vous.

Heureusement, parce que vous avez lu ce livre, vous avez atteint la seule arme efficace contre la complexité . Cette arme a plusieurs noms :concentration, simplification, réduction, réduction, minimalisme. C'est ainsi que vous obtenez le succès :vous vous concentrez sur la maîtrise d'un domaine et oubliez tout le reste. Vous réduisez la complexité avec le minimalisme. Vous pensez aux premiers principes et oubliez le bruit. Vous créez un programme, pas plusieurs. Philosophiquement, vous visez une vie pleine et n'essayez pas d'en vivre cent partielles.

Complexité des réseaux sociaux

La complexité apparaît partout où il y a interaction entre de nombreux composants différents. Les réseaux sociaux en sont un parfait exemple. Si vous travaillez dans une grande organisation, vous savez que des centaines, voire des milliers de personnes doivent travailler ensemble pour atteindre des objectifs communs. Dans le même temps, des milliers de personnes ont également des milliers d'opinions et de perspectives différentes sur les mêmes sujets.

Atteindre le même objectif peut être un étirement pour une personne et un jeu d'enfant pour une autre. L'écriture de 100 lignes de code peut prendre un programmeur par semaine et un autre par jour. Un troisième programmeur écrit 200 lignes de code en une demi-heure, offrant une qualité supérieure aux deux. De plus, certaines personnes travaillent bien en équipe, d'autres travaillent mieux seules.

La complexité fait partie intégrante des réseaux sociaux. Mais en quoi est-ce pertinent pour un livre technique comme celui-ci ? De nombreux ingénieurs logiciels talentueux finissent par devenir des chefs d'équipe. (Vous êtes promu jusqu'à ce que vous atteigniez votre niveau d'incompétence.) Ils quittent maintenant le monde simple et propre des logiciels, parlant comparativement, et entrent dans le monde des interactions sociales, de la politique de bureau, du leadership et de la motivation d'équipe. Naturellement, ils utilisent les outils qu'ils ont appris en programmation et les appliquent à leurs nouvelles tâches de direction d'équipe. Ils essaient de programmer chaque membre de l'équipe avec des journaux d'activité détaillés et des structures rigides et, par conséquent, finissent par microgérer les gens comme ils ont microgéré des machines stupides. Pourtant, cela n'évolue clairement pas et ne maintient pas le moral !

Si vous vous trouvez en tant que chef d'équipe, commencez à vous reprendre. Oubliez vos livres de règles et vos algorithmes. Au lieu de cela, faites confiance et motivez, soyez empathique et écoutez, défendez les membres de votre équipe contre les distractions et les influences néfastes tout en reprenant vos propres intérêts pour nourrir votre équipe , et créer un micro-organisme sain et fonctionnel avec sa propre intelligence, sa culture et sa dynamique pour résoudre les problèmes au fur et à mesure qu'ils surviennent.

Une interaction sociale efficace est un problème hautement multidimensionnel et il existe des exceptions à chaque règle que vous pourriez formuler pour des situations sociales. De nombreux codeurs ne peuvent pas le gérer :ils préfèrent maîtriser la complexité des ordinateurs avec des règles et des algorithmes, plutôt que d'embrasser la complexité désordonnée des relations humaines.

Existe-t-il d'autres sources de complexité ? Vous pariez qu'il y en a !

Complexité des processus

Un processus est une série d'actions que vous, un groupe de personnes ou même une machine entreprenez dans le but d'obtenir un résultat défini.

La complexité d'un processus est donnée par son nombre d'actions, de participants ou de branches. En général, si vous avez plus d'actions, le processus devient plus compliqué (voir Figure 3).

Illustration 3  : Deux exemples de processus :développement par une personne ou développement en équipe.

De nombreux processus ont été développés et de nombreuses sociétés de logiciels suivent des modèles de processus pour développer des logiciels (par exemple, développement agile, scrum), maintenir la relation client (par exemple, CRM, scripts de vente) et créer de nouveaux produits et modèles commerciaux (par exemple, modèle commercial Toile). Si les personnes sont la pierre angulaire d'une entreprise, les processus en sont les veines et les artères. Si vos artères sont cadencées, vous devez vous débarrasser rapidement des goulots d'étranglement ou votre corps en souffrira. C'est la même chose pour une entreprise :si l'entreprise souffre, vous devez éliminer les goulots d'étranglement dans vos processus commerciaux pour rester en vie.

Dans une organisation, il est souvent plus facile d'établir un nouveau processus que de modifier un processus existant en raison des parties prenantes des processus établis. Try to shut down an unprofitable department in your organization and you’ll quickly learn this lesson. Many organizations deteriorate into bureaucracies through the continuous accumulation of more and more processes. Complexity starts to accumulate in the system. Innovation finds less and less vehicles for change—it can’t break through the complexity. Resources are wasted and an increasing number of actions within processes become redundant or even unnecessary. Trying to fix the suffering business, management invests energy to establish new processes and new actions and the vicious cycle begins to destroy the business or organization.

Complexity is the enemy of efficiency. If you want to build an efficient organization, or if you want to become an efficient individual, radically weed out unnecessary steps, actions, and processes. Keep your house clean and engage in radical minimalism! Don’t worry, you most likely won’t reach the point where you have weeded out too much. There’s no point in telling yourself that complexity in processes is useful and things can be oversimplified. This is like telling an obese society that they must ensure to eat enough sugar to feed their bodies with energy. Yes, but no – an increase in complexity and sugar consumption is built into the modern world and takes care of themselves!

Complexity in Your Daily Life or the Death of a Thousand Cuts

The purpose of this book is to increase the productivity of your programming efforts. To become a more efficient programmer, you must tackle the daily distractions and the constant competition for your valuable time. There’s a never-ending stream of external distractions that keep you from doing the deep work required for programming. Computer science professor Cal Newport talks about this in his excellent book Deep Work (a recommended read). He argues that there’s both an increasing demand for work that requires deep thinking—programming, researching, medicine, writing—and a decreasing supply due to the proliferation of communication devices, opportunities, and entertainment systems. If increasing demand meets decreasing supply, economic theory suggests that prices will rise. If you’re capable of engaging in deep work, your economic value will increase and your income will rise.

In fact, you can observe this trend in the programming industry:the average freelance developer earns $61 per hour. There never has been a better time for programmers who can engage in deep work. For instance, highly skilled machine learning engineers demand multiples of hundreds of thousands of dollars in yearly salaries.

Now, the caveat:it has become almost impossible to engage in deep work if you don’t brutally enforce it. The external world demands your attention. Your boss and your colleagues will regularly pop into your office. Your smartphone will demand your attention in, say, 20 minute intervals. Your email provider will present you with email after email—each asking for a slice of your time. To make matters worse, not only the external world plays against your plan to engage in deep work—your internal work does, too. Deep work results in delayed gratification. It’s a satisfying feeling to have spent weeks of your time to complete a computer program that works.

However, what you desire in most moments is instant gratification . If you’re about to dive into deep work, your subconsciousness realizes how much effort it is and looks for ways to escape from the effort engaging in deep work. You want to answer the message from your friend because it will produce an easy boost of your endorphins. You want to engage in meaningless chit chat in the coffee corner. You want to watch Netflix and TV. The promise of delayed gratification becomes less and less attractive compared to the happy, colorful and lively world of instant gratification.

Due to the abundant availability of external stimuli in today’s world, your efforts to become productive are likely to die the death of a thousand cuts. Yes, you can switch off your smartphone once and use willpower to not watch an episode of your preferred series today. But can you do it consistently day after day? And even if you could force yourself not to use social media, will you be able to resist the urge of answering all emails in your Inbox—and use this time to write on your first novel? There’s an important difference between being busy and being productive!

How to Handle a Complex World

I hope that by now you are properly motivated why you need to overcome complexity—this was the purpose of this whole chapter. You should now see how complexity is the enemy of the lean and efficient organization and individual. You simply cannot become productive without mastering tactics and strategies to handle complexity. A simple but efficient tactic to overcome complexity in social networks is to uninstall them from your smartphone (I won’t water down this recommendation only because some people assume it’s not possible—read Deep Work from Cal Newport if you want to learn how it can be done). A simple strategy to overcome complexity in business is to schedule a monthly session where you discuss with your teams tasks you can get rid of—even knowing that these tasks may provide some value to some people (think:opportunity costs, not absolute value).

Let’s recap some of the most important consequences of the preceding arguments:

  • Complexity harms productivity due to the loss of focus it incurs.
  • If you don’t take control and full responsibility for this problem, it will quickly consume your most precious resource:time.
  • At the end of your life, you won’t judge whether you’ve led a meaningful life based on how many emails you’ve replied to, how many hours of computer games you’ve played, or how many Sudokus you’ve solved.

In the previous chapter, you’ve learned about the power of the 80/20 principle. Focus on the vital few and ignore the trivial many. How is the 80/20 principle connected to complexity? This is an interesting question – both seem to be two sides of the same coin! In a way, complexity creates the opportunity of focusing on the vital few . If only the vital few existed, everyone would only focus on them and there wouldn’t be any opportunity to create more with less.

But fear not – this is not how the world works. Instead, you’ll have plenty of opportunities to achieve more with less because complexity is an integral part of modern life. In fact, with inflating opportunities to spend your time, a growing amount of educational and entertaining content, and proliferating opportunities to visit every place and connect to every person under the sun, you can be sure to face an increasing amount of complexity in the decades to come. However, by learning how to handle complexity, by keeping it simple, you’ll be able to fight complexity better than most people and you’ll create a powerful competitive advantage for yourself and your business.

As the 80/20 principle, complexity is everywhere, and you constantly need to think about how to reduce complexity and simplify things. Keep it simple, stupid!

In the next chapter, we’ll learn how to apply this idea of keeping it simple by radically reducing complexity in the software development cycle and the value creation process as a software developer:minimum viable products .

… to be continued …

This article is based on a draft of a new chapter of my upcoming book “From One to Zero:A Minimalistic Approach to Programming” . Stay tuned for launch updates!



Post précédent