An Introduction to Checkstyle


Checkstyle is a tool that can be used by developers in order to help teams follow coding conventions on a Java project. I recently used this whilst developing a Battleships game in Java with a group of others as part of a university module (maybe a post for another day?..).

Why use Checkstyle?


Coding conventions and standards are a way to ensure that code is formatted consistently across a project, team or organisation. The benefits of using them are pretty well known and well documented but it essentially comes down to making the code more readable and accessible to yourself and other developers.

Checkstyle helps developers to follow a coding convention by pointing out errors or warnings within the IDE based on an XML configuration file that you provide in the project. The configuration file’s format is well documented, easy to read and easy to edit. On our project we chose to base our standards on Google’s guidelines (google_checks.xml) which we then adapted to suit our own coding style (checkstyle.xml). We also used Travis CI to build our project each time someone pushed new code and if compilation and tests passed then we would get a notification in our team’s Slack channel, similarly if anything went wrong we would get a notification to let us know we needed to fix something. As we were using Checkstyle with the Maven plugin this meant that if code was committed which didn’t comply with our standards then the build would fail1.

How to install & use Checkstyle


Installing and getting Checkstyle to work with Maven initially took a few attempts and gave quite the headache but I put that down to my lack of experience with Maven and in the end it was worth it. I’m hoping that by documenting the process here others will be able to save time by not having to follow my process of trial and error!

Maven

In the pom.xml put the following block of code into the <plugins> section.

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-checkstyle-plugin</artifactId>
	<version>2.17</version>
	<executions>
		<execution>
			<id>validate</id>
			<phase>validate</phase>
			<configuration>
				<encoding>UTF-8</encoding>
				<configLocation>checkstyle.xml</configLocation>
				<consoleOutput>true</consoleOutput>
				<failsOnError>true</failsOnError>
				<linkXRef>false</linkXRef>
			</configuration>
			<goals>
				<goal>check</goal>
			</goals>
		</execution>
	</executions>
	<dependencies>
		<dependency>
			<groupId>com.puppycrawl.tools</groupId>
			<artifactId>checkstyle</artifactId>
			<version>7.6</version>
		</dependency>
	</dependencies>
</plugin>

Note – the configLocation field can be removed and Checkstyle will use the default config (sun_checks.xml) but as mentioned earlier on our project we used a custom configuration and simply named it “checkstyle.xml” in the root of our project.
It’s also worth mentioning the dependencies section where we explicitly tell Maven to use version 7.6. Without this section Maven will use version 6.11.2. This was something I only solved recently but it prevented us from using some of the newer checks available during development.

After setting up the configuration file (or choosing to use the default) running ‘mvn validate’ in the command line should give you the following output.

...
[INFO] --- maven-checkstyle-plugin:2.17:check (validate) @ Battleships ---
...

Below that line you will see a list of errors or warnings if your code does not follow the defined convention.

That’s it, your project is now set up to run Checkstyle with Maven!

Eclipse

There is also an Eclipse Checkstyle Plugin available for Checkstyle which will allow Eclipse to display errors and warnings to the user in the ‘problems’ tab. This makes it easy for developers to see jump to the offending pieces of code and fix it to comply with the coding standards in the configuration file.

Checkstyle throwing a variety of errors in Eclipse.
Checkstyle throwing a variety of errors in Eclipse.

Happy Coding!


1 The severity of “non-compliance” could be configured to either throw a warning or an error based on which rule had been broken. For example a line length of greater than 100 may throw an error but an extra whitespace somewhere may just cause a warning.

 

The Monty Hall Problem (Part 2)

If you are unfamiliar with The Monty Hall Problem please read the first part of this blog post here.The monty hall problem program

Due to my interest in programming and interest in this problem I decided to bring the two together and created a program that replicates the situation and outputs the statistics of wins and losses with switches and without (where the results can be seen further down).

Computing the Problem

I have uploaded the source code to the program which can be found here.

The program works by creating 3 doors at the start of each game and randomly choosing 1 to be the winner. The program then asks the user to pick one of the doors either 1, 2 or 3, after this it will then display one of the other doors (if the user has picked the winning door it will randomly choose one of the other 2 doors to show). The user is then given the choice to switch the door if they want to. The program then tells the user if they won or lost and prints out all the statistics of the total games which can be viewed below.

To make it easier to quickly run the program multiple times I created short java program to produce a file that can then be fed into the standard input of the main file to run the game 1000’s of time quickly and view the results. That program can be found here.

The Results

I ran the program multiple times using the file printing program to give me a different number of inputs each time from 20 games to 20,000 here you can see the screenshots of the results below.

