11
$\begingroup$

It is a really worrying situation. I do well with CS subjects, but at the end of day it is all useless as I don't know how to code.

How do I learn to code to make projects? I can make small programs easily. I can't use programming to create good stuff.

What should I start with? Recommend a book and course that teaches me enough to get started with projects.

$\endgroup$
13
  • 5
    $\begingroup$ Are you looking for web programming? Mobile apps? To get involved in an open source project? "Projects" is very vague. $\endgroup$
    – Ben I.
    Commented Oct 26, 2021 at 6:32
  • 4
    $\begingroup$ Cross-posted: cseducators.stackexchange.com/q/7094/1106, cs.stackexchange.com/q/145123/755. Please do not post the same question on multiple sites.. $\endgroup$
    – D.W.
    Commented Oct 26, 2021 at 18:44
  • 1
    $\begingroup$ Where exactly is the line between "small programs" and "good stuff" in your opinion? $\endgroup$
    – Philipp
    Commented Oct 26, 2021 at 19:11
  • 4
    $\begingroup$ projecteuler.net is a great way to get some practice in. $\endgroup$
    – Stephen
    Commented Oct 26, 2021 at 20:37
  • 3
    $\begingroup$ Big projects are often just small projects that got bigger and bigger and bigger. $\endgroup$
    – user20574
    Commented Oct 27, 2021 at 10:14

6 Answers 6

24
$\begingroup$

Computer Science vs. Programming

Really worrying situation. I do well with CS subjects but at the end of day it is all useless as I don't know how to code.

That is normal. Computer Science and Programming are two completely different things. You should not expect that studying one will not automatically make you learn the other, any more than you should expect studying astronomy will automatically make your learn how to blow glass.

It has been said that Computer Science is really a misnomer, and is akin to calling Astronomy "Telescope Science" – just because computers can be used to investigate information and processes doesn't mean that they are somehow inherent to that science, just like the fact telescopes can be used to investigate planets and stars doesn't mean that telescopes are somehow inherent to astronomy.

There are some languages, for example German, French, and Italian, where the scientific discipline makes no reference to computers at all: in German, it is called Informatik, in French informatique, in Italian informatica – all are a neologism based on information and the Greek suffix -ik. In Spanish, it is called ciencias de la informática (similar to German, French, and Italian) or ciencias de la computación: note the subtle difference to English, it is the science of computation, not the science of computers. Danish uses the terms datalogi (a neologism formed by combining data with the -logi suffix as in geology, meteorology, metrology, etc.) for the stricter sense of the science of information, data, computation, and processes, and informatik for a broader inter-disciplinary view of the effects of "datalogi" on society, politics, humanity, and the broader world in general; what might be called Social Informatics in English.

As you can see, in many languages, there is a clear distinction made between "Informatics" and computers. It is a rather unfortunate accident of history that the language which confuses the two also happens to be the lingua franca for it.

… and Software Engineering

How do I learn to code to make projects? I can make small programs easily. I can't use programming to create good stuff.

You studied Computer Science to become good at Computer Science. In the same way, you need to study Programming to become good at Programming. In addition, you also need to study Software Engineering to become good at what they call "programming in-the-large", i.e. programming large and complex systems collaboratively in a team over a longer period of time.

Books that teach Programming

What should I start with? Recommend a book and course that teaches me enough to get started with projects.

I am personally a huge fan of How to Design Programs (HtDP). It teaches you, well, how to design programs. And it does this by giving you recipes to follow for how to analyze problems, solve them, transform them into algorithms and further into working programs.

Note that "recipe" is basically another word for "program", so in other words, the book teaches you programs for humans to run in their heads in order to generate programs to be executed by computers. How cool is that? :-)

Note that the current, second edition of HtDP does not include Imperative Programming. That material was present in the first edition, but was removed to be covered in an as-of-yet unwritten second volume How to Design Components / Classes. However, if you are interested in Imperative Programming, the first edition of HtDP is still available as is an early draft of How to Design Classes.

