Tuesday, September 27, 2016

Lego Mindstorms EV3

A couple of months ago, I purchased Lego Mindstorms EV3 31313. I am very satisfied, it exceeded my expectations. It lets you build and program robots without bothering you with time consuming electrical/electronic details.

When programming it, I noticed that some things that would be very easy with languages like Java or C# take longer with the EV3 programming environment. As an example, I wanted to record the reflected light intensity from the color sensor for 5 seconds and then display the largest value. Below you can see the screen shot of the program. You can download it from my GitHub lego repo.


Thursday, September 01, 2016

Keywords in code comments

When writing comments in my code, I sometimes use HACK, TODO and NOTE keywords to mark that comment as especially important. I can easily search for these keywords to find the comments and review the code.

HACK: Used for sections that are not obvious/easy to understand. Worse, one might misunderstand and try to change the code.
Examples:
/* HACK: Do scrolling back and forth so that active tab will be visible even when the there are multiple tabs and the active tab does not fit pane. This happens after the fourth tab, i.e. the 5th tab is created and selected but is not visible on frame. Worse, the right arrow of tabbed pane is disabled. I only could come up with this hack to solve it. There must be a better solution... */

/* HACK: Analyze stack trace to check if call was due to mouseRelease because we need to ignore the other calls due to mouse press and click to prevent adding the same point twice. */
TODO: Used for remaining work.
Examples:
//TODO: When is this called? I could not get here by closing the window.

//TODO this calculation has to be updated when user changes height.

//TODO: To have correct normals, vertex orders have to be the same. It will show its effect when CULL_ is selected.

//TODO: Add reference.

//TODO: Enable this try-catch when color problem is resolved.

//TODO: Should we also issue an error message?

//TODO This method similar (same?) to the method in Sphere.

//TODO Review this validity check.

//TODO : Due to a bug, it starts from t = 1 second.
NOTE: I add this keyword to sections where in the past I changed the code to a seemingly better form and failed because I did not think about some edge cases. The next time I am tempted to change the code, I read the comment and think twice.
Examples:
//Note: You cannot use showException() here because that would cause recursive calls and lead to stack overflow.

//Note: We cannot load the same dll two times in a row, even after garbage collection. But we can load it after a different one has been loaded.

//Note: In order the use invokeLater here, the whole GUI creation process has to be refactored, i.e. couple of days work.

//NOTE: We had to use JButton instead of JLabel because only JLabel does not gain focus while JButton can.

//Note: mousePressed is more responsive than mouseClicked.

//NOTE: Do not perform lengthy operations (e.g. setting font to bold) inside this paint method because it causes 100% CPU load.

//Note: Math.IEEEremainder(10.04, 10) = 0.03999999999999915

/* NOTE: Due to precision limitation (15 digits after decimal point) of double, Long.MAX_VALUE + 1024.0 is the same as Long.MAX_VALUE. Only after +1025.0 are we able to see a difference. double d = Long.MAX_VALUE results in a double value of 9.223372036854776E18 although Long.MAX_VALUE = 9223372036854775807 = 9.223372036854775807E18. The last three digits (807) are lost due to rounding during double conversion. Same is true for lower bound. */

Saturday, August 13, 2016

What makes software development difficult

The Law of Leaky Abstractions: "...suddenly one day we need to figure out a problem where the abstraction leaked, and it takes 2 weeks."

I don't have time to read the spec of every function before using it, I make assumptions based on the name of the function. This means that I take risks by using something without completely understanding it. The benefit is speedy development. As long as the problems are limited to a couple of things that leak, it is manageable by testing and debugging. But sometimes many of them team up and you have a "bugfestation". Unfortunately, even one simple error can crash and burn the whole system in unpredictable ways.

Example1: I assume that the strlen function in C returns the whole length of the string and use strlen result in malloc. Later I am greeted with system crashes which happen only on some versions of Windows. After months of debugging looking for the bug in unrelated places, I realize that strlen does not return the terminating null character and in malloc you have to do strlen+1.

Example2: I write a script to synchronize my drive to my network backup. Then I realize that some folders were not copied. After analysis I see that xcopy fails with "insufficient memory" error when path+file name is longer than 255 characters, but I don't infer that at first from the error message. A better message would be "file name longer than 255 characters". It would be even better if xcopy didn't have this limitiation in the year 2016!

Example3: I assume NASA code is correct, but that is not always the case.

Example4: I assume MATLAB functions are correct, but that is not always the case. The more depressing fact is that the MATLAB folks will resist your claims, even after you mathematically demonstrate that there is an error.

These issues make self discipline and testing early/often so critical. It's also the reason why 95% of code takes 95% of the time and the remaining 5% take another 95% of the time, because in the last 5%, you realize that libraries you trusted had errors in them. Therefore it is common to be late by at least 2x the planned time.

Bonus: Case of the Unexplained

Friday, August 12, 2016

What do I add to science?

From time to time, during discussions with my fellow engineers, the question of what we add to science comes up. To contribute something new to existing science knowledge is very challenging. If you focus on newness you might feel bad, and it will not help you move forward. My approach is to make sure that I get better at something everyday. That thing might not be new for science, but it will be new for me.

A similar post: Obsession with authenticity

A software training instructor's interesting observation [Hanselminutes podcast 331]: Men do a small thing and feel amazing while women worry about the stuff that is still left.

