Monday, 18 May 2020

This week 2/2020 - Python

I had always aversion to Python but finally I forced myself to try it. I am developing myself in machine learning area and most examples and algorithm sources are in Python - life forced me.

In this post in a nut shell I describe basic and most important topic of language like:
- why it was created?
- who use it and why?
- a very short characteristic of language and biggest differences which I noticed.

Python was created 1985 by Guido van Rossun as an interpreted, interactive, object-oriented high level language. Name of language is after Monty Python's Flying Circus TV comedy series. It was designed to be readable and easy to run in academic environment. It uses dynamic data typing validated in runtime. It supports functional programming and it is possible to compile Python code into bytecode usually in bigger applications.
It is good to add that till this year (2020) there were two major versions: 2.x and 3.x. Since 2008 when version 3 was introduced, the older version has been still developed. Versions are incompatible to themselves, so when you learn Python focus on which version you use.
When I write this post current version is 3.8.3 but I trained on 3.6.9 and I used only a few features of the language.

Creator cared of interactive console so each command can be added add-hoc and executed. Probably that's why this language won in scientific community, where code doesn't need to be compiled to be executed.
Currently in Python we can find a lot of tools and libraries to load data, process it and present it (plotters, etc.). Dynamic data type definition is useful when we experiment with code but from my point of view can be dangerous during runtime, when we can meet type incompatibility in runtime.

How Python stand out from the rest languages? The first difference is that Python required some code layout. It doesn't use semicolons and braces so it requires lines and indentations. This is what doesn't convince me to Python. Of course I like pretty formatted code but I acclimated to braces and I don't belief that we can live without them.

1
2
3
4
if filename and os.path.isfile(filename):
    with open(filename) as fobj:
        startup_file = fobj.read()
    exec(startup_file)

Other differences that language uses words "not", "and" and "or" in conditional statements.
Python widely support list. Programmer can add lists, multiply elements, search and simply filter it by two or there additional signs.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
print([1, 2, 3] + [4, 5, 6])  # [1, 2, 3, 4, 5, 6]
print(['blog'] * 4)  # ['blog', 'blog', 'blog', 'blog']
print(3 in [1, 2, 3])  # True
for x in [1, 2, 3, 4]:  # 1 2 3 4
    print(x, end=' ')
print("")
L = ['one', 'two', 'there', 'four']
print(L[1])  # there
print(L[-1])  # four
print(L[2:])  # ['there', 'four']
print(L[:2])  # ['one', 'two']

Python includes tuples which support similar operations as for list and dictionary type as well.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Tuple
tuple1 = ('cat', 'dog', 19, 200)
tuple2 = "a", 4, "c", 2.3

print("tup1[0]: ", tuple1[1])  # tup1[0]:  dog
print("tup2[1:4]: ", tuple2[1:4])  # tup2[1:4]:  (4, 'c', 2.3)

# Dictionary type
dict = {'Name': 'Tom', 'Age': 27, 'eyes': 'blue'}
print("dict['Name']: ", dict['Name'])  # dict['Name']:  Tom
print("dict['Age']: ", dict['Age'])  # dict['Age']:  27



Python allows to inheritance, overriding but I didn't find possibility to overloading methods.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Parent:  # define parent class
    parentAttr = 100

    def __init__(self):
        print("Calling parent constructor")

    def parentMethod(self):
        print('Calling parent method')

    def setAttr(self, attr):
        print('setAttr(self,attr)')
        Parent.parentAttr = attr

    def getAttr(self):
        print('setAttr(self)')
        print("Parent attribute :", Parent.parentAttr)


class Child(Parent):  # define child class - inheritance
    def __init__(self):
        print("Calling child constructor")

    def parentMethod(self):  # method overriding
        print('Calling parent method in child')

    def childMethod(self):
        print('Calling child method')


Python contains annotations mechanism:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
def decorator(annotatedText):  # definition of annotation
    def text_generator(old_function):
        def new_function(*args, **kwds):
            return annotatedText + ' ' + old_function(*args, **kwds)
        return new_function
    return text_generator # it returns the new generator

# Usage
@decorator('prefix') # text attached before function resul
def return_text(text):
    return text

