17

I've always liked physics, and I've always liked coding, so when I got the offer for a PhD position doing numerical physics (details are not relevant, it's mostly parallel programming for a cluster) at a university, it was a no-brainer for me.

However, as most physicists, I'm self taught. I don't have broad background knowledge about how to code in an object oriented way, or the name of that specific algorithm that optimizes the search in some kD tree.

Since all my work so far has been more concerned about the physics and the scientific results, I undoubtedly have some bad habits - more so because my coding is my own, and not really teamwork. I have mostly used C since it is very straightforward and "what you write is what you get" - no need for fancy abstractions. However, I have recently switched to C++ since I'd like to learn more about the power that comes with abstraction, and it's pretty C-like (syntax-wise at least).

How do I teach myself to code in a good, abstract way like a graduate in computer science?

I know my code is efficient, but I want it to be elegant as well, and readable. Keep in mind that I don't have time to read several 1000-page tomes about abstract programming. I need to spend time on actual, physics related research (my supervisor would laugh at me if he knew I spent time thinking about how to program elegantly). How do I assess if my work is also good from a programmer's perspective?

8
  • 12
    A question: How do you know your code is efficient?
    – Matsemann
    Aug 25, 2012 at 18:16
  • I have seen lots of people saying no to C++ as first OO language. I am learning java and i found Mark Dexter's video tutorials here eclipsetutorial.sourceforge.net/totalbeginner.html, they are pretty good and will teach you in TDD way. Also check out Head First Java it is pretty good in covering up Java in OO way.
    – Garv
    Aug 25, 2012 at 18:27
  • 4
    @DeveloperDon, computation was a central part of physics even before there were electronic computers. The calculations were done by hand, or on mechanical calculators. Ever since World War II physicists have been deeply involved in software. If you are calculating the return of a comet, simulating the production of neutrons in a nuclear chain reaction, or analyzing gigabytes of data looking for signs of the Higgs Boson, you have to do a lot of number crunching. Back in 1974 the first half of my first year physics lab was devoted to teaching FORTRAN. Aug 26, 2012 at 16:45
  • 1
    @DeveloperDon When the physicists at CERN, for example, get data, they get data from millions of particle collisions. You need a computer to handle this amount of information. Also consider an area like solid state physics where you try to understand the macroscopic properties of a material from the microscopic interactions of atoms. In such a system a single electron feels the repulsion/attraction from billions of nuclei and electrons - and to describe such a system accurately you need a fast computer and efficient algorithms (and some good approximations to the fundamental equations).
    – user787267
    Aug 26, 2012 at 19:21
  • 1
    Maybe you should change your language from C/C++ to Python so that you can have more time? Python is often used by scientists, there are modules like NumPy - package for scientific computing with Python or SciPy. If you need the speed of C/C++ in Python then use Cython, it allows you to use C/C++ types and structures so you get speed similar to C/C++, it's also easy to integrate with existing C/C++ libraries using Cython. Sep 13, 2012 at 4:54

12 Answers 12

20

Keep in mind that I don't have time to read several 1000-page tomes about abstract programming.

So are you asking for someone to give you a five step check list that will make you a skilled programmer? That's not going to happen!

As with any other discipline, if you want to get good at programming you have to spend time and effort practicing and studying. You learn to write clear, elegant code by writing a lot of code and carefully reading other people's code. Some of those 1000 page tomes will actually save you time by summarizing the hard lessons other folks have learned. It's delusional to think that you can become a skilled programmer as a painless side effect of getting a physics Ph.D.. It's not that you can't come out of a physics Ph.D. with mad programming skills, it's just that it will cost you time and trouble.

Code Complete is a good introduction to the mechanics of software development, including advice on how to write and structure clear, maintainable code. Yes, it is a huge tome, but it certainly not as dense as say, Dirac's "Principles of Quantum Mechanics" or MTW's "Gravitation". Code Complete is as close as you are going to get to a five step checklist to writing better software.

Matlab, VIM, C, MPI, and Valgrind are excellent tools to know. You don't mention using a version control system. If by some fluke you are not already using a version control system you must start using one immediately. Version control is also a god-send for writing your thesis. Other basic tools you should know are a debugger, an execution profiler, a logging framework, and a unit testing framework. You don't have to read a 1000 page book for each of these. Work through the online tutorials to get the basics and then start working with them. Delve more deeply into the documentation as your needs become more sophisticated.

Advising you about learning computer science fundamentals (as opposed to software construction fundamentals) is more difficult. You don't specify what problem you are working on, whether you are developing new algorithms or applying existing algorithms. Depending on your research problem a survey of the basic data structures and standard algorithms might be helpful. Other problems would benefit more from a solid background in numerical analysis. If you do want to learn the basics of algorithm analysis there several good texts. The Algorithm Design Manual and Introduction to Algorithms spring to mind. There are also a couple of good introductory courses available online now: Design and Analysis of Algorithms, and Algorithms.

3
  • Thanks for the links, I will look into it. I know I won't become a coding guru in a weekend, however I expect to gradually improve with time - especially if I seek inspiration outside physics (as a lot of the physicists I know couldn't care less for good coding practices).
    – user787267
    Aug 26, 2012 at 19:29
  • 1
    I would add python in tools as readable count Aug 27, 2012 at 18:15
  • 2
    +1 for suggesting Code Complete. It really is the best thing that the op can read to solve the issue in question.
    – JW01
    Aug 30, 2012 at 16:16