An example of a small step for mankind but joy for me, my very first Lego Mindstorms EV3 line follower:

Sunday, May 22, 2016

Life as a Game

I like computer games. In the past, I played Starcraft to the point of exhaustion, playing it more than 10 hours at a time for days. The problem with games is that they don't add much to your life. Besides, games are not all fun. Every game I played had a lot of boring repetitive tasks, which resembles real life in that respect.

A good game starts simple and builds up over time whereas in real life I am usually confronted with a large mess. That is what makes games fun and real life a chore. A main reason of procrastination is that I don't know where to start, so I keep postponing it. When I spend some extra time to analyze the problem and divide it into smaller pieces, it becomes manageable, even fun. Writing down what I think helps a lot. And when I solve a problem in real life, I gain skills that I carry with me my whole life, besides having the satisfaction of doing something useful and being able to control my environment.

I still play games (currently Clash of Clans) but I only spend about half an hour a day. I have more fun doing real things (teaching my 4 year old, learning how to make Mousse, developing web apps). I encourage you to view life as a growth opportunity, as a game where every skill you gain unlocks new ones. The key is mentally breaking large chunks of work down into less threatening smaller ones. These small chunks can be dealt with as if they were levels of a larger game.

Inspiration:



Saturday, May 21, 2016

Puana Göre Üniversite Sıralama

İstediğin taban puan aralığını girip üniversitelerin bölümlerini sıralayabileceğin bir web uygulaması oluşturdum, linki şu: http://universite-sorgulama.appspot.com/

Kodu GitHub'a koydum, meraklısı oradan inceleyebilir.

Başkaları tarafından yapılmış daha profesyonel hali: http://universitetercihleri.com/ygs-lys-tercih

Sunday, May 08, 2016

Graphical User Interface Nightmares in Java

Compared to Windows Forms, doing GUI work in Java is painful because you have to deal with a lot more detail. Recently, I was trying to customize tab drawing in JTabbedPane to make the font of the selected tab bold and its background color green. I ended up creating a class (MyTabbedPaneUI) that extends BasicTabbedPaneUI and overrides paintTabBackground().
public class MyFrame extends javax.swing.JFrame {
    public MyFrame() {
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        javax.swing.JTabbedPane jtp = new javax.swing.JTabbedPane();
        getContentPane().add(jtp);
        jtp.setUI(new MyTabbedPaneUI());
        jtp.add("My Tab 1", new javax.swing.JPanel());
        javax.swing.JLabel jl1 = new javax.swing.JLabel(jtp.getTitleAt(0));
        jtp.setTabComponentAt(0, jl1);
        jtp.add("My Tab 2", new javax.swing.JPanel());
        javax.swing.JLabel jl2 = new javax.swing.JLabel(jtp.getTitleAt(1));
        jtp.setTabComponentAt(1, jl2);
    }
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new MyFrame().setVisible(true);
            }
        });
    }
}
public class MyTabbedPaneUI extends javax.swing.plaf.basic.BasicTabbedPaneUI {
    /**
     * NOTE: Do not perform lengthy operations (e.g. setting font to bold) 
     * inside this paint method because it causes high CPU load and has 
     * side effects like not being able to update java3D drawings.
     */    
    @Override
    protected void paintTabBackground(Graphics g, int tabPlacement, 
                       int tabIndex, int x, int y, int w, int h, 
                       boolean isSelected) {
        for (int i = 0; i < tabPane.getTabCount(); i++) {
            Color bgColor = Color.YELLOW;
            javax.swing.JLabel jl = (javax.swing.JLabel) 
                tabPane.getTabComponentAt(i);
            if (jl != null) {
                if (i != tabIndex) {
                    bgColor = Color.GREEN;
                    //jl.setFont(jl.getFont().deriveFont(Font.PLAIN));//BAD
                } else {
                    //jl.setFont(jl.getFont().deriveFont(Font.BOLD));//BAD
                }
            }
            Rectangle rect = rects[i];
            int pad = 2;
            g.setColor(bgColor);
            g.fillRect(rect.x+pad, rect.y+pad, rect.width-2*pad,
                rect.height-2*pad);
        }
    }
}
Setting font to bold (by uncommenting the lines commented as "BAD") in BasicTabbedPaneUI.paintTabBackground causes more than 7x CPU usage:


I have witnessed cases where CPU usage shot up to 100% and my app could not update a java3D drawing on another window. You can imagine that it was not easy to find out why.

Other examples of why Java should be avoided for GUI work:
  • Changing color of a JTable cell is a lot of work.
  • For background color to have any effect, JLabel has to be opaque while JTextArea has to be not opaque (opposite of their defaults)!
  • Due to the unintuitive layout mechanism, what I see on design view is completely different from what I see when I run the application.
  • When I change the layout, sometimes all the components dissappear (their width and height becomes zero).
  • Setting the width/height to "Preferred" sometimes causes the component to shrink to zero size. From what I understand, the layout mechanism is there to ensure proper resizing, i.e. to have a similar look when screen resolutions, font size etc. change. As usual, when trying the solve the most general case, you make it more difficult to solve simple cases. 
My layout strategy:
  • Create a frame
  • Add a panel with null layout.
  • Add subpanels to group components
  • Set the layout of subpanels. The layouts I use most often:
    • null
      • Advantage: You can set the location and size of components.
      • Disadvantage: If your form is resizable, components won't resize.
    • GridLayout;
    • BoxLayout