Ask HN: I've learned a programming language – how do I solve problems with code?

205 points by bnb ↗ HN
I've spent a lot of time learning JavaScript (done the Codecademy JS course, finished CodeSchool's Real Time Web with Node.js, and read and implemented most of Node.js in Action), and I thought all I would need to do after I learned it was to start writing code.

Well, I can write code, sure. But I don't know how to _solve problems_ with it. I know how to create a webserver in Node that echos "Hello, World!" because I've done it a thousand times. But I don't know how to make a site with logic and structure behind it that will lend itself to solid functionality that users can benefit from.

How do I learn that?

111 comments

[ 3.2 ms ] story [ 218 ms ] thread
Start small then build up. Give yourself lots of small nonsense throw-away challenges, or maybe take one small part of somebody else's website and see if you can duplicate it.

You have to keep challenging your boundaries. Don't do stuff you know, try to to do things you don't know. But keep each step upwards simple - don't try to build a skyscraper before you can build a house.

I think this is great advice. The only thing I can add from my own experience is - take your time to reflect on what you've learned once you achieve a new goal.

I also sometimes like to redo old stuff without looking at the code of my old solution and then compare. It is time consuming but really helps to see how you have grown.

The best way to learn is always to just do it. Now that you r got some fundamentals down, think of a project that you would enjoy building. Now Google the little pieces together :)
Are you having troubles coming up with problems to solves or in getting started on a problem you've identified?
Find a problem first. Then try to implement a solution using your language of choice (Node in this case). An example could be: "I want to create a service that parses books and lists the most frequently words used. A step further would be to have the user enter a longer piece of text and analyzes it (http://www.online-utility.org/text/analyzer.jsp)"

Another example is "I want to create a service that auto-corrects text that users enter."

Try to find something that would make your own life easier. Chances are that other people are having the same problem.

Shameless plug. Hopefully you get some ideas out of it: http://jairampatel.com/projects.html

I was in this same situation for a long time and when meteor 1.0 came out I went through several tutorials, including discovermeteor, bulletproof meteor. Its like a wave of ok, now I can build stuff and its dynamic, I had a plan to learn socket.io and now it just works. I have also signed up for the free mongodb class jan-Feb so that I don't make a big mistake at some point and dump my database. I also used erlang zotonic for a while but meteor has a bunch more kool-aid that makes it easier when you get stuck or have a question. Oh man, good luck I have been in that situation and can really feel your pain.
This is a very common problem for people getting into software development. You are not alone!

A lot of other people in this thread provided some good advice to finding problems to solve, but I'd just like to comment a bit on how to solve them.

My advice: read code. Lots of it. Find popular libraries in your language of code and pick them a part to see how they work. Set up some open source project that solves a real problem (a CMS, chat bot, whatever) and explore how it operates.

Seeing how other people solve problems will give you a good frame of reference on how to tackle other challenges you encounter. You will also occasionally come across sub-optimal solutions: learn from those as well. Seeing how to do something badly can be just as valuable as seeing something done well!

At the end of the day I think programming is a lot like writing: a good writer reads a lot of books and writes often.

Just keep at it, there's a whole community of people here who've gone through this exact same thing. Good luck!

>How do I learn that?

I had (have?) the same issue. Maybe it's something that experienced programmers take for granted; there is a huge disconnect between writing code and developing software.

I've asked the same question, and received the same answer: get your hands dirty. I agree with the premise, and am working on it. But there's the disconnect. I can write a little Python, but have you ever tried to set up a Python development environment on your computer? I don't understand 95% of what is required.

All that said, I'm way ahead of where I was when I started, a year or so ago. I'll keep plugging away, and recommend doing the same. Hopefully we see a few good replies here to help us out.

You are exactly right on this description of the the pain that is learning to develop.

Example: If you want to learn to play baseball. You learn the mechanics of the game. You learn to hit, catch, and throw. You can be an expert baseball player, and you can practice the shit out of mechanics all day long, and play games, and win games all day long for decades.

But if you want to manage a club and win games, you need to take that next step to learning the mechanics of the game beyond playing baseball, or all you will ever be is a player, and you will never be able to actually build a team that wins games.

Telling someone to go practice hitting, throwing, and catching in order to perfect their ability to orchestrate and manage an entire team of different moving parts would sound crazy.

