Some advices to improve my level / Quelques conseils pour améliorer mon niveau

Good evening everyone,
excuse me if there are mistakes in the english version of my message but i am trying to master english since a little time and i wanted to also post in english.
it makes few years I’m a programmer but I always found myself not very good.While trying to solve online puzzles and, with my participation on codingame I realised more about my weaknesses because I use for example a lot of nested loops and complex manipulations of Strings that unnecessarily complicate my code . When I compare the proposed solutions, I realize the fact that there is a large gapwithin them and my approach to algorithmic problems.
I usually analyze the algorithm to write as a result of processing to be performed, write her treatments then try to optimize them after. However I think that in some cases the process must be different. So I am asking to the community for advices to improve my approach of algorithms problems. Are there things I need to learn in particular? I have a good knowledge of the main data structures and basic algorithms associated with it but it does not seem enough. Thank you for all your help and I think it may help others in my situation that fail to exceed a certain level of algorithms solving.

Bonsoir à tous,
cela fait quelques années déjà que je suis programmeur mais je me suis toujours trouvé moyen. A force d’essayer de résoudre des puzzles en ligne et, avec ma participation sur codingame je me rend encore plus compte de mes lacunes car je fais par exemple très souvent des boucles imbriquées et des manipulations complexes de chaines de caractère qui complexifient inutilement mon code. Lorsque je le compare aux solutions proposées, je me rend compte du fait qu’il y a une grande lacune au niveau de la façon d’aborder les problèmes algorithmiques.
J’ai l’habitude d’analyser l’algorithme à écrire comme une suite de traitements à effectuer, écrire ses traitements puis essayer de les optimiser tant bien que mal. Cependant je pense que dans certains cas il faut procéder autrement ou améliorer cette façon de faire. Je me tourne donc vers la communauté pour demander des conseils pour améliorer mon approche des problèmes. Y a t’il des choses que je dois apprendre en particulier? J’ai une assez bonne connaissance des principales structures de données et des algorithmes de base qui y sont liés mais ça ne semble pas suffisant. Merci pour votre aide à tous et je pense que ça aidera éventuellement d’autres personnes dans mon cas qui n’arrivent pas à dépasser un certain niveau de résolution de problèmes.

Sur quel langage ?

Je parlais en général mais s’il faut choisir un langage java

2 choses qui me viennent en lisant ton post :

Pour la complexité du code, repose toi au maximum sur le langage que tu utilises, a chaque fois que tu veux faire quelque chose (surtout en java) il y a 90% de chances qu’une ou plusieurs fonctions/structures existent déjà pour te mâcher le travail. Sois paresseux :stuck_out_tongue: Le code “bas niveau” est obligatoire dans certains langages, pas en java.

“J’ai l’habitude d’analyser l’algorithme à écrire comme une suite de traitements à effectuer, écrire ses traitements puis essayer de les optimiser tant bien que mal.”

Essaie l’inverse, utilise des choses bien optimisées comme des structures à accès rapide, et vois si tu peux construire ton algo avec. En gros aller du bas vers le haut au lieu du haut vers le bas. Ça n’est clairement pas adapté à tous les algos, mais l’exercice peut t’aider à voir les choses sous un autre angle.

merci pour tes conseils Djoums. C’est vrai que je n’ai jamais vraiment essayé de me reposer sur les forces du langage.

Internet is a wonderfull tool for your mind, not so much for your ego! As long as it doesn’t make you utterly depressed, having your ego turn off put you in a good state of mind to start learning new things.

To go back to your problem, the answer is always the same: getting inspiration from others’ works, trying new stuff by yourself and making as many errors as possible (Churchill would probably phrase it better than myself). The only thing that really matters is to think first (or afterward, preferrably both) and not letting the keyboard (and your habits) take control. Starting by the code could quickly lead you to time consuming quagemires. Of course, if you really master a language, you can start drafting with it in a very efficient… and misleading way, because you never take the full measure of how much a language has shaped your mind until you try a very different one.