Note that HtDP assumes no programming knowledge and is targeted at high school students. But don't let that stop you: it just means that you'll probably be able to finish some early chapters faster, but I don't think you will be bored.

Concrete Abstractions is also a good read along similar veins. Like HtDP, it doesn't assume any programming knowledge.

Another book that you might hear mentioned is Structure and Interpretation of Computer Programs aka SICP. It is one of the greatest programming books ever written, and again, it doesn't assume any programming knowledge.

It is, however, geared to complete newbies who study at MIT. And so, while it does not assume any programming knowledge, it does assume quite a bit of domain knowledge, e.g. in the fields of electrical engineering, physics and math. Note: these have nothing to do with the concepts being taught, they are just needed to understand the exercises and examples. So, it might be better to read HtDP or Concrete Abstractions first, and then read SICP. However, since you are familiar with CS in general, I don't think you will have many problems.

Learning Programming vs. Learning Programming Languages

All three of these books teach Programming. What they don't teach, is a complex Programming Language. I personally think that is a good thing. Learning a programming language takes a lot of time, just like learning anything takes a long time. So, any second you spend learning a programming language, you are not spending learning programming.

In my opinion, learning programming is more important than learning programming languages. You will almost never be in a position to choose your programming language anyway, and will have to learn whatever gets thrown at you. Let's face it: almost nobody gets hired to develop something completely novel completely from scratch based on no constraints whatsoever. You will almost certainly join an already existing team working on an already existing system, where the programming language to use has been chosen and set in stone long ago.

All three (series of) books I mentioned above use very simple languages that can be fully taught / learned and understood in minutes.

How to learn Software Engineering

What all three books also (unfortunately) don't teach is Software Engineering. HtDP does at least teach Testing and a bit of Debugging, and even suggests something similar to Test-Driven Development / Design. HtDP also teaches documenting requirements.

Unfortunately, and much to my regret, I cannot recommend any books or courses for learning Software Engineering. That is not to say there aren't any, only that I don't know of them. I, personally, consider myself to have been taught Software Engineering very badly, and been permanently damaged.

There is the Software Engineering Body of Knowledge (SWEBoK) and the Software Engineering 2004 (SE2004), but I feel that both of those are not really up-to-date with modern real-world Software Engineering practices and ignore modern real-world Software Engineering challenges. (For example, it is almost impossible nowadays in our interconnected world to disentangle good software engineering from security engineering.)

Personally, I found it very enlightening to study both the Manifesto for Agile Software Development and the Twelve Principles of Agile Software and the Manifesto for Software Craftsmanship. Please note: I am not saying that Agile and Software Craftsmanship are the be-all-end-all of Software Engineering. I am merely saying that I personally found it interesting to study those two documents and their history, and think about what experiences made the people who wrote them become convinced that this is the best way to engineer software. The authors of both of those documents are experienced software engineers, who have both delivered many successful large, complex projects, and have seen many large, complex projects fail. What made them draw those particular conclusions from those failures and successes? I find that fascinating.

Deliberate Practice

However, here is the hard truth: whether it is Computer Science, Programming, Programming Languages, or Software Engineering, or even playing an instrument, painting, woodworking, sports, etc., the only way to truly master something is lots of deliberate practice. Note that the "deliberate" part of "deliberate practice" is important. Sitting and noodling "Knocking on Heaven's Door" on your acoustic guitar is not practicing guitar, that's playing a song. Going to the beach is not practicing swimming.

And writing small tools for yourself is not practicing programming, that's working. Someone once said: if you don't delete what you wrote immediately after writing it, then you're working, not practicing.

Kata

Some people swear by so-called Code Kata. Kata are an idea from several martial arts; they are a series of formalized techniques that are practiced repetitively and are performed in front of an audience.

Similarly, Code Kata are simple exercises that you solve over and over again, ideally at some point performing them in front of an audience. Some people have tried setting their performances to music, such that, for example, some big refactoring which results in the deletion of a bunch of code coincides with a big climax in the piece.