# Now return_text is decorated and reassigned into itself
print(return_text('myText')) # 'prefix myText'


and finally lambda expressions:

1
2
d = lambda d : d + 20
print(d(10)) # 30

My feeling a bit changed after I went through a tutorial and wrote some code but it is too little to feel free in it. Maybe after more machine learning exercises I will love it.

Resources:
1. Python 3 Tutorial (tutorialspoint)
2. Python documentation
3. How to Use Python Lambda Functions

Thursday, 12 March 2020

This week 1/2020 - Elm lang

In this article I will describe what is Elm, how to start adventure with it and some details about this language. I am still exploring this language so please forgive some mistakes.


1. What is Elm lang?

Elm is statically typed strongly functional language compiled to JavaScript. Structure of code is similar to Python - Elm doesn't use braces but requires indentations. Strong typing protects developer from most of technical errors and unknown state of application. All technical errors are caught in compile time and developer is informed about them by detailed messages which usually contains suggestion how to fix it.

2. What tools includes Elm?

Elm command support development and module upgrading. The most useful command are:
  • elm init - initialize project structure. creates src directory and elm.json file.
  • elm repl - starts interactive programming session,
  • elm reactor - runs local web server to see project 
  • elm make - compile code to JavaScript
  • elm install - fetches packages
and less popular: 
  • elm-test init - creates tests dictionary with example sources and updates test dependence in elm.json 
  • elm bump - updates version of packages depending on this changing package
  • elm diff - detects changes between versions of packages
  • elm publish - publish your code in elm lang repository
For more detail please check documentation.

3. How to start?

Using npm Elm tools can be installed by few commands:

npm install elm
npm install elm-format
npm install elm-test

and then to initialize first project

elm init

and initialize test to this project
elm-test init

In project dictionary there are created directories and files:
  • src - directory where should be stored production sources
  • tests - directory with test sources
  • elm.json - file with project description and dependence, ex. below


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
{
    "type": "application",
    "source-directories": [
        "src",
        "tests"
    ],
    "elm-version": "0.19.1",
    "dependencies": {
        "direct": {
            "elm/browser": "1.0.2",
            "elm/core": "1.0.5",
            "elm/html": "1.0.0",
            "elm/http": "2.0.0",
            "elm/json": "1.1.3",
            "elm/random": "1.0.0"
        },
        "indirect": {
            "elm/bytes": "1.0.8",
            "elm/file": "1.0.5",
            "elm/time": "1.0.0",
            "elm/url": "1.0.0",
            "elm/virtual-dom": "1.0.2"
        }
    },
    "test-dependencies": {
        "direct": {
            "elm-explorations/test": "1.2.2"
        },
        "indirect": {}
    }
}

When project is initialized, we can create first elm application.
I use IntelliJ with Elm plug-in, however it is possible to create elm source file in notepad and save file with elm suffix.

When elm file is created, it should be compiled to JavaScript. It is done by command

elm make src/Main.elm

By default is created a file "index.html" with JavaScript included.

4. Architecture

In a null shell about architecture of Elm. Elm uses pattern Model View Update. To update view is used virtual DOM tree, where each update operation creates new copy of virtual DOM tree, then each new copy is compared with previous one and then all changes are applied finally on real DOM tree in one big batch. This solution much improves changes on real DOM tree.

source: https://elmprogramming.com/virtual-dom.html



5. Basic of language?


Types


All variables in Elm are immutable by design. It offers:

- simple types:

  • Bool
  • Int
  • Float
  • Char
  • String

- complex types:

  • typed List is a linked list what simplify operations on it. List can be created by collecting elements one type in square brackets
    [elem, elem, elem]
    or add new elements by calling
    elem :: [elem]
  • array is also typed as List and can be created from List. Array allows for direct access to each field
  • tuple is a set of different type elements and is typed as well. tuple is created by collecting elements in round brackets
    ( elemA, elemB, elemC )
  • record is a structure of data. Record is created by collecting name of data and values in braces
    var1 = { field1 = elemA, field2 = elemB }
    or
    var1 = RecordType elemA elemB
    where record's variables must be in the same order as in definition
    type alias RecordType = { field1 : String, field2 : Int}
  •  Maybe is wrapper on object to avoid null pointers. It contains values: Just with value or Nothing.

