↓ Skip to main content

Business model

Context
#

Learned in this study
#

Things to explore
#

Overview
#

Cartalyst
#

Models
#

Subscription based
#

  • Some development must be done in order to protect the software against forbidden use (no subscription)
  • May require a “call-to-home” (Internet connection) to verify the subscription is still valid
    • Might be easily countered by firewalling the application
      • We may allow it to go unchecked for 1-X days until we tell the user to connect, but that is bad user experience

Examples
#

On demand
#

  • Similar to subscription based, but on a per use basis

Examples
#

Open source
#

  • Code is freely available
    • Makes it more difficult to live on producing the software

Support based
#

  • ($X*0.2)/user/year in support fees
  • Fee per request

Traditional - Major version and upgrades
#

  • X$/user (one time fee)
  • ($X*0.2)/user/year in support fees

Software as a service
#

  • Tools are never shared with the outside world

Consultancy
#

  • Develop tools to use on a per-project basis, where clients spent 5k$+ on a single pass
  • Tools are never shared with the outside world

See also
#

References
#


Licensing CLI

Context
#

Learned in this study
#

Things to explore
#

Overview
#

  • Encapsulate the application within a .phar
  • Use obfuscation (can only obfuscate variables inside function/methods as anything else must remain with the same name in order to allow for dynamically called methods (or simply do not support such code))

Requirements
#

  • Must not make it easy to extract the original source code
  • Must checksum itself for modification
  • Should prevent usage by sharing a single license (TBD?)
  • Should not be possible to reuse a trial forever in a VM

Issues
#

  • Relying on opcode (to act as a binary) probably implies you are dependent on the php version used. Furthermore, it also means that the extension must be available and enabled for the code to work
  • Given the current implementation of opcache, the cache cannot be reused on other machines as it contains the system ID as part of an opcache file header

PHP OPCache
#

Header #

  • OPCACHE

  • System ID

  • Timestamp

  • Checksum

-> zend_accel_load_script (persistent_script, from_memory)

Obfuscation
#

  • Replace classes methods with (generated) traits that contain one or many of the classes method
  • Compression/optimization by creating variables

Issues
#

  • Even with obfuscation, PSR0/4 based code is too easy to distinguish (no reason to obfuscate libraries)

Ideas
#

  • Find some way to transform the original source such that it is in symbiosis with a client identifier (and thus cannot be removed)

Packaging
#

  • Replace variables within functions with obfuscated names
  • Concatenate all files into a single file (or bundle of files)
    • Pre-process require/include, or do not allow their use (as the files will not be available)
  • Randomize file order
  • Scramble method order
  • Inject junk code
    • Insert junk code with encrypted user identification
  • Generate a differently scrambled version per download/user

See also
#

References
#

Obfuscation
#


Obfuscator

Context
#

Learned in this study
#

Things to explore
#

Overview
#

  • Encapsulate the application within a .phar
  • Use obfuscation (can only obfuscate variables inside function/methods as anything else must remain with the same name in order to allow for dynamically called methods (or simply do not support such code))

Requirements
#

  • Must not make it easy to extract the original source code
  • Must checksum itself for modification
  • Should prevent usage by sharing a single license (TBD?)
  • Should not be possible to reuse a trial forever in a VM

Issues
#

  • Relying on opcode (to act as a binary) probably implies you are dependent on the php version used. Furthermore, it also means that the extension must be available and enabled for the code to work
  • Given the current implementation of opcache, the cache cannot be reused on other machines as it contains the system ID as part of an opcache file header

PHP OPCache
#

Header #

  • OPCACHE

  • System ID

  • Timestamp

  • Checksum

-> zend_accel_load_script (persistent_script, from_memory)

Obfuscation
#

  • Replace classes methods with (generated) traits that contain one or many of the classes method
  • Compression/optimization by creating variables

Issues
#

  • Even with obfuscation, PSR0/4 based code is too easy to distinguish (no reason to obfuscate libraries)

Ideas
#

  • Find some way to transform the original source such that it is in symbiose with a client identifier (and thus cannot be removed)
  • Obfuscate php built-in functions
  • Zend Host ID limited deployment: It appears that Zend Guard allows the software to be limited to run on only specific “Zend Host” (what are those?)
    • Zend Guard Loader is a custom extension? for PHP which requires a licence_path to work

