Thursday, January 30, 2020

Modulo operation in programming languages - differently implemented

Many programming languages support an operation which they call modulo operator and which is often designated by the symbol
    %
Often it is also referred to as the remainder after division.

Only recently I found out that this operation does not behave as one might think. The results differ depending on which programming language you are using.

Before I go into the details I would like to illustrate the difference which shows when using negative numbers.

Example

I want to calculate these two expressions:
 27 % 10
-27 % 10
The result for the second expression will be different depending on the programming language.

C

When you are using this statement in C
printf("%d  %d\n", 17 % 10, -17 % 10 );
you get
7  -7

Python

When you are using this statement in python
print( '{0}  {1}'.format( 17 % 10,  -17 % 10 ) )
you get
7  3

Explanation

modulo as remainder by division

Some programming languages implement modulo as a remainder of division operation. Thus -27 % 10 results in the leftover of -27 when you take away the maximum multiple of 10 , so you are left with -7.

modulo as mathematically correct number

Other programming languages implement modulo as correct in the mathematical sense.
Mathematically modulo is defined as the number which needs to be added to a multiple of the divisor to get to the original.
x = m % n
There must be a number 'a' so that
a * n + x = m
and this condition should be met:
0 <= x < n
In our case:
x = 3
a = -2
=>
a * 10 + x = -2 * 10 + 3 = -17

Conclusion

Since I am not a programming languages expert I can only refer to the interesting Wikipedia article about modulo operations.
This subject is worth knowing if any of your programming efforts involve some number operations.
My personal "watch out" topic is awk programming where the behaviour is non-mathematical like C.

Wednesday, November 20, 2019

Ansible - dictionaries vs. lists

When working with more complex variables in Ansible (often based on yaml input files) you always have to be aware whether the variable is a list or a dictionary. Applicable filters and methods differ and can lead to errors or unexpected results.

Example input yaml

Here I am defining two variables x and y with some sub elements.
At first glance there doesn't seem to be much difference and if you are about to design a yaml for whatever purpose both solutions might seem interchangeable. The difference lies in its usage which we will see below.
x:
  b1:
    c1: 1
    c2: "aaa"
    c3:
  b2:
    c2: "bbb"
    c3: 5

y:
  - b1:
      c1: 1
      c2: "aaa"
      c3:
  - b2:
      c2: "bbb"
      c3: 5
Call the file dict.yml.

How to check the variable type

Lately there is a new filter in Ansible called type_debug which I find incredibly useful when in doubt.
(unfortunately it was not available in Ansible 1.x, it would have saved me a lot of time)
- hosts: localhost

  tasks:
  - include_vars: dict.yml

  - debug:
      msg: "x: {{x | type_debug}} / y: {{y |type_debug}}"
will show
TASK [debug] ************************************************************************************
ok: [localhost] => {
    "msg": "x: dict / y: list"
}
i.e. I have a dictionary and a list.

How to access the elements

The elements of
  • a dictionary are accessed by name i.e. x['b1']
  • a list are accessed by position i.e. y[0]
    Something like x[0] or y['b1'] would generate a VARIABLE IS UNDEFINED.
    I also show the variable type of the sub elements.
    - hosts: localhost
    
      tasks:
      - include_vars: dict.yml
      
      - debug:
          msg: "{{x['b1'] | type_debug}}"
    
      - debug:
          var: x['b1']
    
      - debug:
          msg: "{{y[0] | type_debug}}"
    
      - debug:
          var: y[0]
    
    will show
    TASK [debug] ************************************************************************************
    ok: [localhost] => {
        "msg": "dict"
    }
    
    TASK [debug] ************************************************************************************
    ok: [localhost] => {
        "x['b1']": {
            "c1": 1,
            "c2": "aaa",
            "c3": null
        }
    }
    
    TASK [debug] ************************************************************************************
    ok: [localhost] => {
        "msg": "dict"
    }
    
    TASK [debug] ************************************************************************************
    ok: [localhost] => {
        "y[0]": {
            "b1": {
                "c1": 1,
                "c2": "aaa",
                "c3": null
            }
        }
    }
    
    
    You should also note the difference in the result. They are both dictionaries but in the x-case we get a simple dictionary with 3 elements whereas in the y-case we get a dictionary with one element b1 which a sub element of type dictionary.

    How to loop through sub elements

    You can loop easily through the elements by supplying the variable to with_items. The distinction is in what you get as an item. with_item provides
  • dictionary elements as strings and you need to access the sub elements via the {{x[item]}} method
  • list elements are dictionaries
    - hosts: localhost
    
      tasks:
      - include_vars: dict.yml
      
      - debug:
          msg: "{{item}}: {{item|type_debug}} / {{x[item]}}: {{x[item]|type_debug}}"
        with_items: "{{x}}"
    
      - debug:
          msg: "{{item}}: {{item|type_debug}}"
        with_items: "{{y}}"
    
    TASK [debug] ************************************************************************************
    ok: [localhost] => (item=b1) => {
        "msg": "b1: AnsibleUnsafeText / {u'c3': None, u'c2': u'aaa', u'c1': 1}: dict"
    }
    ok: [localhost] => (item=b2) => {
        "msg": "b2: AnsibleUnsafeText / {u'c3': 5, u'c2': u'bbb'}: dict"
    }
    
    TASK [debug] ************************************************************************************
    ok: [localhost] => (item={u'b1': {u'c3': None, u'c2': u'aaa', u'c1': 1}}) => {
        "msg": "{u'b1': {u'c3': None, u'c2': u'aaa', u'c1': 1}}: dict"
    }
    ok: [localhost] => (item={u'b2': {u'c3': 5, u'c2': u'bbb'}}) => {
        "msg": "{u'b2': {u'c3': 5, u'c2': u'bbb'}}: dict"
    }
    

    How to access the bottommost elements

    Say we want to access the value of c2 of b1 for both x and y. There is in both cases the bracket and the dot approach for the dictionary sub elements. In the y-case you need to supply the list position too but it also can be used with the dot approach.
    - hosts: localhost
    
      tasks:
      - include_vars: dict.yml
      
      - debug:
          var: x['b1']['c2']
    
      - debug:
          var: x.b1.c2
    
      - debug:
          var: y[0]['b1']['c2']
    
      - debug:
          var: y.0.b1.c2
    
    will lead to
    TASK [debug] ************************************************************************************
    ok: [localhost] => {
        "x['b1']['c2']": "aaa"
    }
    
    TASK [debug] ************************************************************************************
    ok: [localhost] => {
        "x.b1.c2": "aaa"
    }
    
    TASK [debug] ************************************************************************************
    ok: [localhost] => {
        "y[0]['b1']['c2']": "aaa"
    }
    
    TASK [debug] ************************************************************************************
    ok: [localhost] => {
        "y.0.b1.c2": "aaa"
    }
    

    Conclusion

    Filters like join, unique, setaddr, map etc. only make sense for the correct variable type. You always need to know what you are dealing with and thus you will be able to create working playbooks faster. It might also influence your design decision when you want to map data into a fitting yaml.

    Why did I write this article

    When I am writing Ansible playbooks they are often based on input yaml files (sometimes my own, sometimes from others) and also often these yaml files contain complex structures which need to be parsed and interpreted correctly.
    I am parsing complex structures by creating intermediate steps and creating new variables with set_fact which contain sub structures of the original one. A common mistake I make is that at certain points in my code I am not sure whether the variable in use is a list or a dictionary. Subsequently when I am using a method or filter this can lead to an error or - worse - to a valid but incorrect result (e.g. an "empty" variable) which will lead to further content errors downstream and the end result is puzzling.
    So I thought for my sake and the sake of the reader a little summary article would help, in particular since I find the Ansible documentation not always as helpful as it could be.