A list of practical projects that anyone can solve in any programming language
github.com
github.com
Even if you are looking to hone your skills in a new language, creating something genuinely new seems like it would be more useful and motivational.
I.e. look at the TodoMVC as the comparison benchmark for various frontend frameworks.
The point of reinventing the wheel is to develop a more intimate familiarity with the tool or framework or utility you're trying to re-create. Yes the original ls program is perfectly functional but recreating it can be a good way to learn how to write C programs. This is applicable to any type of project really.
For many of us (me included), it's not REinventing the wheel, it's inventing it. I've taken a quick look through here, and some of these are in the 'yeah, I can do that straight off' category, some are in the 'I -think- I could do that' and some are in the '...right.... I'm not sure how I'd approach that' category. Remember that not everyone is in the same boat as you, and at the same level. I'm sure I'm way behind 99% of the people on HN, so maybe this is the wrong audience.
In addition, there's also the element of the development of the wheel - after all, they used to be wooden, and then gained a steel tyre, a proper bearing, etc... The code you create today may well be completely different (and hopefully better in every respect) than the code from yesteryear.
>Even if you are looking to hone your skills in a new language, creating something genuinely new seems like it would be more useful and motivational.
Maybe, but sometimes having the limitation of producing a specific thing can be useful - certainly when teaching music in the past, there has been room for both approaches, and I think that carries across into coding. There are also plenty of people who don't know -what- to create, and anything they look at is such a massive, difficult project combining multiple skills they may not have 100% down that it's probably better to do some simple 'test pieces' like I had to do when I was an engineering apprentice.
Two things about this:
First, I seriously doubt you're in the bottom 1% of HN users when it comes to programming ability. Not only is it statistically very unlikely, but there are many people who read and participate here who aren't programmers at all. While I realize you probably didn't mean that statement literally, in my experience being self-deprecating is something of a self-fulfilling prophesy. You're almost certainly more skilled than you believe yourself to be.
Second, speaking of skills as "ahead" or "behind" without context isn't very precise. I'm mostly a back-end web dev, but I have a little over a decade of experience. A brand new developer fresh out of a bootcamp that teaches modern React would be "ahead of me" if the task were to build a SPA front-end for an existent API. On the other hand, I would be far "ahead of them" if implementing the API itself was part of the task.
Making a wheel is pretty much the "Hello, world!" of engineering. It ensures that you know how to operate the equipment, procure materials, safely work them, and retrieve the finished product from the machinery.
Just getting started with a lathe? Go make a wheel. Just got a 3D printer? Go make a wheel. Just getting started with a whittling knife? Go make a wheel.
I used to go to primitive skills meetups, and at one of them I met a guy who taught woodworking. At the meetup, he carried around a few blocks of wood and some basic tools, and when he sat down to eat he'd bang out a wood spoon and eat with that. This was good advertising, but he said he did that sort of thing a lot for practice.
But whenever I learn a new language (many times over many decades), I want to build lots of small projects of many different sorts in order to habituate myself to the new tools and patterns (using the tools in various combinations) as quickly as possible. My ideal is when I find a set of these small but diverse projects implemented by an expert in the language, so I can try it my way, see how a "native speaker" does it, get some explanation from him (again, ideally), adjust my approach to be more "native", and repeat, again, and again, and again. I can usually find the problems, but finding the "native" solutions is harder.
I don't need the exercises to be "useful" in any way other than delivering the desired fluency efficiently, and I don't need them to be "motivational". If I want the skill, I'm motivated by anything that can help me get it, and if I don't want it, the problems don't matter. I have other things to do.
Once I've done this I'm usually much more comfortable reading other code in the language and navigating the language documentation. From there it's much easier to do things where I want to use external libraries, frameworks, build tools etc.
This took me by surprise!
Why do people complete crossword puzzles that millions of people have also completed? Why do people learn to play songs on the piano that millions before them have learned? Why do people learn math proofs that have been known to others for hundreds of years?
I can't quite apprehend the kind of confusion required to provoke such questions.
> Why do people learn to play songs on the piano that millions before them have learned?
I honestly asked myself that same question when I was a teenager, and I decided to quit piano lessons. It felt like a waste of time and a useless skill now that we have MIDI and self-playing pianos. So I switched to jazz and improvisation, and tried to compose my own music (although I'm not very good.) But I enjoy the creativity a lot more than playing songs from sheet music.
-- C. S. Lewis
Why wouldn't that hold for programming, at least if you make something you actually want and use? For me, it's about being able to make something exactly how I want it, without having all the stuff I don't need.
For example, I started out with a simple CMS that was based on text files. The next iteration used MySQL, but each "type" of page (link, text, image, audio) was it's own thing. That sucked, so I did it a third time, this time everything was a node that could have a type and a parent and children, but could also nodes "inside" it, which in turn also can also be nested and have nodes inside themselves, initially just because I thought "why not", but it's so useful, I didn't realize how much so until after the fact.
The commenting system is the same, imagine a tree like this discussion, but then every comment could have such a tree of comments inside it, as well as nested replies on the level it is on. I know it's dumb to do that for comments (but it's dumb in a way that makes me laugh so it stays in), but for content it's just awesome.
Some node types like empty, text, links, etc., then let every node decides how subnodes and nodes inside it get displayed, and that's been all I need for over 6 years now. I don't worry about my setup being no longer supported, ever, because my setup is the developer setup. And the project will also by definition not be abandoned before I stop using it. Those are huge benefits actually. I keep checking out what's available on the "shelf", and I want none of it, while my CMS contains a lot of deal breakers for anyone who doesn't have my exact setup and needs.
The point of not getting something off the shelf is not to remake the same thing, but to get something that's not "off-the-shelf", what you count as just a negative is actually also plus. You might say e.g. Drupal can do all that and much more, but Drupal is a huge, and trimming it down to exactly what I want would mean I have to do it again when it updates. Sure, it took years to get to a point where what I had was better for me than off-the-shelf, but I wouldn't have gotten there at all if I had just stuck with off-the-shelf. That also kinda limits the imagination to off-the-shelf.. how can I know I needed something that didn't exist before I made it, right?
Speaking of imagination, that wheel analogy has to die, no offense. It's always more than just "the idea that a round thing rolls", apart from the ideas being more complex the implementation details do matter.
My own experience with this phenomenon was when I virtually rolled my eyes at someone insisting that an evolved biological adaptation "wasn't designed", and explained what "designed" meant in that context, and someone praised it for being a good definition he hadn't seen before.
Recreating existing tools is a perfectly valid way to 1) learn or become proficient in a language, 2) learn how the tool works, and 3) position yourself to improve the tool if you wanted
People who argue against reinventing the wheel are the same ones sticking bicycle wheels on jumbo jets, and wondering why it can't handle the load.
To be fair, I think there can be some value to the approach where everything is new, but it probably shouldn't be the norm. Feeling out of control because you don't understand multiple elements can generate energy and growth at times, but it may require more time to progress.
For people looking to demonstrate their skills for a job, having examples like these can be useful. They don't take time to for an interviewer to understand so the focus can be on how the interviewee built the solution.
Some more project related resources are awesome-for-beginners[2], The UChicago X-Projects[3], and Beginner Projects[4].
1. https://github.com/rby90/Game-Clone-Challenges
2. https://github.com/MunGell/awesome-for-beginners
I don't think any of the projects mentioned are incompatible with a server-side implementation. You could even use something like HTML's image ismap attribute to implement an online white board.
I would just change Classes sot something more generic like Domain modeling?
I.e. I am thinking of using this as a list to help me learn some languages I find interesting, currently Purescript/Haskell and ReasonML/Ocaml. I don't think you would model any of the solutions to the projects in the list by creating class-hierarchies (and Ocaml even is capable of creating class-hierarchies.)
Even in more mainstream languages, such as Golang or Javascript, you wouldn't go with classes/inheritance.
Lisps, some low level c-style languages (go and rust among the newer ones), and some ML languages with algebraic data types don't really have the same object orientation abstractions as Java, C#, and Python. Further more the class system in Javascript ES6 are a bit special.
It would be better to talk about domain modelling, suggest interesting domains to model, without actually specifying any particular way to do it.
Edit: I must add that the author have done a great job of collecting these suggestions for tasks though!
The last update seems to be five years ago and I have to admit, If were writing this 5+ years ago, I too might assume "All modern languages have class hierarchies, right?" comming from Object-Pascal/Java/Python/Ruby
Funny enough, 5 years ago I started workin on a Clojure project at work, which changed my perspective somewhat :)
Learn about stacks, state, GUI... Small enough in scope, lots of additional features imaginable.
Easily solvable if you set that limit low and cheat. Just put a string representation of pi in the program, and chop it off at the requested length:
n = Input “num digits?”
if n between 0 and 8 inclusive
print left(“3.1415927”, n+1)
else
print “number out of supported range”
If you don’t cheat or if ”Keep a limit to how far the program will go” doesn’t mean what I read in it, I have my doubts anyone can write that program, even with support from Google. def nthHexDigitOfPI(n):
return 4/(8*n+1) - 2/(8*n+4) - 1/(8*n+5) - 1/(8*n+6)[1] https://en.wikipedia.org/wiki/Bailey%E2%80%93Borwein%E2%80%9...
I don't fully comprehend the code still, but the SCALE parameter suggest that it handles the elements of the array as a fixed point representation of real numbers. I wonder if it's correct for large number of digits.
P/(2*r) > Pi > P/(2*R)
Once you have approximated it, returning a string with the first x digits is trivialSimon Plouffe did it, years ago, with no help from Google.
http://plouffe.fr/Simon%20Plouffe.htm
https://en.m.wikipedia.org/wiki/Bailey–Borwein–Plouffe_formu...
For the lay-programmer, e.g., “any person or people”, everything on that list is an exercise in learning how the problem was solved by someone else, and writing the code for it. The idea is to learn, not to invent the solution from scratch without help. The way to code the spigot algorithm for pi is to lookup the formula, understand it, figure out how to deal with precision and numeric base conversion, and write the code. Pretty much anyone can do that.
Where did I imply it? The site being discussed uses “anyone” in the sense “any person”. I questioned that, but didn’t realize that I used the word in the second meaning the second time I used it.
”The way to code the spigot algorithm for pi is to lookup the formula, understand it, figure out how to deal with precision and numeric base conversion, and write the code. Pretty much anyone can do that.”
That, we disagree about. We live in a world where “Fizz-Buzz” is a thing, so I’m not that optimistic that anybody can do what you describe.
It seems weird you asked that since I just said where, explicitly. This part of the conversation feels tedious and unnecessary. The precise meaning of “anyone” being used by you & the article is pretty irrelevant.
> I’m not that optimistic that anybody can do what you describe.
You’re right, I disagree. I’m sorry for your pessimism. My children can and do lookup formulas on Wikipedia and code them, it’s not hard, if you care to try. I understand if you feel it is too difficult. FWIW, that’s precisely what the post we’re commenting on is aiming to help curious and optimistic people with. Maybe consider how it might be able to help your situation rather than criticize? Everyone can do fizzbuzz too, it’s existence doesn’t prove anything.
That is how I got interested in computer science, and I can bet, a significant fraction of the others here had that experience too.
That could probably be addressed in part by focussing on types or data structures rather than classes per se.
Similarly, there are problems which mandate threading rather than either concurrency or parallelism, whichever is intended; there are languages in which threads as such are not directly supported, but with one or more structures for concurrency/parallelism that could solve the problem (and languages where threads are supported but directly using them may not be the idiomatic approach depending on the actual concurrency/parallelism requirements.)
So, for a language-neutral set of tasks, it focuses in some places too much on specific languages solutions rather than the problem to be solved.
Write an autopilot module to take inputs from altimeters, airspeed instruments, compasses, gyros, GPS, and user input. Give outputs suitable for controlling ailerons, elevator, rudder, and throttles. Extra credit: deploy it in an airliner. :-) :-)
Very fun little project! Got a hairy bug, which took me about 1-2 hours to figure out, which involved not realising that when I created a struct and added it to a slice, it was not the same struct as I had just created, in terms of memory address!
So in pseudo code:
myThing := struct{attributes...} mySlice[0] := myThing sameThing := mySlice[0] &sameThing == &myThing False
Definitely know Go a lot better now. Looking forward to doing some others on this list.
It's a great little book that is unfortunately only available in German.
the readme mentions rosettacode as inspiration, which is great. i live the idea of working on tasks through git, but i'd love it even more if i could work on rosettacode tasks directly this way.
greetings, eMBee.