9

My background is a little similar to yours-I was a physics graduate who was self taught programming. After I graduated though I took on a few IT jobs and ultimately became a software engineer; including a bit of time working on OpenGDA (software used to run experiments at various synchrotron sites).

The main thing I learned about the questions you have while I was getting here is that it's much easier to get these skills from other people than to try to pick them up yourself. An experienced mentor can easily help you identify where your code is weak or where common patterns and practices can help you. While I learned how to write C and Objective-C by myself, I didn't know exactly what I didn't know (if you see what I mean) until I was working with other people on the same code. The fact you're asking here for advice means you're doing better than I did already :-).

Now, where do you find a tame professional software engineer? I recently joined MentorNet, a system that partners experienced programmers with protégés.

But you don't have to go for a formal system like that. Finding a local programmer meet-up group (or where your university's software engineering department goes after work on Friday) is a great place to start.

2
  • MentorNet looks very interesting - I will look into it. Was it a difficult transition from physicist to software engineer?
    – user787267
    Aug 26, 2012 at 19:24
  • @user787267 Because I was interested in programming (and was already a hobbyist programmer), I was motivated to make the transition as it sounds like you are so I didn't find the technical side difficult. What it took me longer to get to grips with was the wetware: understanding my place in a bigger project team and who was expert at what is a big change from the "lone wolf" coding I was doing before.
    – user4051
    Aug 28, 2012 at 7:26
5

No Royal Road to Software

In ancient times, Euclid was asked a questions like yours by his student King Ptolemy. His response: "There is no royal road to geometry."

You mention that your supervisor would laugh if he knew how much time you spend trying to write code like a professional developer. Others answered your questions with a laundry list of things to learn ranging from source control to Design and Analysis of Algorithms.

They fall short of your goal:

"I need to spend time on actual physics"

Concert Pianist or One Man Band?

The world moves too fast for people to dabble. If you want to be a concert pianist, don't divide your time learning instruments to become a one man band.

My concept for the role of a PhD in physics on medium to large projects is as an idea leader for system definition, expert in theory, subject matter expert during use case creation, and end user / judge for results generated by software artifacts. Work closely with the best software engineers you can.

How do I assess if my work is also good from a programmer's perspective?

If you want to set the bar high, start here:

Software Architecture in Practice, Len Bass, Paul Clements, Rick Kazman

Look for the chapter "Understanding Quality Attributes". Beyond code, it considers usability, modifiable, performance, security, availability, reliability, testability, maintainabiilty, and portablity (not can you carry it, but can you port the design from one platform to another). All need specific measurable goals. Similar references include:

http://msdn.microsoft.com/en-us/library/ee658094.aspx

http://www.sei.cmu.edu/reports/95tr021.pdf

Your Goals vs. C and C++

Like FORTRAN, these are hard and old languages. Positive indicators for C/C++ include:

  • Application with hardware, embedded systems.
  • Existing project you want as a starting points.

There are a lot of people doing web development, data visualization, and big data. Many are motivated to find or make other languages. For example, physicist Sir Tim Berners-Lee made his success with HTML (but is little know for physics). Evaluate your goal vs. your programming language.

Consider Using Matlab