Better start with a paper, a pen and an eraser. If you can find something convincing this way, it won’t be brighter in Java or any other languages (let be clear, the choice of your language is just barely more significative than the color of your sockets, so, as long as you like it, it’s ok).

Lastly, don’t hesitate to post draft of your solutions on this forum. As long as you are providing work in progress and not posting a monoline “Thor keeps dying, help me!”, you will get answers.

2 Likes

Quelques conseils au pif et pas exhaustifs :

  • Il faut pratiquer. Le plus possible. C’est en forgeant qu’on devient forgeron.
  • Il faut pratiquer !
  • Ne pas hésiter à se lancer dans des gros projets personnels. Au pire tu te rates tu t’en fous.
  • Apprendre des autres. Il y a des projets opensources partout sur le net qui cherche des développeurs bénévoles dans le seul but d’apprendre. Tu en trouveras forcément un qui t’intéresse.
  • Pratique pratique pratique pratique !!!
  • Informe toi du côté des “design patterns” et apprend par coeur les plus utiles et les plus connus. L’encapsulation, le design factory, MVC, etc …
  • Rien ne remplace l’expérience et la pratique dans une entreprise avec une bonne équipe de dev. Je ne sais pas si tu es amateur, étudiant ou professionnel. Mais si je dois comparer mon niveau à ma sortie de fac (il y a 5 ans) et maintenant, c’est comme comparer un gamin qui fait un château de sable à un architecte. Et j’ai encore tellement de choses à apprendre
  • Toujours apprendre, ne jamais stagner.
  • Si tu rates un projet ou un challenge mais que tu as appris quelque chose, alors tu n’as pas perdu ton temps. Par contre si tu rates des choses sans rien apprendre, il faut changer ta méthode de travail.
  • Les algorithmes de bases (les différentes boucles, bien faire ses if), ça sert a faire les petits morceaux de codes. Bout à bout ça permet de faire un programme entier. Mais un bon développeur doit être capable d’adapter le niveau de zoom de son “œil” pour passer d’une vision d’ensemble de son projet / programme à une vision au microscope pour réussir à gérer un morceau de code en faisant abstraction du reste. C’est un exercice extrêmement complexe et c’est une capacité qui ne vient qu’avec la pratique.
  • Pourquoi t’es encore la ? Va pratiquer !
  • Se tenir à jour : Dans la vie d’un dev, si on ne tient pas à jour sur ce qui sort ou change dans les technologies qu’on utilise, on termine vite à la traine. Twitter aide énormément de ce côté la. Même si tu ne tweet pas (c’est mon cas), tu peux juste follow les twitter des technologies qui t’intéressent.
  • Comme le dit Djoums : Il faut savoir être une énorme feignasse. C’est assez compliqué à saisir le sens de cette phrase alors je vais tâcher d’expliquer. Imagine 2 devs, un dev malin mais paresseux et un dev moins malin mais dur à la tâche. Demande à ces 2 devs de faire un travail rébarbatif, je prend un exemple dans mon travail : On a 240 fichiers textes qui contiennent des plans de tests fonctionnels avec des nomenclatures de scénarios qui ressemble à @H-XX-Y. On a fichier excel qui est censé contenir tous ces scénarios. Petit problème, parfois on modifier les plans de tests fonctionnels et donc les scénarios ne correspondent plus. Catastrophe. On demande donc à ces 2 développeurs de mettre à jour le fichier excel pour contenir tous les scénarios des 240 fichiers textes. Le 2ème développeur (moins malin mais dur à la tâche) va se taper les 240 plans de tests à la main. Aucun problème il est rapide et c’est pas une feignasse il va terminer en moins d’une heure. Le 1er développeur, plus malin mais fainéant donc il est hors de question qu’il se tape les 240 fichiers, va y passer 4 heures. Mais en 4 heures, il a créé un programme qui lit le fichier excel pour trouver les scénarios déjà présents dedans, et un autre programme qui va lire les 240 fichiers textes. Pour ensuite comparer les 2 listes pour trouver les scénarios qui manquent ou qui sont en trop. Le 1er développeur a perdu 3 heures ? Clairement pas. Car toutes les fois suivantes où il faudra refaire ce travail, ça prendra 10 minutes. C’est ça être un développeur paresseux, toujours trouver un moyen d’automatiser et de faire plus rapidement ce qui est rébarbatif ou répétitif.
  • Je pense que tu pratiques pas assez
  • BRUTEFORCE IT !!!
  • La relecture de code est la meilleure chose qu’on a inventé pour ça. Demande à d’autres devs de regarder ton code pour te donner des conseils. Tu peux le faire par codingame (avec d’autres devs java qui ont déjà fait les puzzles pour qu’ils puissent voir ta solution). Mais tu peux aussi le faire ici : http://codereview.stackexchange.com/ Si c’est un gros projet, tu peux aussi demander à quelqu’un de regarder ton github directement.
  • Moins de code, plus de tests (mon leitmotiv)
