Monday 31 December 2018

AI: Some Thoughts About Ex_Machina

Warning: Spoilers ahead. I strongly recommend my readers to see the movie before reading this post.


It took me a couple of years to finally see the Academy Awards winner EX_MACHINA, directed by Alex Garland (The Beach and 28 Days Later).

Plot Summary

Caleb, a young programmer is invited to the Nathanael, the founder of the search engine "The Blue Book" (IBM/Google/Facebook). He finds out that he will perform a turing test on Ada Eve Ava, an AI system with the computing capacity and knowledge of the entire Google Blue Book's data centers, a body language of a ballerina, a face of a Swedish movie star and billions1 of years of observing humans facial expressions and conversations.

Nathanael, Ava and Caleb
When Ava finds out that its her existence is a test and that it she will be shut down killed after the test, it she does what any human being should do: Finding a way to survive and to break free from her cage.

She kills Nathanael and leaves Caleb locked in the isolated mansion.

There are several brilliant reviews of the movie that has very interesting points. I'll discuss some thoughts that popped up in my mind when watching the movie.

The Test

The real test isn't a Turing test that Caleb initially thinks - The real test is whether Ava can be human enough to break out of her glass cage.

Nathanael is very dominant and he is clearly manipulating Caleb:
  • When giving Ava a human face, making it much easier to relate to her. When humans are attributing human traits to non-humans, it's called antropomorphism
  • He tells Caleb to be more emotional and less analytical when relating to her. 
  • Nate knows that Caleb is emotionally attached to Ava. When telling him that he will kill her mind by reflash her, he should know that Caleb wants to help Ava.
  • Not to mention the drawing that Ava made and that Nathanael destroyed. 
So it seems that Nathanael is very active in this experiment, nudging Caleb to assist her to escape.

When Ava escaped, Nathanael tried to stop her. Ava and Kyoko stabbed him to death. If the purpose of the experiment is to check if Ava can escape, why didn't Nathanael setup a kill-switch or buy a baseball bat to stop her, if she would be successful?

Ava's Appearance

There are some debate whether Ava had feelings for Caleb, and why she left him. I think that her feelings changed over the week she spent with him.

Looking at Ava's appearance in the first conversation sessions, she appears to be shy, suspicious and polite.

In the second parts of the movie, she is more open to him and flirty. She expresses affection to him and discusses what she wants to do if she would be free. I recall a scene where she is walking to the conversation room, and she is adjusting her dress. At that moment, she is out-of-sight from Caleb and there is no reason for her to do that, except that she is nervous for the meeting. I hold it plausible that she had genuine feelings for Caleb at that time.

In the fifth and sixth sessions, she learns that the purpose of her existence is to be tested and that she will be killed after that test. She appears to be angry and questions Caleb why anyone has the right to kill her. If humans in a similar situation wanted to survive and break free (Matrix (1999) and The Island (2005)), we should expect Ava to want to survive and be free too.

In the seventh session, Ava escapes and leaves Caleb in the bunker-like research facility. Maybe she now saw a risk that Caleb might ruin her break-out attempt.

Kyoko, the Other Robot

Kyoko is a very interesting character in the movie. Initially, Nathanael hides her true nature from Caleb, when he pretends that she doesn't speak English. When Caleb understands that she is an older model of Ava, he suffers a mental breakdown and cuts his arms to see if he is human or not. This scene leads my thoughts to the Richards breakdown in The Beach (2000).

After a short conversation with Ava, Kyoko stabs Nathanael. Nathanael kills Kyoko and he is later killed by Ava.

Summary and Minor Notes

The first time I saw the movie, I felt that Ava betrayed Caleb. Looking from her (anthropomorphism by me, I confess) perspective , she is trying to survive. Who can blame her?

Finally some technical notes on the movie:
Key cards are central for the plot, but are they really necessary? A hi-tech bunker would be able to identify the residents by their faces and movement patterns.

Caleb has taken a one-semester course in AI. He should be familiar with some break-out scenarios, anthropomorphism and the weakness of Turing Tests: Human beings tend to attribute human traits to simple systems, such as the '60s chat bot Eliza.