Mentorship

One of the best ways of learning Software Engineering, or well, pretty much anything, is to find a mentor. Especially in the Software Craftsmanship movement, which models itself somewhat after the concept of Master Craftsmen in e.g. carpentry, mentorships / apprenticeships are fairly common, so you might find a mentor in one of their programs. You don't have to go to such extremes as e.g. Corey Haines did, who actually spent the better part of a year on something akin to traditional Journeyman Years, but it wouldn't be the worst way to learn either.

Programming Languages

A note on programming languages: there are thousands of them. It is impossible to learn them all. However, programming languages implement Programming Paradigms and there are only a few dozen of those. Programming Paradigms, in turn, are composed of Concepts, and there's only about 20 of those. So, if you understand Concepts, that will help you understand Paradigms, which in turn will help you understand Languages, without actually having to learn dozens of paradigms or hundreds of languages.

Paradigms

Peter van Roy has made a nice poster with the 34 most important Programming Paradigms. A more thorough explanation of that poster is contained in the article Programming Paradigms for Dummies: What Every Programmer Should Know which appeared as a chapter in the book New Computational Paradigms for Computer Music, edited by G. Assayag and A. Gerzso. Some examples of paradigms include the well-known imperative programming, functional programming, ADT imperative programming, ADT functional programming, and sequential object-oriented programming / stateful functional programming, but also lesser known ones such as concurrent constraint programming, active object programming / object-capability programming, constraint (logic) programming, or multi-agent dataflow programming.

Concepts

Paradigms, in turn, are composed of Programming Concepts. E.g. sequential object-oriented programming is composed of record, closure, cell, and procedure. If you add thread, you get concurrent OO programming. The most important concepts include some well known ones like cell (state), procedure, and record, but also lesser known ones like by-need synchronization, nondeterministic choice, or solver.

I would argue that understanding about 1/3 of those 18 concepts allows you to understand about 90% of the top 100 mainstream languages, if not more.

This is an interesting example, where Computer Science concepts, more specifically concepts from the field of Programming Language Theory are directly helpful in an industrial context, helping you to quickly learn programming languages by analyzing their paradigms and concepts.

By far the best explanations of programming paradigms are found in Peter van Roy's works. Especially in the book Concepts, Techniques, and Models of Computer Programming by Peter Van Roy and Seif Haridi. (Here's the companion wiki.) CTM uses the multi-paradigm Distributed Oz programming language to introduce all the major programming paradigms.

My own experience has been that really understanding a programming paradigm is only possible

  • one paradigm at a time and
  • in languages which force you into the paradigm

Learning Concepts through Paradigms through Languages

Ideally, you would use a language which takes the paradigm to the extreme. In multi-paradigm languages, it is much too easy to "cheat" and fall back on a paradigm that you are more comfortable with. And using a paradigm as a library is only really possible in languages like Scheme which are specifically designed for this kind of programming. Learning lazy functional programming in Java, for example, is not a good idea, although there are libraries for that.

Here's some of my favorites:

  • object-orientation in general: Self
    • prototype-based object-orientation: Self
    • class-based object-orientation: Newspeak
      • static class-based object-orientation: Eiffel
    • multiple dispatch based OO: Dylan
    • functional + object-orientation: Scala
  • functional programming: Haskell
    • pure functional programming: Haskell
      • lazy pure functional programming: Haskell
    • static functional programming: Haskell
    • dynamic functional programming: Clojure
  • imperative programming: Lua
  • concurrent programming: Clojure
    • message-passing concurrent programming: Erlang
  • metaprogramming: Racket, Scheme
  • language-oriented programming: Intentional Domain Workbench, unfortunately defunct; try JetBrains MPS instead

What about syntax?

The most-often talked about part of programming languages are their respective syntaxes. Personally, I also find them the least important. You can learn to ignore syntax, or if it really bothers you, write a preprocessor. You cannot easily change a language's semantics or type system.

