Sonntag, 27. August 2017

Playing and Pausing CSS Animations

I was recently asked how I would implement a slide show for a website. The requirements were that the slide show should start playing when hovering over it and pause while the mouse is elsewhere. GIF images are out of the question, because we can't control the playback. We could use javascript timers to control the animation and use the CSS transform: translate() property to pick the correct image from a spritesheet. Sounds like a total mess and also it would break if the user has disabled javascript. So maybe we could solve the whole thing using only CSS? I made a small codepen example demonstrationg how the slide show could be implemented. Instead of using images I'm using a colored div and change the background-animation as part of the animation. The container class contains the basic setup. The @keyframes block contains the information about what will happen during the animation. In this case the color will change from blue to purple to red. The animation class contains the setup for the animation. The animation has the name color, is initially paused and will last 4 seconds. When the user is hovering over the object with the animation class it will continue playing.

Samstag, 15. Juli 2017

Tutorial - ASP.NET Core and Selenium Webdriver

Since I'm going to do lots of web development stuff in the near future, I thought that I should take a look at the Selenium testing framework. Selenium comes either as a Firefox plugin (Selenium IDE) or as a framework (Selenium Webdriver) that supports multiple programming languages.

Preparations:

  • Get CoreCompat.Selenium.Webdriver
  • Get a plugin for the browser you want to use for testing, e. g. Selenium.Firefox.WebDriver
  • (optional) If you have issues with running the project you can place the executable for the plugin on your PATH environment variable
The code sample is for a simple console project, that will open the google website and search for racoons. Usually you would combine Selenium with the testing framework of your choice .

using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;

namespace SeleniumTutorial
{
    class Program
    {
        static void Main(string[] args)
        {   
            //Create a driver for a browser
            IWebDriver driver = new FirefoxDriver();
            //navigate to the page
            driver.Navigate().GoToUrl("https://www.google.com/");
        
            //find the search bar
            IWebElement searchInput = driver.FindElement(By.Id("lst-ib"));

            //send date to the seach bar
            searchInput.SendKeys("trash panda" +Keys.Enter);            
        }
    }
}

Sonntag, 2. April 2017

1GAM April - Preparation

I intend to participate in one game a month this april. My plan is to make a game about solving nonograms. The game could have some kind of twist like the pokemon picross game. In pokemon picross you collect pokemon by solving nonograms and you can use the pokemon's abilities to make solving nonograms easier. The game also could be educational. If the nonograms are grouped by starting letters of words there could for example be a nonogram for the letter C followed by words that start with C like cat or car.
    TODOs:
  • figure out how to implement the base mechanic
  • Create a tool to make nonograms. This could be a level editor made with WPF, a custom editor for unity or a script that creates a nonogram from an input image.
  • make a overworld/level selection thing
  • add some juice
  • (optional) add some kind of twist (custom rules)
When the game is done you can find it on itch.io.

Sonntag, 19. März 2017

A Short Introduction to Unit Testing

Why should we unit test

Writing tests before writing the actual algorithms helps in understanding the intended behaviour and potential edge cases. Another advantage is, that bugs might be found earlier, when it is easier (and thus cheaper) to fix them. Also unit tests immediately show if a refactoring or new feature breaks existing code.

Example

As example I implemented a complex number class. The class implements the basic algebraic operations (addition, subtraction, mutiplication and division). The class also implements toString and equals. For the unit tests JUnit will be used. Here is the skeleton for the ComplexNumber class with only equals being implemented:

package com.example.pfogeltech;

public class ComplexNumber {
 
    private double real;
    private double imaginary;
 
    public ComplexNumber(double real, double imaginary){
        this.real = real;
        this.imaginary = imaginary;
    }
 
    public void add(ComplexNumber other){
  
    }

    public void subtract(ComplexNumber other){
  
    }

    public void multiply(ComplexNumber other){
  
    }

    public void divide(ComplexNumber other){
  
    }
 
    @Override
    public String toString(){   
        return "";
    }
 
    @Override
    public boolean equals(Object o){
       boolean equal = false;
  
       if(o instanceof ComplexNumber){
           ComplexNumber other = (ComplexNumber)o;
           if(real == other.real && imaginary == other.imaginary){
               equal = true;
           }
       }
  
       return equal;
    }
 
}
The equals method is already implemented because the unit tests will use assertEquals to compare the results of the computations to what one would expect. JUnit uses annotations to tag tests (@Test), methods for setting up (@Before, @BeforeClass) and methods for cleaning up (@After, @AfterClass). The methods tagged with @Before and @After have a print statement to demonstrate that both methods will be called before/after every test. The test cases for the different algebraic operations compute a single result and compare it against the expected value with assertEquals. The test case for toString tests against multiple values because the formatting changes depending on the value of the complex number. Here is the code for the test cases:

package com.example.pfogeltech;

import static org.junit.Assert.*;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class TestComplexNumber {

 @Before 
 public void setUp(){
  System.out.println("setting up next test");
 }
 
 @After
 public void tearDown(){
  System.out.println("clearing up after test");
 }
 
 @Test
 public void testAdd() {
  ComplexNumber a = new ComplexNumber(1,0);
  ComplexNumber b = new ComplexNumber(0,1);
  a.add(b);
  ComplexNumber expectedResult = new ComplexNumber(1,1);
  assertEquals(expectedResult, a);
 }

 @Test
 public void testSubtract() {
  ComplexNumber a = new ComplexNumber(1,0);
  ComplexNumber b = new ComplexNumber(0,1);
  a.subtract(b);
  ComplexNumber expectedResult = new ComplexNumber(1,-1);
  assertEquals(expectedResult, a);
 }
 
 @Test
 public void testMultiply(){
  ComplexNumber a = new ComplexNumber(0,1);
  ComplexNumber b = new ComplexNumber(0,1);
  a.multiply(b);  
  ComplexNumber expectedResult = new ComplexNumber(-1,0);
  assertEquals(expectedResult, a);
 }
 
 @Test
 public void testDivide(){
  ComplexNumber a = new ComplexNumber(1,1);
  ComplexNumber b = new ComplexNumber(1,1);
  a.divide(b);
  ComplexNumber expectedResult = new ComplexNumber(1,0);
  assertEquals(expectedResult, a);
 }
 
 @Test
 public void testToString(){  
  ComplexNumber real = new ComplexNumber(2,0);  
  ComplexNumber imaginary = new ComplexNumber(0,-2);  
  ComplexNumber mixedPositive = new ComplexNumber(3,14);
  ComplexNumber mixedNegative = new ComplexNumber(3,-14);
  
  assertEquals("2.0", real.toString());  
  assertEquals("-2.0i",imaginary.toString());
  assertEquals("3.0 + 14.0i",mixedPositive.toString());
  assertEquals("3.0 - 14.0i",mixedNegative.toString());
 } 
}

Running the tests will show that all five tests fail. With each successfully implemented method one of the tests will succeed. Here is the code for addition and subtraction:

public void add(ComplexNumber other){
  real += other.real;
  imaginary += other.imaginary; 
 }

 public void subtract(ComplexNumber other){
  real -= other.real;
  imaginary -= other.imaginary;
 }
These methods are pretty straightforward. Here is the code for the multiplication and division:

public void multiply(ComplexNumber other){
  double realResult = real * other.real - imaginary * other.imaginary;  
  imaginary = real*other.imaginary + other.real * imaginary;
  real = realResult;
 }

 public void divide(ComplexNumber other){
  double divisor = other.real*other.real + other.imaginary*other.imaginary;
  double realResult = (real*other.real + imaginary*other.imaginary) / divisor;
  imaginary = (imaginary*other.real - real*other.imaginary)/divisor;
  real = realResult;
 }
Since the new values for the real and imaginary parts depend on each other it is important to save one of the values into a temporary variable. Imagine we wrote the following code instead:

    public void multiply(ComplexNumber other){
        real = real * other.real - imaginary * other.imaginary;  
        imaginary = real*other.imaginary + other.real * imaginary;
    }
If we now compute the result for i * i using the code above we get -1 - i instead of the expected -1. Finally here is the code for the toString method:

@Override
 public String toString(){
  String value = "";
  if(real == 0.0 && imaginary != 0.0){
   value = String.valueOf(imaginary)+"i";
  }
  else if (real != 0.0 && imaginary == 0.0){
   value = String.valueOf(real);
  }
  else{
   if(imaginary > 0.0){
    value = String.valueOf(real) + " + " + String.valueOf(imaginary)+"i";
   }
   else{
    value = String.valueOf(real) + " - " + String.valueOf(Math.abs(imaginary))+"i";
   }
    
  }
  
  return value;
 }
This method checks if we only have a real (e.g. 0.0) or imaginary (e.g. -2i) part and then returns a suitable string representation. The special case where the imaginary part is either 1 or -1 is not handled. Also it may be a good idea to use a formatted string instead of the string concatenations.