Results of 10 switches and 10 none switches.
Results of 10 switches and 10 none switches.
Results of 100 switches and 100 none switches.
Results of 100 switches and 100 none switches.
Results of 1,000 switches and 1,000 none switches.
Results of 1,000 switches and 1,000 none switches.
Results of 10,000 switches and 10,000 none switches.
Results of 10,000 switches and 10,000 none switches.

The main point of interest of these results is the percentages, and for anyone who wasn’t convinced of the solution to the problem these results clearly show that you have a greater chance of winning if you change from your original choice (as you’d expect). Also, we can see that the more games that are played the closer we get to the values of 1/3 (wins without switching) and 2/3 (wins with switching).

The Monty Hall Problem (Part 1)

This part of the post is about explaining the problem itself and why the answer is what it is, whilst the second part is about computing the answer and “proving” it. Therefore, if you are already familiar with the problem skip to part 2 of the post.

Since reading about the problem in a book when I was young, the monty hall problem, has always been something I have found interesting, and found myself on the Wikipedia page for it multiple times (including when it was used in one of Derren Browns shows, and in the movie 21). So I decided to write a program that demonstrates it and write a blog post about it.

The “Problem”

Imagine you are on a game show and the host shows you 3 closed doors and asks you to pick one – either 1, 2 or 3. You are told that behind 2 of the doors there is a goat, but behind one of the doors is a grand prize of a car. After you have made your choice, let’s say you choose door number 1, the host (knowing which doors contain the goats) will then open one of the doors you haven’t picked to reveal a goat. For this example let’s say he shows you door number 2. After, showing you the goat behind this door, you are then given the option to swap your choice to the remaining door if you wish.

The question is, do you have a better chance of winning if you stick to your original choice (door 1) or are you more likely to win if you switch (to door 3)?
Or worded differently:
What are the chances of the car being behind door number 1, and the chances of it being behind door number 3?

The Solution

It seems like the answer is obvious – there is a 50% chance of winning whether you stick with your choice or if you switch, and therefore switching has no benefit. This answer is actually incorrect, despite it seeming so simple and clear.

The fact is you actually have 1 in 3 (33.33%) of chance of winning if you stick with your initial answer BUT if you decide to switch your chances of winning increase to 2/3 (66.66%).

Explanation

The main reason the chance of winning changes from 1/3 to 2/3 is because the host has to choose one of the losing doors.
On my first choice there is 1 in 3 chance of picking the grand prize, and a 2  in 3 chance of picking a goat.
If I pick a goat on my first choice (which is more likely), the host will then show the door which doesn’t have the car behind it, meaning when I switch I will win the car.

The wikipedia page does a nice job of explaining why the odds change, or if you prefer here is a youtube video which explains why (Skip to 2m 40s for the explanation of why):

The second part of this post can be found here where I discuss the program I created based on the problem and the results it produces.

 

Java Sudoku Solver

I have just uploaded a program I wrote a couple of weeks ago to GitHub. The program is a sudoku solver which I wrote in Java. I am also posting the source code below.

Usage
The program reads the sudoku from a text file called “Sudoku.txt”. Which should be formatted like so:

860020000
000700059
000000000
000060800
040000000
005300007
000000000
020000600
007509000

Where the 0s are the blanks in the given puzzle. The program will then print the solution to the command line.
When input the puzzle above:

Sudoku Solver

Here is the source code:


import java.util.Scanner;
import java.io.File;

public class SudokuSolver
{
  public static void main(String[] args) throws Exception
  {
    Scanner fileScanner = new Scanner(new File(&quot;Sudoku.txt&quot;));

    int[][] sudoku = new int[9][9]; //Will hold the puzzle in a 2D array.
    //We will use this variable to hold the next line of the puzzle, then parse
    //each digit on that line.
	String line = fileScanner.nextLine();

    //Loops round placing the digits into the correct place of the array.
	for (int y = 0; y &lt; 9; y++)
	{
	  for (int x = 0; x &lt; 9; x++)
	  {
        //Gets the digit converts it from a char to an in and places it in the array.
        sudoku[y][x] = Character.getNumericValue(line.charAt(x));
        //At the end of each line we load the next line, but check there is a next
        //line before trying to load it so the program does not crash.
	    if (x == 8 &amp;&amp; fileScanner.hasNextLine())
		{
		  line = fileScanner.nextLine();
		}
	  } //for x
    } //for y

    //The recursive function that actually solves the sudoku (starting at 0,0)
    solve(sudoku, 0, 0);

  } //main

