Hacker News new | past | comments | ask | show | jobs | submit login

I'm looking for courses that seem to be the opposite of this... no language or programming at all, but instead looking at the process of breaking down problems.

We've hired several devs out of bootcamp, and they're all taught how to code, but not how to solve problems using code...

Anyone have material that might be good for this? Books, videos, courses?

I have three recommendations:

Think Python: http://greenteapress.com/wp/think-python-2e/

Polya's How to Solve It: https://en.wikipedia.org/wiki/How_to_Solve_It

Udacity's Design of Computer Programs: https://www.udacity.com/course/design-of-computer-programs--...

there's also Clean Coders: https://cleancoders.com/videos/programming-101

these videos are quirky (!) for sure, but filled with some real gems and a depth of perspective that's rarely found in other online courses.

the link goes to a free video intended as an intro to the aspiring programmer.

I'm posting this only because I've seen several of these videos and think they've got something special.

It's from the guy who wrote Clean Code and Clean Coder which are gems themselves !

Thank you so much for posting these links. I started reading How to Solve It and am a few pages in, and am so happy to have found this book. This is the value that I find here at HN that keeps me coming back every day. The new tools and new technologies, and the interesting tech news are all very interesting, but none as valuable as the gems that people leave in comments for others to discover, thereby enriching their lives.

Put the newbie gumshoes to work by tracking down simple bugs and designing simple patches to fix them. They need to be able to read other people's code to decipher and debug the coding style they are seeing before they are allowed to build any new module themselves. They need to understand other styles so they can form their own. They should be able to detect any code "smells" and reason with pros/cons why their implementation could work better and provide proof (like execution timing or better readability).

Playing a lot of puzzle games help as well, especially games where the thing to do is very abstract like in a point-n-click adventure game.

>> They need to be able to read other people's code to decipher and debug the coding style they are seeing

>> They need to understand other styles so they can form their own

After 15 years of working professionally, I kindly have to disagree to a fair extent. It turns out that most - if not all - developers are not very good at writing clean code. Including (especially?) seniors who think they write the best code on their team. The code you're having the juniors dig through to tweak/maintain is probably terrible code that should not be used as a shining example of anything good. They're more likely to pick up someone else's bad habits than learn something useful.

It took me a very, very long time to realize that it's simply a matter of fact that no two developers think alike, and that any set of developers could argue all day as to why each other's code is ugly, unmaintainable, etc. There are extremely few instances where one implementation of any problem is "better" or "worse" than another - we simply think differently. My code will always be "smelly" to you, and your code will always be "smelly" to me.

Junior developers must be permitted to write new code from scratch. Whether it hits production as-is, or goes through weeks of refactoring, it's a must. No developer ever improved by only reading and maintaining other people's code. I have never met a developer who feels at home maintaining someone else's rushed garbage. And 80%+ of the code we write is rushed garbage to attain the 3 week mandatory deadline handed down by management even though we told them it would take 3 months.

There is a finite amount you can learn by reading other people's code. You might find specific idioms you admire and adopt, but you will not - and probably should not - try to conform to other developers' methods.

Not to mention, forcing new recruits to deal with everyone's legacy garbage is a surefire way to turn them off the industry before they've even begun. Let them code a small new feature; then sit down and find out what they did well and what needs improvement; truly tangible issues, not the typical "that's not how it's done" - which really only means "that's not how I would have done it".

>> It took me a very, very long time to realize that it's simply a matter of fact that no two developers think alike, . .

I was part of ThoughtWorks interview process sometime back. In one of the rounds called Pair Programming, a senior developer worked with me on the given problem statement. I arrived at right solution, but he wasn't happy with the solution just because he didn't like the way I solved it. I came back and discussed the same solution with another senior developer and he liked the approach. However ThoughtWorks rejected me in the interview process.

I often wonder how pair programming is good (or even bad) in this context. How they can assume or think that two programmers going to solve the problem in "same" (or even ThoughtWorks "expected") way!

>> How they can assume or think that two programmers going to solve the problem in "same" ... way!

It takes a lot of restraint and stepping back from being in "first-person developer mode" to understand that someone else's unique approach is quite likely valid. I purport to be able to do so but I still find it incredibly difficult to ignore my brain's initial instinct to start pointing out the supposed flaws in someone else's structure, when the simple fact is my own code for the same problem would probably be filled with the same holes - just in a different form.