7 Likes

Tu as oublié de dire qu’il faut pratiquer le plus possible.

6 Likes

Merci beaucoup pour tous vos conseils. Je pensais pratiquer suffisamment mais je pense que je vais augmenter la fréquence. Par contre une chose qui est vrai c’est que je n’ai pas l’habitude de présenter mon code puisque habituellement il fonctionne. C’est juste que comparé à celui des autres je pense qu’il est de moins bonne qualité. Je vais donc plus souvent présenter mes solutions entre autre sur ce forum car je pense que de très bons programmeurs sont ici. Je partager dans l’après midi le problème qui m’a convaincu d’écrire ce post sur le forum. J’espère que je peux partager des problèmes qui ne viennent pas du site.

Thank you! you are right about the use of the paper. At the begining I always did it before programming but now i have lost this habit. Thank you

1 Like
  • Avoir un code qui fonctionne ce n’est pas un pré-requis, tu le sais déjà que ça va fonctionné (tu as pas le choix :wink: ) donc ce qui est important c’est le moyen et non la fin.

  • Un code plus cours ou optimisé à fond n’est pas forcément meilleur, bien souvent les performances sont secondaires et donc c’est souvent mieux d’avoir un code facilement lisible

  • Évite au maximum les nested loop/if, si tu en as “trop” c’est sûrement que ton choix pour résoudre le problème est mauvais, sinon fait des fonctions/helper/…

  • Le copier-coller c’est le mal, ne jamais avoir deux (ou plus) choses identiques ou qui ce ressemble.

  • Être vraiment faignant (Magus a pas assez insisté sur ce point ^^) et donc faire le maximum pour en faire le moins

  • Sur les sites comme CG le code que tu peux voir n’est pas forcément bien. Par exemple un extrait de mon code pour “Notation Polonaise Inversée”

    boolean error = false;
    for (int i = 0; i < N && !error; i++) {
    String instruction = in.next();
    try {
    Operation.valueOf(instruction).perform(st);
    } catch (IllegalArgumentException ex) {
    st.push(Integer.valueOf(instruction));
    } catch (Exception ex) {
    error = true;
    }
    }

Si tu regardes le code dans son ensemble c’est “classe”, notamment parce-que c’est cours mais enfaîte c’est complètement nul et je ne code pas comme ça dans une “vrai” appli.
Le try catch est un “bad practice”, ça ne gère pas tout les cas (si instruction est ni une Operation ni un Integer ça crash), …
Ce n’est pas facilement lisible non plus et pourtant à l’heure actuelle c’est (je pense) la “meilleur” solution partagé en java pour ce puzzle.

  • Ça suit le point d’avant, remet en question le code des autres aussi et pas que le tien.
  • Même ceux qui font du code qui te parait vraiment meilleur que le tien font aussi du code tout moche/pas bien. Ça met arrivé plus d’une fois de tomber sur du code en me disant “o_O qui a pu faire cette horreur” et quand tu regardes l’historique des commit tu vois ton nom.