Packaging
#

  • Replace variables within functions with obfuscated names
  • Concatenate all files into a single file (or bundle of files)
    • Pre-process require/include, or do not allow their use (as the files will not be available)
  • Randomize file order
  • Scramble method order
  • Inject junk code
    • Insert junk code with encrypted user identification
  • Generate a differently scrambled version per download/user

See also
#

References
#


Business

  • Identified a problem
  • Determine if it is of importance (metrics)
  • Explain why your solution is better than existing ones
  • Define a clear pricing model
  • Define how your product will be marketed
  • Define how the product will scale from personal to large corporate use

Evaluate business opportunities
#

  • Determine sale pricing
  • Evaluate various sale models
    • Packages
    • Monthly
    • Per action/item/amount
  • Determine various cash flows
    • Money paid to employees/self
    • Money paid for services required by the product
  • Evaluate tasks that have to be done globally and per client/project (if any)
  • Evaluate anything that has to be paid for every client/project and once/globally
  • Determine all factors that may vary
    • Number of customers
    • Number of days/months/years
    • Disk space usage, bandwidth usage, computer usage

Unsorted
#

  • Track users requests
  • Track users feedback

Automated refactoring

Context
#

Learned in this study
#

Things to explore
#

Overview
#

  • Component extraction (find all dependencies and attempt to create a self-contained library)
  • Convert function-based code into class-based code (static calls)
    • Copy all functions in a file into a new class where each function is static
    • Find all calls to the initial functions and replace them with calls to the class
    • Verify that all entry points load the autoloader (how to check that? search for the autoload.php string and require/include calls?)
  • Template/logic separation
  • Extraction of functions into a separate file
  • Extraction and replacement of inline style
  • Extraction of string resources
  • Extraction of inline JS
  • Extraction of inline CSS
  • Conversion of raw view logic to template logic
  • Removal of inline PHP code in js code
  • Convert raw SQL into builder queries
  • Move queries in controller into a service/repository
  • Convert <? to <?php
  • Convert echo calls to string concat + return
  • Update outdated phpdoc
  • Improve typing (parameters and return)

Difficulties of code refactoring
#

  • Lot of code is SQL queries

Refactoring to MVC
#

See also
#

References
#


Javascript datastores

I am currently looking into javascript based libraries that will allow me to do in-browser queries, similar to how a server-side application would query a NoSQL database.

In order to pick the most appropriate database for my project, I first search for available solutions online. Then, I build a comparison table like the one below in order to determine the most popular database and its current health.

Repository Watch Stars Forks Last commit Open issues Open PR
pouchdb/pouchdb 245 5730 630 2016-02-12T17:23:21Z 128 8
google/lovefield 173 4143 195 2016-02-11T05:59:09Z 17 1
louischatriot/nedb 167 3680 237 2016-02-11T11:23:44Z 19 8
typicode/lowdb 87 2833 96 2016-02-09T21:16:31Z 9 3
techfort/LokiJS 102 1800 167 2016-02-08T19:18:40Z 64 0
coresmart/persistencejs 89 1586 226 2015-09-08T18:47:06Z 66 14
typicaljoe/taffydb 100 1309 215 2016-01-07T22:21:06Z 57 16
agershun/alasql 60 927 107 2016-02-09T15:35:07Z 250 0
Irrelon/ForerunnerDB 25 439 33 2016-02-12T16:20:29Z 17 0

My AGI journey

Over the next year (and hopefully years), I plan on working on AI, but more particularly what is known as AGI, Artificial General Intelligence.

Since I am the kind of person that enjoys to overly plan, I’ve been thinking about the whole process for a while. Here’s a brief overview of how I plan to construct my days as well as my work.

Daily
#

Beginning of the day
#

  • Decide and plan on which projects I will work today
  • Video log
    • What will I be doing today?
    • What might be blocking me or will be difficult and how do I plan to tackle that?

During the day
#

  • Record my thoughts: Either through video logs or through written notes, which is the more likely option. This will allow me to search my thoughts as well as organize them as necessary. Furthermore, I hope I’ll be able to optimize my thought flow through tools.