  //This is a recursive function used to go through each cell and place a valid number.
  //Until they are filled in.
  private static void solve(int[][] sudoku, int cellX, int cellY)
  {
    //If the y value is 9 then the sudoku has been solved.
    if(cellY &gt; 8)
    {
      printSudoku(sudoku);
      System.out.println();
      //System.exit(1); // = This will end the program quicker as it does not have to
      //&quot;go back up&quot; through the levels of recursion, but means the main
      //routine will not continue running.
      //Also if there is more than one solution to the sudoku using this will only print
      //the first solution found.
    }
    else
    {
      //Here we calculate the next digit for the solve routine to try.
      int nextX = cellX;
      int nextY = cellY;
      if(cellX == 8)
      {
        //When at the end of a row add 1 to the row and reset the &quot;column&quot; to 0.
        nextX = 0;
        nextY++;
      }
      else
      {
        nextX++;
      }

      //If the digit was already given to us, we can move onto the next one.
      if(sudoku[cellY][cellX] != 0)
      {
        solve(sudoku, nextX, nextY);
      }
      else
      {
        //Otherwise, starting at 1 through 9 we check if the number is &quot;legal&quot;
        //and if so place that number, and move on to the next cell.
        for(int checkNum = 1; checkNum &lt; 10; checkNum++)
        {
          if(checkSquare(sudoku, cellX, cellY, checkNum)
             &amp;&amp; checkRow(sudoku, cellY, checkNum)
             &amp;&amp; checkCol(sudoku, cellX, checkNum))
          {
            sudoku[cellY][cellX] = checkNum;
            solve(sudoku, nextX, nextY);
          }
        }
        //If we get to here it means in it's current state the sudoku is impossible
        //which means that one of the numbers we &quot;placed&quot; earlier is incorrect.
        sudoku[cellY][cellX] = 0;
      }
    }
  }

  //This method is given a cell location and a number to check, it then checks
  //whether that number is already in the 3x3 square and returns false if so.
  private static boolean checkSquare(int[][] sudoku, int reqX, int reqY, int toCheck)
  {
    int rowY;
    int colX;

    //First we work out which column the &quot;square&quot; belongs to.
    //We take the given x value and if it is below 3 then that means
    //the square we need is in the first column (out of 3). etc.
    if(reqX &lt; 3)
    {
      colX = 0;
    }
    else if (reqX &lt; 6)
    {
      colX = 3;
    }
    else
    {
      colX = 6;
    }

    //We do the same but for the rows. For example if the y value is 5 then
    //the related square would be on the second row.
    if(reqY &lt; 3)
    {
      rowY = 0;
    }
    else if (reqY &lt; 6)
    {
      rowY = 3;
    }
    else
    {
      rowY = 6;
    }

    //We have now defined the square we need to check and have the top left
    //co-ordinate stored in the variables rowY and colX.
    //We now loop round and check each digit in the square, and if a digit matches
    //we return false.
    for(int y = rowY; y &lt; rowY + 3; y++)
    {
      for(int x = colX; x &lt; colX + 3; x++)
      {
        if(sudoku[y][x] == toCheck)
          {
            return false;
          }
      }
    }

    return true; //number not in the square.

  }

  //Checks if a given number is in a given row and returns false if it is.
  private static boolean checkRow(int[][] sudoku, int rowY, int toCheck)
  {
    //loops round each digit in a row.
    for(int x = 0; x &lt; 9; x++)
    {
      //Checks if the given number is the same as the current digit
      //and returns false if so.
      if (toCheck == sudoku[rowY][x])
      {
        return false;
      }
    }
    return true; //the number is not in the row.
  }

  //Checks if a given number is in a given column and returns false if it is.
  private static boolean checkCol(int[][] sudoku, int colX, int toCheck)
  {
    //Loops round each digit in a column.
    for(int y = 0; y &lt; 9; y++)
    {
      //Checks if the current digit is the given digit and returns false if so.
      if (toCheck == sudoku[y][colX])
      {
        return false;
      }
    }
    return true; //the number is not in the column.
  }

  //Prints the sudoku to the screen.
  private static void printSudoku(int sudoku[][])
  {
    //Loops round each digit and prints it.
    for(int y = 0; y &lt; 9; y++)
	{
	  for(int x = 0; x &lt; 9; x++)
	  {
	    System.out.print(sudoku[y][x]);
	    //Starts a new line when at the end of a row.
        if(x == 8)
		{
		  System.out.println();
		}
	  } //for x
	} //for y
  } //printSudoku
} //SudokuSolver