Saturday 7 August 2021

Python crash course part 10: inheritance and polymorphism

In the last part we've shown how to create and use a class in Python. Today we're going to talk about inheritance: wchich means creating sub-classes, which add different behaviour to the class they inherit from (or extended class, in Java nomenclature).

Suppose we have a class like this:

class Runner:
    def __init__(self):
        self.shoes = True
    def hasShoes(self):
        return self.shoes

We can create an object of this class and call the method hasShoes on it:

# !/usr/bin/python3

class Runner:
    def __init__(self):
        self.shoes = True
    def hasShoes(self):
        return self.shoes

def main():

    myRunner = Runner()
    print(myRunner.hasShoes())

if __name__ == "__main__":
    main()

The code results in:

True

Now let's extend this class by creating a subclass (LongDistanceRunner) and adding a method there - and let's create an instance of subclass and call this method:

# !/usr/bin/python3

class Runner:
    def __init__(self):
        self.shoes = True
    def hasShoes(self):
        return self.shoes

class LongDistanceRunner(Runner):
    def run(self):
            if self.hasShoes():
                print("Running slowly")
            else:
                print("Not running (no shoes)")

def main():

    myRunner = Runner()
    print(myRunner.hasShoes())

    ldRunner = LongDistanceRunner()
    ldRunner.run()
    print(ldRunner.hasShoes())


if __name__ == "__main__":
    main()

The code results in:

True
Running slowly
True

As we can see, we can call both run() - which is method from the subclass (LongDistanceRunner) and hasShoes() which is method defined in superclass ( Runner ) on the object of class LongDistanceRunner. What' more - in the class LongDistanceRunner (in the method run() ) we can use our superclass features (in this case: the method hasShoes() ).

Now let's add another class inheriting from Runner :

# !/usr/bin/python3

class Runner:
    def __init__(self):
        self.shoes = True
    def hasShoes(self):
        return self.shoes

class LongDistanceRunner(Runner):
    def run(self):
            if self.hasShoes():
                print("Running slowly")
            else:
                print("Not running (no shoes)")

class ShortDistanceRunner(Runner):
    def run(self):
            if self.hasShoes():
                print("Running fast")
            else:
                print("Not running (no shoes)")
def main():

    myRunner = Runner()
    print(myRunner.hasShoes())

    ldRunner = LongDistanceRunner()
    ldRunner.run()
    print(ldRunner.hasShoes())

    sdRunner = ShortDistanceRunner()

if __name__ == "__main__":
    main()

We can add both our "runners" to a collection and call the method  hasShoes() on both of them:

# !/usr/bin/python3

class Runner:
    def __init__(self):
        self.shoes = True
    def hasShoes(self):
        return self.shoes

class LongDistanceRunner(Runner):
    def run(self):
            if self.hasShoes():
                print("Running slowly")
            else:
                print("Not running (no shoes)")
    def drinkWater(self):
        print("Drinking water (while running)")

class ShortDistanceRunner(Runner):
    def run(self):
            if self.hasShoes():
                print("Running fast")
            else:
                print("Not running (no shoes)")
    def drinkWater(self):
        print("Drinking water (not while running)")
def main():

    myRunner = Runner()
    print(myRunner.hasShoes())

    ldRunner = LongDistanceRunner()
    ldRunner.run()
    print(ldRunner.hasShoes())

    sdRunner = ShortDistanceRunner()

    runners = [ldRunnersdRunner]

    print("Do runners have shoes?")
    for runner in runners:
        print(runner.hasShoes())
        
if __name__ == "__main__":
    main()

Which results in:

True
Running slowly
True
Do runners have shoes?
True
True

What's interesting here is that the hasShoes() method works "polymorphic" here - although it's not defined in the superclass. This behaviour is what differs polymorphism in Python from Java, C# or C++ - in all these languages polymorphism is strictly connected to inheritance.

Tuesday 3 August 2021

Python crash course part 9: basic object-oriented code examples


Today we'll take a look at some examples of object-oriented code in Python.

As I'm learning this topic almost in the same time I'm writing this, I'll do lot of mistakes - especially because some topics seem different than C++/Java/C# style I'm used to.

Ok, let's begin with creating a class with one method, creating an object of this class and calling this method.

# !/usr/bin/python3

class ClassWithMethod:
    def say_something(self):
        print("Elementary!")

def main():
    objectWithMethod = ClassWithMethod()
    objectWithMethod.say_something()

if __name__ == "__main__":
    main()

We define a class ClassWithMethod, with one method: say_something(self) simply printing some text. self param is, as we will see, the reference to the calling object. For now, we just instantiate the class:

    objectWithMethod = ClassWithMethod()

...and call the method:

    objectWithMethod.say_something()

The result of running this code is:

Elementary!

Now let's define other class with one field (or attribute).

class ClassWithField:
    def __init__(selfname):
        self.name = name

To instantiate and use it we can add the following lines to main function:

    objectWithField = ClassWithField("Lestrade")
    print(objectWithField.name)

As we can see, __init__(selfname) works as a constructor with one parameter. The code now prints:

Elementary!
Lestrade

 What about a method? Well, take a look at another class:

class ClassWithFieldAndMethod:
    def tellName(self):
        print(self.name)

If we instantiate it, and set field name to something, we can call our method (in main!):

    objectWithFieldAndMethod = ClassWithFieldAndMethod()
    objectWithFieldAndMethod.name = "John Watson"
    objectWithFieldAndMethod.tellName()

Giving result:

John Watson

What's interesting, we can add fields to a class object on the fly, without declaring them. Add this to main:

    objectWithFieldAndMethod2 = ClassWithFieldAndMethod()
    objectWithFieldAndMethod2.name = "Sherlock Holmes"
    objectWithFieldAndMethod2.tellName()

    # you can add field on the fly...
    # ... to the object!
    objectWithFieldAndMethod2.age = 33 
    
    # you can do this only if field has been added:
    print(objectWithFieldAndMethod2.age)

We create another object (objectWithFieldAndMethod2), add the field named age to it (simply by initializing it) and then we can access it. The code execution result becomes:

Elementary!
Lestrade
John Watson
Sherlock Holmes
33

Please note we've added the age field to our object, not class. It means that if we try to get to this field on our previous object, we get error.

def main():
    objectWithMethod = ClassWithMethod()
    objectWithMethod.say_something()

    objectWithField = ClassWithField("Lestrade")
    print(objectWithField.name)

    objectWithFieldAndMethod = ClassWithFieldAndMethod()
    objectWithFieldAndMethod.name = "John Watson"
    objectWithFieldAndMethod.tellName()

    objectWithFieldAndMethod2 = ClassWithFieldAndMethod()
    objectWithFieldAndMethod2.name = "Sherlock Holmes"
    objectWithFieldAndMethod2.tellName()

    # you can add field on the fly...
    # ... to the object!
    objectWithFieldAndMethod2.age = 33 
    
    # you can do this only if field has been added:
    print(objectWithFieldAndMethod2.age)

    # this results in error!
    print(objectWithFieldAndMethod.age)

...gives:

Elementary!
Lestrade
John Watson
Sherlock Holmes
33
Traceback (most recent call last):
  File "d:\Projekty\Python\controlflow.py", line 71, in <module>
    main()
  File "d:\Projekty\Python\controlflow.py", line 50, in main
    print(objectWithFieldAndMethod.age)
AttributeError: 'ClassWithFieldAndMethod' object has no attribute 'age'

What about private fields? We define it by preceding initialized field name with double underscore:

class ClassWithPrivateFieldAndMethod:
    def setName(selfname):
        self.__name = name

We can create an object of this class and call the method to set field __name:

    objectWithPrivateField = ClassWithPrivateFieldAndMethod()
    objectWithPrivateField.setName("Mary Watson")

..but we can't do this:

 print(objectWithPrivateField.__name)

... as the program will behave as such attribute doesn't exist:

  File "d:\Projekty\Python\controlflow.py", line 71, in <module>
    main()
  File "d:\Projekty\Python\controlflow.py", line 55, in main
    print(objectWithPrivateField.__name)
AttributeError: 'ClassWithPrivateFieldAndMethod' object 
has no attribute '__name'

BUT in fact, we can access this field - as "private" in Python does not mean the attribute is unaccesible - it rather means it should not be accessed. So we can access this attrbute using the following syntax: objectName._ClassName__field_name (please note the underscores, one before class name and two before field  name):

print(objectWithPrivateField._ClassWithPrivateFieldAndMethod__name)

This gives us:

Mary Watson

Now let's take a look at a param passed in the constructor.

The following class:

class ClassWithParamaterInConstructor:
    def __init__(selfname):
        self.name = name

...can be created like this:

   objectConstructedWithParam = ClassWithParamaterInConstructor("Moriarty")

We can then normally access the name field, so:

   print(objectConstructedWithParam.name)

...gives us this ominous result:

Moriarty

The last thing: static (class) fields. They're defined simply in class body, not in the methods:

class ClassWithStaticField:
    field = 40

But beware: they can be accessed with both class name and object name. In the first case, they behave like static. In hte latter - they're simply fields, initialized with given value.

An example should give us more light on this:

    stat1 = ClassWithStaticField()
    stat2 = ClassWithStaticField()
    stat2.field = 41
    print(stat1.field# object's field default value is 40
    print(stat2.field# this object's field value is 41
    print(ClassWithStaticField.field# static field value is still 40!

... which code gives us:

40
41
40
40

We create two objects of class ClassWithStaticFieldstat1 and stat2. Then we assign value 41  to the field field of the first object. It changes this instance's value, but the field field of object stat1 stays the same! What's more - the ClassWithStaticField.field is also another reference. We can change it, of course, by calling:

    ClassWithStaticField.field = 42

  So the code:

    stat1 = ClassWithStaticField()
    stat2 = ClassWithStaticField()
    stat2.field = 41
    print(stat1.field# object's field default value is 40
    print(stat2.field# this object's field value is 41
    print(stat1.field# object's field default value is 40
    
    print(ClassWithStaticField.field# static field value is still 40!
    ClassWithStaticField.field = 42
    print(ClassWithStaticField.field# not anymore!

results in:

40
41
40
40
42

Confusing? Well, for me it certainly is ;D The full program  listing illustrating the concepts above looks as follows:


... and gives the following result:

Elementary!
Lestrade
John Watson
Sherlock Holmes
33
Mary Watson
Moriarty
40
41
40
40
42

I hope it happens to be useful for some of you :)

Sunday 1 August 2021

Android Java to Kotlin migration by example part 13: operator overloading

This time again we're going to be talking about something available in Kotlin, but not in Java: operator overloading.

Operator overloading means that we can apply operators, like + (someobject+anotherone) or [ ] (someobject[5]) to our objects. Expression like this (someobject + anotherone) can be thought of as methods: it's just another way of expressing someobject.plus(anotherone)someobject[5] would mean "call the method [] with parameter 5 on someobject.  

Altough operator overloading is an old concept (it's common in C++, where - for example - the famous cout<<"Something"; actually uses overloaded left bit shift operator for object cout of class ostream; it's also available in C# and Python), it's not implemented in Java (which was a deliberate choice of its creators).

Still, it can be very useful and Kotlin allows it.

Let's get to our code. I think the most basic example of operator overloading is use of class representing complex numbers (the code below is the full program, with both class definition and it's use):

package com.mypackage

import kotlin.Exception
import kotlin.math.sqrt

class Complex(var re: Float, var im: Float){

fun modulus(): Float{ // just a method
return sqrt(re*re+im*im)
}

// "this" can be omitted
operator fun plus(another: Complex): Complex{ // a+b
return Complex(this.re+another.re,this.im+another.im)
}

operator fun minus(another: Complex): Complex{ // a - b
return Complex(re-another.re, im-another.im)
}

operator fun times(another: Complex): Complex{
var resultRe = re*another.re-im*another.im
var resultIm = re*another.im+im*another.re
return Complex(resultRe, resultIm)
}

operator fun compareTo(another: Complex): Int{ // == > < <= >=
if(this.modulus()<another.modulus())
return -1
if(this.modulus()>another.modulus())
return 1
return 0
}

operator fun get(arg: Int): Float{ // someComplex[0]
if(arg==0)
return this.re
if(arg==1)
return this.im
throw IllegalArgumentException()

}

override fun equals(other: Any?): Boolean {
if(other is Complex)
return (this.re==other.re && this.im == other.im)
else
throw Exception("wrong class")
}

override fun toString(): String{
return "($re,$im)"
}

}

fun main() {
val c = Complex(1.0f,0.0f)
val c2 = Complex(1.0f, 0.0f)
val c3 = Complex(10.0f,10.0f)
val sum = c+c2

val sum2 = c.plus(c2)

val someMul = Complex(10.0f,5.0f)* Complex(7.0f,-2.0f)

println("multiplied:$someMul")

println(sum)
println(sum2)
println(sum[0])
println(c3>c2)

println(c==c2)
}

... which defines the class Complex representing a complex number, and overloads the infix "+", "-", "*", comparison (<, >, >=, <=) and [ ] operators. There is also modulus function, which is just a method... And which we use to define our overloaded comparison operators behaviour (operator fun compareTo).

The execution of the code above results in the following output:

multiplied:(80.0,15.0)
(2.0,0.0)
(2.0,0.0)
2.0
true
true

We can see that my implementation of complex multiplication is correct ;)

The +, -, * operators, implemented as plus,  minus, and times are quite self-explanatory: they take one parameter, and use this.re and this.im (or just re and im) of current (left to operand) values to compute the results, which they return. 

In order to override them, we use operator keyword before a method definition. Please note they can be called both as operators ( val sum = c+c2 ) or just as methods ( val sum2 = c.plus(c2)).

In comparison operator overload (operator fun compareTo(another: Complex)) I've used previously defined modulus method, because there is no unequivocal way of comparing complex numbers - so I compare their moduli. This operator should return -1 if the first operand is "smaller" than second one (in our case it's modulus is smaller), 1 if it's "bigger" and and 0 it they're the same.

I've also overloaded get operator, which affects suqare brackets, like in the call println(sum[0]). What it does, is simply return real part of our complex as 0-th element and the imaginary part as 1-st one. If called with something else than 0 or 1, it would throw IllegalArgumentException(). Typically this operator would be used for some class representing collection (like list - please note in Java you'd have to use somelist.get(i) instead of just somelist[i] to get i-th element of the somelist List or like text string, where it would return n-th character).

There are other operators to overload, like not (!) - but I simply can think of no use of it regarding complex numbers :). When you type operator fun  (with the spacebar after the word fun) and hit Ctrl+Space in IntelliJ Idea or Android Studio, you'll get the full list of the operators possible to overload with their symbols on the right and corresponding keywords (like plus or minus in the example above) on the left:



Please note compareTo does not affect == comparison effect: that's what overriden function override fun equals(other: Any?) does.

A word on Java - of course, lack of operator overloading in Java doesn't mean we could not implement a class Complex in this language. We can, of course. But the only way of representing "sum of complex1 and complex2" would be some function or method, like complex1.add(complex2) or maybe sum(complex1, complex2) - not the intuitive and obvious Kotlin's complex1+complex2.

Well, that would be basics. More details, including the full list of operators available for overloading in Kotlin are available in the Kotlin's documentation.


Saturday 31 July 2021

Android Java to Kotlin migration by example part 12: a few Kotlin features

Today I'm not going to use the format typical for this series, instead - I'll just show you two features of Kotlin I've just learned about. As there are no named arguments and default parameter values in Java, I cannot provide you the Java code counterpart this time :)

Kotlin functions have named arguments, actually exactly as in Python.

What that means (assuming you haven't read the previous post?). Well, let's consider the following code:

package com.mypackage

fun divide(nominator: Float, denominator: Float): Float{
return nominator/denominator
}
fun main() {

val result = divide(10.0f,5.0f)
val result2 = divide(nominator = 10.0f, denominator = 5.0f)
val result3 = divide (denominator = 5.0f, nominator = 10.0f)

println(result)
println(result2)
println(result3)
}

It produces the following result:

2.0 2.0 2.0

The function divide has (quite obviously) two arguments: nominator and denominator. If you call the function without specifying their names, their order matters: in our case, the first argument is divided by second one.

But... You can also call our function with named parameters: as in Python, here also it means you can switch their order (the calls initializing result2 and result3.

And second thing: also exactly as in Python, the parameters in Kotlin can have default values.

So that the following code, for example:

fun power(base: Float, exponent: Float = 2.0f): Float{
return base.pow(exponent)
}
fun main() {

val a2cubed = power(10f,3f)
var a2squared = power(10f)

println(a2cubed)
println(a2squared)
}

... makes power function actually a square function, when called with just one argument.

The code above produces the following result:

1000.0
100.0

I think that's all for today. Both named parameters and default values are neat features - especially in functional language - and another advantage of Kotlin over Java - it's good to know they're available.

Wednesday 28 July 2021

Unity editor scripting (part 4): basic scene management

If you have lot of assets in your project, and multiple scenes in particular, it can be hard to navigate between them.

I've encountered two basic problems while working in Unity:
1) doing something (or checking something) in multiple scenes
2) running a particular scene which is required to run for your game (for instance, it loads all assets), while working on another one.

This is where editor scripts come to the rescue :)

In the following code I'll show how to create a tool for iterating over enabled scenes (and logging their root count object as an example), and another - for simply running some chosen scene.

Create a file ScenesHelper.cs and put it in Assets/Editor folder of your project.

The code is simple:

using UnityEditor;
using System.Linq;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;

class ScenesHelper
{
    static EditorBuildSettingsScene[] GetEnabledScenes()
    {
        return  EditorBuildSettings.scenes
          .Where(s => s.enabled).ToArray();
    }

    static string[] GetEnabledSceneNames()
    {
        var scenes = GetEnabledScenes()
            .Select(s => s.path)
            .ToArray();

        return scenes;
    }
    
    [MenuItem("Tools/Iterate over scenes. %#p")]
    static void Iterate()
    {
        foreach (string s in GetEnabledSceneNames())
        {
            Scene scene = EditorSceneManager.OpenScene(s);
            Debug.Log("Root object count in scene" + 
                scene.name 
                + ": " + scene.rootCount);
        }
    }

    [MenuItem("Tools/Play particular scene. %#o")]
    static void PlayScene2()
    {
        EditorSceneManager.OpenScene(
            GetEnabledSceneNames()[2]);
        EditorApplication.isPlaying = true;
    }

}

The method GetEnabledScenes() returns all enabled scenes (by omitting the Where clause you can also include those not enabled), or to be precise - objects of class EditorBuildSettingsScene , which represents scenes "identifiers" in editor build settings. 
The method GetEnabledSceneNames() returns their paths/names (retrieved via Linq Select).

Then we have the method Iterate()  (available from the Tools menu or via Ctrl+Shift+P shortcut) which iterates over all the enabled scenes (using their names) and logs the root objects count for each of them, and  PlayScene2() (Tools menu or Ctrl+Shift+O) which makes the editor play the second scene in our list.

Please note opening a scene in  Iterate() uses Scene class object, returned by EditorSceneManager.OpenScene(s) - it's not the same as EditorBuildSettingsScene. The former represent Unity scenes with objects, which can be inspected or played, the latter is sort of id of a scene in editor build settings.

Sunday 25 July 2021

Tray icon management in Windows Forms C# app

Today something different. The problem I’ll write about is: how to make a Windows Forms (C#) app minimize to tray when cliked on „X” and prevent it from displaying in the taskbar.

In other words – how to make a „typical tray app”.

To be honest – I was quite sure there would be some component (control) for it.

And there is (NotifyIcon) but… It’s not enough just to drag it to our app designer form in Visual Studio to make it work as we would like to.

Let’s begin with opening Visual Studio and creating a new Windows Forms App:

File -> New -> Project -> Windows Forms Apps -> Ok

First, wee drag NotifyIcon component from Toolbox to our form (it will appear below it, as it’s not visible in the form area, but outside it)



And here is the first strange behaviour: if we run (F5 or Ctrl+F5, but i’d suggest F5 as it allows it to kill the app if something goes wrong, and it can in this case) our app, the NotifyIcon component doesn’t seem to work. The tray icon doesn’t show up, and neither minimization nor clicking the „X” button causes our app to minimize to tray.

That’s because our tray icon is not set and we haven't implemented minimization by clicking "X". First the icon: in order to set it, we need the tray icon itself :)

We can just use Paint to create it – set the canvas size to 16x16 (this is the standard tray icon size in Windows), draw something beautiful and save it as .jpg file. Now rename it to something.ico – simply change the extension! The ico files are simply graphics files with a particular extension.

Now you can copy it to project – you can just drag it to project name in Solution Explorer view in VS.



It should show up below (myicon.ico) in the image above.

Now if you hit F5, the icon should show in the tray :)

The problem is it doesn’t do anything. The app still minimizes to the taskbar.

So let’s edit the code. Double click on the form project appearing in VS. The form code should appear, and it should be similar to this:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object senderEventArgs e)
        {

        }
    }
}

 

First of all, let’s make our icon actually do something: it should show form if clicked twice, and hide it if clicked twice again. In order to do it, select our NotifyIcon component in the designer (Form1.cs [ Design] tab):


Now select the lightning icon in Properties windows (F4 if the window is not visible), click the empty area on the right of „MouseDoubleClick” and then double click on it again :)



 An empty method should appear in the editor:


private void notifyIcon1_MouseDoubleClick(object senderMouseEventArgs e)
{

}

Let's implement it:


private void notifyIcon1_MouseDoubleClick(object senderMouseEventArgs e)
{
    if (this.Visible == true)
    {
        this.Hide();
    }
    else
    {
        this.Show();
    }
}

Now when you run the app and double click on the tray icon, the window should disappear. Double click on the icon again, and the window should appear. Now close the window – let’s get back to the code: we’ll add a context (right click) menu to the tray icon.

The remaining problems are as follows: the application exits, when we click „X” in the top bar. This is correct behaviour for most apps, but those enabled on tray should keep working even if „X” is clicked (the typical way of closing them is to right click on the tray icon and choosing „Close” or something similar from the context menu). The second problem is: the application still appears on the „normal” taskbar, and we want it to be minimized only to tray.

To fix the first issue, modify the Form1 constructor in this way:  


public Form1()
{
    InitializeComponent();
    this.FormClosing += this.Form1_FormClosing;
}

 … and add the callback for FormClosing event below:


private void Form1_FormClosing(object senderFormClosingEventArgs e)
{
    if (e.CloseReason == CloseReason.UserClosing)
    {
        this.Hide();
        e.Cancel = true;
    }
}

If you want to run the app now, do it using F5 (not Ctrl+F5) – you’ll need to terminate it using „Stop Debugging” (red square button or Shift+F5 in Visual Studio). If you forget about it, you’ll have to close it via the task manager :)

Now let’s add a possibility of closing the app via the context menu for the tray icon. In order to do that, switch to the Form1.cs [Design] view and drag ContextMenuStrip component to your designer view (window).



Now click on the "Type Here” area, type "Exit” and double click on it. It should take you to the editor, with generated code stub:


private void exitToolStripMenuItem_Click(object senderEventArgs e)
{

}

We want to close app when choosing ‘Exit’ option, so implement like this:


private void exitToolStripMenuItem_Click(object senderEventArgs e)
{
    Application.Exit();
}

Of course, you can add more items to the menu (and add whatever code you want to it).

The last thing to do is to attach this menu to our tray icon. In order to do that, choose notifyIcon1 from the area below the designer:



 ...and choose our ContextMenuStrip in the Properties window on the right:



When you run the app now and right-click on the tray icon, "Exit” option should appear (and should work).

To last thing to do is to prevent the app from showing on the "normal” taskbar. To do this, add one last line to Form1 constructor:


public Form1()
{
    InitializeComponent();
    this.FormClosing += this.Form1_FormClosing;
    ShowInTaskbar = false;
}

That's all for today - I think I was able to show you a simple stub of Windows app using tray in C#. If you have any questions about this - ask them in comments :)

Python crash course part 10: inheritance and polymorphism

In the last part we've shown how to create and use a class in Python. Today we're going to talk about inheritance: wchich means cre...