Matlab has a great installed base, is specialized for math and sciences. It has tools for data visualization. It allows scientist and mathematicians to express problems in the problem domain rather than the solution domain. Matlab makes a Parallel Computing Toolbox and Distributed Computing Server products.

I expect Matlab's success is due to using multidisciplinary teams with people who are experts in physics, math, electronics and instrumentation, operating systems, programming languages, software development, software testing, software architecture and design. The analogy may be a stretch, but why would you put yourself out there alone, starting with a hammer, chisel, and rasp to make something when you have a 3D printer available? As Newton might ask, why not stand on someone's shoulders?

4

How do I assess if my work is also good from a programmer's perspective?

  • Is it correct? Does it produce correct results in all cases?

  • Are other people able to read and easily understand your code?

  • When your supervisor says "Great, now make it also do X..." do you have to rewrite a lot of code?

  • When you've written a program, does it become a tool that you can use over and over, or is it a use it once and throw it away kind of thing?

If you can answer yes, yes, no, and 'yes, I try to make tools rather than one-off calculations', then you're doing pretty well already. A good deal of what we do as programmers is meant to help with the kinds of things listed above.

4

You will be able to go a long way in Physics without knowing anything about "professional" style (speaking from experience). But I have seen many people waste endless time because they lost track of what they where doing or after having grown their code for a couple of years just got lost in it's complexity (even in academia there is no "throw away" code, but things stick around much longer than you think initially).

I would suggest you get a head start into algorithms and data structures, e.g. with this course. After that you should be able to think about performance on a more productive level and be able to follow up with e.g. articles on Wikipedia.

After that get used to what is available in the core of your language, e.g. for C++ cppreference.com. I would also strongly recommend you to read the Effective C++ series by Scott Meyers and Accelerated C++ by Koenig & Moe. At least for C++ this will give you a solid foundation on the language side.

In parallel you should try to get to know your tools well. It isn't unlikely that you will develop your code under Linux, so try to learn how to get more diagnostics (warnings) from your compilers (at least gcc and clang). Also learn about static analysis tools like cppcheck or clang's scan-build. Learn how to make these tools an integral part of your development process, e.g. by integrating them into your build setup (yes, you should use at least GNU make, or even better something like GNU autotools/cmake/...). You should also add profiling tools to your toolset. For C++ I would strongly recommend you to learn everything you can about valgrind which can profile on a very low level (it also can help you find resource leaks).

All this will help you focus on what you care most about (your research) instead of wasting time finding bugs or doing useless optimizations. Of course this is almost impossible to sell to an advisor, but they (and you) will be impressed but the speed with which you be able to get reliable results.

You mentioned C and C++, but for numeric calculations I cannot recommend Python with numpy and scipy enough. It allows you to write in a clean pretty clean language on a very high level (you can even work interactively), while still taking advantage of extremely optimized routines implemented in C, C++ and FORTRAN. Also, interfacing your own C or C++ code with Python is almost trivial.

5
  • Thanks for the links! I will definitely look into it (but I don't think I have time to read several books - although I have read accelerated C++ back in high school at some point). I'm working in a Unix environment (I'm using Vim as my editor and liking it), and I use make and Valgrind extensively. I have also triggered the -pedantic option in gcc and -Wall as it helps quite a bit. Maybe I should have mentioned that I do high performance computing (with the MPI library for parallel programming) on the university's supercomputer.
    – user787267
    Aug 25, 2012 at 19:54
  • I should also mention Python is not really an option since my code needs to be very fast - although I do like it for plotting for example. I have used Matlab a lot as well.
    – user787267
    Aug 25, 2012 at 19:57
  • I pretty often use Python as front-end to talk to routines implemented in my own C++. With Boost this is really easy and you get the full flexibility of Python (e.g. for processing data for plotting). Also, Python is pretty neat for prototyping. Once I know something gets crucial I can always move it to C++. Since you mention MPI, I would recommend you to spend an evening with IPython with makes a nice interface for distributed computing. Aug 26, 2012 at 2:05
  • @user787267 It is no longer necessarily true that Python performs slow - have a look at youtube.com/watch?v=Iw9-GckD-gQ for example. The key is you can use Python to quicker write a working code that you can then speed up by 1) using numpy/scipy 2) using Cython or shedskin, and 3) putting only the core algorithm into a C/C++ or FORTRAN module if you really need that last 5% improvement. Also remember, time you spend on coding is time the code doesn't already run, so it may sometime be more efficient to have a 80%-performance code written in half the time Aug 26, 2012 at 17:23
  • I typically make prototypes in Matlab to test the easy stuff, but I've wanted to change to Python for a while. I'll take a look at it. Due to large parts of my code already written in C++ I don't want to change the language halfway through however. While it is true you also have to consider the time actual time programming (and believe me, I do), I don't think that should be an excuse to not improve your programming skills (gradually).
    – user787267
    Aug 26, 2012 at 19:35
