Hey there!

I’m a chemical physicist who has been using python (as well as matlab and R) for a lot of different tasks over the last ~10 years, mostly for data analysis but also to automate certain tasks. I am almost completely self-taught, and though I have gotten help and tips from professors throughout the completion of my degrees, I have never really been educated in best practices when it comes to coding.

I have some friends who work as developers but have a similar academic background as I do, and through them I have become painfully aware of how bad my code is. When I write code, it simply needs to do the thing, conventions be damned. I do try to read up on the “right” way to do things, but the holes in my knowledge become pretty apparent pretty quickly.

For example, I have never written a class and I wouldn’t know why or where to start (something to do with the init method, right?). I mostly just write functions and scripts that perform the tasks that I need, plus some work with jupyter notebooks from time to time. I only recently got started with git and uploading my projects to github, just as a way to try to teach myself the workflow.

So, I would like to learn to be better. Can anyone recommend good resources for learning programming, but perhaps that are aimed at people who already know a language? It’d be nice to find a guide that assumes you already know more than a beginner. Any help would be appreciated.

  • Ephera@lemmy.ml
    link
    fedilink
    arrow-up
    0
    ·
    8 months ago

    Could be good to try to ‘reset’ your brain, by learning an entirely new programming language. Ideally, a statically typed, strict language like Rust or Java, or Scala, if you happen to have a use for it in data processing. They’ll partially force you to do it the proper way, which can be eye-opening and will translate backwards to Python et al.
    Just in general, getting presented the condensate of a different approach to programming, by learning a new language, can teach a lot about programming, even if you’re never going back to that language.

    For learning more about Git, I can recommend Oh My Git!. It takes a few hours to get through. In my experience, it’s really useful to have at least seen all the tools Git provides, because if something goes sideways, you can remedy it with that.

  • wargreymon2023@sopuli.xyz
    link
    fedilink
    arrow-up
    0
    ·
    edit-2
    8 months ago

    Think two things:

    1. optimize the control flow of your code

    2. make it easy to read

    You should also be disciplined with these two ideas, your code will look better as you become more experienced, 100% guaranteed.

  • Andy@programming.dev
    link
    fedilink
    arrow-up
    0
    ·
    8 months ago

    Two books that may be helpful:

    • Fluent Python by Luciano Ramalho
    • Python Distilled by David M. Beazley

    I’m more familiar with the former, and think it’s very good, but it may not give you the basic introduction to object oriented programming (classes and all that) you’re looking for; the latter should.

  • MxM111@kbin.social
    link
    fedilink
    arrow-up
    0
    ·
    8 months ago

    As one physicist to another, the most important thing in the code are long variable names (descriptive) and comments.

    We usually do not do multi-people multi year projects, so all other comments in this page especially the ones coming from programmers are not that relevant. Classes are cool, but they are not needed and often obscure clarity of algorithmic/functional programming.

    S. Wolfram (creator of Mathematica) said something along these lines (paraphrasing) if you are writing real code in Mathematica - you are doing something wrong.

    • abhibeckert@lemmy.world
      link
      fedilink
      arrow-up
      0
      ·
      edit-2
      8 months ago

      We usually do not do multi-people multi year projects

      Seriously - why not?

      Say you’re doing an experiment, wouldn’t it be nice if someone else could repeat that experiment? Maybe in 3 years? in 30 years? in 3,000 years time? And maybe they could use your code instead of writing it themselves and possibly getting it wrong?

      If something is worth doing, then it is worth doing properly.

      Classes are cool, but they are not needed and often obscure clarity

      I write code all day professionally. A lot of my code doesn’t use classes. I agree they often “obscure clarity”.

      But sometimes they do the opposite - they make things crystal clear. It’s important to know how to use classes and even more important to know when to use them. I guarantee some of the work you do could benefit from a few simple classes. They don’t need to be complex - I wrote a class the earlier today that is only four lines of code. And yes, a class was apropriate.

  • robinm@programming.dev
    link
    fedilink
    arrow-up
    0
    ·
    8 months ago

    Read your own code that you wrote a month ago. For every wtf moment, try to rewrite it in a clearer way. With time you will internalize what is or is not a good idea. Usually this means naming your constants, moving code inside function to have a friendly name that explain what this code does, or moving code out of a function because the abstraction you choose was not a good one. Since you have 10 years of experience it’s highly possible that you already do that, so just continue :)

    If you are motivated I would advice to take a look to Rust. The goal is not really to be able to use it (even if it’s nice to be able able to write fast code to speed up your python), but the Rust compiler is like a very exigeant teacher that will not forgive any mistakes while explaining why it’s not a good idea to do that and what you should do instead. The quality of the errors are crutial, this is what will help you to undertand and improve over time. So consider Rust as an exercice to become a better python programmer. So whatever you try to do in Rust, try to understand how it applies to python. There are many tutorials online. The official book is a good start. And in general learning new languages with a very different paradigm is the best way to improve since it will help you to see stuff from a new angle.

  • MxM111@kbin.social
    link
    fedilink
    arrow-up
    0
    ·
    8 months ago

    As one physicist to another, the most important thing in the code are long variable names (descriptive) and comments.

    We usually do not do multi-people multi year projects, so all other comments in this page especially the ones coming from programmers are not that relevant. Classes are cool, but they are not needed and often obscure clarity of algorithmic/functional programming.

    S. Wolfram (creator of Mathematica) said something along these lines (paraphrasing) if you are writing real code in Mathematica - you are doing something wrong.

  • owenfromcanada@lemmy.world
    link
    fedilink
    English
    arrow-up
    0
    ·
    8 months ago

    While there are lots of programming courses out there, not many of them will explicitly teach you about good programming principles. Here are a couple things off the top of my head:

    • High cohesion, low coupling. That is, when you divide up code into functions and classes, try to minimize the number of things going between those functions (if your functions regularly have 6+ arguments, that’s a red flag and should be reviewed). And when something needs to be broken up into pieces, try to find the spots where there are minimal points of contact.

    • Try to divide code between functions and files in a way that doesn’t feel too busy. If there are a bunch of related functions that are cluttering up one file, or that are referenced from multiple places, consider making a module for those. If you’re not sure what “too busy” means…

    • Read a style guide. There are lots of things that will help you clean up and organize your code. The guide won’t necessarily tell you why to do each thing, but it’s a great tool when you don’t have another point of reference.

    If you have a chance to take a “Software Engineering 101” class, this is where you’d learn most of the basic principles for writing better code.

  • ericjmorey@programming.dev
    link
    fedilink
    arrow-up
    0
    ·
    8 months ago

    Do you want to work as a developer? Or do you want to want to continue with your research and analysis? If you’re only writing code for your own purposes, I don’t know why it matters if it’s conventional.

    • agent_flounder@lemmy.world
      link
      fedilink
      English
      arrow-up
      0
      ·
      8 months ago

      I guess if you are unlikely to go back and change it, or understand how it works, then sure. And yeah that happens.

      I write scripts and utilities like that. Modularity is overkill although I do toss in a comment or two to give a hint to future me, just in case.

      Although tbf, I took plenty of CS classes and some of the instructors beat best practices into our heads… So writing sloppy, arcane, spaghetti code causes me to flinch…

  • Vahtos@programming.dev
    link
    fedilink
    English
    arrow-up
    0
    ·
    8 months ago

    This is only tangentially related to improving your code directly as you have asked. However, in a similar vein as using source control (git), when using Python learn to manage your environments. Venv, poetry, conda/mamba, etc are tools to look into.

    I used to work with mostly scientists, and a good number of them knew some Python, but none of them knew how to properly manage their environments and it was a huge problem. They would often come to me and say “I ran this script a week ago and it worked, I tried it today without making any changes and it’s throwing this error now that I don’t understand.” Every time it was because they accidentally changed their dependencies, using their global python install. It also made it a nightmare to try to revive old code for them, since there was almost no way to know what version of various libraries were used.

    • ericjmorey@programming.dev
      link
      fedilink
      arrow-up
      0
      ·
      edit-2
      8 months ago

      This is huge. Unfortunately, as you indicated, there’s no standard tool for this and new ones are being added to the mix. Many in the science feilds are pushed towards Conda but I’m not sure it’s the best option. However, Conda will be infinitely better than not using anything to manage environments and dependencies.

  • MajorHavoc@programming.dev
    link
    fedilink
    arrow-up
    0
    ·
    8 months ago

    The O’Reilly “In a Nutshell” and “Pocket Guide to” books are great for folks who can already code, and want to pick up a related tool or a new language.

    The Pocket Guide to Git is an obvious choice in your situation, if you don’t already have it.

    As others have mentioned, you’re allowed to ignore the team stuff. In git this means you have my permission to commit directly to the ‘main’ branch, particularly while you’re learning.

    Lessons that I’ve learned the hard way, that apply for someone scripting alone:

    • git will save your ass. Get in the habit of using if for everything ASAP, and it’ll be there when you need it
    • find that one friend who waxes poetic about git, and keep them close. Usually listening politely to them wax poetically about git will do the trick. Five minutes of their time can be a real life saver later. As that friend, I know when you’re using me for my git-fu, and I don’t mind. It’s hard for me to make friends, perhaps because I constantly wax poetically about git.
    • every code swan starts as an ugly duck that got the job done.
    • print(f"debug: {what_the_fuck_is_this}") is a valid pattern that seasoned professionals still turn to. If you’re in a code environment that doesn’t support it, then it’s a bad code environment.
    • one peer who reads your code regularly will make you a minimum of 5x more effective. It’s awkward as hell to get started, but incredibly worth it. Obviously, you traditionally should return the favor, even though you won’t feel qualified. They don’t really feel qualified either, so it works out. (Soure: I advise real scientists about their code all the time. It’s still wild to me that they, as actual scientists, listen to me - even after I see how much benefit I provide.)
    • rolaulten@startrek.website
      link
      fedilink
      arrow-up
      0
      ·
      8 months ago

      Along a similar vain to making a git friend, buy your sysadmins/ops people a box of doughnuts once in a while. They (generally) all code and will have some knowledge of what you are working on.

    • IonicFrog@lemmy.sdf.org
      link
      fedilink
      English
      arrow-up
      0
      ·
      8 months ago

      print(f"debug: {what_the_fuck_is_this}") is a valid pattern that seasoned professionals still turn to. If you’re in a code environment that doesn’t support it, then it’s a bad code environment.

      I’ve been known to print things to the console during development, but it’s like eating junk food. It’s better to get in the habit of using a logging framework. Insufficient logging has been in the OWASP Top 10 for a while so you should be logging anyway. Why not logger.debug("{what_the_fuck_is_this}") or get fancy with some different frameworks and logger.log(SUPER_LOW_LVL, "{really_what_the_fuck_is_this}")

      You also get the bonus of not going back and cleaning up all the print statements afterward. All you have to do is set the running log level to INFO or something to turn all that off. There was a reason you needed to see that stuff in the first place. If you ever need to see all that stuff again the change the log level to whatever grain you need it.

      • MajorHavoc@programming.dev
        link
        fedilink
        arrow-up
        0
        ·
        edit-2
        8 months ago

        Absolutely true.

        And you make a great point that: print(f"debug: {what_the_fuck_is_this}") should absolutely be maturing into logger.log(SUPER_LOW_LVL, "{really_what_the_fuck_is_this}")

        Unfortunately I have found that when print(“debug”) isn’t working, usually logging isn’t setup correctly either.

        In a solidly built system, a garbage print line will hit the logs and raise several alerts because it’s poorly formatted - making it easy for the developer to find.

        Sadly, I often see the logging setup so that poorly formatted logs go nowhere, rather than raising alerts until they’re fixed. This inevitably leads to both debug logs being lost and critical but slightly misformatted logs being lost.

        Your point is particularly valuable when it’s time to get the system fixed, because it’s easier to say “logging needs to work” than “fix my stupid printf”, even though they’re roughly equivalent.

        Edit: And getting back to the scripting scientist context, scripting scientists still have my formal official permission to just say “just make my print(‘debug’) work”.

  • cosmicrose@lemmy.world
    link
    fedilink
    English
    arrow-up
    0
    ·
    8 months ago

    Learning new programming languages is an awesome way to expand your programming brain. If you want to stay in the same scientific computation niche, you can check out Julia or Mathematica. If you’re just looking to broaden your horizons, the world is your oyster. For me, learning Clojure really cooked my noodle but made me a much better programmer since it taught me functional programming.

    Also, just read other peoples code! You can learn the conventions that way. Though for you it would best to find other products within your niche, because I’m not sure if general web dev code would be super helpful.

    There are techniques that are broader than any single language’s conventions, and I think learning those are how you can improve. That’s hard to teach, though, and it comes from experience with a few different languages, in my opinion.

    And honestly, I can totally respect the “conventions be damned” attitude, because at the end of the day, you’re trying to make something that works, and if nobody else is reading that code, you’ve made the right trade-off.

  • demesisx@infosec.pub
    link
    fedilink
    English
    arrow-up
    0
    ·
    edit-2
    8 months ago

    Learn Haskell. Since it is a research language, it is packed with academically-rigorous implementations of advanced features (currying, lambda expressions, pattern matching, list comprehension, type classes/type polymorphism, monads, laziness, strong typing, algebraic data types, implement DSL in 20 lines, pattern matching, making illegal states unrepresentable, etc) that eventually make their way into other languages. It will force you to learn some of the more advanced concepts in programming while also giving you a new perspective that will improve your code in any language you might use.

    I was big into embedded C programming years back … and when I got to the pointers part, I couldn’t figure out why I suddenly felt unsatisfied and that I was somehow doing something wrong. That instinct ended up being at least partially correct. I sensed that I was doing something unsafe (which forced me to be very careful around footguns like pointers, dedicating extra mental processes to keep track of those inherently unsafe solutions) and I wished there was some more elegant way around unsafe actions like that (or at least some language provided way of making sure those unintended side effects could be enforced by the compiler, which would prevent these kinds of bugs from getting into my code).

    Years later, after not enjoying JS, TS (IMO, a porous condom over the tip of JavaScript), Swift, Python, and others, my journey brought me to FRP which eventually brought me to FP and with it, Haskell, Purescript, Rust, and Nix. I now regularly feel the same satisfaction using those languages that I felt when solving a math problem correctly. Refactoring is a pleasure with strictly typed languages like that because the compiler catches almost everything before it will even let you compile.

  • catacomb@beehaw.org
    link
    fedilink
    English
    arrow-up
    0
    ·
    8 months ago

    If you don’t already, use version control (git or otherwise) and try to write useful messages for yourself. 99% of the time, you won’t need them, but you’ll be thankful that 1% of the time. I’ve seen database engineers hack something together without version control and, honestly, they’d have looked far more professional if we could see recent changes when something goes wrong. It’s also great to be able to revert back to a known good state.

    Also, consider writing unit tests to prove your code does what you think it does. This is sometimes more useful for code you’ll use over and over, but you might find it helpful in complicated sections where your understanding isn’t great. Does the function output what it should or not? Start from some trivial cases and go from there.

    Lastly, what’s the nature of the code? As a developer, I have to live with my decisions for years (unless I switch jobs.) I need it to be maintainable and reusable. I also need to demonstrate this consideration to colleagues. That makes classes and modules extremely useful. If you’re frequently writing throwaway code for one-off analyses, those concepts might not be useful for you at all. I’d then focus more on correctness (tests) and efficiency. You might find your analyses can be performed far quicker if you have good knowledge about data structures and algorithms and apply them well. I’ve personally reworked code written by coworkers to be 10x more efficient with clever usage of data structures. It might be a better use of your time than learning abstractions we use for large, long-term applications.

  • RandomUser@lemmy.world
    link
    fedilink
    English
    arrow-up
    0
    ·
    8 months ago

    All the other comments are great advice. As an ex chemist who does quite a bit of code I’ll add:

    Do you want code that works, or code that works?! It’s reasonably easy to knock out ugly code that only works once, and that can be just what you need. It takes a little more effort however to make it robust. Think about how it can fail and trap the failures. If you’re sharing code with others, this is even more important a people do ‘interesting’ things.

    There’s a lot of temporary code that’s had a very long life in production, this has technical debt… Is it documented? Is it stable? Is it secure? Ideally it should be

    Code examples on the first page of Google tend to work ok, but are not generally secure, e.g doing SQL queries instead of using prepared statements. Doesn’t take much extra effort to do it properly and gives you peace of mind. We create sboms for our code now so we can easily check if a component has gained a vulnerability. Doesn’t mean our code is good, but it helps. You don’t really want to be the person who’s code helped let an attacker in.

    Any code you write, especially stuff you share will give you a support and maintenance task long term. Pirate for it!

    Code sometimes just stops working. - at least I’m my experience. Sacrifice something to the gods and all will be fine.

    Finally, you probably know more than you think. You’ve plenty of experience. Most of the time I can do what I need without e.g. classes, but sometimes I’ll intentionally use a technique in a project just to learn it. I can’t learn stuff if I don’t have a use for it.

    I’m still learning, so if I’ve got any part of the above wrong, please help me out.

    • ericjmorey@programming.dev
      link
      fedilink
      arrow-up
      0
      ·
      8 months ago

      “Pirate for it” was probably the wrong phrase. “Plan for it” was probably what you were thinking when your fingers did something else.

      • RandomUser@lemmy.world
        link
        fedilink
        English
        arrow-up
        0
        ·
        8 months ago

        Thought I did so well on my phone. It kept auto correcting code to coffee. Maybe it was telling me something.

        Yes, plan for it!

  • Elise@beehaw.org
    link
    fedilink
    arrow-up
    0
    ·
    8 months ago

    I’ve got two tips to add to the pile you’ve already read.

    I recommend you read the manuals related to what you are using. Have you read the python manual? And the ones for the libraries you use? If you do you’ll definitely find something very useful that you didn’t know about.

    That and, reread your code. Over and over until it makes total sense, and only run it then. It might seem slow, and it’ll require patience at first. Running and testing it will always be slower and is generally only useful when testing out the concept you had in mind. But as long as you’re doing your conceptual work right, this shouldn’t happen often. And so, most work will be spent trying to track down bugs in the implementation of the concept in the code. Trust me when you read your code rigorously you’ll immediately find issues. In some cases use temporary prints. Oh and avoid the debugger.