- custom type - created by developer

type UserStatus = Regular | Visitor

- special types

  • "_" has special meaning. It represents any type. It can be used as default value in case construction or as unused input of function
  • unit type "()" - represent empty value
  • inline function requires "\" before declaration
\elem -> elem + 1
  • redirecting function result to the funtion on the left "<|" or right "|>" function


Let / if / case constructions

let
    definition
in
    function body
   
   
case variable of
    case_element -> body handling case
    _ -> body of default handling


if condition then
    body
else
    body


Modules:

When application is bigger and bigger it is required to split code into separated files. Elm defines each separate file as module. Each module can contain private or public elements, what is defined in header of elm file.
module ModuleName exposing (list_of_elements_to_be_public)
for all elements instead of elements list is used two dot, ex.
module ModuleName exposing (..)
Importing module can import all elements but there is required source module prefix,ex.
import Module
or it is possible to make alias to prefix name, ex.
import Module as M
or in some cases it is better to create direct connection to element in depended module - like a static import in Java
import Module exposing (exposing_function1,exposing_function2)
there is also possible to make mix of those solutions, ex.
import Module as M exposing (exposing_fun1,exposing_fun2)
if there is need to move modules to subfolders, module name is preceded with folder path separated with dot (similar to Java packages), ex 
module folder1.folder2.ModuleName exposing (..)
To compile application it is needed only to indicate main module of application.


source: https://elmprogramming.com/

Ports

Elm can be run as separated from surrounding world or can communicate with it. When Elm need to communicate with JavaScript it is required to add port specifier.


1
module MainTable exposing (..)

When communication is from Elm to JavaScrit it is required only defining port function in Elm and callback function in JavaScript.


1
2
3
4
5
6
7
--- ELM ---
port sendData : String -> Cmd msg

-- JavaScript  ----
app.ports.sendData.subscribe(function(data) {
    alert("Data from Elm: " + data);
});

In other way in Elm it is required to define subscriptions parameter in Browser.element, handling port function and in JavaScript code call function.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
--- ELM ---
main =
    Browser.element
        { init = init
        , view = view
        , update = update
        , subscriptions = subscriptions
        }

subscriptions e =
    receiveData changeRowValue

port receiveData : (Int -> msg) -> Sub msg


-- JavaScript  ----
function jsEvent(idx){
  app.ports.receiveData.send(idx);
}

Application Entry Point

Similar to other languages, "main" function is defined as entry point to application. If compilation is run with other output than /dev/null, error is thrown.

6. Test

At the beginning it is required to install elm-test
npm install elm-test
what modifies the file "elm.json".
Test module shares developers a few tools, what are:

  • Test - test definition
  • Expect - set of assertions
  • Fuzz - tool to generate random data and run test for each generated value

7. Sources

[1] - Elm Guide
[2] - Beginning Elm

Sunday, 29 December 2019

This week 3/2019 - WebApp with Spring Security

Yesterday I did small exercise. I upgraded one of my old applications from xml (web.xml) configuration to class version as a first step to later upgrading.
There was no problems until I run application and all world could see everything what only an authorized user should see.

I couldn't find simple example which I could I adopt to my needs so I decided to describe this by my self.

Some examples proposed to extend AbstractSecurityWebApplicationInitializer, other proposed to import just import security configuration but it wasn't work as I expected. I created servlet initializer as below.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class StockDispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

  @Override
  protected Class<?>[] getRootConfigClasses() {
    return new Class<?>[]{MySecurityConfig.class, MyRootConfig.class};
  }

  @Override
  protected Class<?>[] getServletConfigClasses() {
    return new Class<?>[]{MyServletConfig.class};
  }

  @Override
  protected String[] getServletMappings() {
    return new String[]{"/"};
  }

  protected Filter[] getServletFilters() {
    return new Filter[]{new DelegatingFilterProxy("springSecurityFilterChain")};
  }

}


MySecurityConfig I extended with WebSecurityConfigurerAdapter and implemented configure method as below:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
@EnableWebSecurity
@Configuration
@ComponentScan("org.my")
public class SecurityConfig extends WebSecurityConfigurerAdapter {