1 Like

Your English is much better than mine, and I’ve been speaking English for a few decades now (it isn’t my first language… uh… just lets have this casual reference to a human rights violation pass)

In the case of algorithms… using multiple loops is usually a terrible idea. As is the string manipulation you are talking about…

If you will, look into old books on programming theory/hypothesis… stuff from around the 1970s/1960s. Most of the programs here have solutions for them from those decades. There are programmers who state, “everything was programmed in the 1970s” as a somewhat joking boast. It isn’t entirely unaccurate either.

Try to find stuff written back when the standard home computer chip was the 6502 or z80 processors… or when for most real programming you’d need a Time Share on a Mainframe somewhere. Those books usually contain less of the, “get a better computer” that most modern day books tend to contain. Yeah… learning how to program for a RadioShack Timex Computer might seem silly—but… eh… it gives you a better appreciate for making the best use of limited run cycles… back when having something with barely a million instructions per second was considered bleeding edge. You know–back when having 480K or RAM was a ridiculous amount of RAM to make use of.

You can generally find these in various library burn sales (that is when they sell out dated books)–but there are also several places on the Internet that will keep these things… in a somewhat modified format for medium transference. They will generally contain several errors to them (eeeh… there was a time when an error in a programming text book was considered part of the deal)… but yeah.

When you’re writing down your methodology (before you start, as was mentioned), spend a good amount of time figuring out how you’re going to represent the data too. Write up classes or structs that will support the algorithm and make it easier to implement. Sometimes, just doing that will make you think of different ways to accomplish the goal.

Nested loops have their place and are sometimes unavoidable, but often they are a sign that your data structures are lacking in some way.

1 Like

En ce qui concerne l’aspect algorithmique, voici quelques trucs que j’ai appris à force de pratiquer:

  • force toi à approcher le problème à résoudre sous différents angles. Quand tu commences à résoudre un problème, tu as probablement tendance à te lancer plus ou moins à l’aveugle sur la 1ère méthode qui te semble bien (c’est probablement le cas de beaucoup de programmeurs, dont moi jusqu’à il y a quelques semaines). Essaie d’envisager plusieurs solutions (algorithmes et/ou structures de données) dès le début (avant même de prendre ton papier et ton crayon!!), tu te rendras vite compte si ta 1ère idée et bonne ou pas, et tu verras probablement émerger des solutions hybrides entre tes idées qui seront meilleures.

  • quand tu a un programme qui commence à fonctionner (pas forcément totalement), alors normalement tu as une bonne vision du problème à résoudre et de ses difficultés. A ce moment, oublie tout ce que tu as fait jusque là et trouve une autre solution (algo et structure de données encore). Avec la connaissance que tu as du problème à ce stade, tu verras que tu trouveras des solutions beaucoup plus simples et de meilleure qualité que celles que tu peux trouver au début.

  • un autre point dont je me suis rendu compte et qui m’aide énormément, c’est de trouver la structure de données minimale qui te permet de décrire entièrement tes données. J’entend par là de trouver une structure de données sans aucunes informations redondantes. Si tu devais faire une copie du problème, comment faire pour avoir le moins de choses à copier?
    Exemple: pour décrire un graphe, la structure qui me venait à l’esprit en premier c’est une structure récursive avec des noeuds qui connaissent leurs voisins. Selon le problème, tu peux peut-être te contenter de garder uniquement les arcs entre les noeuds (pas de structure récursive, même pas de classes).
    Pose toi aussi la question de qu’est-ce qui peut être modifié et qu’est-ce qui ne peut pas l’être (par exemple dans un graphe, certains algos peuvent modifier les arcs sans toucher aux noeuds (Skynet ou tu supprime des arcs), d’autres peuvent modifier les noeuds sans toucher aux arcs (tag des noeuds lors du parcours d’un graphe non orienté))
    Le but de cette démarche n’est pas d’utiliser cette structure minimale qui peut conduire à du code incompréhensible et à des algos plus compliqués que nécessaires, mais ça permet non seulement de te forcer à voir le problème sous un angle qui n’est pas forcément évident, mais aussi et surtout à te rendre compte que tu as des choses totalement inutiles et/ou redondantes dans ton code. Et ça ça peut t’éviter beaucoup de problèmes (oublie de mise à jour d’une partie du modèle quand tu modifie une autre partie, passages compliqués à gérer entre les différentes données redondantes), ça simplifiera ton code et ça te fera probablement gagner en performances.

  • comme l’ont dit d’autres avant moi, pratique! essaie d’adapter des algorithmes classiques à différents problèmes et différentes structures de données, renseigne toi sur les algos les plus adaptés selon les problèmes: est-ce que tu veux une solution? la meilleure solution? est-ce qu’une solution localement optimale suffit? quelle est ta ressource limitante: le temps ou la mémoire?