Most mainstream languages nowadays borrow their syntax heavily from a small number of influential ancestors: blocks structured with curly braces from B (e.g. C, C++, Java, C#, ECMAScript, PHP, Rust, Go), blocks structured with keywords from Algol (e.g. Ruby), blocks structured through indentation from ISWIM (Python, Haskell), member selection with . from … I don't know where :-D (almost all of them), message sending with whitespace from Smalltalk (Objective-C), types in front of identifiers from Algol, types after identifiers separated with a colon from maths, types after identifiers separated with whitespace, plus the Lisp family and ML family.

Once you have seen some of them, you have seen (almost) all of them, and they are easy to learn. Also, modern code authoring tools help tremendously with intelligent autocompletion for writing code, and specific syntactical intricacies are often not that important for reading and understanding code. For example, many coding styles require parenthesizing complex expressions, so that knowing the subtle differences in operator precedences between different languages becomes a non-issue: except in interview puzzles designed to stump you (for which you can prepare and memorize them, and promptly forget them after the interview), or in really badly written code (which you need to carefully study anyway, since operator precedence typically is the least of your problems), you simply will not encounter them.

$\endgroup$
9
  • 5
    $\begingroup$ Other than the fact that this will probably bury the OP, this is pretty awesome. $\endgroup$
    – Buffy
    Commented Oct 27, 2021 at 13:36
  • $\begingroup$ I freely admit that most of these are pre-made soapboxes I have preached on before that I just pulled off my shelf. (Have I strained the metaphor enough?) One soapbox that I left out is Project Euler and friends, which I find to be interesting Maths exercises, but, at least for me, don't seem to be doing much for programming and certainly not for software engineering. $\endgroup$ Commented Oct 27, 2021 at 21:54
  • $\begingroup$ I think this answer would be better without the lists of "paradigms" and "concepts", which seem arbitrary. Otherwise, right on the point! Regarding language concepts, 7 languages in 7 weeks is also popular $\endgroup$
    – Bergi
    Commented Oct 28, 2021 at 2:41
  • $\begingroup$ "in German, it is called Informatik, in French informatique, in Italian informatica – all are a portmanteau neologism based on information and mathematics" Every single source I've read about this says the word comes from "information" and "automatique", not "mathematiques". Etymologically, "Informatique" is about automated processing of information. $\endgroup$
    – Stef
    Commented Oct 28, 2021 at 16:24
  • 1
    $\begingroup$ The best answer about the industry/discipline I've ever seen on SE and something I've personally been wondering about for a while, especially about the difference between the different degrees; thanks for this and please don't get rid of the paradigms and concepts part. Is there a good resource for learning all of the "concepts" in either Object-Oriented Programming or Functional Programming? $\endgroup$ Commented Oct 28, 2021 at 21:55
13
$\begingroup$

My advice is not too dissimilar from Buffy. I would try to get involved in projects with others. You might look into the indie game development community, or into the open source community. Join a project, contribute and observe.

Aim small. Even tiny-sounding projects will be surprisingly complex, and will help you to get your programming sea legs ("C" legs? Haha) under you. Scale is the enemy of project completion.

Finally, pair program whenever you can. You'll start to get a feeling for how to choose and utilize libraries instead of building things from scratch.

Actually, this is the main trick of the people who seem to be mystifyingly good at building solo projects. Their big skill is to get good at choosing and utilizing libraries instead of building everything themselves. By leveraging preexisting code, you can take an apparently large project (very hard for a person) and convert it into a small project. The closer the library you choose to your needs, and the better you are at using it, the smaller the project becomes.

Honestly, this is a big block for many of my students, who can learn to code themselves, but don't want to face the comparatively harder (or at least "surprisingly different") task or learning to read and use code bases developed by other people. Needless to say, the students who don't develop that skill are not able to build larger projects on their own. There is just too much headwind if you can't utilize the work of others and instead must build everything yourself.

Good luck!

$\endgroup$
9
$\begingroup$

If you're really new to programming, joining an open source project can be quite overwhelming. I would recommend picking up a puzzle challenge like Project Euler. Make a habit out of solving a challenge or two a day. Its great fun, and you'll find that you'll learn the basics quite quickly.

Although I cannot agree more with what was said above, practice makes perfect, I would also recommend reading the language reference of the language you plan on using. In the case of Python, that would be Python Language Reference.

After that you can pick up on what the others suggested, like joining an Open Source project, etc.

Best of luck to you!

$\endgroup$
2
  • 6
    $\begingroup$ This is by far the best suggestion, all these "JuSt CoNTrIbUtE To OpEnSoUrcE!" answers are way too naive. You can't "just" contribute to open source. If you don't understand real code, you won't easily be able to navigate their codebase. And the sense of accomplishment is probably far far off. With puzzle challenges (and I'd recommend Advent of code as well) you get a lot quicker with the gratification loop and are encouraged to program more in a much simpler easy to verify environment (even if the challenges themselves are hard). $\endgroup$
    – Krupip
    Commented Oct 27, 2021 at 16:13
  • 1
    $\begingroup$ While good advice, solving programming challenges seems unrelated to projects as I understand them. I'm guessing OP wants to make a "real" application, like a game, web app, mobile app, etc. Algorithm challenges are solved with tiny scripts that run on the command line and can be solved with 20-30 lines of code seem disjoint to making apps. OTOH, open source projects are far too intimidating and prohibitive to get involved with -- too real. $\endgroup$
    – ggorlen
    Commented Nov 2, 2021 at 17:08