End of the day
#

  • Video log
    • What have I done during the day?
    • What are the key takeaway of the day?
    • What didn’t I do?

While reading books/papers
#

  • Take notes (of interesting sections and ideas)
  • Write down thoughts
  • Write down questions related to what is being read (for further exploration)
  • Explore right away a question I might have had

After each mini project
#

I plan on working on multiple mini projects in order to ensure diversity as well as to allow me to spot projects which have the potential to be interesting and rewarding. However all projects are valuable in their own and it is important to reflect on the project at the end in order to extract things we’ll want to repeat in the future as well as things we’ll want to avoid.

  • Post mortem
    • What went wrong
    • What went right

At the end of each month
#

  • Update the status of all tracked activities
  • Write a list of things that were done during the month regarding each activity that was done. The purpose is to review what was done as well as provide a way to determine how well a project may/may not be progressing. It is also a good time for me to look at each individual activity that was done during the month and evaluate if I want to keep doing it or not.
  • Write a post-mortem of the month, describing the good/bad of my current process and progress, with a section suggesting improvements to try for the next few months.
  • Plan the projects/activities I will be working on next month, as well as their time allocation.

Living process
#

I will be experimenting with this process in the next few weeks and will iterate on it as I see fit. I will thus be updating this post as changes occurs and I think of better ways to do my work.


Things I do

  • Work
    • Software development
    • Analysis
    • Conception
    • Implementation
    • Testing
    • Debugging
    • Deployment
    • QA
    • Maintenance
    • System administration
  • Sleep
  • Eat
  • Exercise
  • Entertainment
    • TV series
    • Reddit
    • Youtube
    • Twitch
    • Streams
    • Video games
  • Read
  • Write
  • Chat
  • Email
  • Transit
  • Anki
  • Piano
  • Guitar
  • Google
  • Prepare food
  • Bathroom
  • Shower
  • Wikipedia
  • Groceries

Docker-based jenkins slaves

Overview
#

In this article, we’ll go over how to setup Jenkins on an Ubuntu machine to run PHP 7.1 jobs. The steps should easily be adapted for any other OS and target environment.

Install Jenkins
#

Install Jenkins plugins
#

  • Docker Slaves Plugin

Install Docker on the slave (or host)
#

Create a Docker image
#

  • In a Dockerfile

FROM ubuntu:xenial

COPY sources.list /etc/apt/sources.list
RUN useradd -m --uid=1001 jenkins
COPY known_hosts /home/jenkins/.ssh/known_hosts
RUN chown jenkins:jenkins -R /home/jenkins/.ssh

RUN apt-get update
RUN DEBIAN_FRONTEND="noninteractive" apt-get install -y git vim curl wget build-essential python-software-properties software-properties-common unzip

RUN add-apt-repository -y ppa:ondrej/php
RUN apt-get update
RUN DEBIAN_FRONTEND="noninteractive" apt-get install -y --force-yes php7.1 php7.1-xml php7.1-mbstring php7.1-zip php7.1-pdo-mysql php7.1-pdo-sqlite

RUN apt-get -y autoremove && apt-get clean && apt-get autoclean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
  • docker build -t your/image:1.0.0 -t your/image:latest .

Configure your Jenkins jobs
#

Specify the Docker image to use
#

  • your/image (will use your/image:latest)

Use SSH keys within Docker
#

This is particularly useful if you need to pull git repositories from a private repository.

Notes
#

As of December 2016, if you want to be able to use the SSH key in a docker container, you have to first start the ssh agent on the node used that will run the docker container and when you run the docker image, pass in the SSH_AUTH_SOCK as a volume so that it is shared with its host.


sshagent(['IDENTIFIER']) {
	docker.image('your/jenkins-slave-image').inside('--volume $SSH_AUTH_SOCK:$SSH_AUTH_SOCK') {
		// Here your SSH_AUTH_SOCK is shared with the host machine, which may be a jenkins slave
		// All commands that would use SSH for authentication (such as git or composer when installing from private repositories) should work
	}
}

Example Pipeline
#