Honestly, there are only a few metrics that really matter when it comes to quality code:

1. Does the code accomplish the task it's supposed to? I mean really, this is practically the only thing that really matters in most cases. Simply: if deployed, will it work?

2. Are there no glaring security problems with the implementation?

3. Does the code not excessively overuse resources (cpu, memory, network/system calls, etc.)? Real excess beyond what is reasonable, not micro-optimizing.

4. Is the code not a complete mess? No serial use of copy/paste, crazy spaghetti mess, or inability or blatant refusal to follow basic coding standards?

That's it. Deploy that shit, and move on to the next problem. ;)

This is exactly what I was thinking! The points that were written is just as what I had in mind. But I guess still your missing one important point on testing. The code should work if deployed, but at the same time, we need to have through testing for the same.

I always start with reading test cases rather than source code directly. Thats the way it should be (IMHO).

After experience with several junior developers I plan to do the following to train the next one. First, let them solve an isolated problem in our code base. At pull request step comment excessively (this is what inevitably happens with all junior developers, the PR is so huge that GitHub chokes on it). Finally, pair them with a senior developer to solve the issues raised in the PR, rather than letting them fix them alone and engage in an endless loop of commits and comments.

I agree - you very much need to learn the rules first, before you go and break them

This is really a good idea. I have seen this happen with several teams in my organization.

I've been the other side of this as part of the interview process.

One person we were interviewing solved a problem pretty much exactly opposite to the way that we (and every other candidate) had solved it.

At first glance it simply looked wrong, but after a discussion with the candidate the strengths of the solution became apparent.

Happy to say they got the job, and ultimately turned out to be one of our best hires.

Your advice here probably applies more to beginner programmers where the goal is to prevent them from just copying/pasting code and following bad practices. It's a good thing for them to learn to write things from scratch. I've been programming for a while and I've felt for a long time like my skills kind of plateaued. Writing things from scratch and reading a lot about design principles haven't really helped me improve at all. But lately I've started to read code, really read it to understand what it does and this has vastly improved my skills.

> There is a finite amount you can learn by reading other people's code. You might find specific idioms you admire and adopt, but you will not - and probably should not - try to conform to other developers' methods

From my own experience I disagree with this since reading other people's code has helped me improve a lot. I've noticed that I am so much more creative and intuitive about good software design when I go to write code now and I believe it is credit to reading code everyday

As much as this is mostly true, its not always true... I've met at least 3 developers in my career i consider to write very good code, often better than my own... and a small handful i consider 'not-shit' and 'employable'...

The vast majority are just shit though. That was a hard lesson to learn. You want to give people the benefit of the doubt, but the industry is full of people who have learned nearly nothing in their careers compared to a really good grad who has never worked anywhere but has raw talent and good problem solving skills.

I'm hoping there's a way to teach them problem solving BEFORE they learn to code... I feel like it should be a prerequisite to enrolling in the bootcamp. I don't remember how I learned it, but it certainly wasn't reading other people's code at my first job.

Some people can be taught to write code, however far fewer can be taught to or have the natural ability to problem solve. This is the 'art' aspect behind software development that I feel the 'teach everyone to code' approach overlooks. With any creative field there is a huge amount of 'prior art' that exists and that is also constantly evolving, and the more of this you are at least aware of or - better still - capable of reproducing, the better you will be able to express yourself / problem solve with software.

I hope I am not alone in feeling that looking at the code of a well-engineered and well-structured project can be quite the artistic-appreciation experience, and that this experience always leaves you with some piece of knowledge and understanding you didn't have beforehand.

I know that I learned the basics of chaining things together to get an effect by experimenting on my own in QBasic; basic graphics and audio were super easy, so I could also experiment with the difference between internal data state and how to represent that state.

When I started a directed education, learning new programming concepts always expanded the set of problems that I could solve. Learning how to reason through them didn't come separately, it came through writing programs of increasing complexity over time.

Before learning any meaningful amount of programming, I was introduced to the idea of examining the capabilities of your available tools and using them to find creative solutions...with adventure games.

I would consider a curiosity for exploration and experimentation to be central requirements to become a problem solver (at least through the path that I did). Start with that general mindset, present a world for them to explore, introduce them to the tools they can do it with, and there's no way to stop them from that point on.

I don't really know of anyone who learned problem solving with a computer before they learned to code. Supposedly Dijkstra, but that man thought computers cheapened computer science.

