Why Codewars is the best way to learn a new programming language!
Tags: csharp, challenge
Published: 2019-07-27 14:38:06

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](https://en.wikipedia.org/wiki/Programming_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.

![Codewars Difficulty Image](https://i.imgur.com/rrPCLMH.png "Difficulty")

They've also got a pretty awesome leveling system!

![Codewars leveling system](https://i.imgur.com/iwXCr7M.png)

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. 

[Reverse Words](https://www.codewars.com/kata/51c8991dee245d7ddf00000e)
![Easy Example](https://i.imgur.com/Sg1EMyw.png)

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]("dotnet.microsoft.com/download").

*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:

```csharp
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](https://social.msdn.microsoft.com/Forums/vstudio/en-US/e8e9a55e-6e43-4c4d-93f6-5a89157b12f1/what-is-csproj-file?forum=csharpgeneral) 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](https://www.nuget.org/) 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](https://stackoverflow.com/questions/233081/whats-the-obj-directory-for-in-net)

## 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.

```csharp
  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.

```csharp
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!


```csharp
     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:


```csharp
  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/