My experience with Open Water Scuba certification in Dallas

This year I crossed off one of my bucket list item, got Open Water Diver certification. I had done scuba diving before at Honolulu. It is among my top 3 best experiences. Ever since that vacation, I had been wanting to get into diving more seriously.

But since we live in land locked Dallas, I didn’t think it was possible or worth it. Then this year in February I saw Groupon from International Scuba and I decided to just go for it. I think Groupon was for $250 but then there was a fine print which said we need to buy our own mask, fins, snorkel, and boots. I bought all this gear from International Scuba as they offered free gear rental for checkout dives. But this added about additional $200.

This certification consist of three parts, online education, in-person classes and training in a pool, and checkout dives in open water body such as lake.

Online classes were easy and interesting. Production quality is sadly extremely low though. It looks like they shot videos in 1980s.

My in-person classes and checkout dives were scheduled in March. It was still pretty cold outside, but International Scuba has nice heated indoors pool. Our instructor was great and very thorough.

This was around the time when COVID19 was spreading in the US but DFW had no such cases yet.

Our checkout dives were at Scuba Ranch in Terrell. Water temperature there was about 60 F then. However, instructor assured that with thick enough wetsuit, we will be fine.

I got 7mm wetsuit but I was still cold in the water but it was bearable. One thing about thick wetsuits is that they increase your buoyancy significantly. We did our training in pool in just swimsuits, it was already hard enough to get neutrally buoyant in the pool without wetsuit. Now we had to not only do our skills in much colder water but also have totally different buoyancy profile. In addition, water is pretty murky there, so that is another new factor to consider. We had to do 4 dives, 2 on Saturday and 2 on Sunday.

But first 2 dives really pushed me exhausted me and I woke up on Sunday with low grade fever. I would have been fine if I had taken some Advil but with COVID19 in the news and just didn’t wanted to push myself, I didn’t go.

Then lockdown happened. So I could not do my last 2 dives until June.

Scuba International was really nice about it, I thought I had to pay for gear rental this time but the loaned me the gear for free again. Also I had prepaid for Sunday entry at Scuba Ranch, but they mailed me a raincheck. So I was able to my last 2 dives for the same cost as if I had not missed my dives initially.

This time water temperature was about 80F. It is amazing how big of difference 20F is, we dived in just swimsuits, no need of wetsuit at all. Also skills were so much easier to do too. Water was still murky but it wasn’t as bad as I remembered from the first time.

I highly recommend that you do your Open Water Diver training during summer. And checkout Scuba International, they are awesome.

iPad Pro as main machine after 2 years

I got my iPad Pro at the end of 2017. Before buying it, I had read many blog posts by various developers who were using iPad for programming and web development. But soon after I bought it, I realized that serious web development on iPad is hard. The biggest issue was debugging JavaScript and CSS without web tools.

At first, I was having buyer’s remorse but I loved the form factor of iPad and loved drawing on it. I am used to reading on Kindle and iPad was just too heavy for long reading sessions but it was very decent reading device for quick reading sessions. So I kept it.

Initially, iPad was fun device for infotainment. But slowly I started to become more productive on it. I stopped doing web or app development. Instead, switched to command-line based projects such as algorithmic trading or data science experiments. It was sort of subconscious change as I carry iPad around a lot more than my laptop and when I had iPad with me, I didn’t wanna build anything with GUI.

Currently, I cannot get rid of my personal laptop completely because I use it for some dev projects, I was learning Flutter and been playing with Godot. I tried to setup Flutter on my VPS but I could never get it to work right. Also laptop is needed for various trading softwares like Wealth Lab Pro or Think or Swim. Wealth Lab Pro is what got me into algorithmic trading but unfortunately it is Windows only. However, I am using RDP to log into Windows machine from my iPad. It is not a smooth experience but doable.

Currently, I use following apps on iPad Pro:

  1. Blink shell for ssh connections to my VPSes.
  2. ia Writer for writing fiction.
  3. Kindle app
  4. Working Copy for working with my repos on github and bitbucket.
  5. Photos app
  6. Procreate for drawing and painting
  7. Affinity Photo for drawing and editing photos
  8. Snapseed for editing photos
  9. Apple Notes for quick notes with Pencil
  10. Dropbox for transferring files between Windows machine, Android phone, and MacBook Pro
  11. Microsoft Remote Desktop
  12. And then usual entertainment apps such Netflix, YouTube, etc

Also I tend to avoid installing most apps and use websites, like Reddit or Facebook. I rather login to website instead of an app on my machine that is constantly monitoring everything I do.

The biggest reason I still need a personal laptop or desktop is for trading softwares. Day trading is one of my favorite hobby. I don’t trade everyday but it is very enjoyable when I do. I could use RDP for day trading but that is clunky and you don’t want to hit the wrong button in your trading software.

WordPress vs Hugo