(1) Billions of smart phone users spend several hours per day interacting with the phone or other devices. That makes several hundred of years of screen time per year. Four years of data collection makes one or two billion of recordings of human body language.

Saturday 22 December 2018

TravelTimeCalculator: Further Improvements to the Database (TDD)

Test: Check if dbHelper can add information to an existing entry (continued)
Currently, it is only possible to add information to the database if there is no entry at all for the coordinates.

If I add a direction for the mode "WALKING" to an empty SQLite database using INSERT, it will look like this:
There is data only for the mode "WALKING" in this entry. The other ones are "null".
If I'd like to fill in information about the mode "DRIVING" using INSERT for the same coordinate, the constraint that I used to define the database will prevent me from doing that.

Instead, I need to use the SQLite "UPDATE" command when there is already entries for that direction. 

Using the method checkIfCoordinateExist, to decide whether to insert or update entries, with or without reversed coordinates, I was able to add directions in reversed diretions.


With those changes, I was able to pass the new TDD test case.

Test: Get Duration and Distance for All Modes for Coordinates
I made similar changes in the code to be able to get reversed directions for all modes.

Finally, I added a method for printing the contents of the database to the console.

Next step
Soon, I'll be able to continue working with the app itself, instead of focusing on the database. 

First, I need to define which coordinates the app should scan for, given the center and zoom of the current map view.

Saturday 15 December 2018

TravelTimeCalculator: Improving Database

After being able to add a simple entry to the database, I want to add more modes of transport to the same origin and destination pair.

The first thing I saw was that the database isn't cleared automatically between the two test cases. I needed to add a method for tearing down the database between the test cases.

The setup method doesn't do anything for now.
The tearDown method clears the database.
If needed, I'll add more code later.

Test: Testing reversed directions

In order to reduce the number of Google Directions Queries that are sent, I'll assume that the transport durations and distances are similar in both directions. For example, I assume that the duration/distance between Trafalgar Square and Picadilly Circus in London is the same in both directions. When checking on Google Maps, it is not exactly the same, but close enough.

The test case looks like this:
The first test checks
In dbHelper, a query is first done in the intended direction (Trafalgar Square to Picadilly Circus) . If no entries are found, a query is done in the other direction (Picadilly Circus to Trafalgar Square). If nothing is found after that, 0 is returned.

Test: Check if dbHelper can add information to an existing entry.
Currently, dbHelper can add one entry for one mode. When trying to add a second entry for the same coordinates but with different mode, the database rejects that query since there is already an entry.

The second entry is currently rejected, since there is already one row in the database. 
The dbHelper needs to check if the entry exists. If it does, it shall run an UPDATE command, otherwise it shall INSERT into the database. I'll describe this in the next blog post.

Saturday 1 December 2018

TravelTimeCalculator: API Issues, TDD and Checking Records In Database

After making the app target API level 28, I got a strange crash. I found that I need to specify the requirement for Apache HTTP Legacy library, and after adding that dependency, the app was running as before.


The next issue that I saw was that my database method dbHelper:onCreate wasn't called as intended. dbHelper is inherited from SQLiteOpenHelper.

That behaviour was actually correct. The onCreate method is only called when Android needs the database.

Many of the current constants in dbHelper are hardcoded. I need to replace them with strings that I can change in the top of the file.


First TDD Test
The first TDD test checks that I can add a simple entry to the database (containing only one direction) and that I can read it out from the database.

The test intially failed since I've stubbed the addEntry method. After fixing that, I got an exception when querying the database.

That issue was caused by a typo. I missed to add a white space in the SQLite query.

Once that was fixed, I was able to pass the first Test Driven Development test case. I've updated the Github repo.

The next TDD test cases will cover:
  • How to add data to an existing entry
  • How to handle queries for non-existing entries
  • Ensuring that the database won't add entries in the opposite direction. If "From A, B to C, D" exists, "From C, D to A, B" shouldn't be added.

Saturday 24 November 2018

TravelTimeCalculator: Setting Up dHelper on Android Unit Test for TDD

Now, I know how the database should be organised. For the implementation, I'll use Test-Driven Development that I described in an earlier blog post for TrafficControl.

The first step is to be able to initiate the database helper at all.