I feel like there's so much intrinsic to the code to solve the problem though, like how the debugger works, git bisect / git blame to determine where an issue might have arisen, commenting out lines of code and checking if they cause a particular issue, etc.

I don't think I learnt about problem solving in the abstract, it was more about specific applications of problem solving in the programming world.

Someone gives you a one paragraph description of a feature... I assume you don't immediately open up the debugger and start git bisecting... I'm talking about the things that happen immediately after being presented with a problem, and before you start typing code.

Just to leave some suggestions of puzzle games that are little hidden gems and that provide great logic thinking training. IMO they should be played in the order below:

1) Blockly Maze game (free) (https://blockly-games.appspot.com/maze?lang=en)

2) Jelly no Puzzle (free) (http://qrostar.skr.jp/index.cgi?page=jelly&lang=en)

3) Human Resource Machine (paid) (http://tomorrowcorporation.com/humanresourcemachine)

I agree on the puzzle games: also, get them on Zachtronics games: Spacechem, namely.

This is the only thing I've seen that remotely comes close - but truthfully, the reason it's so hard is because it just comes with experience.


> We've hired several devs out of bootcamp, and they're all taught how to code, but not how to solve problems using code...

Frankly any Algorithms & Data structures book should do the trick. Choosing the right data structure is often half the solution when solving a problem. That plus SICP and a book about Discrete Math should be enough for 90% of the daily problems.

I'm not sure Algorithms & Data Structures will help you all that much in the real world. In most modern languages, all the algorithms and data structures are already implemented in the standard library, and while having heard of them is beneficial, you won't get a lot of value out of knowing how to do a binary search.

The problems that I see most junior devs struggling with are at a much higher level. How do you organize large scale programs? How do you make sure that different parts interact flawlessly? A book about design patterns could help here, but without experience you won't appreciate what the patterns are good for.

But by far the most difficult part to wrap your head around is concurrency. How do you make sure your assumptions all hold up when multiple threads / processes / users are all doing stuff in parallel? That's really hard to understand, and you need a combination of theory and experience to master this.

I'm not sure what my point is. Software development is hard, a bootcamp and an Algorithms book is probably a good start, but after that you need to still put in a lot of effort to reach your full potential.

I'll disagree with this.

Algorithms and data structures can actually be great not because you implement your own but because you can find out why your N^3 algorithm is slow (give you three guses) and why iterating through your data is slow (since you used the wrong data structure)

I like Bootcamps for what they are, a tool to fill Junior level positions for people to begin working their way into a career and I love teaching the people who graduate and are interested in continuing their career, but there is more to programming than paying for a Bootcamp and spinning up a Rails/React app.

PS: Forget anyone who says "I already know how to code, I don't need to learn this". Those people are fucking boat anchors, they just sink.

I'm inclined to disagree as well. Organization of large scale programs/problems is straightforward if the composing parts are sensible. The datastructure is root of all. A proper explicit structuring of the data is crucial to constructing a good abstraction. I usually accent reading others' programs or solutions, with objective of finding new ways to see the problems. Of course it's important that said programs are good quality. Inspirational properties of elegant programs should not be underestimated. To me, most influential such readings were classic textbooks (Norvig's PAIP), classic algorithms (like qsort) and others' kata solutions. Also, another thing that I find is very important is if you work on very complicated stacks like web or native apps, to step back from time to time and do some cleaner programming in simpler environments. This helps maintain curiosity. What I do is write small programs, and I don't implement actual stack calls (like filesystem calls or dependency calls), just stub them. This let's the mind feel free. When I'm done, if I want to have it functional, I'll implement the calls. Point here is not to burden self.

As an algorithmist, I strongly agree. Algorithms are of value, but they are not a high priority for junior devs. For a tiny fraction of problems, algorithms knowledge is absolutely essential, and often cannot be picked up at the time of need. But for almost all problems, especially the problems facing junior-to-intermediate devs, there is rarely any algorithms work. As you said, code organization. Long lists of things to remember to take into account (e.g. what areas require one to stop and get a security expert). Etc.

I think the best thing you can say for algorithms training is that, without it, you often don't notice that you need to get an algorithmist.

