As a Programmer, you'll probably find yourself having to learn a number of programming languages whether it be for work or just for fun. In this blog, I will share what I personally think is the best way to learn a new language provided you're fairly proficient in one of the same paradigm. I'll be taking a stab at learning C# with prior knowledge in Object-Oriented programming with languages like Java, TypeScript, and C++.
So whenever we learn something the majority of us head to YouTube or grab a book or use some learning website to get stuck in. But for us programmers who already know the basic principles of programming, watching tutorials telling us how to do an if statement can be quite laborious. However, I know there are books and even tutorials out there which cater to people who already understand the basic principles of programming, but I'd like to share an alternate approach which works well for me.
Why Codewars?
Because they sponsor me. Just kidding π€£, I am in no way affiliated with Codewars, although I'd bloody love to be.
https://codewars.com/ is a brilliant website which has community made programming challenges called Katas in which are split by their difficulty.
They've also got a pretty awesome leveling system!
I encourage you to check it out if you've not heard of it as my description is only brief!
Getting started 8kyu
In Codewars the easiest type of problem is an 8Kyu and this is where I always start when learning a new language.
And I'm sure the majority of you are looking at the kata thinking it is far too easy and potentially a waste of time, but the beauty of this approach is it forces you to ask questions, and these questions are vital for sculpting your mental model of the language.
Setting up the environment
Codewars has its own built-in editor, but for us, we will be wanting to use our own so we can get knee-deep in the language using tools such as the debugger and setting up our own tests!
**********Inner monologue written in italics**********
So, what do I know about C#? I know it runs on this magical thing called the .NET framework, so I guess I've got to download that?
After some googling I've found out that .NET Core is the framework which works on Windows, Linux and macOS, so I guess I'll start with that. I downloaded the .NET core SDK.
I'm assuming provided I have this framework I should be able to use any editor? I know the majority of C# devs use Visual Studio, but I'll see if I can get this going in VSCode
Project structure:
8Kyu
βββ src
β βββ ReverseWords
βββ test
βββ ReverseWords.Test
With .NET you can create the project using the command line, so I'll cd into ReverseWords and dotnet new console
(A console app will do the job here). Now my ReverseWords folder contains:
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 27/07/2019 13:53 obj
-a---- 27/07/2019 13:53 194 Program.cs
-a---- 27/07/2019 13:53 178 ReverseWords.csproj
What the hell are all these? I guess .cs is the CSharp file, that would make sense and csproj probably contains some metadata for creating the project? Obj? only god knows..
So I wasn't too far off there, .cs does indeed contain the simple hello world program:
using System;
namespace ReverseWords
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}
The .csproj file has information about the files included in the project assemblies used in the project, project GUID and project version, etc.
I assume this is where you'd specify packages you want in the project?
Yup, my assumption was right you pop your nuget packages in here, by either adding through the .NET cli:
dotnet add package NETCore.Encrypt --version 2.0.7
or plonking in the package reference directly.
"The obj/ folder is used to store temporary object files and other files used in order to create the final binary during the compilation process." -splattne
Running the thing
Just playing around with the dotnet
command there is a dotnet run
command. Let's give that a shot:
PS \8kyu\src\ReverseWords> dotnet run
Hello World!
Brilliant stuff, let's actually try and solve this kata then. Let's grab the function they have for us to solve.
public static string ReverseWords(string str)
{
return "";
}
Now add the example tests, my current test folder is empty, how do I create a test project?
After some research it seems a lot of people use xunit:
dotnet new xunit
Xunit is not apart of .NET Core and looking in my .csproj this further solidifies my findings earlier about referencing nuget packages!
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.1" />
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
</ItemGroup>
Now let's add the test examples to our new test project.
namespace ReverseWords.Test
{
public class UnitTest1
{
[Fact]
public void Test1()
{
Assert.Equal("world! hello", ReverseWords.Program.ReverseWords("hello world!"));
Assert.Equal("this like speak doesn't yoda", ReverseWords.Program.ReverseWords("yoda doesn't speak like this"));
Assert.Equal("foobar", ReverseWords.Program.ReverseWords("foobar"));
Assert.Equal("kata editor", ReverseWords.Program.ReverseWords("editor kata"));
Assert.Equal("boat your row row row", ReverseWords.Program.ReverseWords("row row row your boat"));
}
}
}
I can't seem to reference our actual program, how do I do that?
dotnet add reference ..\..\src\ReverseWords\ReverseWords.csproj
Now I'm getting a compile-time error saying the class is the wrong protection level, okay, I know this from other OO languages, I suspect it's not been set to public
I was right, I made the class public and now when I run all the tests they fail, time to code!
public static string ReverseWords(string str)
{
StringBuilder sb = new StringBuilder();
string[] words = str.Split(' ');
foreach(var word in words)
{
sb.Insert(0, word + " ");
}
return sb.ToString().Trim();
}
Okay so I've learnt about StringBuilder, which is pretty much the same as Java, the foreach statement is pretty different and I enjoy the implicit types!
It is a very naive solution but it passes all their example tests.
Now when I submit my code I can view other peoples solutions and see how mine compares, luckily it's usually the better solutions are at the top as Codewars has special tags to denote whether a solution is Clever or a Best Practice!
Here's what the top solution looks like:
public static string ReverseWords(string str)
{
string[] words = str.Split(' ');
Array.Reverse(words);
return string.Join(" ", words);
}
Recap, what have I learned from doing this one problem?
- What .NET core is
- There's power in
dotnet
commands! - What .cs is
- What the obj/ folder is
- What the csproj is
- What Nuget packages are and how to reference them
- How to set up a simple project
- How to set up a testing project
- How to reference a project from another project
- What xunit is and how to use it
- How to add tests
- The type system, value and reference types
- The string builder
- The Array class filled with useful static methods
- The string class also has static methods in
Far more than I'd have likely learned from watching a video, and in a much shorter time!
Then what?
Well, we programmers love a good loop and this is exactly what we do here, if you struggled on the 8ku then stick to doing other 8kyus until you are confident, then move down to 7kyu, 6kyu etc. I could do another challenge, but you get the idea π
I really hope some people adopt this strategy in learning new languages, I'd love to hear peoples opinion on it or other alternative approaches to the standard!
Thank you, if you like my rambling check out my personal blogging site at https://codeheir.com/
Top comments (40)
I actually did this with Python, it was a great we to introduction to the language.
Ended up writing my own Kata in Python too, might be of interest to anyone who likes cards games:
codewars.com/kata/rummy-find-lowes...
That's brilliant, I'll have to put on my python boots and give this a whirl.
If you do give it a shot, let me know how you get on. Any questions at all, I'll be happy to help.
Fun, bite-sized problems are always a nice way to start the morning.
Filtering through the answers, I'd love to see more functional solutions from the C# crowd, maybe not super keen on the democratic answer rankings.
I completely agree, start the day with a win π
Oh really? I'm surprised by that, I know from doing a tonne of Java problems clever buggers solve a Kata that's taken me 200 lines of code in just 4 streams, show offs π€£
I do love some Java streams :)
Glad to hear that you are enjoying Codewars π One thing I really like about Codewars is its sheer diversity: you can find plenty of entry-level exercises in the likes of Codecademy, algorithmic exercises similar to those found in Hackerrank/Leetcode, insane mathematical puzzles not found in any other competitive programming site, puzzles involving advanced language features ... you name it. Hell, they even have theorem-proving challenges in the likes of ProofGround!
Your Esolang Interpreters series is awesome :)
Thanks for the compliment, don't forget to check out other Kata I have authored π
Awesome approach! I love that you don't use their web based editor for even more learning opportunities.
Thank you Victor! Yeah the whole process of setting up the environment is a huge learning experience and it really gives you a good feel of the language.
This seems like a fun challenge, but personally I prefer to dig deeper into my language of choice in order to find more (or more standard) ways to solve more complex problems. Which means solving ever more complex problems on leetcode (my choice of coding challenge platform, and no, I'm not getting paid either). I choose more complex problems because it involves digging deeper and getting experience instead of having shallow depth and great width. Remember: both time and learning capacity are limited. You may be able to learn more than me (and many others) but there's always a limit, and then there's a time limit.
In short: learning more languages is not always the thing you benefit from the most. Sometimes it is (changing careers or taking another kind of challenge), but remember that you have other options. This is coming from someone with experience in 7 languages ;)
Of course, learning new languages might not be the thing you benefit from the most, but this blog is purely under the assumption that you need to learn a new language and it's a method I find works very, very well.
If the goal is to learn a new language, then this advice is fantastic, as learning by doing is one of the best ways to do it!
Thanks for clarifying!
What if I even canβt solve the easiest 8kyu problems? Are there any step by step tutorials for those problems?
If those are a little too hard, I suggest Edabit! The easiest problems are easier than the 8kyu on Codewars imo, and become comparable as you level up. Codewars is frustrating to me because even the easiest problems require some higher level knowledge I don't yet have, but on Edabit I get to practice what I have learned so far and they provide a link to the MDN or SO pages that will help you get the answer.
I haven't tried Edabit before but I've heard that they have been allegedly involved in some shady practices. For example, their testimonials(?) do not contain any links to their original sources (unlike, say, Codewars which provides links back to the original tweets) and if you do a reverse image search on the portraits used in the testimonials, you'll notice that they appear in dozens of other websites, many of which are completely unrelated (to programming, programmers and such). They explain in this "Hacker News" post on Y-Combinator that the testimonials are real but with the names changed but one has to wonder why someone writing a testimonial would deliberately want to use a fake name ... π€
Also, the general difficulty has definitely shifted upwards in Codewars over the past few years but if you look hard enough, there should still be plenty of exercises for true beginners.
I just tried Edabit and the types of problems do have a bigger variety compared to Codewars. However, it offers users a "Go Pro" package when they solve up to 10 challenges or so which is rather a shame since Codewars is a free-learning platform with more choices of language to choose from. So, I'll still stick with Codewars at the end of the day.
What I like to do is choose a Kata that I know I can do in another language then itβs just a case of bumping my head into things until I find a solution. I donβt believe thereβs a step by step tutorial for problems on Codewars but you can view answers to problems if you get really stuck, you just wonβt gain the xp to lvl up for it.
Idea is good. But please don't forget that some languages require not only copy paste mental models, but deeper understanding why it is like that. For example JavaScript...and theoretical knowledge must be learned.
My point is that some people remember examples and do silly mistakes later
Absolutely, but the idea is to learn these differences whilst putting the language into practice, itβs not written in stone that you have to understand the theory of a language by reading a book, you can figure it out one problem at a time by asking guided questions at every hurdle, thatβs the beauty of it!
I just discovered CodeSignal (a similar coding challenges platform) and I'm now addicted, having fun while improving my skills on C#. I also want to learn Ruby and I was wondering if a platform like any of these could actually be helpful in the process. You just gave me the perfect answer:
Thank you for sharing this experience, Luke!
Interesting approach
Thank you Dheeraj!
Ok you've convinced me... i love me a bit of levelling to help me learn.... GoLang here I come
That's awesome mate, I warn you it's very, very addicting. Try to get your friends to get involved as well, there's nothing more motivating than a friend that's a higher level than you π
I also like Code Signal and leetcode for this similar approach.
Thanks a lot..! It was very useful. I love your fluent and cute method of explaining. Now that I found you, I'll follow you and read all of your post, because they're treasures!
Thank you Rabist that means a lot, I'll definitely be posting more on dev.to!
Sadly it doesnt support recent versions of swift :(
If you want a more recent version of Swift on Codewars then you can always open an issue at github.com/Codewars/codewars-runne... π Mind you, someone has recently requested for Swift 5.0 in github.com/Codewars/codewars-runne... so you may simply want to upvote that existing issue instead.
They support version 3.1 and 4.0 of Swift, if you're new to the language I'm sure a lot of the key concepts will be the same!
This is an excellent thing as I was looking because sometimes you learn on the books but you don't know how to do a practical example... Will check, thank you!
Yeah reading books is great, itβs just very easy to forget what youβve read if you donβt put it into practice!
I have been using C# for game-development. But I absolutely have no idea how to use command line at all. Help me?
Awesome, Unity has been on my to-learn for ages. For learning the command line I'd definitely recommend just watching a Youtube video and then playing around with it, once you understand the basics you'll feel as though you have a superpower!