And that is how it sounds when people continually say "just go write, fix, and build."

I do not have an answer for this problem. But, the answers that always rear their heads when this question comes around, have the opposite ideals of how anyone that has taken the time to learn the mechanics of development. Those people that have taken the time and effort to learn the mechanics are mostly those that appreciate clear and concise paths to solutions. And, as far as I know there is not good resource for bridging that big gap between mechanics and craft. I could be wrong, and there could be a wealth of this information on this process stashed away somewhere. But, the problem is that most of these paths are most likely buried somewhere in a course or resource that is shrouded in mechanics, when the learner is just looking for craft.

The person that clearly outlines this path from Mechanic to Craftsmen will undoubtedly be very successful.

I agree with this, but I do think there must be something that we're missing. Many, many skilled developers are saying "just go out there and build." The problem is we don't know how to build.

I think there might be an implied aspect of this that we're not getting. Someone said to (paraphrasing here) "Google every problem you come up against; 'how do I do x with y, how does a work, how do I implement b, etc.'" That seems like it would work--if you Google every problem you have, or look at the docs for every function you use, a pattern will start building in your head that shows you how to do x with y. I think the key here is looking at the core source of the tools you're using and connecting the dots in your head.

Perhaps following along with an open-source project in active development?
I can't relate to baseball but I notice a common pattern that applies to most fields.

You are told to do the basics over & over again so you:

a) Learn the motions

b) Learn how they work

You can't successfully apply your knowledge/tools/skills without knowing what makes them tick.

Let me phrase that with an example from my past. I was big into Starcraft at one point in my life.

Started with SC:BW. I was terrible back then, doing builds like an automaton following a recipe - I lost as soon as someone stepped out of the cannon and did something non-standard. Why? Easy. I had the mechanics but was missing the know-how on what made them work and how to apply them.

Instead of going that route I started to watch better players. They quickly diverged from the builds - enlightenment came when I noticed that they were playing reactionary. They observed their opponents and made decisions.

Why am I expanding now? Not because the build says so but because my opponent invested in tech so will not have the resources to pressure my new base etc. The basics are important, if you have your mechanics down then your mind is clear to react and just execute the movements to achieve the goal you want based on what you observed.

It works the same with programming. If you're stumbling with language syntax, your framework - the basics. You will then loose a lot of time hunting small issues and constantly loosing the big picture. When you're basics are down you are free to experiment and will notice patterns that beg you to apply one of the basics you learned.

Some problems are specific, fall into the 'what data structure, algorithm' should I use. Some are structure/flow related - how do I make those two things connect to each other and pass data around. Some are new - but they all mingle and repeat themselves very often.

When you read a lot of code, write a lot of code - you will start noticing the patterns. In the worst case scenario - knowing the basics will make it easier for you to ask better questions/find answers to hard problems faster.

Absolutely agree with this.

There are hundreds of tutorials on how to write JavaScript, use the for loop, use if else statements, and so on. But not very many that I have found actually show how to use those to build a real program, explaining the steps and thought process behind the program along the way.

There are definitely ones that show you how to do things with it, but there's often not an explanation of _why_ something works the way it does.

Pick a small, simple project that will force you to learn new things and put pieces together. My favorite starter server project is building a super simple URL shortener. You just need to render a page with a form, accept a POST from that form submission with the URL to shorten, hash the URL, store it in a database, return the hash, and set up a GET that maps your hashes to your URLs by looking up against the database.

The most important thing with beginner projects is scope. Pick MVP versions of things you want to make and build out.

I've often felt the same way. I've found things just by spending time brainstorming, and keeping it in the back of my mind as I go about my week. You can actually come up with a lot of ideas just by practicing observation of daily tasks you have.

I'd also recommend attending a Startup Weekend or hackathon of some kind and just joining up with a group working on something interesting. Being around the creativity at these can the wheels turning even afterwards

Excellent question for a Friday. Coding is like welding, how do you find two pieces of metal that need to be joined? Generally the answer is visualize something that could exist, but does not exist, and then fill in the parts that need to be there for it to exist.

What you need at this point are a series of assignments which are self-contained problems with known solutions. The assignment 'create a web server that displays "Hello World"' is an example of one.

Here are some more:

Create a web site that allows a person to identify what would be an 'affordable' mortgage. (or flip it, shows them how much they need to save each month in order to retire). These are both applications of the compound interest / annuity calculation, but built in such a way that you can pick different parameters to see the results. Pick an interest rate, or pick a home value or retirement amount.

The goal of that assignment is to have you create a web site which has a built in formula (logic) which can be manipulated by user entered data.

Next assignment, build a web site that collects data about a particular commodity that changes day to day (could be a stock price, could be oil, unemployment, could be Eve online credits, what ever), then plots that data on a graph. Allow the user to annotate the graph by date with specific events. You will find the d3 library helpful here. Once annotated allow the annotated graph to be shared by URI.

The goal of that assignment is to get you to store data over time, use third party APIs, and provide a way of getting to a particular state based on arguments in a URI.

Now for third assignment, create a market site for three commodities, we'll call them 'stone', 'wood', and 'sheep'. Have a system random number generator periodically generate one or more units of one or more commodities. Simultaneously create a Sudoko board such that the first player to solve the puzzle gets the commodities. In the Market people can buy and sell commodities, the market creates a currency for recording those transactions. Players with a specific quantity of individual commodities can produce a 'product' and that product adds to their 'production' score. Rank all players by the quantity of currency in their account and their production score.

The goal of that assignment is to create a fun market simulation game that echoes some of Settlers of Catan and gives you something fun to put into a Show HN posting.

Bottom line, practice problems. Then when you, or someone you know says, I'm trying to do this ... you can tell them you can do it or not.

One of my favourite comments ever on HN. The welding analogy is apt.
(comment deleted)
I am learning to code and the welding analogy is helpful and encouraging. I am a competent welder (TIG, MI & Arc). I'm confident that with enough practice and commitment I will be an even more competent programmer.
In fact my gravatar is a welding guy. (since 2011 :)
(comment deleted)
Like said, I normally buy a domain and setup an idea and work on it. In the process I learn a lot.
Why would you buy a domain per idea for learning to develop? Sure for production this is a given but for fiddling about with things unless you have a good reason to work remotely why would you?
Because domain names are cheap, and feeling like you are actually producing something that the world can see is a great source of motivation. You also run into problems when you deploy to a real domain that you never encounter if you're just noodling around with code on your local computer.

The risk of creating a bunch of toy programs on your local disk that you never show to anyone is that you avoid the hard parts. Accountability is a good thing, in programming and in homework.

Because a domain would provide a real world example on a live server rather than a 127.0.0.1.

Also one would learn to tweak a server to the application.

Because a domain would provide a real world example on a live server rather than a 127.0.0.1.

Also one would learn to tweak a server to the application.

(comment deleted)
That comment. It made my day. It's one of the finest comment on HN
@ChuckMcM, your assignment on market theory is nicely put.

I particularly like the idea of the sudoku part as a way to get raw materials. Get some crypto there and here and gateways with the "real" economy, and... you know what I mean ;)

The sudoku idea is a game version of Bitcoin, some sort of proof-of-work to get raw materials (mine). There have been some great write-ups of in game economies and since you want a simple one as a programming project it seemed like a reasonable stand in.
Programming languages are a tool. Problem solving is a skill.
(comment deleted)
based on what you wrote, i would say the next goal is to write a twitter clone.

write something that takes user input, stores in a database, and represents it later on.

CRUD (create read update destroy)

many webapps could be categorized as a CRUD app, or start as a CRUD app. if you've only gotten as far as "hello world" then i'd consider this a worthy "next target"

Remember, programming languages are a tool and problem solving is a skill. Learn data structures and algorithms. There are plenty of good books and websites out there on those topics. Once you have a basic understanding of those you can learn to apply your language of choice to implement solutions to problems. Next, find problem and solve. Also, some languages lend themselves to solving certain problems better than others. Don't limit yourself to one language. Once you have the knowledge of one language you are only a different syntax away from the next. Logic does not change, problems do.
Read Programming Pearls to begin flexing your mind in the right direction. It's a somewhat older book in terms of the actual practicalities, but in terms of getting you thinking about how code is applied to situations, it's timeless.
I learn it backwards. Take something slightly complicated (so much so that you find it challenging to read) that solves a problem that you understand.

Then think of a feature or modification that you think would be useful. Try and implement it.