When people say, as my sibling commenters do, "find out why your n^3 approach is slow", or "do a substring match", I wonder what problems they're solving. Has this shit actually come up in your career, or is it just something that you imagine will come up? How many times has a cubic algorithm actually been the problem? As compared to doing five hundred DB queries, instead of one query that JOINs properly and returns a 500-row result set, which I see juniors and students do all the time, and is not an algorithms problem at all (it's the same asymptotic complexity, btw!). How many times have you tried to figure out a fast approach to substrings, and how rude was your code reviewer when they pointed you at the standard library?

> The problems that I see most junior devs struggling with are at a much higher level. How do you organize large scale programs? How do you make sure that different parts interact flawlessly? A book about design patterns could help here, but without experience you won't appreciate what the patterns are good for.

I couldn't disagree more. Algorithms are the base level that you build on. Anything non-trivial you will have to understand what is available to you and create something new. Take something common, doing a substring match on a list of items. If you don't have algorithms knowledge I'd bet your solution is going to adversely affect the final program.

Good choices of data structures, and solid understanding of algorithms are the units of composition in creating software. IMO

> But by far the most difficult part to wrap your head around is concurrency. How do you make sure your assumptions all hold up when multiple threads / processes / users are all doing stuff in parallel? That's really hard to understand, and you need a combination of theory and experience to master this.

Or use Rust and have the compiler check it for you, so you don't have to be a wizard.

> How do you organize large scale programs? How do you make sure that different parts interact flawlessly?

All junior (and many senior) devs struggle with that. This is solved with experience, not training.

Pretty much this. I show/tell people all the time that most of solving the problem is how you structure the input data. `Rock, Scissors, Paper` is perhaps the best simple demonstration of this.

That said, I don't think it's something that correlates to being a bootcamp grad. I'm usually the one `solving problems with code` and the closest thing that I have to an education in this industry is the boot camp I attended (lifelong programmer regardless). I know other boot camp grads who are the same way.

I encounter developers from all backgrounds who know how to code but can't solve problems. There's just _a lot_ of bootcamp grads right now.

FYI, it's spelled 'discrete math.' I know this only as someone who spent years incorrectly spelling 'discreet' as 'discrete' because of my math background.

It's very discreet of you to use a pseudonym!

I agree that it would do the trick... but given that Problem Solving is such a basic skill, I would hope that someone could have figured out how to do it without requiring years of college math and csci.

