Live data from Hacker News

How to write better scientific code in Python?

zerowithdot.com

61–70 of 79 posts

Re: How to write better scientific code in Python?

#61

I don't like the code. My start point would be that import pandas as pd import numpy as np if __name__ == "__main__": n_samples = 10000 samples_np = pd.DataFrame(np.random.randint(1, 7, n_samples), columns=["face_value"]) print(samples_np.face_value.mean()) Speaking about abstraction, I don't know math, so first thought would be to look for *existing* abstractions. When I work with relational data, my first option to…

> I don't believe "scientific code" is fundamentally different from any other code, I would go with following normal development practices

> 1) review design ("don't reinvent wheel")

> 2) add tests

> 3) make code review

> 4) version control

> etc.

In my experience, this is pretty quixotic and will lead to your failure as a scientist. Basically nobody is writing tests. Code review is pretty much unheard of. There only "design review" comes from your journal's peer review process and generally has nothing to with the code. You can jump through all those hoops while your colleagues keep cranking out papers.

Re: How to write better scientific code in Python?

#62

I don't like the code. My start point would be that import pandas as pd import numpy as np if __name__ == "__main__": n_samples = 10000 samples_np = pd.DataFrame(np.random.randint(1, 7, n_samples), columns=["face_value"]) print(samples_np.face_value.mean()) Speaking about abstraction, I don't know math, so first thought would be to look for *existing* abstractions. When I work with relational data, my first option to…

> I don't believe "scientific code" is fundamentally different from any other code, I would go with following normal development practices

That depends on the field. In the part of bioinformatics I work (mostly combinatorial algorithms; floating point numbers are rare) normal software development practices often cease to be relevant the moment someone mentions design.

Writing research code is a part of doing research, and a key feature of research is that you often don't know what you are supposed to do. When I start writing code, I tend to expect that the code will solve the wrong problem in the wrong way. Once I have something that runs, I start experimenting with data to learn more about the problem domain. Eventually I have a better idea what the code is supposed to do (and maybe even how it should do that), and then it's time to rewrite and iterate. Design only becomes relevant in late stages of the project when I'm confident I know the problem I'm supposed to solve.

There are some similarities to prototyping, but it's prototyping over problems rather than over solutions to a particular problem.

Re: How to write better scientific code in Python?

#63

Earlier quoted context omitted.

I agree, the bad code at the start is clearer than 99% of the scientific code I've read, without exaggeration. The typing & the abstractions proposed are not only unnecessary but also unrealistic for research code. If scientists want to improve their code, the first and most important step is to get them to use descriptive verbose names for their variables and functions, and to learn the single responsibility princip…

I disagree with the first half. Scientific code is meant to be read with the corresponding journal paper in hand. The journal paper didn't use "descriptive, verbose variable names", and foisting that into the code makes it even less comprehensible. The more the code looks like the paper, the better.

A paper is not a sufficient specification for code, the gap is too large. Most code I've read uses the naming scheme you propose and I've never seen it succeed, and I always read it with the paper in hand. It always degenerates when the author has to glue together those few well defined variables into a working piece of code. You end up with sub-variables named after the original ones whose purpose are not well defined, and with objects whose purpose and nature you aren't sure of (is q a function or number? whats q_enc, qp and qs for? Only q is defined in the paper.). And it only gets worse when they try to use latex syntax. In the end you have to read through a 500 lines function of obfuscated 1 character variables, it's a nightmare.

A verbose name makes which variable it corresponds to in the paper immediately obvious, and makes the code understandable.

Re: How to write better scientific code in Python?

#64
post #9

Having worked in the field long enough, I always feel the need to add: A) If you're writing high-performance code DON'T you _will_ hit bottlenecks which are non-trivial to the language unless you're a guru. If you're a scientist you're going to have to work to get to this level. Apart2) Python is excellent for saying "perform analysis A with variables B,C,D,E,F on X,Y,Z 30 times using this random seed library". What…

Insightful writeup!

I am just not sure what did you mean to discourage in part A.

> A) If you're writing high-performance code DON'T you _will_ hit bottlenecks which are non-trivial to the language unless you're a guru.

DON'T do what? don't try to hyper-optimize your code? don't use all types of "fancy" constructs like how the post shows?

Re: How to write better scientific code in Python?

#65

Earlier quoted context omitted.

I disagree with the first half. Scientific code is meant to be read with the corresponding journal paper in hand. The journal paper didn't use "descriptive, verbose variable names", and foisting that into the code makes it even less comprehensible. The more the code looks like the paper, the better.

A paper is not a sufficient specification for code, the gap is too large. Most code I've read uses the naming scheme you propose and I've never seen it succeed, and I always read it with the paper in hand. It always degenerates when the author has to glue together those few well defined variables into a working piece of code. You end up with sub-variables named after the original ones whose purpose are not well defin…

A paper is a better specification for code than pretty much any design doc I've seen. It's usually not that hard to figure out what qp and qs and q_enc stand for from the context. It's much preferable to listening to the software engineers who want to explode a simple 10 character expression into an unreadable rats nest of line-continuation logorrhea.

It may be _possible_ to have a verbose variable that makes it obvious what it corresponds to in the paper, but I've never seen it. That really rings like a No True Scotsman argument to my ear. I much prefer the creole of latex style naming that most researchers tend towards. For example, take this code/paper pair

https://www.web.stanford.edu/~boyd/l1_ls/

The first line in the main loop is

    z = A*x-y;
Yes, they could have written

    residual = dictionary_matrix * optimization_variable - sensed_data 
or some such nonsense, but it is just exhausting to read. Further, it's actually more confusing because it conflates an application (compressed sensing) with what is actually a generic algorithm for l1 regularized least squares. This is a persistent problem with verbose names. In the search for an expressive name, people reach for names from a specific problem. This is a violation of separation of concerns.

Re: How to write better scientific code in Python?

#66

I think to any audience other than fairly hardcore software engineers this is going to read a little... mad. The first code example was exceptionally clear, from then on, we get increasingly incomprehensible. "Better" it isnt. Scientific code is often write-once, run-once, done. And since mathematics/statistics is largely already formalised at the level of distributions, sampling, and so on -- we shouldn't expect to…

> The first code example was exceptionally clear, from then on, we get increasingly incomprehensible.

I think the problem here is that each iteration is solving a different and more general problem, but while the use of the flexibility at each level is discussed, it's not framed as code solving one problem and the difficulty as the same approach is applied to a broader version of the problem.

IMO, from a pedagogical point of view, this could be improved a couple of ways:

(1) First, the initial code is not, and should not be described as, “bad code”. Given a simple initial case, it is clear, straightforward, good code. It's not abstracted to handle diverse cases, but it's not intended to be. It should be held up as an excellent model of solving a simple initial problem and a good starting point.

(2) Each of the subsequent levels of abstraction enables the code to solve a more general problem more clearly than just layering on more special-case code. So, each step should expand the problem, show code to solve the expanded problem at the pre-existing level of abstraction, and then introduce the refactoring that is appropriate for it. (An extra nice thing would be to show another extension to the problem after each that fits into the new level of abstraction well, leveraging the abstraction introduced.)

We should get out of the mindset that either more or less general code is “better” in some universal sense: different levels of abstraction and generality are suitable for different problems, and often you’ll start out solving, and coding for a narrower version of the target problem than the eventual goal. Eventually, you may develop a level of intuition for the level of abstraction necessary to solve the general problem initially, but it's also easy to overabstract a solution if you don't have a keen awareness of the limits of needed generality. It's a lot easier to avoid overabstraction—which makes code harder to read and understand—if you start simple and refactor incrementally as you generalize up to just what you need.

Re: How to write better scientific code in Python?

#67
post #55

Scientist here, who has been writing code for > 20 years. I don't buy pretty much anything in the article. This was a bunch of opinionated examples. Science programming in my opinion has many different levels which require different approaches and techniques. Very often the first code written will be just a quick and dirty. If the idea worked out, I may refactor it, make the code prettier, speed it up a bit. Very-ver…

Exactly! The real decision you're making with scientific codes in lightly-explored problem domains is, how permanent and versatile of a solution do I need here? Alas, the OP is deploying some CS abstractions to genericize very simple problems that have already been very well-explored ("find the sample mean"). It's stirring up antibodies among all the investigators who ever over-engineered an approach that was subsequ…

> It's stirring up antibodies among all the investigators who ever over-engineered an approach that was subsequently junked! (shuffles feet awkwardly)

Me!

And I was supposed to be a CS major, a programmer. But I came along right when the industry was crazy into "objects". Then we had to have more "Java".

Simplicity was an accident.

I felt like I was losing my mind, so I returned to scientific computing.

Simple is hard. Simplicity via the correct application of abstraction, while keeping in mind the performance impact of your design changes, is what we do, on a good day.

Re: How to write better scientific code in Python?

#68
post #18

I think to any audience other than fairly hardcore software engineers this is going to read a little... mad. The first code example was exceptionally clear, from then on, we get increasingly incomprehensible. "Better" it isnt. Scientific code is often write-once, run-once, done. And since mathematics/statistics is largely already formalised at the level of distributions, sampling, and so on -- we shouldn't expect to…

I want to disagree with you. But I just can't. We go from having to read ten lines to about forty? With about five or six new concepts that are not related to the original.

The thing is the abstractions on the last code are optimized for solving a far more general version of the problem, that just to exercise (not even exhaust) all the kinds of variation supported would take hundreds, probably thousands, of lines with code taking the initial approach. But you don't really have even a hint of that, because the article doesn't show at each abstraction level a broader problem, the cost of solving it without the new abstractions introduced, and then the benefit of the abstractions.

Re: How to write better scientific code in Python?

#69

I don't like the code. My start point would be that import pandas as pd import numpy as np if __name__ == "__main__": n_samples = 10000 samples_np = pd.DataFrame(np.random.randint(1, 7, n_samples), columns=["face_value"]) print(samples_np.face_value.mean()) Speaking about abstraction, I don't know math, so first thought would be to look for *existing* abstractions. When I work with relational data, my first option to…

> I don't believe "scientific code" is fundamentally different from any other code, I would go with following normal development practices > 1) review design ("don't reinvent wheel") > 2) add tests > 3) make code review > 4) version control > etc. In my experience, this is pretty quixotic and will lead to your failure as a scientist. Basically nobody is writing tests. Code review is pretty much unheard of. There only…

Yes, that part is different, reusability of the code is not expected to be the same as normal software code. Not different that the code starts from requirements (which are different) and it should be correct, which basically is the "following normal development practices".

Re: How to write better scientific code in Python?

#70
post #18

Earlier quoted context omitted.

I want to disagree with you. But I just can't. We go from having to read ten lines to about forty? With about five or six new concepts that are not related to the original.

The thing is the abstractions on the last code are optimized for solving a far more general version of the problem, that just to exercise (not even exhaust) all the kinds of variation supported would take hundreds, probably thousands, of lines with code taking the initial approach. But you don't really have even a hint of that, because the article doesn't show at each abstraction level a broader problem, the cost of…

No. I actually got that. But it doesn't help on a science report.

That is, I agree that this is better engineered code. I disagree that this is better science code.

Post reply on HN