It's incredibly painful but I find this works better than trying to build something from 'hello world'. Before you know it, you can understand why stuff was implemented that way and what not.

What have you done that's more advanced than 'Hello World'?

I'm assuming you don't literally mean you've written 'Hello, World!' a thousand times, and I assume you've tried more complicated projects, so where do you keep getting stuck?

Logic and structure doesn't leap, fully formed, from the head of an architect like some prophecy. It starts with some notions that are carefully honed into a working implementation.

Try make something that interests you, see how you would go around implementing it. If you're stuck with a feature, google it. Then see how you did against the "proper" way of doing something, and maybe adapt your code to use the "proper" method. By proper, I mean that it's a more efficient way to do something than to hack it together and have it just about work.

You've learnt the language and the syntax, but it's the experience of just doing something that counts is where it's at! Good luck :)

Don't start by trying to solve a problem. That way lies madness.

(The problem is that your mind, your approach, needs to change, and that change comes with practice and time. And practice always starts with the simple, the controlled, the repeatable, not the full fury of all skills brought together in a high pressure win-or-lose moment.)

Computers are nothing more than repetition machines. Start by writing code to do things that you yourself now do multiple times per unit time.

Start small. Simple things. Let the computer handle the repetition for you, no matter how simplistic and rude and hacky your solution.

Then notice how program A and program B, written to repeat different procedures, have similar processes or structures.

Generalize A and B to make a C that does both.

Do this again for other processes. Over time, your approach will shift. You will notice patterns: Patterns of process, patterns of structure, patterns of relation.

Then you will start solving problems. Only afterwards will you realize you have done so.

(I started coding shell scripts for anything I had to do more than twice - or anything that required "too many characters". I got tired of typing "ls -alt *|head" so I wrote nwst to do it for me. Then I added a numeric option to nwst to control how much head wrote. I got tired of writing "find . -iname" so I wrote fndi. Etc. Etc.)

I don't know why this got downvoted, it is very intelligent and I completely agree. Especially for kids, the most effective way to learn coding is to have complete visibility over all the underlying components.
Outside academia it is all about conformance to requirements -- i.e. you get paid to solve a problem for somebody somewhere.
True. But my read of the OP is that they learned for the pleasure and interest of it. They want to "solve problems" for the intellectual satisfaction and joy of doing so, not because someone is paying them or anticipating doing so.

We have to master the skills before we get rewarded for them.

Thank you very, very much for your main comment. I am actually a member of both academia and the realm of "regular people/programmers/hackers/whatever." I'm a college student, so a lot of my work is for the most part free (despite what most people think about academia). However, I also want to do programming for a living, and know I will have to conform eventually.

That said, you're absolutely right in saying that I want to "solve problems" (that's just the best term I could come up with after months of trying to convey my meaning to many people--I have no attachment to it) for the intellectual satisfaction and joy of doing so. I really just love what I have done with writing code. It's really fulfilling and the structure of it resonates with me at a deep level.

So, your comment is very helpful. There's no end to the small problems or ideas that I have, especially within my work writing code. You may have answered this and I didn't understand, but the main thing I'm getting at with my OP is that I don't have the skill set to actually solve the problems. I know it probably sounds completely ridiculous, but I've approached many small problems and have always produced the absolute barest skeleton of the program which solves the problem I have. I then draw a blank on what I need to do next to continue solving the problem--the structure and the logic don't exist in my brain yet. That's what I really want to get from this thread, and I think there are some excellent responses that help with that, including yours.

I don't know your career ambitions and goals, but there is a lot to be said for the technician/mechanic/custodian (not really sure of the best word) who solves one problem and moves on.

If you are at all inclined to system administration, your approach (notice problem, solve problem quickly and effectively, move on to next problem) can translate to solid work.

Now I speculate: As an employee, this will probably lead to low to medium pay positions - at least until you start seeing and solving larger scale problems. As a consultant, however, if you can get a stable of repeat clients, preferably under retainer, you may actually do quite well.

Back to reality. How to make progress? Find an OSS project or two that you quite like, preferably ones with really good communities. Go through the lists of current bugs. Find and fix those you can.

Heck, just start finding flaws in people's code and documentation on GitHub, fix, and issue pull requests.