  private final MyLogoutSuccessHandler myLogoutSuccessHandler;
  private final MyAuthenticationProviderImpl myAuthenticationProvider;

  public SecurityConfig(final MyLogoutSuccessHandler myLogoutSuccessHandler,
                        final MyAuthenticationProviderImpl myAuthenticationProvider) {
    this.myLogoutSuccessHandler = myLogoutSuccessHandler;
    this.myAuthenticationProvider = myAuthenticationProvider;
  }


  @Autowired
  public void configureGlobal(final AuthenticationManagerBuilder auth) throws Exception {
    auth.authenticationProvider(myAuthenticationProvider);
  }

  @Override
  public void configure(final WebSecurity web) {
    web.ignoring()
       .antMatchers("/css/**")
       .antMatchers("/img/**");
  }


  @Override
  protected void configure(final HttpSecurity http) throws Exception {
    formLogin(http);
    logout(http);
    headers(http);
    authorizeRequests(http);
    sessionManagement(http);
  }
.......
}


MyServletConfig looks like


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
@EnableWebMvc
@Configuration
@ComponentScan({"org.**.mvc"})
public class StockServletConfig implements WebMvcConfigurer {

  @Override
  public void addResourceHandlers(final ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/img/**").addResourceLocations("/img/");
    registry.addResourceHandler("/css/**").addResourceLocations("/css/");
  }

  @Bean
  ViewResolver viewResolver() {
    return new InternalResourceViewResolver("/WEB-INF/jsp/", ".jsp");
  }

  @Bean
  PropertiesFactoryBean propertiesFactoryBean() {
    final PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
    propertiesFactoryBean.setLocation(new ClassPathResource("version.properties"));
    return propertiesFactoryBean;
  }

  @Bean
  ObjectMapper customObjectMapper() {
    return new CustomObjectMapper();
  }

  @Bean
  LocaleResolver localeResolver() {
    final SessionLocaleResolver sessionLocaleResolver = new SessionLocaleResolver();
    sessionLocaleResolver.setDefaultLocale(ENGLISH);
    return sessionLocaleResolver;
  }

  @Bean
  public LocaleChangeInterceptor localeChangeInterceptor() {
    final LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
    localeChangeInterceptor.setParamName("lang");
    return localeChangeInterceptor;
  }

  @Override
  public void addInterceptors(final InterceptorRegistry registry) {
    registry.addInterceptor(localeChangeInterceptor());
  }

  @Override
  public void configureMessageConverters(final List<HttpMessageConverter<?>> messageConverters) {
    messageConverters.add(new MappingJackson2HttpMessageConverter(customObjectMapper()));
  }
}


Now I am analysing MyServletConfig and it is possible to do it other way - by adding some specific interceptor. Nevertheless current solution works:)

Any other better ideas ???

--
I used in example Spring/Spring Security 5.2.1 and Apache Tomcat 8.5.50

Wednesday, 25 December 2019

This week 2/2019 - Spring Integration


This is my first meet with Spring Integration. I started with version 4.3 so I will not mention of older version which I don't know.
For whom who don't know what is it Spring Integration. In a nutshell, this is a framework to create flows between betweens input adapters and endpoints.

In a short story I describe what I'd like to reach.

I've got some configuration in XML version which is included in to class version of configuration. I have as well test context (class version) which override some beens - adapters from/to external world). I'd like to translate this XML to have:
  • consistent configuration in production and test code,
  • to be able override production configuration of some adapters (ex. file adapters)
  • to use inline transformations (not included in example).
Below I added a sample of configuration for class version and commented out a equivalent XML code.



  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
@Configuration
//@ImportResource("/spring-int.xml")
@EnableIntegration
public class IntConfig {


//    <int:channel id="inChannel"/>

//    <int:transformer input-channel="inChannel"
//                     output-channel="srcEmailChannel"
//                     ref="inTransformer"/>
//    <bean id="inTransformer" class="PublisherTransformer"/>
//

    @Bean
    @Transformer(inputChannel = "inChannel", outputChannel = "srcEmailChannel")
    PublisherTransformer inTransformer() {
        return new PublisherTransformer();
    }

//    <int:channel id="srcEmailChannel">
//        <int:interceptors>
//            <int:wire-tap channel="backup"></int:wire-tap>
//        </int:interceptors>
//    </int:channel>


    @Bean
    public MessageChannel backup() {
        return new DirectChannel();
    }

    @Bean
    public MessageChannel srcEmailChannel() {
        final DirectChannel directChannel = new DirectChannel();
        directChannel.addInterceptor(new WireTap(backup()));
        return directChannel;
    }


//    <int:router input-channel="backup" expression="headers.country">
//        <int:mapping value="PL" channel="plChannel"/>
//        <int:mapping value="EN" channel="enChannel"/>
//    </int:router>

    @Bean
    @Router(inputChannel = "backup")
    public AbstractMessageRouter backupRouter() {
        HeaderValueRouter router = new HeaderValueRouter("country");
        router.setChannelMapping("PL", "plChannel");
        router.setChannelMapping("EN", "enChannel");
        return router;
    }


//    <int:channel id="plChannel"/>
//    <int-file:outbound-channel-adapter id="plChannelOutFile"
//                                       directory="/tmp/plChannel/"
//                                       channel="plChannel"
//                                       mode="APPEND"
//                                       charset="UTF-8"/>

    @Bean
    @ServiceActivator(inputChannel = "plChannel")
    MessageHandler plChannelOutFile() {
        final FileWritingMessageHandler fileWritingMessageHandler = 
                new FileWritingMessageHandler(new File("/tmp/plChannel/"));
        fileWritingMessageHandler.setCharset(UTF_8);
        fileWritingMessageHandler.setFileExistsMode(APPEND);
        fileWritingMessageHandler.setExpectReply(false);
        return fileWritingMessageHandler;
    }

//    <int:channel id="enChannel"/>
//    <int-file:outbound-channel-adapter  id="enChannelOutFile"
//                                        directory="/tmp/enChannel/"
//                                        channel="enChannel"
//                                        mode="APPEND"
//                                        filename-generator="fileGenerator"
//                                        charset="UTF-8"/>
//    <bean id="fileGenerator" class="FileNameGen"/>

    @Bean
    @ServiceActivator(inputChannel = "enChannel")
    MessageHandler enChannelOutFile() {
        final FileWritingMessageHandler fileWritingMessageHandler = 
                new FileWritingMessageHandler(new File("/tmp/enChannel/"));
        fileWritingMessageHandler.setCharset(UTF_8);
        fileWritingMessageHandler.setFileExistsMode(APPEND);
        fileWritingMessageHandler.setExpectReply(false); // I don't need return
        fileWritingMessageHandler.setFileNameGenerator(new FileNameGen());
        return fileWritingMessageHandler;
    }


//    <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl"/>
      // this not complete mail server configutation
      @Bean
      MailSender mailSender() {       
          return new JavaMailSenderImpl();
      }
//
//
//    <int-mail:outbound-channel-adapter channel="srcEmailChannel" mail-sender="mailSender"/>
    @Bean
    @ServiceActivator(inputChannel = "srcEmailChannel")
    MessageHandler messageHandler(MailSender mailSender) {
       return new MailSendingMessageHandler(mailSender);
    }
    @Bean
    PublisherService publisherService() {
        return new PublisherService();
    }
}

As you can see all of used channels must be defined manualy in XML version. In class version I defined only those which I'd like add some additional behaviour.

Is it true that in Java we can't change Spring Integration configuration with simple editor an restart applicaton - we need compile this configuration but we have plenty of possibilities to do.

Starting from version 5.0 there is additional implementation supporting mixed configuration in test, ex.
  • @SpringIntegrationTest
  • MockIntegrationContext
However this works in other way than overrding bean definition as I did it. This stops current MessageHandler lifecycle and replace condext with mocked bean.

In version 5 it was added as well DSL to make configuration more readable. More information in [1]


Sunday, 13 January 2019

This week 1/2019 - STM32 microcontroller

Today I'd like to write about my first experiences with STMicroelectronic. My set is Nucleo board with STM32F466RE chipset - 160Mhz with 512k flesh memory.
I started from looking for articles and YouTube tutorials about hardware platrorm. I didn't know difference between Raspberry PI and Andurino. I found a few interesting [in resources] and then I decided to buy STM32 hardware platform with at least 256kB flash memory.
Next step was to choose IDE. I'd like to use IntelliJ because daily I work in this IDE, unfortunately JetBrains has other tool with separate licence and not so popular as other IDEs. Finally I chosen Atollic TrueSTUDIO for STM32 9.2.0 especially it is supported by tool STM32Cube MX.
STM32Cube MX is a tool to generate project for selected IDE with C code initializing selected by developer modules and ports of STM32 processor.
To create and load first program on microchip we need to install compiler. I am using Linux system that's why I executed commands:
sudo apt-get install gcc-arm-none-eabi
sudo apt-get install binutils-arm-linux-gnueabi
sudo apt-get install libnewlib-arm-none-eabi
My hardware platform has integrated ST-link and storage where I can copy my binary file and load it automatically on my STM microchip. No additional tool needed.
At the beginning I used external libraries libopencm3 [5] with examples. However there is no tool to generate initializing methods like STM32Cube MX what it is useful at the beginning.
I watched presentation [10] and I was inspired to create code in C++. Bartosz convincing that C++ takes similar resources. In come cases is even much better then code from C compiler.


Till now I created following projects basing on examples:
  1. Change GPIO port state. Both sources of code have example of blinking LED. I used my own external LED to blink.
  2. Read GPIO port state. We can read state of each pin. For pin 1 it will be value 0 or 1, for pin 2 value 0 or 2 and so on. I closed selected pin with 3.3V source.
  3. Communicate via serial port USART. I get connected using ST-link integrated with nucleo board and by external ST-link module.
  4. Read system time. This operation looks different than in OS Linux system. We need to open timer module of chip and then we can read counter.
  5. Ethernet connection. I have Ethernet module with chip ENC28J60. I connected it to SPI connectors however I couldn't run it. :( After spend some time I found correct example and adopted it in my project [8]. It works fine. However I don't know why one request is processed 4 times. Maybe clock of buffer reader is too fast. I must check it.
  6. DAC - set voltage on output an modulate speaker.
  7. ADC - read voltage on input in range 0-3,3V.
  8. Store and read data from flash memory [9]. I have to change memory mapper file.


Resources:
  1. How to start
  2. STM32 tutorial
  3. List of useful links
  4. STM32 HAL layer - documentation
  5. Alternative library with examples - libopencm3
  6. STM32Cube MX tutorial
  7. Setting STM32 clock speed
  8. Ethernet module - ENC28J60
  9. Read/store data in memory
  10. Bartosz Szurgot - C++ vs C the embedded perspective 



Monday, 23 April 2018

This week 2/2018 - JavaFX

Long time I was looking for some solution to create simple desktop application. My previous choice was SWT and JFace but I was not satisfied because of its OS dependence and different presentation depending of OS. There were some other problems with windows resizing and tree view updating.
This time when I developed something for desktop, I was looking for something what is supported by all most famous IDE and is OS independent.

I've tried JavaFX and I think it was good choice. Even a few small problems which I list in the end of article.

JavaFX  it has to be successor of Swing library. It was initialized in the end of 2008 as external library. It was included to JDK only since JDK7 update 6. Since JDK8 is a standard part of JDK/JRE and uses the same version numbering. Most common Java IDEs include scene builder GUI. The output of this tool is a fxml file which is more less an equivalent of programmatic scene creation and is updated when fxml is updated. My experience with this GUI in IntelliJ on Linux was not ideal because sometimes of rendering problems but it is helpful tool for beginner and to arrange elements on scene.

The JavaFX thread needs to be run from class extending Application class. Then creation of stage, scene have to be in JavaFX thread. The same is with every action which changes view. To make change from other thread it is required to call async method:
Platform.runLater(Runnable runnable);

Stage (representing a window) and its elements (scene nodes) can be loaded from fxml file and coded in Java as well. Fxml file is a xml file loaded during stage building.
JavaFX allows defining css styles of formulas which can be used in fxml file and java code as well.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.Spinner?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.TreeView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.Pane?>
<AnchorPane prefHeight="400.0" prefWidth="380.0" xmlns="http://javafx.com/javafx/8.0.121" xmlns:fx="http://javafx.com/fxml/1"
            fx:controller="example.TaskListController">
    <children>
        <TreeView fx:id="taskTree" layoutX="6.0" prefHeight="334.0" prefWidth="374.0" AnchorPane.bottomAnchor="65.0"
                  AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="5.0"/>
        <Pane layoutY="338.0" prefHeight="65.0" prefWidth="470.0" AnchorPane.bottomAnchor="0.0">
            <children>
                 <TextField fx:id="taskNameInput" layoutX="70.0" layoutY="1.0" prefHeight="26.0" prefWidth="392.0"
   style="-fx-padding: 0px; -fx-border-insets: 0px; -fx-background-insets: 0px; -fx-control-inner-background:#BBB; -fx-font-size: 10px;"/>
                <CheckBox fx:id="autoClose" selected="true" layoutX="7.0" layoutY="35.0" mnemonicParsing="false" text="auto close"/>
                <Button fx:id="updateButton" layoutX="294.0" layoutY="31.0" mnemonicParsing="false" onAction="#onTaskUpdate" text="update"/>
                <Spinner fx:id="positionSpinner" amountToStepBy="1" max="1000" min="0" prefHeight="26.0"  prefWidth="104.0"/>
                <CheckBox fx:id="moveCheck" layoutX="205.0" layoutY="35.0" mnemonicParsing="false" text="move" onAction="#onMove"/>
            </children>
        </Pane>
    </children>
</AnchorPane>

I don't remember how it was in Swing but JavaFX on every user action creates an event. This is handled by hierarchy of registered by programmer event handlers. Each event has source of event, target and type. Some events can be triggered by other event, ex they change state of observed element.

Another problem was, how to test it? Hopefully there is a TestFX. It resemble a little Selenium - it is possible to find element by xpath query and execute some action. I did only a few such tests and I know that this tool has some problems with dual-screens on linux. I have to turn off one monitor to resolve problem.


Below a few problems which I met:
1. I could set only one icon for all stages.
2. CheckboxTreeItem - chain of calls, I don't know who triggered event (user/previous element in chain)
3. On linux I can't play mp3. I found out that I must install some libraries and after that it doesn't work as well.



Sunday, 28 January 2018

This week 1/2018 - IntelliJ plugin

Hi Fellows,
this time I started year from creating a tool to automate my work. I always meet with problem of creating builder, mappers and some test data filling dto/vo for test purpose.
At the beginning I started from some simple examples of such plug-ins. Then I was looking for tutorial "how to start", what is concept and what are main interfaces, files, classes required to create plug-in. Unfortunately I didn't find any good for me tutorial with diagrams and main steps. Finally I had to experiment and iteratively find the solution. Now I know the main steps and I described them below in nutshell.


1. IntelliJ project - it is easy to create new plugin project, isn't it ?

2. Plug-in information stored in path META-INF/plugin.xml.



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<idea-plugin>
    <id>example</id>
    <name>Builder plugin</name>
    <version>1.0</version>
    <actions>
        <action id="builderCreator" class="intellij.BuilderAction" text="Builder creator">
            <add-to-group group-id="GenerateGroup" anchor="last"/>
        </action>
    </actions>
</idea-plugin>

The most important part is to define action, where class is extension of AnAction abstract class.


2. Dependencies - we need at least a IntelliJ IDEA SDK - define it in project structure.

3. Class hierarchy - as I wrote above, in my case the main class of plugin is AnAction. Because of error connected with startTransaction problem I found some example where was used other class BaseCodeInsightAction. As I checked its parent class overwrite startInTransaction method. Anyway this extension add a few other function. I'd like to have list of classes with sublists of class fields. This works fine with MemberChooser class.
Panels and other elements are good know from Swing and AWT.

4. Artefacts - to create module jar, you just need to execute Build -> Prepare All Plugins Modules For Deployment.

5. Import project  - when I'd like to import my sources to new IntelliJ project I had  to in a hacky way change my project iml file. Type of module from JAVA

<module type="JAVA_MODULE" version="4">

to PLUGIN

<module type="PLUGIN_MODULE" version="4">

and check path to my plugin.xml

Project Structure -> Modules -> Plugin Deployment -> Path to META-INF/plugin.xml
 
I didn't make this project as maven project. I had some problems with maven dependencies and I didn't spend much time to resolve it.