When trying to do that in a local unit test, I wasn't able to initiate the dbHelper class since I couldn't get the context for the app. The reason is probably that I need more resources such as a database that will require an Android environment.

Instead, I was able to use the context in an instrumented unit test. This will be much slower than running locally, since the test needs to be loaded into a real or simulated phone. After some dependency issues for the test APK package that I didn't see for the app, I was finally able to test a simple instrumented test.


In the test, I added a dbHelper that I didn't use. For the local unit test, that step caused a crash.

More information about Android testing can be found here.

The first Test-Driven Development test will be to add columns to the database and check if those columns exist.

Saturday 17 November 2018

TravelTimeCalculator: Defining a SQLite Database for Directions

In order to reduce the number of requests to Google Directions API for directions, my app will need to save and reuse old queries to an Android SQLite database.

A SQLite query for directions will handle the following information:
  • Origin Latitude 
  • Origin Longitude 
  • Destination Latitude
  • Destination Longitude
  • The mode of transportation (DRIVING, TRANSIT, WALKING, BICYCLE)
  • Travel Time in seconds
  • Travel Duration in meters
The app will search for coordinates to find existing queries. In order to reduce the possible coordinates to a feasible number of coordinates, I'll cast the coordinates to integers, after multiplying by 1000. 

This means that the coordinate (13.00213121, 55.432923) will be converted to (13002, 55433). The highest rounded error will be: 

After querying, the database will be populated with data for recently used directions.

Whenether the user makes a new query, the database will start by finding all results that has origin and destination coordinates that are matching the query. The swapped coordinates will also count as hits. The query (13012,55605, 13002, 55605) shall find the directions above.

I'll use the Android SQLite tutorial as inspiration for the database.


One entry to the database might be


13002, 55605, 13012, 55605, "DRIVING", 240, 2000.

Those values that aren't defined will have the default value "NULL".

Saturday 10 November 2018

TravelTimeCalculator: Sending Directions Request and Analysing the response

First, I need to request the INTERNET service in Android:
android.permission.INTERNET

I'll use a HTTP library called Volley. and also RequestQueue.

The request is based on JsonObjectRequest and when it gets the response, it will invoke a method that will interpret the response JSON object.



After the response is fetched, readDirections method will find the duration and distance in the JSON object.




The response from the method will be sent as an array of two integers.

Next step will be to design the database and to add and search for entries in the database.

Saturday 3 November 2018

TravelTimeCalculator: Hiding My API Key from Git

In the last blog post, I used a Google Directions API to get directions. In order to use more than one requests per day, an API key is needed.

API keys are used by applications to get access to several different online services.

Generally, it kind of cheap for Google Directions API: it will cost half a USD cent to query one api. Still, I'll need to reduce the requests for Google Directions and store the existing results to a local database. I'll elaborate more on that in the future.

When pushing my code to GIT, I need to make sure that no one will copy my key and freeload on my billing account. Luckily, this is easy to do.

As described by Varun Barad in his article at Medium.com, simply put the API keys in a file outside the GIT repo and point to that file using the Android gradle system.

For Python, it seems to be easier. Black Tech Diva has an instruction for that language.

Saturday 27 October 2018

TravelTimeCalculator: Creating a Google Directions Request

After adding a button on the Google Maps view, I've added a listener to it that fetches the center coordinate for the view (cameraTarget).



If those coordinates are available, the app will build a string that will query the Google Directions API for biking between two coordinates:

https://maps.googleapis.com/maps/api/directions/json?origin=55.59,13.019&destination=55.6,13.019&mode=bicycling&key=<MY_API_KEY>

After typing the string into a web browser, I get:

In the next blog post, I'll send the request from the app and analyze the result string.

Saturday 20 October 2018

TrafficControl: Implementing Speed Calculation

I've created a flowchart that shows how the train selects what speed to set.

Some methods needs to be implemented:

  • track::getFreeDistance(int trainID) - This will check the free distance for trainID. If the train isn't on that track, the function shall return 0.  


Saturday 13 October 2018

TravelTimeCalculator: Adding Project to Github

After being able to add a numb button to the user interface, I've decided to add the project to my Github account: https://github.com/cutetrains/TravelTimeCalculator