4
$\begingroup$

The way to learn how to do this (or most anything) is to practice it so that experience gives you better results. You aren't going to learn it from a book or a video.

And, a good way to do it is in partnership with someone else (search for Pair Programming, say at wikipedia).

I suggest that you find someone, such as another student with similar concerns and approach one of your CS profs and ask them for an informal project that they might be willing to give you some feedback on. It might even be possible to arrange a bit of course credit in some places (Independent Study). One possibility for projects is to provide a "reference implementation" for some project that the professor already assigns to students or is contemplating doing so. A compiler, for example.

One of the more interesting projects that I once built was an "Entity Relationship" modeling tool (a graphical program) to be used to design databases. I also built compilers for a variety of simple languages.

I was self taught in CS in the early years and only got guidance later, but one of my earliest projects was to build a simulator for a simple computer. It had a few registers and a few instructions. The professor that teaches architecture probably has a machine specification that can serve as the basis.

But the way to learn it is to do it. More than once. And try to get feedback from a professor on your trials. This will help you avoid building poorly designed and impossible to maintain projects.

Some universities have a senior "capstone" project course that tries to bring together much of the curriculum in a single project. These are more likely to be team projects than otherwise, however.

$\endgroup$
3
  • $\begingroup$ "The professor that teaches architecture probably has a machine specification that can serve as the basis." I suspect you might be showing your age a bit there, Buffy. What university would teach Assembly code nowadays, when nobody in industry uses it anymore? $\endgroup$
    – nick012000
    Commented Oct 27, 2021 at 3:40
  • 2
    $\begingroup$ The purpose of building a machine simulator isn't to learn assembly language program, @nick012000, but to get an idea of how low level computation actually works. Building a Turing Machine simulator is also valuable for learning, but has little "practical" use. $\endgroup$
    – Buffy
    Commented Oct 27, 2021 at 14:52
  • $\begingroup$ @nick012000 Almost all universities I've known teach assembly nowadays. Why? It's foundational to how computers work. It's untrue that nobody in the industry uses assembly. Sure, if your goal is to make React apps, assembly is not helpful and in that sense, I understand your point. Universities still teach CS and deeper knowledge than exclusively "just get me a job ASAP" skills, although they do that too. $\endgroup$
    – ggorlen
    Commented Nov 2, 2021 at 17:12
4
$\begingroup$

While I did study CS, I learned most of what I use daily on my own, previous to my studies. As an adolescent, I would find something that interests me, and figure out how to do it from whatever sources of information that were available (paper books mostly, at that time, there was no Internet yet, at least not for the general public).