node('docker') {
	catchError {
		timestamps {
			wrap([$class: 'AnsiColorBuildWrapper']) {
				sshagent(['private-git']) {
					docker.image('tomzx/jenkins-slave').inside('--volume $SSH_AUTH_SOCK:$SSH_AUTH_SOCK') {
						stage 'Checkout'
							checkout scm

						stage 'Setup dependencies'
							sh 'wget -nc https://getcomposer.org/composer.phar'
							sh 'php composer.phar install'

						stage 'Test'
							sh 'vendor/bin/phpunit'
					}
				}
			}
		}
	}
}

References
#


Fitness trackers

Context
#

I’ve recently become interested in the Quantified Self and wanted to compare a few trackers in order to determine the quality of their solution.

In this study, I compare the Fitbit Charge HR, the Jawbone UP3 and the RS300X. The Fitbit and the Jawbone are known as activity/fitness trackers while the RS300X is an heart rate tracker.

Learned in this study
#

Things to explore
#

Overview
#

Fitbit and Jawbone are known fitness brand trackers. It’s been a couple of years now that these types of trackers are popular, so I’d expect them to have come to some level of maturity. The goal of this study is to evaluate the quality of the products, as much in term of hardware as software.

In my case, I will be testing the Android applications since I own a Nexus 5. I would expect the experience to be quite similar on iOS.

I’ve also bought an RS300X in order to test a live heart rate tracker.

Fitbit Charge HR
#

Pros
#

  • Has a little OLED display.
  • UI/UX is pretty straightforward.

Cons
#

  • The bracelet broke about 3 months after I purchased it. Fitbit support was excellent though and I received a replacement bracelet within 2 days.
  • Website errored out when I tried to create an application (preventing people from creating apps?)
  • Cannot get fine grained data.
  • Heart rate day availability is very odd. Seems to lag out and may display only in chunks.
  • Shows up in my android smart lock as a bluetooth device I could pair with, but I can’t select it.

Jawbone UP3
#

Pros
#

  • None at the moment.

Cons
#

  • The bracelet broke about 4 months after I purchased it.
  • Cannot get fine grained data.
  • Doesn’t do real time heart rate tracking.
  • Heart rate day availability is very odd. Seems to lag out and may display only in chunks.
  • No idea why they decided to go with some weird buckle design. It looks like it’s a nice point of failure.
  • After about a month it feels like the buckle is becoming loose. It is more and more frequent that it becomes undone and comes close to falling and I have to attach it back…
  • After about two months the buckle is becoming loose very frequently. I’d say I have to “re-buckle” it at least 10-20 times per day. That is ignoring the fact that it’ll unbuckle while I sleep, making it pretty useless to sleep heart rate while sleeping.
  • The four heart rate sensors on the lower part of the bracelet are uncomfortable.
  • All the people I’ve shown the device to asked “why is there no display, show at least the time…”.
  • Terribly clunky UI/UX. Why can’t I just swipe from day to day in any of the stats
  • For that matter, why is it so hard to display the metrics I’m interested in and get rid of all those “pretty” suggestions cards?
  • Why would you put unit selection (metric or imperial) as being configured through my height or weight? Is it to save me time or to confuse me?

Fitbit Charge HR vs Jawbone UP3
#

Heart rate
#

The following chart is the data I’ve collected over 3 days. In black is the Jawbone UP3 data and in blue the Fitbit Charge HR data.

Overall, the Fitbit Charge HR data is more consistent (every 5 minutes) while the Jawbone UP3 may end up having no data point for up to 2 hours. I assume this might be caused by how I’ve been wearing the bracelet but that is a weak argument.

Pedometer
#

Accuracy between the two devices can vary a lot.

[Pedometer chart for comparison]

Sleep monitoring
#

Both devices seem to measure approximately the same amount of sleep. However the Jawbone UP3 has a nicer chart that goes into the various stages of sleep while the Fitbit Charge HR only displays Asleep/Restless/Awake.

[Sleep monitoring chart for comparison]

Polar RS300X
#

Pros
#

  • None at the moment.

Cons
#

  • Cannot get data out of device (for free).
  • “If you want your data, pay us another 70$ +taxes for a transmission device”.
  • “Oh, and by the way, you’re going to send us those precious data over our web service so we can mine it for $”.
  • Watch freaks out if too close from chest strap.
  • Who thought of this terrible buckle design? If I want to break the strap, that’s how I’d design the buckle.

See also
#

References
#