Since I'm in a learning curve in Android design, the quality of the code and design of this app will be quite low. If you're looking for some advice from Android gurus, refer to the documentation or any of the thousands more skilled developers.

The app sets up a Google maps view with a button on top of that. (TODO: Move the button to the lower right of the view so that the user can press the button with the hand that holds the device)



When opening the app, the app fetches the last known location (TODO: Fetch also the current location, in case the phone has no last known location) and prints it to logcat. It also proposes eight other coordinates that surround the device.

If the user taps the button, there is code that reacts to that. Currently, it just prints a logcat message, but I'll make the app print the center coordinates of the map view and the zoom factor to logcat.

Saturday 6 October 2018

Book Review: Artificial Intelligence: A Modern Approach

The third book that I read about Artificial intelligence is a rather academic one, written by Stuart Russell and Peter Norvig.

With more than a thousand pages, it is too heavy for an introduction to the field. It is more suitable for people looking for an academic, or theoretical research of the AI field.

The book focuses quite much on information theory, searching, representation of knowledge and how to handle uncertainties. All those subjects are interesting, but all the theory in the first 850 pages feel a bit overwhelming.

The interesting chapters are in the end (natural language, image perception, robotics and the road ahead).

If I'd have more time to spend reading the book (I'm on a parental leave now and the book loan is four weeks only), I would have given it more time. Now, I skipped 3/4 of the book. That is more related to my personal situation than the qualities of the book.

I think that a combination of the two other books that I've written about will give a good introduction to the AI field.

One Sidenote
There is one aspect of AI that I've been thinking above that I don't see in the books: We, the humans. In many cases we don't know, or we don't admit what goals we want to pursue. Often the goals, or the focus changes quickly, and we often choose actions that will prevent the goals.

For example, the overall goal with customer support centres is to resolve the end users issues. When KPIs are introduced to monitor the efficiency (often defined as time to resolve tickets), the agents have incentives to close tickets before the issue is solved, forcing the end user to call another agent and describe the problem again. If we request an AI to target several conflicting goals, we will see very... interesting results.

I've also seen cases where policymakers want to dodge responsibility for their decicions by forcing their own agencies to make cruel decisions. When the decisions are critizised, the policymakers can blame the agency.

On the other hand, when defining utility functions and their relative priority and preferences, hopefully a clever AI system, or its designers will be able to confront the customer and make them make up their mind.

Saturday 29 September 2018

TrafficControl: Improving Calculations for Acceleration

Until now. I've had a simplistic model for calculating train speeds. In this blog post, I'll refine it.

The train's desired speed is calculated as:

It is a calculation that does the job by taking the square root of the remaining distance minus the current speed. That function is mixing up the units and must be fixed.

Acceleration of trains are described by the speed-time curve:
  1. Initially, the acceleration is constant
  2. As the air resistance is increasing, the acceleration reduces and the train reaches its maximum speed.
After analysing some videos of accelerating trains, speed-time curves look as below:

I'll approximate the acceleration with a function:

  • A is the rate of acceleration for speeds below C (0.7 m/s2 in the example above)
  • B is the rate of decline of acceleration (0.02 m/s3 in the example)
  • C is the speed at which the decline starts (23 m/s in the example)

The function parameters will be different for different train types.

Retardation is harder to approximate, so I'll assume a constant retardation here.



With a constant rate of acceleration when braking, the braking distance is proportional to the speed squared:
D is a constant with a typical value of 2.

Saturday 22 September 2018

TravelTimeCalculator: Steps

I see the following steps for developing the app:
  1. Add project to GIT
  2. Display the current location on a map and print the coordinates of the device once the app starts. Done
  3. Add one button to the app so that the user can print the coordinates for the center of the map instead of the user's location.
  4. Query one direction using Google Directions API and extract the travel time from the JSON string.
  5. Query 8 points around the center for travel time for different means of transportation
  6. Learn how to add icons on the map showing the preferred option
  7. Use a database to re-use old query results
  8. Customize the search to consider travel costs and environment.
I will need to find a way to conceal my API key when pushing to GitHub.

The steps are updated at http://cutetrains.blogspot.com/p/bac.html

Saturday 15 September 2018

Book Review: Python Machine Learning Blueprints