So, let your thoughts roam and find something - anything - that sounds interesting to you. If you're studying CS, then there should be some reason why you picked that topic (aside from there being a lot of jobs on offer, and often substantial salary for good graduates). What fascinates you?

Then whip out your programming language of choice and just "do it". Implement whatever you want. It should not even matter if it's big or small.

Think about what you learned in your studies, and try to apply it. It is normal that CS is not very applicable - some universities tend to focus a lot on the theoretical parts. Still, you can find out ways to do so.

Example projects from myself:

  • I programmed a moderately simple 3D modelling tool (I daresay you would call it CAD these days).
  • ... made my own version of Breakout.
  • ... programmed a client-server 2D isometric multiplayer game (you would call it ARPG today, or if there were ever more than 2 players online for the very short time the servers were running, an very small MMORPG), including the net code, an integrated scripting language, and all the tooling, everything from scratch.
  • ... a tool which would parse a hypothetical programing language and displayed the internal representation as a graph on the screen (combining topics from Compiler Theory and Graph Theory)
  • ... (one of my favourites) a floppy disk utility for an 8 bit computer, written in assembler, and includinf a lot of low level features including a disk formatting routine. You get one try at guessing how I lost the source code to this application eventually.
  • ... used Prolog to make a tool to ... don't know what it was, maybe putting pupils into classes.
  • ... worked on a popular open source rogue-like game (similar to Nethack), ported it to a fringe OS and maintained it for some time.

And so on and so forth. You do not need to pick those projects of course, but they all interested me. That stuff was possible back then even with quite limited information, and many more impressive projects should be much more accessible today with better tools and information.

TL;DR: Pick something of interest, and then use your skills and knowledge to make it - if you are lacking skills and knowledge, obtain them in the process.

$\endgroup$
4
  • $\begingroup$ I'm currently in the same situation as you prior to your CS degree, and am deciding whether to study CS or something else. Do you think the CS degree was worth it in the end, or do you think you might have benefitted more from doing something like Software Engineering, or even just studying online programming courses? $\endgroup$ Commented Oct 28, 2021 at 22:01
  • 1
    $\begingroup$ For me it was perfect. I find almost all CS topics very interesting, and while the occasions where I could really apply the knowledge from those studies were very sparse in the last decades, occasionally it did happen. If I had not studied CS, I would never have come in contact with most of these topics (i.e., functional aspects - lambda calculus etc., logic programming (as in prolog or constraint programming), theoretical CS (temporal logic, complexity theory etc.) and so on and so forth. Even our even then very old-fashioned Compiler courses were benefitial at one point for me... ;) $\endgroup$
    – AnoE
    Commented Nov 2, 2021 at 9:58
  • 1
    $\begingroup$ That said, if you are just thinking in terms of increasing the worth of your CV, a more practically oriented course might maybe be more efficient, hard to know. If I'm looking at applications, I am looking at the whole picture, not just the degree. $\endgroup$
    – AnoE
    Commented Nov 2, 2021 at 9:59
  • $\begingroup$ Thank you, I appreciate the answer. $\endgroup$ Commented Nov 2, 2021 at 16:32
2
$\begingroup$

As others have pointed out practice makes perfect. The best way to learn is by trying. Even recreating something that you have created before is a valuable since you often times realize what you could have done better once you are in the later stages of a project.

If you are lacking an idea of what to build you could try:

http://www.raytracerchallenge.com/

It‘s a book that teaches you how to create your own ray tracer. The neat thing is that it does not use any specific programming language. It gives you instructions on what to do and test cases to test your code.

If you are willing to spend some additional dollars you might also want to check out the Live Projects from Manning:

https://liveproject.manning.com/#catalog-list

They often run promotions where they cut prices by ~50%.

$\endgroup$
1
  • 1
    $\begingroup$ Those are some very interesting resources! $\endgroup$
    – Ben I.
    Commented Oct 27, 2021 at 11:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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