This is a popular old blog post, I have moved back to WordPress now. Posting this here with updates about why I moved back to WordPress.

Managing WordPress can get time consuming. I have tried to move to static website several times but kept going back to WordPress. But there are several advantages of static sites generators that I finally moved for good. I am also advising a lot of my clients to use Hugo especially when they know that they will rarely ever update their sites.

Here are some of main advantages of Hugo (or other static site generators) vs WordPress and other CMS.

No System Administration

In order to run WordPress, you need a web server. You will need to configure it, install database and PHP. A server hosting a website is always connected to Internet. So it is always available target for hackers. This means you need to secure the server properly and keep it up to date.

When using Hugo, you don’t need PHP and database. All you need is a web server, this reduces attack surface area significantly. As long as you don’t have any extra software running on the server, all you need to worry web server being properly secured.

Of course, you can use shared hosting for WordPress and avoid all headaches of System Administration.

No WordPress or plug-ins to update

The one huge advantage of Hugo is that there is no code to execute. Well no code on server to execute. You may still have some Javascript. But this Javascript code executes in a user’s browser and unlikely to be easily exploitable.

WordPress & plugins executes code on a server. This mean bugs in WordPress can be exploited to access your server or even install malicious code. That code can further infect your users’ machines. I have spend hours and hours restoring websites for clients when their websites got hacked. Of course, you can avoid this by keeping your WordPress installation up to date and carefully choosing plugins & themes. But this means regularly logging in the WordPress admin interface and applying any new updates.

On other hand, you will never have to update Hugo generated site once generated. Only time you will update is to change some content on it.

Simpler Backups

Normally, I don’t give admin login for WordPress & server because of risk involved with client installing bad plugin or messing up something else. I used to manage backups myself.

But I have tried to restore WordPress sites that were developed by someone else. Backup were too old, theme didn’t work with current version of WordPress. Some plugins were not in backup file and are no longer available. And the worst backup file contained viruses & malware.

With Hugo, client gets zip file but it includes full functioning website. While it is still technical, but it should be a lot simpler to restore a static website. It can be as simple as uploading a folder to web server.

No Updates that Break your Site

Since static sites don’t need to be updated to secure against hacks, there is very little worry about any update that will break theme. If you don’t update your Hugo version, you should get same results if you run it against same source files.

In WordPress land, I have seen some people not updating their website for months or years and then when they do, it breaks their theme or plugins.

Where WordPress Wins

There is one area where Hugo cannot touch WordPress. When client is actually using their WordPress site as blog or if they regularly post new content. With static sites, client will need to be technical enough to use markdown and git. Or they will email posts to you.

In my experience though most people rarely update their websites regularly enough to warrant all the extra headache involved with hosting WordPress.

My Hugo Workflow

Personally, I moved my blogs to Hugo because of above reasons and I like the new workflow. My workflow consist of

  1. Email myself a blog idea as I get it.
  2. Write a rough draft either in iA Writer on iPad or skip this step and
  3. Write final version in Sublime Text on my laptop
  4. Commit and push

I love iA Writer for its typewriter mode where the line that you are writing stays in the middle of screen rather than at the bottom.

Setup Outgoing Email on Lightsail Ubuntu VPS

I followed instructions here: https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-postfix-as-a-send-only-smtp-server-on-ubuntu-18-04

Everything seemed okay but email were not getting delivered. Logs showed me that smtp connections were timing out:

tail -f /var/log/mail.log
May  3 12:28:10 postfix/smtp[3160]: connect to gmail-smtp-in.l.google.com[172.217.197.27]:25: Connection timed out
May  3 12:28:10  postfix/smtp[3160]: connect to alt1.gmail-smtp-in.l.google.com[2800:3f0:4003:c00::1a]:25: Network is unreachable
May  3 12:28:40 postfix/smtp[3160]: 4984C41A1E: to=<xxxx@gmail.com>, relay=none, delay=3246, delays=3186/0.01/60/0, dsn=4.4.1, status=deferred (connect to alt2.gmail-smtp-in.l.google.com[2a00:1450:400b:c00::1a]:25: Network is unreachable)

However, I could ping any of above ip addresses just fine.

Next step was to see if ip address of my VPS was blacklisted in RBLs, I used https://mxtoolbox.com/blacklists.aspx. None of my ip addresses were in any black list.

Port 25 was open in firewall, both on server and in Lightsail’s networking UI.

After spending another hour or so troubleshooting, I found this thread: https://forums.aws.amazon.com/thread.jspa?threadID=316397. It seems AWS/Lightsail have recently started to throttle outgoing emails, but by throttling they meant completely blocking it. You need to open a support ticket to remove these limits here: https://console.aws.amazon.com/support/contacts?#/rdns-limits

So I submitted my request, hopefully, this will resolve the issue.

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

This is from my old blog, it is one of more popular post so copying here. I had been playing with Cordova then 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


Full re-install of Xcode didn’t fix this error. The solution was to run following command:

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

Hello World, Again!

As a child, I fell in love with video games and wanted to make my own video games. This is the main reason why I got into programming.

While in college I made a few games/demos using DirectX and random tutorials. Then I applied for job at many game studios but never heard back from them. Then life got in the way, I got a regular programming job. Then I got a startup bug and worked on various side-projects. After various failure of programming side-projects, I decided I should have non-programming side-project/hustle. So I worked as a part-time photographer and got my real estate license.

Now almost 20 years later since first I made games using tutorials, I am again learning game programming.

Over last few weeks, I did research on various game engines, and finally settled on Godot and Flutter. Godot looks like is a beginner friendly game engine. Whereas Flutter is not really a game engine, but it seems perfect for some of simpler educational type games that I am envisioning.

Another thing I did is moving back to WordPress for blogging. I am hoping to write more often about my indie programming and game development journey ahead. I am slowly copying my older popular posts from Hugo but mostly starting over here.

Wealth Lab Pro Earning Play Screener

This is a quick script that I use to find options to buy or sell.

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using WealthLab;
using WealthLab.Indicators;
using Community.Components;

namespace WealthLab.Strategies
{
	public class MyStrategy : WealthScript
	{

		protected override void Execute()
		{
			DataSeries maFast = EMAModern.Series(Close, 50);
			DataSeries maSlow = EMAModern.Series(Close, 200);
			DataSeries maFast_1 = EMAModern.Series(Close, 10);
			DataSeries maSlow_2 = EMAModern.Series(Close, 50);
			DataSeries ma = EMAModern.Series(Close, 10);
			DataSeries maFast_3 = EMAModern.Series(Close, 10);
			DataSeries maSlow_4 = EMAModern.Series(Close, 50);

			PlotSeries(PricePane,EMAModern.Series(Close,50),Color.Red,LineStyle.Solid,2);
			PlotSeries(PricePane,EMAModern.Series(Close,200),Color.Green,LineStyle.Solid,2);
			PlotSeries(PricePane,EMAModern.Series(Close,10),Color.Blue,LineStyle.Solid,2);
			PlotSeries(PricePane,EMAModern.Series(Close,50),Color.Red,LineStyle.Solid,2);
			PlotSeries(PricePane,EMAModern.Series(Close,10),Color.Blue,LineStyle.Solid,2);

			//for(int bar = GetTradingLoopStartBar(201); bar < Bars.Count; bar++)
			int bar = Bars.Count - 1;
			{
				if (IsLastPositionActive)
				{
					Position p = LastPosition;
					if (p.EntrySignal.Contains("Group1|"))
					{
						if (CrossUnder(bar, maFast_3, maSlow_4))
						{
							SellAtMarket(bar + 1, p, "Group1");
						}
					}

				}
				else
				{
					if (maFast[bar] > maSlow[bar])
					{
						if (maFast_1[bar] > maSlow_2[bar])
						{
							if (Close[bar] < ma[bar])
							{
								if (EarningsDate.InWindow(this, bar, "earnings per share", 7, 0))
								{

									BuyAtMarket(bar + 1, "Group1|");
								}
							}
						}
					}

				}
			}
		}
	}
}

TypeError: require.extensions.hasOwnProperty is not a function

While playing with https://github.com/alexa/interactive-adventure-game-tool, I ran into following error:

> interactive-adventure-game-tool@1.0.0 start /Users/amer/alexa/interactive-adventure-game-tool
> node node_modules/gulp/bin/gulp.js

/Users/amer/alexa/interactive-adventure-game-tool/node_modules/require-dir/index.js:97
            if (!require.extensions.hasOwnProperty(ext)) {
                                    ^

TypeError: require.extensions.hasOwnProperty is not a function
    at requireDir (/Users/amer/alexa/interactive-adventure-game-tool/node_modules/require-dir/index.js:97:37)
    at Object.<anonymous> (/Users/amer/alexa/interactive-adventure-game-tool/gulpfile.js:1:85)
    at Module._compile (module.js:660:30)
    at Object.Module._extensions..js (module.js:671:10)
    at Module.load (module.js:573:32)
    at tryModuleLoad (module.js:513:12)
    at Function.Module._load (module.js:505:3)
    at Module.require (module.js:604:17)
    at require (internal/module.js:11:18)
    at Liftoff.handleArguments (/Users/amer/alexa/interactive-adventure-game-tool/node_modules/gulp/bin/gulp.js:116:3)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! interactive-adventure-game-tool@1.0.0 start: `node node_modules/gulp/bin/gulp.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the interactive-adventure-game-tool@1.0.0 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/amer/.npm/_logs/2018-01-02T05_12_24_832Z-debug.log

The solution was to update require-dir to version 0.3.2 in package.json and run npm install again.