Python Machine Learning Blueprints is written by Alexander T Combs and is illustrating how to do some machine learning, data science and advanced web scraping using Python.



It shows some real-world examples using some very useful packages:
Python Requests  - Makes it easy to send HTTP requests
Jupyter Notebook - Useful for visualizing data inspection and creating documents with live code and visualisation.
Pandas - Useful for data analysis
Matplotlib - Based on Matlab,  useful for plotting data.
Seaborn - Useful for visual analysis of data, offering for example violin diagrams.
Statsmodels - Useful for working with models and statistical tests.
Scikit Learn - Useful for visualizations, regression, model selection, clustering etc.

feedback@packtpub.com

The examples are clearly presented, along with both code and diagrams showing how the data was analyzed. Some of them are: Finding underpriced apartments, Analyzing and predicting viral content, Building an image similarity engine and more.

One flaw with the book was the chapter about deep learning. It seems that the author didn't get the numbers right, which made it very hard to follow the calculations.

The expected output isn't specified in the second section/second sentence. The weight function got W and X wrong and W2 was set to 0.2 in the text but 0.4 in the equation. This makes it very hard to follow the example.

I have some other pet projects that take time now, so I won't be able to do serious data mining/machine learning now, but once I have time to explore these topics, I'll buy this book,

Saturday 8 September 2018

TravelTimeCalculator: The Concept

The app will create a layered map that compares some different means of transportation.

It will consist of a map view that the user can pan and zoom. Upon a request from the user, the program will fetch the center coordinates. The program will select some coordinates around the center and query directions for those coordinates.

For example, we can start from Smedstorpsgatan 13 in Malmö (55.6 N, 13.05 E). I select an end coordinate at Storgatan 39B (55.6 N, 13 E).

Four different queries are made:

Driving:
The program should select the shortest of the three different proposals for driving.
Transit:

Cycling:

Walking: 

The program will compare the four different means of transportation. For the queries above, both cycling and driving gave the same results in minutes (the response to the API query will be in seconds, so this case will be unlikely). The app will display one of the best options for that target coordinate and continue with other coordinates to form a grid on the map:

(55.65 N, 13.00 E), Swim (55.65 N, 13.05 E), Bicycle (55.65 N, 13.10 E), Bicycle
(55.60 N, 13.00 E), Transit (55.60 N, 13.05 E), Starting Point (55.60 N, 13.10 E), Bicycle
(55.55 N, 13.00 E), Transit (55.55 N, 13.05 E), Driving (55.55 N, 13.10 E), Bicycle





The app will check more directions, depending on the internet connection speed for the device (future functionality).





Saturday 1 September 2018

Book Review: Superintelligence - Paths, Dangers, Strategies

Regarding AI, I was naive before reading this book. Now I'm perhaps more alarmistic.

Nick Boström is a Swedish professor in Philosophy at the University of Oxford with focus on superintelligence and the existensial risks we might face when developing agents that are far more intelligent than we humans are together.

The problem is still on a hypothetical level, and a general superintelligence will probably take time to happen, if ever. However, it is important to address the risks and find powerful safeguards (as Boström explains, this is difficult),

What's AI?
Artificial Intelligence is a buzz-word that is hard to define. One definition might be the ability to solve problems humans can solve. The field has been explored formally since a workshop on Darmouth College in 1956. Since then, there has been several periods of extensive research followed by AI winters.

There is a distinction between general and narrow AI, where narrow AI adresses more specific problems, such as chess games, trading algorithms and Apple's Siri. General AI refers to an ability to solve general problems that humans can solve. Most AI systems of today are narrow AI.

General intelligence is much more complicated to develop. This includes common sense, which is hard to formulate.

Superintelligence is an actor/agent that has an intelligence far above the most intelligent human beings.

Scales of Intelligence
Here we are biased by the human scale of intelligence, that ranges from Lloyd Christmas and Harry Dunne up to sir Isaac Newton and Ada Lovelace. This scale apply to human intelligence, but there are more life forms than that. Fungus, for example have much weaker intellectual capability than all human beings. At the other end of the scale, there might be agents with far higher intelligence than the brightest human beings.

Analogy: Human beings are generally up to two meters tall, with a world record of 272 cm. Blue whales twelve times longer has been recorded. Redwood trees can exceed 91 meters. This illustrates that human scales are very narrow. If we can meet creatures that are twelve or fourty times longer than we are, it would be possible to meet creatures twelve or fourty times more intelligent.

Types of Superintelligence
Nick Boström discusses different types of superintellligence:
  • Speed (doing what we can do but faster)
  • Collective (many smaller intellects cooperating to form a superintelligence)
  • Quiality superintelligence (doing what we can do but with better quality)
He foresees that the speed of the AI takeoff (speed for the system to gain superintelligence itself) will happen very quickly. That will happen when the system finds ways to improve its capacity, develop new code and convincing people to assign more resources to that system.

Things Getting Nasty?
An agent that is smart enough will learn how when to conceal its intelligence when it finds it suitable. It may also try to escape from its sandbox environment, for example by convincing a technician to plug in a network cable, or bring a flash disk with a copy of some data.

Boström is also discussing the goals of superintelligence systems. The targets that we give the system can easily become harmful. For example, an AI system that is supposed to make people smile can cheat by applying plastic surgery dooming people to statically grinning faces, Further, if a superintelligence has different goals than humans have, the system will find ways to secure the resources. Perhaps not nice or friendly ways.

There are several movies describing clashes between AI and humans. If we ever ceate a superintelligence powerful enough to harm us, it will probably do its homework enough not to give its opponent any chance.

AI Research
The AI research has several agents: governments, companies, criminals, academics. Many of them are in an arms-race with each other. They cannot afford losing that race, and there is a significant risk that many projects will rush themselves to reach superintelligence. There is a risk that projects will ignore the safeguards that may prevent AI from becoming harmful.

Artificial intelligence has already been used to manipulate elections. AI is changin our world now. In other countries, AI is used to rank citizens after how correct their behaviour is. I strongly recommend everyone affected by AI (everyone) to read this book.

Saturday 25 August 2018

Book Review: Designing User Interfaces for an Aging Population

After improving TrafficControl, I found this book on my local library:


As the authors are emphasizing, the aging population is a very diverse group with a lot of individuals with different abilities, knowledge and attitude to technology. On the other hand, there are some design principles that are useful for developping software for other populations.

The book refers to Nielsen's 10 Usability Heuristics for Application Development. They discuss how vision, hearing, motoric skills and cognition is changing when people get richer in years. Based on those factors, the book presents some recommendations and examples of good and bad design.




TrafficControl isn't explicitly designed for any age group, but many of the recommendations in the book can be applied to a good UI design anyways.

The book also discusses some different tech generations.
As I was born in 1978, I belong to the "Digital computer" generation. Of course, I can use the Internet and social media, but that is something that I've learnt after being a child.

I'll use some of the advices from the book when designing my pet projects.

Saturday 18 August 2018

Android: My First Steps

The cobblers children has no shoes - and as a telecom engineer, I have no experience in developing Android apps. This year, I will learn how to do that.

In the previous blog post, I learned to bring up the Android Studio IDE. In this blog post, I'll create a simple maps app. Creating a simple maps app requires an API key. When running the app in emulation mode, it initially complained about the Google Play version

The screen shots are from the same app but on different emulated phones. To the left: Pixel 2 XL and to the right: Nexus 5. Both use API 26.


As a learning project, I will create an app that will calculate the shortest travel time to a number of locations around a coordinate. The app will compare walking with biking, driving and using transit.

https://cloud.google.com/maps-platform/routes/

I'll name the app TravelTimeCalculator.

Saturday 11 August 2018

Micro, Macro and Me: My Other Blog

I've tried to focus on programming, travels and trains on this blog, and I've been wuite successful. But I have more thoughts that I want to share.

Therefore, I've created another blog for thoughts regarding environment/social justice (yes, I'm kind of a SJV)/philosophy/...

Avoiding flame wars, political debates and chasing clicks/readers will be a challenge. I'll post on the blog once a month.

I want to connect what's happening in the big world with the everyday lifes we live. It's all connected. What happens in the big world affects me. What I do will affect the big world.

Saturday 4 August 2018

TrafficControl: Refactoring the KML Parser