You will get a reputation in the community as a reliable, dependable problem solver. After a while, reach out to people who seem both approachable and a step or two above you. Ask if you might be able to help them with a larger problem, one which they need assistance with and on which they would be willing to mentor you.

That's one approach, at least.

Your academic environment may also have code that needs maintaining, patching, repairing, refactoring. Food for thought.

Keep at it, the penny will drop, things will click into place.

  1) Go to Github
  2) Browse the Javascript projects
  3)  Look for projects which are active with many follows/forks
  4) Click on the Issues tab
  5) See what open issues there are
  6) See if the maintainer is active and applies pull requests
  7) Pick an issue you can fix, fix it, write a patch
  8) Send a pull request
  9) See if the maintainer has any comments 
  10) Go back to step 1

See - you're solving problems. This is the kind of stuff you'd have to deal with on the job, and is the kind of stuff you'll deal with with your own projects as you or your users discover problems.

I know exactly a problem you can solve right now with Javascript.

   * Go to this website - http://maps.huge.info/zip.htm 
   * Move around the map so you can see where various San Francisco zip codes are.
   * Now try to do this on your phone
I'd love for this to be a mobile-friendly website, but it isn't. It's a useful tool, it looks like it's just a mashup of Google Maps and ZCTA's. A perfect project and problem to solve.
Yes! There are so many comments in this thread and the last one makes the most sensible suggestion: get involved with an open source project!

There is absolutely no point in starting your own projects from scratch when you've never seen other projects.

Fixing random bugs in open source software is great for two reasons:

1) you'll need to read large amounts of code to find bugs, learning things about coding style, design patterns, architecture along the way

2) What you do actually has a purpose. There's nothing more boring than programming for the sake of "practice"

The answer will be 'write code'.

This will teach you a lot of things... I can try to come up with a short list of what I've observed of my own development as a programmer.

You will recurrently come up with particular patterns, you start to identify which approaches will work, which will be dead ends and so on.

Try to separate your understanding and model of a problem to at least data, model and view domains. You will have certain data - you should keep this as simple as can be for the problem you are solving. There will be the model - how is the data mutated, which rules will guide it - and there will be a one or more view to this model and data. Note, that as a pattern the view encompasses both the possibility of an API to your system, as well as the actual display of data.

Try to keep you code as simple as can be. Don't go for the more complex solution unless you know you really need it.

'Pragmatic programmer' and 'code complete 2' are pretty good books about software development in general.

I would suggest you figure out what interests you and then try to implement simple programs in that domain. If something feels too complex, then first try a simplified version... more simplified etc. until you understand how to solve it.

One of the best knacks to learn is how to approach something from a direction which makes the problem easier to solve. There are usually an infinite amount of ways to write something and the challenge is not to just start writing code but actually figuring out which solution method leads to the most understandable and easy solution.

I would suggest you familiarize yourself with the practically important datastructures: the list, the binary tree, the map and the graph, etc. "Algorithm design manual" is a pretty good book for this. Aho's foundations of computer science is a pretty solid and free reference: http://infolab.stanford.edu/~ullman/focs.html

It's probably most motivating to mix the computer science with practical exercises unless you find you get a great kick out of it.

Good luck!

Your best project ideas are going to come to you in day-to-day life, like the time my roommates started complaining that the laundry machine in our basement was always being used. A couple days later, a simple web app was hacked together that displays the washing machine status, and let's anyone "claim" the machine. I did that project when I was in college, and I probably knew way less about web servers and Node than you. I just Googled the first thing I wanted to do "make a website", struggled for a bit figuring out DNS and hosting for the first time, and then put up a test page. Seeing a page show up on the internet at yourwebsite.com for the first time is a pretty magical thing, and the rest was history.

In general, what you need is activation energy - that initial bump to get the project or idea started. After that, you need to practice maintaining the motivation to complete the project you started.

Asking the HN community was an excellent way to start. Good luck!

before i learned to program, i knew what i wanted to create. that was 13 years ago when i was too busy playing an online video game (nba live 2000) and i wanted to create an association league out of it, just like nba.com. first thing i knew i needed was a website, somehow picked php and after heavy amount of trial and error, just under 4 months or so i had a website going with my own forum, standings, team management system, player/team statistics, etc ... little did i know, that was all it took to set me off on a career path i've never have imagined otherwise and i love every day of it. :)