(for reference, my real concern is my cousin is in a csci-150 course, having trouble because her prof isn't used to teaching to students who haven't been programming for years... nobody has bothered to figure out how to teach problem solving, and they're left to teach themselves or drop out)

How to Design Programs is written to address this issue.

From the preface:

The typical course on programming teaches a “tinker until it works” approach. When it works, students exclaim “It works!” and move on. Sadly, this phrase is also the shortest lie in computing, and it has cost many people many hours of their lives. In contrast, this book focuses on habits of good programming, addressing both professional and vocational programmers.

With “good programming,” we mean an approach to the creation of software that relies on systematic thought, planning, and understanding from the very beginning, at every stage and for every step. To emphasize the point, we speak of systematic program design and systematically designed programs.


As an accompaniment, the "How to Code: Systematic Program Design" series at edX: https://www.edx.org/course/how-code-systematic-program-desig...

is based on HtDP and uses Racket.

Ive also been trying to find something similar.

My dad has been trying to learn to code and all the courses labeled "learn to code" seem to be coding on the web. Not learning "How to solve problems using code".

Ive had to take him manually through basics of control structures, variables,etc.

For everyday problem solving have you considering starting with an environment like Mathematica, Jupyter, Octave/Matlab, or even Excel?

From a higher vantage point, the ultimate reference still is from Descartes in Discourse on the Method of Rightly Conducting One's Reason and of Seeking Truth in the Sciences, esp. Part II

[0] https://en.m.wikipedia.org/wiki/Discourse_on_the_Method

This has programming exercises, but also an introduction that has some good advice on translating problems into code: https://pragprog.com/book/bhwb/exercises-for-programmers

I haven't had time to take this course, though I'd like to. It sounds like it is exactly what you are looking for.


Can you give an example of solving a problem using code vs coding?

Parse this file and tell me the total of all $ amounts, and the line where we've reached 50% of the total $.

How do you approach this problem and break it down.

I've seen problems like this solved by looping through the file twice, because they answer one question at a time...

But I'm hoping there is something out there that can teach the general process of breaking down the problem, identifying loops, identifying generalizable code, and anything else that needs to happen before your code can work.

I have no idea if this works (it did for 3 test cases), and I still end up reading through the array (but not the file) twice.

  # assuming file with $100\n$200\n$23\n$50 etc.
  linenum_vals = []
  with open('numbers.txt') as input_file:
      for i, line in enumerate(input_file):
             linenum_vals.append([i, float(line[:-1][1:])])
         except ValueError:
             print("Not a number value on line", i)
  total = 0
  for i in linenum_vals:
      total += i[1]
  half = total/2.0
  for p in range(len(linenum_vals)):
      if linenum_vals[p][1] == half:
          print("Half of total found on line", linenum_vals[p][0])
          if linenum_vals[p-1][1] < half and linenum_vals[p][1] > half:
              print("Half of total in between lines", p-1, p)
              if p+1 != len(linenum_vals):
                  if linenum_vals[p][1] < half and linenum_vals[p+1][1] > half:
                      print("Half of total in between lines", p, p+1)
          print("Half of total wasn't found in the file.") # probably because the list of values isn't in order
What way would you do it? I feel like I'm missing something.

I would probably keep a running total as I read through each line, then store `line_number: running_total` in a dictionary.

At the end, return the highest key in the dictionary for your total, and then run a reduce that returns the first key/value pair that is >= half the total

Thinking a little outside of the box - but if you could sort the lines by amount in ascending order, then total from both ends, take half after each addition, then shift a pointer to where "about half" would be based on where you were in the totaling (and which end) as you go.

I don't have any specific implementation - or if this idea would even work - but I do think sorting the lines first might be of help toward a better solution (I could be completely wrong on this). As well as tackling the totaling and checking from both ends of the list.

You'd have to keep track of everything, of course, in order to know at the end where in the -real list- (unsorted) the half-way total point is at. If this idea has any merit at least.

He didn’t mean solving problems using code but solving problems conceptually before starting to code at all.


coding: "write a socket listener that reads from a buffer and converts it into a null-terminated string".

solving a problem: write a program that does (some open-ended business problem). Or generalize the socket listener so that it works on any platform, OS, hardware, network configuration, etc.

A coder might do great on confined problem space, but when you ask them to write a larger program they dont normally know how to design it. This isn't just true of bootcamp coders though. Tons of CS grads wouldn't do any better. Otherwise FizzBuzz would have never been a thing.

Current database:

- When you have multiple layers of "companies" ( in a single table: Company) and every company has employees (table: Employee).


- List all company employees that have a random company as mother company, including their childs, all layers deep.

So you create a optional integer parentCompanyId on the Company for the inheritance ( that's easy)

How would you go further?

- You may not use a recursion of sql Queries (or in code) to procedurally get the parentCompany or "child companies" of all layers deep.

- You may change the database ( and you may use joins also)

This is focused on teaching "computer science without a computer" to children, but some of my professors used it for bachelors students too. I'd highly recommended it to people of any age looking to get started with learning computer science: http://csunplugged.org

I would recommend you to start with general problem solving methods https://en.wikipedia.org/wiki/Problem_solving#Problem-solvin... and then choose one that best suites you.

Problem solving .... hmmm

It's not solely a programmer thing. You might like to consider people who have been trained to solve problems eg Engineers or Mathematicians int al - they will probably give you more bang for your buck. They will probably have some rudimentary or rather better programming skills as well.

Bugger bootcamps ...

You pays your money and takes your choice.

Cheers Jon

Well, my current concern is for my cousin, who is in a CSCI program by an ex-Math prof...

The problem is that they're teaching her syntax, but not really about how to solve the problems...

I don't remember being taught either... but it's certainly something I learned... She's incredibly frustrated because she sees her classmates breezing through class, because they've been programming for years and have learned the general problem-solving skills to get through class... she is having to learn both at the same time.

But, since there's so much focus on bootcamps lately, and it's a problem they ALSO have, I was hoping there was a solution there.

(my point being... colleges aren't doing a better job at this inherently... it's likely just that students have 4 years to figure it out or drop out, before joining the workplace)

Human Resource Machine is a decent game (from the creators of World of Goo!) that teaches this.

It's called experience. Invest well in your people and they will pay you back in dividends

if you want something that is language agnostic check out watchandcode.com

He is teaching in javascript but the language he is showing you is irrelevant and it's all about the process

How to solve it: the book is definitely teaching a generic way to break down problems.

Oddly enough, I've been contemplating starting such a service for a while now.

Applications are open for YC Summer 2019

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact