Wednesday 30 June 2021

Various git-related problems and tricks

Today some notes about git tips and tricks, which I often use and regularly forget.

They're not very "pro", just a few things I personally happen to find useful.

Aliases

If you use git from command line, it's helpful to define short aliases for commands like git checkout, git branch, git commit and (especially) git status. The traditional ones are, respectively: git co, git br, git ci and git st.

To do it, type these commands into your console:

$ git config --global alias.co checkout
$ git config --global alias.br branch
$ git config --global alias.ci commit
$ git config --global alias.st status


These commands change the global git config files, so you just have to run them once and you can forget about it (I mean, just remember the aliases).

Of course, you can define them differently, or add aliases for other git commands.

These commands change the .gitconfig file, which you can see by typing cat ~/.gitconfig

There should be something like this in the end:

[alias]
    co = checkout
    br = branch
    ci = commit
    st = status

Of course, you can simply edit this file to change or add new aliases, as you like.

Git language suddenly changed?

For some reason, it happened to me once that git (after some update, I think) on my MacOS machine started to show messages in my system language (which is Polish). I found it quite confusing, and possibly frustrating (in case of, for instance, need of googling some message - most of the world uses English, after all).

The solution is:

1. Check your locale (by typing LOCALE [ENTER] in shell):

~ LOCALE
LANG="pl_PL.UTF-8"
LC_COLLATE="pl_PL.UTF-8"
LC_CTYPE="pl_PL.UTF-8"
LC_MESSAGES="pl_PL.UTF-8"
LC_MONETARY="pl_PL.UTF-8"
LC_NUMERIC="pl_PL.UTF-8"
LC_TIME="pl_PL.UTF-8"
LC_ALL=

It seems my locale is pl_PL.

2. Add this line (of course change pl_PL to the value returned by your 'LOCALE' command):

export LANG=${LANG/pl_PL/en_US}

to the file ~/.zshrc (or .bashrc, or any other shell configuration file - zsh is default on MacOS).

Git tags listed from the newest, not the oldest.

The git tag command shows all the tags starting with the oldest ones, and if you are interested in the newer ones (which is typical, I suppose), you'll have to change the git config a bit, like this:

git config --global tag.sort -version:refname

Tuesday 29 June 2021

Unity hack - logging full object path instead of just its name

When debugging some Unity-related problem, there is often need of finding which game object in the scene does something. We can use transform.name (or gameObject.name), but there are often multiple objects in the scene with such name. The better solution would be to log full path in the scene graph (in a manner : objectsGrandParent/objectsParent/theObject). 

I don't know of any built-in solution for that, here is the helper class I've created for that purpose.

It takes transform as a parameter, of course we can call it with gameObject.transform if necessary.

using UnityEngine;

public class ScenePath
{
    public static string getPath(Transform transform)
    {
        string result = "";
        while (transform != null)
        {
            result = transform.name + 
                ((result!="")?("/" + result):"");
            transform = transform.parent;
        };

        return result;
    }
}

It can be used like this:

class MyBehaviour : MonoBehaviour
{
    void Awake()
    {
        Debug.Log(ScenePath.getPath(transform));
    }
}

As a result, if we add the MyBehaviour script to MyObject object in hierarchy like this:



... and run our scene, the logs will show up:




Tuesday 22 June 2021

Unity editor scripting (part 2) - basic menus, basic object selection

As mentioned in part 1, Unity editor is very easily extensible by scripting.

It basically allows to do almost everything you could by clicking by a script. And programmers do not like clicking, if something can be automated.

In the following article, I'll show you some simple steps to achieve some simple results with Unity editor, beginning with the basics of creating an editor script, and focusing on selecting, inspecting and modifying objects in scene. The information below is, of course, available in the Unity documentation - my goal is to put it in one place, in a simple question-answer format.

In the future I'll provide more similar examples, maybe a bit more complex (so that one would show a few editor features/how-to's)


1) How to create a veery basic editor script, accessible from menu?

Create folder named Editor in Assets folder, create a file named SceneTools.cs and put this code inside:

using UnityEditor;
using UnityEngine;

public class SceneTools
{
    
    [MenuItem("Tools/Show some log.")]
    static void ShowLog()
    {
        Debug.Log("Showing this log");
    }

}

It's veery basic. It simply adds a menu item called "Do something" to Unity's Tools menu (and creates Tools menu itself, if it hasn't been added before). When clicked, it shows "Showing this log" text in the Console view.

Menu looks like this:


If we want to add some function to Unity's menu, we have to use the MenuItem attribute, and the method has to be static.

2) How to create not-so-basic script (maybe connected to scene somehow?)

Ok, let's extend our script. We can add another method below the first one. Remember to change the name in MenuItem annotation (the menu item name). You can add as many methods (and, therefore, items), as you like to your custom menu. Just remember to change the names (in both annotations and methods' names) This time it will log the selected object's name and print it to console (only if at least one object is selected).

[MenuItem("Tools/Show selected object's name.")]
static void ShowObjectsName()
{
    if (Selection.gameObjects.Length > 0)
        Debug.Log(Selection.activeGameObject.name);
}

And here is our result:



Without the check in if, the line below would throw NRE if no object was selected.

3) How to select the first root object in scene with particular name?

Another method (we select the first object named "Andrew"):

[MenuItem("Tools/Select object with name.")]
static void SelectObjectWithName()
{

    GameObject[] rootGOs = 
    SceneManager.GetActiveScene().GetRootGameObjects();
    
    foreach (GameObject go in rootGOs)
    {
        if (go.name == "Andrew")
        {
            Selection.activeObject = go;
            break;
        }
    }
}

If there is no such object, nothing happens.

For this one and another, update your "using" directives:

using UnityEditor;
using UnityEngine;
using UnityEngine.SceneManagement;


4) Ok, how to remove the first object in the scene with particular name?

Here you go (use cautiously!):

[MenuItem("Tools/Remove object with name...")]
static void RemoveObjectWithName()
{
    GameObject[] rootGOs = 
    SceneManager.GetActiveScene().GetRootGameObjects();

    GameObject objectToRemove = null;

    foreach (GameObject go in rootGOs)
    {
        if (go.name == "Andrew")
        {
            objectToRemove = go;
            break;
        }
    }
    
    if(objectToRemove)
        UnityEngine.Object.DestroyImmediate(objectToRemove);
}

If there is no such object in the scene, nothing happens.

To be continued. I think next time I'll prepare one more complex script, doing some made-up task, using the techniques mentioned above (and adding more).

Meta-blogger note for today: I have to find some way to add line-numbering to the embedded code here, and to make it wrap automatically.

Monday 21 June 2021

Syntactic sugar (and other nice features) in C# part 2


This time some simple things. Possibly obvious for programmers with some experience... But maybe not so obvious for everyone? Once again we're discussing C# 7.0 used with Unity.

1. You can inline an out variable declaration

The first one this time is a very little detail, which may seem obvious - but I wasn't aware it for quite some time. I think this may be quite new (since C# 7.x indeed?)

When using a method with an out param, you don't have to declare it before.

Which means you can write this:

string maybeNumber = "10";
int result;
int.TryParse(maybeNumberout result);
DoSomethingWith(result);

as this:

string maybeNumber = "10";
int.TryParse(maybeNumberout int result);
DoSomethingWith(result);

2. Long numbers made readable (works also in Python and Java)

Do you use big numbers in your code? You know, when something like long bigNumber1 = 2156454565; shows up, and you're not sure whether it's 215 millions 645 thousand and so on, or maybe 2 billions 154 millions or... Well, it's because you don't know it can be written like this:

long bigNumber2 = 2_156_454_565;

Works for other numeric types too:

double bigNumber1 = 100_123.125_324;

This way of declaring numeric literals works also in some other languages: I'm sure about Java and Python. It doesn't seem to work with C(++).

3. A short story about null values and question marks

There is something called conditional operator in most of modern programming languages. It's consists of an expression, followed by ? sign and then some value to be returned if expression is true; then : sign and a value to be returned if expression is false. Long story short:

int number = 42;
string nrDescription = (number==42)?"Ultimate answer":"An ordinary number";

It's pretty well known syntax. But in C#, there are more similar tools.

3.1 Null coalescing operator

One of them is a null coalescing operator, which may be handy when checking if something is null. Let's consider the following code (it does not make use of null coalescing operator yet, see below):

TimeZoneInfo tInfo = TimeZoneInfo.Local// this can be null
          
TimeZoneInfo nonNullTInfo1 = tInfo != null ? tInfo : TimeZoneInfo.Utc;
Console.WriteLine(nonNullTInfo1.DisplayName);

It's simple: it shows the local time zone display name, and if it's not available (TimeZoneInfo.Local is null), it fallbacks to TimeZoneInfo.Utc. It uses the "traditional" conditional operator.
And here is our alternative, using the  null coalescing operator:

TimeZoneInfo tInfo = TimeZoneInfo.Local// this can be null

TimeZoneInfo nonNullTInfo2 = tInfo ?? TimeZoneInfo.Utc;
Console.WriteLine(nonNullTInfo2.DisplayName);

A bit shorter, a bit more elegant. Can save quite a lot of typing in more complex cases.

3.2 Null conditional-operators ?. and ?[]

Let's consider following code:

class SomeClass
    {
        public void someMethod()
        {
            Console.WriteLine("Some method is working");
        }

        public TimeZoneInfo getTimeZone()
        {
            return TimeZoneInfo.Local;
        }
    };

    class Program
    {

        static void Main(string[] args)
        {
            SomeClass someObject = null;

            someObject.someMethod();

            TimeZoneInfo res = someObject.getTimeZone();

            Console.Write("Result:"+res.StandardName);
        }
    }

Obviously, this code will throw an exception. As we never initialize someObject, the call: someObject.someMethod(); will throw NullReferenceException. Of course, we can precede it with if(someObject!=null). But we can change the Main method to look like this:

static void Main(string[] args)
{
    SomeClass someObject = null;

    someObject?.someMethod();
    TimeZoneInfo res = someObject.getTimeZone();

    Console.Write("Result:"+res.StandardName);
}
What happens then? An NullReferenceException is thrown again, but it's the .getTimeZone() call that throws it! someObject?.someMethod(); is simply not called.

So let's add another ?, this time before .getTimeZone(); call:

static void Main(string[] args)
{
    SomeClass someObject = null;

    someObject?.someMethod();
    TimeZoneInfo res = someObject?.getTimeZone();

    Console.Write("Result:"+res.StandardName);
}

.someMethod();.is not called, and then .getTimeZone() is not called. What happend with res? Well, because the initializing expression can't be called, it... stays uninitialized: it's null.
Which means we get our NullReferenceException only in the call to Console.Write("Result:"+res.StandardName);. Which, by the way, can be avoided this way:

Console.Write("Result:"+res?.StandardName);

... resulting in writing to console simply Result: (the value returned by res.StandardName is simply null, which is printed as en empty char).

To sum up, the following code (consisting all the aforementioned features):

static void Main(string[] args)
{
    SomeClass someObject = null;

    someObject?.someMethod();
    TimeZoneInfo res = someObject?.getTimeZone()
    
    Console.Write("Result:"+res?.StandardName);
}

...is equivalent to the following ("old school") code:

class Program
{
    static void Main(string[] args)
    {
        SomeClass someObject = null;

        if(someObject!=null)
            someObject.someMethod();

        TimeZoneInfo res = 
        (someObject != null)?someObject.getTimeZone():null;
        
        Console.Write("Result:"+ ((res!=null)?res.StandardName:""));
    }
}

What about ?[] operator, mentioned in the midtitle? Well, it's similiar to ?. but involved using arrays. So it allows us to write:

int[] array = null;
Console.WriteLine(array?[2]);

instead of:

int[] array = null;
Console.WriteLine(array == null?"":array[2].ToString());

Saturday 19 June 2021

Python crash course (part 2) - functions and lambdas

The script in the previous part included very limited and basic use of functions. They were not returning anything, and they were quite simple. I also wasn't using any lambdas (which in Python mean simple, anonymous functions defined in a specific way). So let's take a look at a little illustrative program, showing how to define and call a function in Python, how to pass a parameter to it and return a value, how to pass a function as a parameter and how to define and use a lambda (in our case, passed as a parameter). 

Once again, some programming experience may be needed to understand what's going on - the code below is just some simple examples of basic language constructions. This time: functions and lambdas. Some details in the comments. In the further part (below), one more notion regarging lambdas. For now, it's much less practical than the code in the first part, but I wanted to simply show (and note for myself) some basic syntax and use cases. Still not object-oriented.

Listing 1:
# a function doing something (printing text), 
# not returning anything ("procedure")
def simply_print_some_text():
    print("To be or not to be")

# a function taking a numeric parameter and returing its squared value
def get_value_squared(x):
    return x*x

# a function taking a function as parameter and printing
# its first 10 non-negative values
def show_first_10_values(some_function):
    for a in range(0,10): #from 0 to 9
        print(some_function(a),end=', ')

def main():
    # call the first function:
    simply_print_some_text()

    # print the value returned by the squaring function with param "3":
    print(get_value_squared(3))

    # call the values-printing method with squaring function as param
    show_first_10_values(get_value_squared)
    print() # print a new line character

    # call the third function with a lambda (also returning squared value)
    show_first_10_values(lambda xx*x)
    print()


if __name__ == "__main__":
    main()

The result of this running this code looks as follows:

Listing 2:
To be or not to be
9
0149162536496481,
0149162536496481,

Note on lambdas in Python

The code in Listing 1 shows use of lambda in Python. The last call in the main

show_first_10_values(lambda argarg*arg))

is the call to a function, which takes another function as a param and calls it 10 times, with arguments from 1 to 10. I think that, although not very practical itself, it shows more-or-less how to use lambdas.

Meanwhile, there is a common example of using such lambdas in Python, which, although technically correct, doesn't make much sense:

Listing 3 (wrong practice?):
doubled = lambda xx * 2
print(doubled(3))

First of all - this code works. It prints a number 6 in that case. But the problem is:

What's the point of using lambda here, if it's basically a function? The same code could look like this:

Listing 4:
def doubled(x):
   return x * 2
print(doubled(x))

... or even like this (please note it's the same code, just one code indentation is ommited):

Listing 5:
def doubled(x): return x * 2
print doubled(x)

... and well, that's what functions are for, right?

Such practice, although quite common in various articles on lambdas in Python, seems to be criticized in the official Python style guide.

In the first example (Listing 1, show_first_10_values(lambda argarg*arg)), there is at least some reason of using a lambda: we need to pass some function as a parameter, and we want to define it ad hoc . Please note this:

show_first_10_values(lambda xx*x)

is simply much shorter (and elegant) than this:

def get_value_squared(x):
    return x*x
(...)
show_first_10_values(get_value_squared)


The next part: collections and data structures.

Tuesday 15 June 2021

Syntactic sugar in C# (part 1): Returning multiple values from a method in C# 7.0 (and Unity)

Here's some syntactic sugar I've discovered recently and I was quite impressed. Please note it requires C# 7.x (Unity 2019 and newer should be ok).

First, a little background:

A typical method in C# returns one value. Until recently, if you wanted to return two values, like an int and a float, you could either use out parameters, or define a helper struct. But there is other way!

Let's take a look on "old" methods first (if you want to see the new way, it' in 4-th point below).

The problem with out parameters is that returning value via them is a bit less readable than a normal return, and the problem with a helper struct is that is has to be defined. Let's see how it looks like, for reference; and then I'll show you a bit more elegant way.

Let's assume we have our method, getSomeData(), which we would like to return two values: integer age and floating point height.

The first 3 examples below are to show you some context, my "discovery" is in the 4-th point :)

1. out parameter version

The typical way, similar to references from C++: we can "return" our values by out parameters:

    private void getSomeData(out int ageout float height)
    {
        age = 100;
        height = 170.5f;
    }

    // Let's use it
    private void someMethod()
    {
        int age;
        float height;

        getSomeData(out ageout height); 

        Debug.Log(age); // 100
        Debug.Log(height); // 170.5
    }

Problem with this? Well, it doesn't quite look like returning a value. It looks like calling a method with parameters.

2. out+return version

We can return one value and get other one via out parameter:

    private int getSomeData(out float height)
    {
        int age = 100;
        height = 170.5f;
        return age;
    }

    // Let's use it
    private void someMethod()
    {
        int age;
        float height;

        age = getSomeData(out height);

        Console.WriteLine(age); // 100
        Console.WriteLine(height); // 170.5
    }

The problem with this version is that either of parameters is returned in a different way. If both are equally important, it looks strange (if not deceptive).

3. Helper struct

We can define a helper struct and return it:

    struct PersonalDetails
    {
        public int age;
        public float height;
    }

    private PersonalDetails getSomeData()
    {
        int ageToReturn = 100;
        float heightToReturn = 170.5f;

        return new PersonalDetails 
        age = ageToReturnheight = heightToReturn };
    }

    // let's use it
    private void someMethod()
    {
        var myDate = getSomeData();

        Console.WriteLine(myDate.age);
        Console.WriteLine(myDate.height);
    }

This version is very clean and readable when we define and call out method, but...


... before that it requires us to create a whole new structure, just for returning two values at once.

4. Sugar in C#7!

So it seems... We can just return two values at once!

        private (int agefloat heightgetSomeData()
        {
            int ageToReturn = 100;
            float heightToReturn = 170.5f;

            return (ageToReturnheightToReturn);
        }

        // now let's use it
        private void someMethod()
        {
            var myDate = getSomeData();

            Console.WriteLine(myDate.age);
            Console.WriteLine(myDate.height);
        }


Aaand here is our magic. In the method declaration we put (int age, float height) in the place we would normally place the returned type.

Then we can assign it to a variable, and use it - just like that! What's more, we can access the returned values after a dot, refering to them by names from the method declaration.


BTW if you wonder what type is myDate here, Console.WriteLine(myDate.GetType()), gives us:

    System.ValueTuple`2[System.Int32,System.Single]

So instead of 

    var myDate = getSomeData();

...we could write:

    (int agefloat heightmyDate = getSomeData();

Also nice and clean, isn't it?

Monday 14 June 2021

Python crash course (part 1 - example)

Today - something different. You'll learn Python (3) in 5 minutes, no need to thank... Ok, not exactly. But... Sort of. You know, when you have a little bit of experience and not much time, there is better way of learning some things (like programming languages), instead of tutorials and books. It's to take a look at the thing in action: in case of a programming language, it would be a short program, using some basic features of the language. The additionary benefit is that you can make it solve some problem you have. 

Please mind this note should be quite helpful, if you already know some programming languages, but not Python in particular. If you are a beginner in programming, maybe you can use it as a simple "practical" reference, but you may have problems understanding what going on - I won't elaborate on all things (of course, if you have questions, please do comment).

Ok, so what was that problem in my case? 

Well, I had been testing some feature of my Android game - to be precise, the notifications' logic. Some time after event A the app was supposed to show a notification, but only a limited number of times and in specific conditions (details are not important here). So at first I've opened Notepad and started to write things like:

10:00:00: App starts 10:00:06: Module initialized 10:10:10: Backgrounding the app 10:15:10: Foregrounding the app, module does not work. Why, o why? 10:16:10: Removing app from the device

...based on my app's behaviour and logcat.

After working with that for a day or so, I've realized that:

1) I have notes in 3 different editors open at the same time

2) I've been taking a note with a timestamp about 2 times a minute for a day (I check time, I write it down, I write the note, lot of work).

3) I can make things a bit easier...

And by 3) I mean: 

I can write a simple script, which simply takes the input by user (followed with [ENTER]) and writes every line (with timestamp) to a file. And then if the user types r [enter] (r), it shows the notes so far. This way: everything is in one editor (which is my script), stored safely in one file (which fixes issue 1) ); and I don't have to manually check and write down the time (issue 2, and - inherently - issue 3).

And here is the script, which by the way is one of the programs I've mentioned in the beginning: it uses functions, flow control (loops, ifs), basic data structures, file I/O... Basically a first few lessons in every Python tutorial ;). Nothing advanced, nothing object-oriented for now. We don't need that for now... Maybe in the future.

# !/usr/bin/python3

from datetime import datetime

# a function appending the line to the 'data.txt' file 
# or create the file first it it doesn't exist
def create_or_append(line):
    # open a file to write:
    file_descriptor = open('data.txt','a'encoding='utf-8')
    file_descriptor.write(line+"\n") # write the line
    file_descriptor.close() # close
    
logs_list = [] # define a global list, empty.

# another function: read all the lines from 'data.txt', 
# print them to screen and add them to logs_list list.
def read_from_file():
    # "global": don't override the global logs_list: use it 
    global logs_list
    # make the logs_list empty list: 
    logs_list = []
    # open a file to read
    file_descriptor = open('data.txt','r'encoding='utf-8')
    # iterate over lines read from file
    for val in file_descriptor.readlines():
        # add each one to list
        logs_list.append(val)
        # print it to console ("strip" removes ending '\n')
        print(val.strip())
    # close the previoously open file
    file_descriptor.close()

# a function showing a prompt
# and doing something in input in a loop
def notes():
    res=""
    while (res!="q"):
        # input function shows the text in param
        # and returns user's input
       # (any text followed by [ENTER]
        res=input('add note => [ENTER], [q]uit, [s]how '
        'all notes so far, [r]ead saved data:\n')
        # if input is 's'
        if(res=="s"):
            #...show this text:
            print("Notes so far:")
            # and iterate over logs_list
            for it in logs_list:
                # strip() removes trailing spaces
                print(it.strip())
        #else if input is 'r'
        elif(res=="r"):
            # call read_from_file() function (see above)
            read_from_file()
        # if input is any other (a note)
        elif(res!="q"):
            # get current time, and...
            now = datetime.now()
            # ...format it
            dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
            # add tab and note to time
            string_with_date = dt_string+"\t"+res 
            # add all of it to logs+list
            logs_list.append(string_with_date+"\n")
            # call method above with param
            create_or_append(string_with_date)

# main, where our program begins execution
def main():
    notes() # call the function defined above

if __name__ == "__main__":
    main()

I won't elaborate on the code - I think the Python syntax is very clean and self-explanatory, and I've commented it quite extensively. I think the most cryptic fragment is the if __name__ == "__main__": statement: it's simply the way you should call the main method in Python. You could just write main() in the last line; but when such script is imported as a module, it would be executed automatically (which most probably is not the desired effect). In our case it doesn't really matter (I would't advice importing this as a module ;) ), but let's follow the tradition.

The code is on github here - the linked version may be a bit different, because using it day-to-day, I'll probably tweak something in the future. Maybe I'll update this post too.

Next time I'll elaborate more about functions (and lambda functions). The next lessons will also be more descriptive about basic things.


Meta-notes for today: if you want such nice, monospace, syntax-colored code in Blogger, you can simply copy the contents of a file opened in VS Code (which makes a very nice Python IDE, BTW, with some plugins applied). It works out-of-the-box only for the files with syntax highlighting, so if you just create a new file and type some text, it won't. But in that case, you can use Ctrl+Shift+P -> type Copy -> choose Copy with syntax highlighting.



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