Voila je ne suis moi-même pas informaticien de formation mais je pratique beaucoup, et pour chaque problème je me renseigne sur les solutions d’autres développeurs (ce que tu as l’air de faire ;)).

Pour un des problèmes, pas trop difficile, j’ai utilisé une double structure qui m’a permis de passer tous les validateurs.

Merci à tous Vraiment déjà rien qu’après avoir lu vos quelques conseils je vois déjà en changement dans mon approche même si je sais que c’est avec le temps que les choses vont être plus solides. J’espère vraiment que ceux qui comme moi ont ces lacunes liront avec attention vos commentaires. Encore merci

Thank you all. Just after reading your advices I already see some change in my approach even if I know that it’s with sometime that things will be more solid. I really hope that people like me that have these weaknesses will read your comments carefully. Thanks again

2 Likes

I’m currently playing with genetic algorithms and neural networks to create a bot in the Coders Strike Back challenge. It actually goes so well that my hopes have gone from releasing a groundbreaking AI in time for the challenge to just succeeding in training a not too much retarded bot before the Codebusters challenge starts…

That make me think of one additional commandment for a successful program: 10% code / 90% tooling. That’s true for any kind of software and that’s the reason why developping usually takes much more time that initially planned (no doing it being the reason why so many softwares go nowhere).

It’s not a obvious thing when looking at code snippets in books or elsewhere, but any useful code grows up from a solid ground of tests, lot of tests, so many tests that your code should be designed first for testability, loggers to produce logs and tools to look at them, visualizers to see your code live and breathe in order to spot overall problems, sandboxes to simulate, evaluate, see what happens under heavy load, etc. Oh, and additionnal tests too when you’re developping a neural network, because the dark side of having an algorithm which is fault tolerant, evolving and able to gracefully handle errors is that it makes any bug all the harder to spot, if not to detect at all!

As a side effect, when developping any significant piece of code, you start to see the advantages of a good old language with a rich environnement VS a shiny new language with a lot of features, but without even a working framework to make a decent UI (and, yes, Haskell, I’m sorry, but I’m partially looking at you when saying that!).

To go back to my actual dumb neural network, the greatest part of my code is now made of tests, simulators and UI interfaces with graphic rendering of genomes and networks. In the same time, my initial expectations have been (greatly) reduced, with the (temporary) removal of collisions and opponents (and after 200 epochs, my bot is still steering like a half-crunched drunk cockroach…). But to quote Churchill again (or was it professor Shadoko?): “success consists of going from failure to failure without loss of enthusiasm”.

4 Likes

As i said:

In english; Less code, more tests

Always think generic, re-usability and testability. Life is easier with less code.

2 Likes