I made an App

I have made several Android apps but never really finished them. Recently, I have been playing with Phonegap/Cordova. These tools let you write your app in html and javascript, and then compile for different platforms such as Android or iOS.

Also lately I have been trying to meditate everyday but it is hard to find time for it. Of course, you don’t need anything for meditation but a timer is nice. At first, I was using an hourglass, my goal with timer is to meditate at least long enough for timer to go off. Problem with hourglass was I would keep opening my eye to see if I meditate enough or not.

So I looked for meditation apps, and there are thousands of them. Many very polished but too complex. You need to tap several times before timer starts. Then there were others which seemed simple but asked too many permissions or showed ads.

So I build a simple timer app using Cordova. It has no settings, as soon as you open app timer starts. When timer reaches 0, it vibrates for half a second. Now you can either continue to meditate or stop your meditation. Another feature I wanted was to slowly increase timer until it reaches 15 minutes. This is exactly what my app does.

At first, I was using it for myself but I decided to polish it a little and release it on Google Play. It is embarrassingly simple, and I doubt anyone else really needs an app like this. But if you do, then here you go: https://play.google.com/store/apps/details?id=com.chaosplay.meditator

The tragedy of 100% code coverage | IG Labs

It is funny how things turn around. ​ For fifteen years I have been preaching TDD (Test-driven development, or as it used to be called: test-first approach), or at least for developers to write some unit tests. However, in recent times I have found myself saying more often, “Why did you write that test?” instead of, “You should write a test.”

Source: The tragedy of 100% code coverage | IG Labs

 

This is something I struggle with too. I see too many unit tests written to cover single line methods. Sometimes, static method calls are moved to wrapper methods for unit tests. It seems to make code cluttered instead of making it easy to read.

Error: xcode-select: error: tool ‘xcodebuild’ requires Xcode, but active developer directory is a command line tools instance

I have been playing with Cordova lately and was getting this error when building iOS version:

Error: xcode-select: error: tool 'xcodebuild' requires Xcode, 
but active developer directory is a command line tools instance

Even full install of Xcode didn’t fix this error.

The solution was to run following command to use full Xcode instead of command line tools version that I had installed earlier:

sudo xcode-select --switch /Applications/Xcode-beta.app/Contents/Developer

Exchanged MacBook Pro with Touch Bar for One without Touch Bar

It didn’t take me long before I started to miss function keys. Yesterday, I exchanged my laptop for MacBook Pro with Function keys. So far this is my favorite laptop.

The main problems with Touch Bar are:
  1. No tactile feedback. While Escape key is always visible and easy to press but without tactile feedback, you are never certain if you pressed it or not. I am so used to certain key combos in vim that without physical Escape key, my fingers could not even find regular keys without me looking down at keyboard.
  2. Cannot adjust brightness of Touch Bar. When working in dark at night, Touch Bar is too bright and distracting.
  3. Drain on battery. Finally, online reviews show that MacBook Pro with Touch Bar have shorter battery life than the one with Function Keys.
  4. Cost – after dealing with above issues, I didn’t think it was worth spending extra $300 for Touch Bar and small performance improvements.

Here is blog post of another programmer who did same exact thing as me because lack of function keys on Touch Bar model.

Pros of Touch Bar

However, I was really impressed with some of the functionalities of Touch Bar. I just wish Apple had included functions keys along with Touch Bar.

  1. In Photos app, you can see and scroll through your photos. I think it was easier and more natural to use Touch Bar for this.
  2. It shows slider when watching YouTube videos. Again it was more natural to use slider on Touch Bar than use slider with mouse. You can also perform various actions like liking a video there.
  3. While typing it shows possible word choices, I can see it increasing typing speed, at least for me.
  4. And of course, login with Touch ID is awesome.
MacBook Pro with Function Keys

Now I have slightly slower MacBook Pro without Touch Bar. I got the base model with i5 2.0GHz processor, 8GB RAM, and 256GB SSD.

However, in my usage so far I haven’t noticed performance difference. During initial setup, beach ball appeared more often on the current MacBook without Touch Bar than the previous one. However, I was able to render 5 minute 1080P GoPro video in less than five minutes. About same speed as my i5 2.9GHz MacBook Pro with Touch Bar. This is no scientific measurement but good enough for me.

My big concern now is SSD space. With only 256GB, it will require me to think about what to store on this laptop. However, I have rethought how I store data. Most of my data is in the form of photos and videos. Perhaps I should start storing these in external harddrives. This might be useful in long-term as then I can upgrade my laptop without thinking much about how to transfer my data.

UPDATE 3/27/2017:

Last Friday, I dropped my Macbook Pro damaging on corner a bit. As you can see it below. Luckily, it still works. But I guess now I am officially stuck with this computer as the resale value of is shot. And while Apple’s Return Policy is only 2 weeks but I still had option to sell it if it was not working out.

Android App Idea

My app idea is pretty simple. Basically, I want to create a voice based chat bot. There are already many APIs from IBM, Microsoft, and Amazon that you can use for text conversations. You add voice to text and then text to speech and you got yourself “Her.”

But there is more to this app. It should help one become a better speaker. By converting speech to text, then we can run various analysis. It can show crutch words or sounds. It could calculate rate of speech or high pitch.

Finally, it could offer suggestions to users on improving their speech.

You Are Not Paid to Write Code

“Taco Bell Programming” is the idea that we can solve many of the problems we face as software engineers with clever reconfigurations of the same basic Unix tools. The name comes from t…

Source: You Are Not Paid to Write Code

This is something I have always argued with my fellow programmers too. Most of regular business problems can be solved by off the shelf products. But most of the programmers I know, prefer to write every solution from scratch. It is almost considered dirty to touch someone else’s software.

 

Magento – Get All Products with Categories in a Flat View

SELECT 
    w1.website_id,
    w1.name as website_name,
    s1.store_id,
    s1.name as store_name,
    p1.entity_id as product_id,
    p1.sku,
    pname.value as product_name,
    url.value as url_path,
    small_image.value as small_image,
    msrp.value as msrp_price,
    price.value as price,
    p1.created_at as product_created_at,
    p1.updated_at as product_updated_at,
    visibility.value as visibility,
    pstatus.value as status,
    case
        when
            (pstatus.value = 1
                and visibility.value > 1)
        then
            1
        else 0
    end as enable_flag,
    c1.entity_id as category_id,
    cname.value as category_name,
    c1.parent_id,
    c1.created_at as category_created_at,
    c1.updated_at as category_updated_at
FROM
    catalog_product_entity p1
        inner join
    eav_attribute p_attr ON p1.entity_type_id = p_attr.entity_type_id
        and p_attr.attribute_code = 'name'
        inner join
    catalog_product_entity_varchar pname ON pname.entity_id = p1.entity_id
        and pname.attribute_id = p_attr.attribute_id
        inner join
    eav_attribute p_attr2 ON p1.entity_type_id = p_attr2.entity_type_id
        and p_attr2.attribute_code = 'url_path'
        inner join
    catalog_product_entity_varchar url ON url.entity_id = p1.entity_id
        and url.attribute_id = p_attr2.attribute_id
        and pname.store_id = url.store_id
        inner join
    eav_attribute p_attr3 ON p1.entity_type_id = p_attr3.entity_type_id
        and p_attr3.attribute_code = 'small_image'
        inner join
    catalog_product_entity_varchar small_image ON small_image.entity_id = p1.entity_id
        and small_image.attribute_id = p_attr3.attribute_id
        and pname.store_id = small_image.store_id
        inner join
    eav_attribute p_attr4 ON p1.entity_type_id = p_attr4.entity_type_id
        and p_attr4.attribute_code = 'msrp'
        inner join
    catalog_product_entity_decimal msrp ON msrp.entity_id = p1.entity_id
        and msrp.attribute_id = p_attr4.attribute_id
        and pname.store_id = msrp.store_id
        inner join
    eav_attribute p_attr5 ON p1.entity_type_id = p_attr5.entity_type_id
        and p_attr5.attribute_code = 'price'
        inner join
    catalog_product_entity_decimal price ON price.entity_id = p1.entity_id
        and price.attribute_id = p_attr5.attribute_id
        and pname.store_id = price.store_id
        inner join
    eav_attribute p_attr6 ON p1.entity_type_id = p_attr6.entity_type_id
        and p_attr6.attribute_code = 'visibility'
        inner join
    catalog_product_entity_int visibility ON visibility.entity_id = p1.entity_id
        and visibility.attribute_id = p_attr6.attribute_id
        and pname.store_id = visibility.store_id
        inner join
    eav_attribute p_attr7 ON p1.entity_type_id = p_attr7.entity_type_id
        and p_attr7.attribute_code = 'status'
        inner join
    catalog_product_entity_int pstatus ON pstatus.entity_id = p1.entity_id
        and pstatus.attribute_id = p_attr7.attribute_id
        and pname.store_id = pstatus.store_id
        inner join
    catalog_category_product ccp ON ccp.product_id = p1.entity_id
        inner join
    catalog_category_entity c1 ON c1.entity_id = ccp.category_id
        inner join
    eav_attribute c_attr ON c1.entity_type_id = c_attr.entity_type_id
        and c_attr.attribute_code = 'name'
        inner join
    catalog_category_entity_varchar cname ON cname.entity_id = c1.entity_id
        and cname.attribute_id = c_attr.attribute_id
        and pname.store_id = cname.store_id
        inner join
    catalog_category_product_index store1 ON store1.product_id = p1.entity_id
        and store1.category_id = c1.entity_id
        inner join
    core_store s1 ON store1.store_id = s1.store_id
        inner join
    core_website w1 ON s1.website_id = w1.website_id