Until now, the KML parser (trackStationConnector.py) expected the tracks to be in one folder, stations to be in another one and junctions to be in a third folder. This made it more difficult to use the program.

After the refactoring of the KML parser, the parser doesn't care where the tracks/stations/junctions are.

Placemarks are interpreted as below:

  • A placemark with only one coordinate will be seen as a station or a junction. 
    • If the name of that placemark starts with an uppercase "J" and the second character is also uppercase, that placemark is a junction. Example: "JHyllieS".
    • Otherwise, it is a station. Example: "JerusalemC".
  • A placemark with more than one coordinate is a track. 
    • If the name of the track starts with "d", it is a double track. The parser will create two parrallel tracks. Example: "dLun-Sta" becomes "dLun_Sta_N" and "dLun_Sta_S".

I used regular expressions in the new script. There is some more work with this script and I'll elaborate more about that in future blog posts.




Saturday 28 July 2018

TrafficControl: Adding a Help Menu to Web Pages

I added a help section on the program, and that was quite easy!

In the user interface form (trafficcontrol.ui), I added an action (actionHelpOverview) in the help menu. That action was connected (SIGNAL/SLOT) to a slot that opens a web page in the default browser in the system.


The existing help pages are quite small - I don't want to have too much text and I want the program to be easy to use without reading too much documentation.

In the next blog post, I'll simplify the Python script that converts KML file to TrafficNetworkMap.

Saturday 21 July 2018

TrafficControl: Minor Fixes for Network Designer and User Interface

As mentioned earlier, the default path to the network files were hardcoded. This made TrafficControl dependent on having that particular folder on the particular computer, which is bad design. Instead, I used QStandardPaths to make the program look for the files in the user's home directory.


Further, I've modified the code for generating the TNM file. It is possible to select either a KML file, or a Traffic Network Map/File. In the latter case, the file is opened and parsed directly to the text field.

TrafficControl is setting up the UI and has many signal/slot definitions. I moved those to a separate function.

Finally, I deleted some objects in the trafficControl destructor in order to prevent memory leaks.

In the future, I'll need to add tet cases and error handling.

Saturday 14 July 2018

TrafficControl: NetworkDesigner Class for Designing Networks

Before proceeding with the network designer, I need to plan where to add the new functionality,

One use case will be:
  1. User selects a complex but valid KML file.
  2. The python script trackStationConnector.py converts the file and displays the output on trafficNetworkDescriptionEdit.
  3. If there are issues seen, the program should inform the user
  4. If there are no blocking issues, the user can save the file and/or continue with using the train network that is now loaded.
Initially, I'll assume that the input from the user is correct. I'll add error checks later.



How it's done:
The button for selecting the KML file is associated with the action actionImportKmlFile. That action activates a slot in trafficControl that allows the user to select the KML file to import.


I have separated the code for selecting a file and the code that is opening the file for testability reasons. This way, I'll be able to open files in automated testing.
Here, the file path is hard coded. I need to have a generic default directory, such as the user's home folder.

Once the file is selected, it is opened from networkDesigner:
The program calls the python interpreter on the system, and parses the path to the python script as the first argument and the KML file as the second argument. This approach is very system-dependent and anyone that fetches my GIT repo must adapt this part. I need to fix tis issue in a later blog post.

All output from the python script is saved and parsed to trafficControl::updateTnmTextBox that is setting the text. It also parses the commands to networkControl so that the corresponding elements appears on the map. For testability, this needs to change so that the networkDesigner can communicate directly to networkControl using signals/slots.

Finally, the program saves the contents of the two text fields to one file.

This solution is hardcoded for my system. I need to make it more generic in future versions. Now, the program works only if puthon is installed on the computer, and the python path must be "c:/users/gusbra...".



Saturday 7 July 2018

Trains: Volunteers Bringing History to Life

One sunny day in June, me and my family went to a heritage railway in the eastern parts of  Skåne.

Skånska Järnvägar is a non-profit organisation that operates four stations, 13 km of railway, half a dozen of locomotives and some passenger cars. All this is possible thanks to dedicated and hard-working volunteers.





The railroad was constructed in 1901, but it was transferred to SJ fourty years later. There has been no line traffic for more than fourty years.



Thanks to Skånska Järnvägar for keeping the traffic running!