3

Your programs will be completely different from commercial source code, therefore many good practices and approaches won't apply in your day-to-day source code development. But there is a good way to learn a few tips and tricks.

Let some good software developer review your code and optimize it together. It will give you much more experience and will teach you good practices. Also review source code written by other people. Search for open source projects on sourceforge or github and read their source code.

But most of all, think whether you actually need to learn anything new in order to accomplish your goals. Doing unnecessary stuff just to make the code look prettier won't add any value to your applications.

2
  • Reading and participating in open source projects is actually a very good idea - but something I would have to do in my spare time (but since I like programming that shouldn't be too much of a problem). One reason I wish to become a better programmer is that I'm not sure if I will stay in academia. When my ph.d. is done I might just get a job in the industry - and here a skilled programmer should be in high demand. Another reason is the intellectual satisfaction of creating something elegant/beautiful - like solving a really difficult differential equation.
    – user787267
    Aug 25, 2012 at 20:09
  • Unfortunately industry requires skills you usually don't gain in academic development. The stuff you'll write during your academic researches is usually less than 5% of commercial application's source code. Aug 25, 2012 at 21:17
3

As far as becoming a better programmers is concerned there is no magic bullet. If you're self-taught the key is self-awareness, which it sounds like you have. However, learning to code well mostly comes down to reading and practice.

Being critical of your own code is one of the best ways to get better. Always be asking yourself:

  • Will this be easy to change?
  • Is this easily testable?
  • Can I simplify this? Can I easily understand this when I see it again in 3 months?

My other suggestion would be don't lock yourself into C/C++. While those are good languages that are used for a reason, they require you to do a lot of things that are not subject matter related. Look into Matlab, I'd be surprised if the university doesn't have that available for you. Consider a scripting language like Python. Strongly consider picking up a functional language like Haskell - the paradigm is very mathematical in nature and would likely fit your problems like a glove. In short explore some other languages/paradigms. Even if they don't become a permanent tool in your belt they'll make you a better programmer.

You may also want to look into some algorithm design. I suspect having gotten the job, you're already relatively up to snuff on this, but algorithms are incredibly important when doing numerical analysis. In fact, I would suspect, there are resources specifically geared towards numerical analysis algorithms.

Never lose sight of your primary purpose in writing the code. You need to get things done. Becoming a better programmer is one method to do that. Selecting the right tools for the job is another.

2

First,"elegant" is a relative term. Abstraction might seem elegant to you but to another C aficionado, it might seem unnecessary. Anyways,to answer your question, you should try posting your code for review on http://codereview.stackexchange.com.
Digressing from the main point, some unsolicited advice based on my own experience. If you can get all your work done with just C, then why do you want to code it in an abstract way? By this, do you want to enable others to resuse your code? If you really have a solid reason to switch to C++, go for the abstraction and learning C++ and OO concepts. Otherwise drop the idea. In my humble opinion, should n t you aim at your code being more readable and your scientific results reproducible than giving it OO abstractions? I myself had this kind of obsession to learn OOPS and code "elegant"ly. But C++ will take time to master.You will have to learn memory management since garbage collection is not automatic in C++. Take my advice since i worked for a research lab myself and lost lots of time learning C++ and OO, instead of concentrating on the main work at hand.

2
  • 1
    But C is even more unmanaged than C++. In C++ there is at least RAII. Aug 25, 2012 at 18:59
  • I like to code, so I want to become a better programmer. I'm a physicist first and a programmer second, but that doesn't mean I shouldn't improve my programming skills - after all, if I decide to publish my code along with the scientific results, it would be better to have nice, readable code.
    – user787267
    Aug 25, 2012 at 20:02
2

Considering your mention of lack of time to study theory.

If you've looked back at your old code after a few months and wondered "what kind of an idiot wrote that code", you're making progress.

How did you progress? By seeing better code written by others. A person never knows the value of 'elegance' or 'good' code unless they see it adding value to their work. Rather than read theory, I would encourage you to keep your eyes open to code written by others in your field of work. Keep your eyes open to concepts being discussed on stackoverflow (C++ tag). Spending just fifteen minutes a day of such searching can randomly expose you to concepts which can help you. It can show you code that is better written than your code. That's when you follow up on Wikipedia and find out more about it. Such learning that comes out of curiosity, will be much longer lasting and useful to you than theory which you will forget when you wake up the next day.

Also consider trying out languages like MATLAB or Python.

2
  • I do spend quite a lot of time on Stack Exchange - it's an invaluable resource for me in my daily work. I've used Matlab a lot, but it's very easy to develop bad habits such as not pre-allocating arrays since it's very forgiving.
    – user787267
    Aug 26, 2012 at 19:40
  • +1 for python @user787267 I don't really catch why not preallocating array is a bad habit Aug 27, 2012 at 18:24
2

As a physicist turned programmer myself, I found my physics background most helpful in forming the right metaphors for understanding software concepts. This perspective also made learning programming more fun for me and helped me develop the sense for "elegance" in software, which you seem to strive for.

I've described the important and under-appreciated role of metaphors and analogies in software in my CUJ column "Patterns of Thinking--names, metaphors, better programming, and the politics of the language". For example, the OO concepts of class inheritance is often compared to passing traits from parents to offspring in a family. This is an incorrect analogy. The correct analogy for class inheritance is biological classification of organisms (e.g., a class RedRose is a kind of Flower, and a Flower is a kind of Plant).

Or take for example the software concept of a hierarchical state machine. A good metaphor here is the concept of a bound quantum system such as the hydrogen atom. As you recall, the states of an atom are numbered by three quantum numbers |n, l, m>, exactly because they are "nested" (hierarchical). This metaphor shows you how to understand that states nest within states (just like states of angular momentum (l) nest in the energy states (n)) and also you immediately see that state nesting is always reflection of some symmetry of the system.

Another interesting analogy from physics is the "actor model of computation", which lately has been re-discovered due to multi-core CPUs and the distributed computing in the "cloud". I found it helpful and fun to think of events exchanged by stateful actors (a.k.a. active objects) as virtual bosons, such as photons in QED, or gluons in QCD. This metaphor explains the fundamental asynchronous nature of communication, the run-to-completion event processing (quantum leap), and strict encapsulation of active objects, which can only interact with each other via the explicit intermediate artifacts.

Anyway, developing a system metaphor is a recommended practice in XP (eXtreme Programming), and as a physicist you will have an edge in coming up with good metaphors. You will also gain a sense for "elegance", because your software will inherit the conceptual integrity from good metaphors you apply.

1
  • Although physics is potentially a rich source of metaphors, the intent in XP is finding a metaphor which facilitates communication with the on-site customer and other team members, so would generally tend to choose metaphors which are more commonly understood. May 13, 2015 at 9:20
2

I can tell you that the biggest gains I have made in terms of how I approach solving problems have all been achieved through learning functional languages and parsers. Both discoveries were made by accident. So I'm telling you now if you are truly serious about becoming a better programmer then you need to learn about the various techniques involved in writing a compiler, e.g. parsers and parser generators, and you need to learn how to compose computations with higher order functions.

An excellent resource for the parser and compiler stuff is PL101: Create Your Own Programming Language. I still haven't found a good intro to functional programming but I hear really good things about SICP.

-5

A graduate in Computer Science doesn't know how to code well when they graduate; they are not so much in demand when they leave University. Only if they get the experience.

The answer to your question is you need to learn Design Patterns. I programmed in Java, .NET and now I work as a PHP, Javascript and MySQL programmer. .NET by the way has a very large level of abstraction, e.g. ASP.NET. It means you can skip the abstraction learning. Languages like Perl, PHP, etc. have a low level of abstraction.

Read Head First Design Patterns, it is a good book. It is quite a comprehensive book. That is all what you will need.

1
  • I have an idea why this answer was downvoted, but maybe it will be useful if the downvoters said why? Feb 24, 2014 at 9:30

Not the answer you're looking for? Browse other questions tagged or ask your own question.