Do Androids Dream of Electric Sheep?

OK, for years I have been pretending that I read books, while I have never read more than 20 books a year. At least that’s what my Goodreads stats say. But I have planned to change that for good now.

Saturday, April 13: Read 11 pages. The chapter is interesting. It talks of a dystopian future and lays out the scene for the story that is going to be told. I can’t believe I bought this book in 2014 and then never read it. The protagonist is a bounty hunter in a distant future where the earth is plagued by radioactivity and the technology has come to a point where electric sheep look exactly like the real ones. But people now want the real ones for some reason. I see, the point maybe is, people just want what’s rare and different. It sounds a lot like a chapter from a coursebook that we read back in the days. It was in Urdu and the title was, “Man is never happy”. I believe this is going to be one of those stories. I don’t know. Let’s see how it goes.

Solution to: zsh: command not found: flutter on macOS Catalina

Since the recent update to Mac OS Catalina and forced update to zsh, I was having problem with a lot of my CLI tools, including flutter. The reason being, zsh uses ~/.zshrc and not ~/.bash_profile

So to solve the problem, simply add your flutter path to ~/.zshrc like this

export PATH="$HOME/your_path/flutter/bin:$PATH"

Change your_path to where you had flutter downloaded and extracted on the earlier version of Mac OS.

Solution to zsh: command not found: expo on macOS Catalina

So I recently upgraded to macOS Catalina and all hell broke loose. Many of my command line utilities kept working but I have definitely wasted close to 30 hours trying to fix everything to make it work just like it did in the previous macOS version.

Recently, I am started working on a demo for my talk at the Wordcamp Islamabad and wanted to try the latest tools for building a react native app. So naturally, I wanted to try expo CLI as it gives all the tools needed to work with react native on number of platforms i.e web, iOS and Android.

I installed the expo CLI using the following command:

npm install -g expo-cli

But when I tried to run expo, it gave me this error

zsh: command not found:

Have rarely worked with zsh and not having any command over it, I tried many ways to fix it, including the path of the npm root which I got via:

npm root

Apparently, it’s not a reliable way to do it. So I ended up adding

export PATH="$HOME/.npm-packages/bin:$PATH

to my ~/.zshrc file. Which solved the problem for good.

Now I can run expo cli with no problem.

Hope this helps others who are stuck like me!

Update the core jQuery version that ships with WordPress

You can replace the default version that ships with WordPress like that:

function replace_core_jquery_version() {
   function replace_core_jquery_version() {
    wp_deregister_script( 'jquery-core' );
    wp_register_script( 'jquery-core', "https://code.jquery.com/jquery-3.4.1.min.js", array(), '3.4.1' );
    wp_deregister_script( 'jquery-migrate' );
    wp_register_script( 'jquery-migrate', "https://code.jquery.com/jquery-migrate-3.1.0.js", array(), '3.1.0' );
}
add_action( 'wp_enqueue_scripts', 'replace_core_jquery_version' );

Python: Measure the execution time of small python code

The “timeit” module lets you measure the execution time of small bits of Python code. This can help you find the execution time of your code and thus help in a quick performance improvement of your code. A tiny example follows.

>>> import timeit
>>> timeit.timeit('"-".join(str(n) for n in range(100))', number=10000)

0.2938678440004878

>>> timeit.timeit('"-".join([str(n) for n in range(100)])', number=10000)

0.26015590599854477

>>> timeit.timeit('"-".join(map(str, range(100)))', number=10000)

0.26461737899808213

Please note that every time, the execution time varies for the same snippet. in the first two cases. The third one does the same thing but has a different execution time. This profiling helps with performant code going to your production.

Also, this different execution time for the same exact code depends on a lot of factors, the major one being how busy your CPU was at the time of executing this code. The module function timeit.timeit(stmt, setup, timer, number) accepts four arguments:

  • stmt which is the statement you want to measure; it defaults to ‘pass’.
  • setup which is the code that you run before running the stmt; it defaults to ‘pass’.
    We generally use this to import the required modules for our code.
  • timer which is a timeit.Timer object; it usually has a sensible default value so you don’t have to worry about it.
  • number which is the number of executions you’d like to run the stmt.

https://docs.python.org/2/library/timeit.html
https://www.geeksforgeeks.org/timeit-python-examples/

Git: Delete all branches except for the master branch

It can be as simple as this alias in your terminal

alias gbr="git branch | grep -v "master" | xargs git branch -D"

In my case, I had multiple branches and when I ran the gbr command, it showed the following result, deleting all three branches I had.

$ gbr
Deleted branch 19EKofcx (was b849981).
Deleted branch chA5sUqj (was 2198d89).
Deleted branch rewrite (was 17a9dba).

Python: Given an array of integers, return a new array such that each element at index i of the new array is the product of all the numbers in the original array except the one at i.

This post is one of my new series solving one problem per day.

For those of you solving coding challenges for your next software engineering job, here is one more problem.

This problem was asked by Uber.

Problem Statement

Given an array of integers, return a new array such that each element at index i of the new array is the product of all the numbers in the original array except the one at i.

For example, if our input was [1, 2, 3, 4, 5], the expected output would be [120, 60, 40, 30, 24]. If our input was [3, 2, 1], the expected output would be [2, 3, 6].

Here is a solution I came up with

def product_ar(arr):
	new_arr = []
	for i in range(0,len(arr)):
		new_arr.append(multiply_all(arr[0:i], arr[i+1:len(arr)]) )	
	
	return new_arr

def multiply_all(arr1, arr2):
	product = 1
	for item in arr1:
		product *= item		
	for item in arr2:
		product *= item	

	return product

# Some tests 

print(product_ar([1, 2, 3, 4, 5]) == [120, 60, 40, 30, 24])
print(product_ar([3,2,1]) == [2,3,6])

Follow-up: what if you can’t use division?

Python: How to merge two dictionaries

In Python 3.5+

>>> x = {'a': 1, 'b': 2}
>>> y = {'b': 3, 'c': 4}

>>> z = {**x, **y}

>>> z
{'c': 4, 'a': 1, 'b': 3}

In Python 2.x:

>>> z = dict(x, **y)
>>> z
{'a': 1, 'c': 4, 'b': 3}

In these examples, Python merges dictionary keys in the order listed in the expression, overwriting duplicates from left to right.

How to sort a Python dictionary by value

# How to sort a Python dict by value
# (== get a representation sorted by value)

>>> xs = {'a': 4, 'b': 3, 'c': 2, 'd': 1}

>>> sorted(xs.items(), key=lambda x: x[1])
[('d', 1), ('c', 2), ('b', 3), ('a', 4)]

# Or:

>>> import operator
>>> sorted(xs.items(), key=operator.itemgetter(1))
[('d', 1), ('c', 2), ('b', 3), ('a', 4)]

Python: Different ways to test multiple flags at once

# Different ways to test multiple
# flags at once in Python
x, y, z = 0, 1, 0

if x == 1 or y == 1 or z == 1:
    print('passed')

if 1 in (x, y, z):
    print('passed')

# These only test for truthiness:
if x or y or z:
    print('passed')

if any((x, y, z)):
    print('passed')

Add a wordpress admin account programmatically

In cases when you have access to code and not to an existing admin account, here is a way to create an admin account for yourself without waiting for someone else to create it for you.

In your `functions.php` file, use the following code:

function wpAddAdmin() {
	$user  = 'fahad';
	$pass  = 'mypassword';
	$email = '[email protected]'; // password in plain text
	if ( ! username_exists( $user ) && ! email_exists( $email ) ) {
		$user_id = wp_create_user( $user, $pass, $email );
		$user    = new WP_User( $user_id );
		$user->set_role( 'administrator' );
	}
}

add_action( 'init', 'wpAddAdmin' );

Save the file and access your wordpress admin area. Use the settings you updated in above code i.e the same username and password and you’d be able to access WordPress as admin. That’s all!

Remember:

With great power comes great responsibility.
~ Not spiderman

Find code comments using regex in an IDE

So if you are a developer,  you might need to clean up comments from a code that you might have copied from somewhere else and updating the documentation needs you to start from scracth, or you just want to get rid of comments. Afterall, it can’t be called code if can be understood. Just kidding!

For Javascript and C/C++ or PHP comments or basically any language that uses this syntax for comments

/* Your comment goes here*/

or

/**
* Your comments here
* Your comments here again
*/

the search query would be like:

/\*(.|[\r\n])*?\*/

just make sure to select regex like I did in my case in the screenshot below, so search with the following and replace with

Regex checkbox in PhpStorm IDE

Regex checkbox in PhpStorm IDE

For HTML comments, you’d use something along these lines for the regex pattern for your search and replace query


\<![ \r\n\t]*(--([^\-]|[\r\n]|-[^\-])*--[ \r\n\t]*)\>

PHP: Adding hours to timestamp fields while printing the formatted date

So imagine your MySQL is on a shared host and you have time stamps which are automatically inserted in the table. In this case, updating MySQL’s time zone settings is beyond your control. Or even if you can set the time zones, for any records that are in a specific time zone, you can add  hours or minutes to the timestamp you get from the database in the PHP code.

Assuming your record object is $record and the timestamp field is ‘timestamp’, the following code will allow you to add 5 hours to your timestamp and print in the d/m/Y format which you can update in the code below.

echo date('d/m/Y h:i:s A', strtotime($record['timestamp'] . '+5 hours'));

Hope you are going to find this tip useful.

PHP: Remove and Prepend zeros in a string

So in a recent project, the hardware being used was sending data always prepended with the zeros. I was using this as a number in my database, so this is what I did for removing the leading zeroes from the string

$str = ltrim($str, '0');

So if you do something like

$str = '000000012'
$str = ltrim($str, '0'); // '12'
echo $str; // prints 12

Adding leading zeroes

Given that the value is in $value, the following code will make the total length of string to be eight, adding the needed leading zeroes accordingly.

To simply print/ echo it:

printf("%08d", $value);

To put it in a variable and use it later:

$formattedValue = sprintf("%08d", $value);
echo $formattedValue;
Uncategorized

LAMP: Linux/ Apache / MySQL / PHP: Upgrading PHP to 7.1 and enabling extensions

Step 1:

sudo add-apt-repository ppa:ondrej/php
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install php7.1   # for PHP 7.1

Step 2:

Install extension with the following commands

sudo apt-get install php7.1-gd php7.1-mysql php7.1-dom php7.1-cli php7.1-json php7.1-common php7.1-mbstring php7.1-opcache php7.1-readline
Uncategorized

Github Pages: Deploying a subfolder to GitHub Pages

Sometimes you want to have a subdirectory on the master branch be the root directory of a repository’s gh-pages branch. This is useful for things like sites developed with Yeoman, or if you have a Jekyll site contained in the master branch alongside the rest of your code. Also, a lot of static site generators create a build folder called ‘dist’ or ‘static’. I was recently using foundation CLI at this website and I came across this problem that I wanted to show all the changes quickly to the client I was building this form. So I used the following process.

For the sake of this example, let’s pretend the subfolder containing your site is named dist.

Step 1

Remove the dist directory from the project’s .gitignore file (it’s ignored by default by Yeoman).

Step 2

Make sure git knows about your subtree (the subfolder with your site).

git add dist && git commit -m "Initial dist subtree commit"

Step 3

Use subtree push to send it to the gh-pages branch on GitHub.

git subtree push --prefix dist origin gh-pages

Boom. If your folder isn’t called dist, then you’ll need to change that in each of the commands above.


If you do this on a regular basis, you could also create a script containing the following somewhere in your path:

!/bin/sh
if [ -z "$1" ]
then
echo "Which folder do you want to deploy to GitHub Pages?"
exit 1
fi
git subtree push --prefix $1 origin gh-pages

Which lets you type commands like:

git gh-deploy path/to/your/site
Uncategorized

Linux/ Debian / Ubuntu: Restart Apache 2 web server

Use

# /etc/init.d/apache2 restart

OR

$ sudo /etc/init.d/apache2 restart

OR

$ sudo service apache2 restart

OR

simply create an alias for the command that works for you.

alias rsws='/etc/init.d/apache2 restart'

Using my alias ‘rswd’

$ rsws
[ ok ] Restarting apache2 (via systemctl): apache2.service.

Uncategorized

Linux: Quickly accessing your project files

Sometimes, all you need is quick command which you can run and land on a directory you access most. In this case, on one of my test servers, I wanted to go to the main directory where I keep my websites. I just created an alias called ‘home’ and now I also use this to go into my directory.

alias home='cd /var/www/'

No memorization needed anymore and no time wasted finding where I kept everything.

Uncategorized

Linux: Add and list aliases

Print all existing aliases

alias

Add a new alias

alias list='ls -la'

In the above example, an alias list has been added which actually runs the command ls -la

Uncategorized

MongoDB: Copy a collection from one database to another

It’s quite simple

db..find().forEach(function(d){ db.getSiblingDB('')[''].insert(d); });

You can do a mongodump of a collection from one database and then mongorestore the collection to the other database.

I used robomongo and it a documents view, just used this query with the right names for collections and databases, I was able to copy around 3000 records in less than a second on my old Macbook air.

Uncategorized

Git: Amend the last commit

So you just committed some code only to realize you had a few files missing from your commit, which you forgot to add. This happens a lot in everyday coding and git has an easy fix for that. If you are like me, you have done something like resetting the head to the commit before last commit and then committing files again but that’s a hack and it’s avoidable. How? Keep reading.

Use git add -u or git add . to stage the new changes or add any missing files.

And then for updating the last commit with newly added / staged files use --amend argument.

git commit --amend

If you just want to update the commit message, use -m option for adding a commit message. If you don’t specify it, you will be prompted with the previous commit message as a default, in a standard vim mode.

For someone new to vim: You could use escape key to get out of editing mode with wq which edits and saves your commit

When you’re done you can check git log --stat to see your amended commit with the extra changes.

For documentation, check out Git’s ‘commit –amend’ documentation.

Uncategorized

My Github Pages

Just released a new version of Github pages which you can find at fahdi.github.io. Github pages are an interesting feature of github to update a personal portfolio or a project page or any static (or dynamic: look at PakistanJS). You push your code as a static html, css and javascript files or in this case I have used jekyll to have some configuration in place and used plain jQuery to pull in my github repos dynamically.

The code is available at github.

Uncategorized

Releasing first version of my postman collection for Teamwork API

Teamwork API is great but while while working on it, I badly felt the need of being able to test different end points before putting them into my app. Naturally, I tried looking for it on the web and didn’t find anything, so I finally created my own collection and here it is, for you to use.

Please open a PR if you improve anything. The collection uses a global i.e {{TeamworkHost}} which can be added in a user defined Postman environment for your own team URL, as in the following screenshot.

Uncategorized

Javascript: Array Reduce

Here is a simple example of using reduce for adding all values in an array

let add = (...args) => {
  return args.reduce(function(a, b) {
    return a + b; }, 0);
};
let args = [3, 5, 7];
console.log(add(...args));

Clean, right?

In regular JS or ES5, you’d do something like:

var total = 0;
var numbers = [3, 5, 7];
for (var i = 0; i < numbers.length; i++) {
  total += numbers[i];
}

You can simplify the above reduce example to

[3, 5, 7].reduce(function (a, b) {return a + b; }, 0);

I'd say reduce makes it simpler and easier. Read more about it here

Uncategorized

Breaking changes from Angular 2 beta to final release candidate

If you’re using the Angular 2 beta version and want to upgrade to angular 2 final release candidate, it’s a good idea to be aware of the breaking changes from beta to final release. I followed a few youtube tutorials and struggled with it, so here is what i learnt:

Most of the content that was posted earlier on internet forms and youtube tutorials deals with Angular 2 beta. I waited for quite a while to move to angular 2 so that it matures before adopting it. But even then the relevant study material is old and you can’t really follow it word by word.

Module Names

Angular packages have been renamed from angular2 to @angular.

import { Component } from ‘@angular/core’;

Components and Directives

In Beta, you had to register a component or directive in directives attribute of the host component:

@Component({
  directives: [FirstComponent, SecondComponent]
})
export class MyCoolComponent { }

In the Final Release, directives is removed from component metadata.

You should register all components and directives in AppModule (The main app’s root module) or the module they belong to (on sub level). Like the following:

@NgModule({
  declarations: [MyHostComponent, ComponentA, DirectiveA]
})
export class AppModule { }

Directives

To access a DOM element, use this.el.nativeElement instead of this.el.

this.renderer.setElementStyle(this.el.nativeElement, ‘width’, ‘200’);

ngFor Syntax

With angular’s final release, the syntax for for loop has changed.  You should now be using the let keyword. here is how to upgrade all your for loops to new syntax.

In Beta:

*ngFor=“#course of courses”

In the final version:

*ngFor=“let course of courses”

Note: I’d keep this post updated if I find anything else as I continue with my study.

Uncategorized

Javascript/ Angular: `ng new` command stuck at ‘Installing packages for tooling via npm’

So I am learning Angular 2 and decided to use Angular CLI this time instead of those seed projects.

BTW, I am following this course to study basics of Angular.

sudo ng new angular-app

And this is what happened

Password:
As a forewarning, we are moving the CLI npm package to "@angular/cli" with the next release,
which will only support Node 6.9 and greater. This package will be officially deprecated
shortly after.

To disable this warning use “ng set –global warnings.packageDeprecation=false”.

installing ng2
 create .editorconfig
 create README.md
 create src/app/app.component.css
 create src/app/app.component.html
 ...
 ...
 ...
 create karma.conf.js
 create package.json
 create protractor.conf.js
 create tslint.json
 Directory is already under version control. Skipping initialization of git.
 Installing packages for tooling via npm.
 

It was stuck at the

Installing packages for tooling via npm

for ages and since I didn’t want to give up using the CLI, here is how I solved it.

$ ng new angular-app --skip-npm

As it was stuck on npm packages install process and using –verbose with the command didn’t help, I used above command to skip installing npm packages and did it manually.

So after above, I used

$ cd angular-app

to get into the directory and then installed npm via

$ npm install

that install script takes care if everything else that CLI does if it all works normally.

Now, since we are using the CLI, here is how to compile and run it

$ ng serve

and it should show something like following when it all works nicely.

** NG Live Development Server is running on http://localhost:4200. **
 Hash: a1114768f326f4da3abe
 Time: 9472ms
 chunk {0} polyfills.bundle.js, polyfills.bundle.map (polyfills) 147 kB {4} [initial] [rendered]
 chunk {1} main.bundle.js, main.bundle.map (main) 3.98 kB {3} [initial] [rendered]
 chunk {2} styles.bundle.js, styles.bundle.map (styles) 10 kB {4} [initial] [rendered]
 chunk {3} vendor.bundle.js, vendor.bundle.map (vendor) 2.62 MB [initial] [rendered]
 chunk {4} inline.bundle.js, inline.bundle.map (inline) 0 bytes [entry] [rendered]
 webpack: Compiled successfully.
 

Heading into the browser, it looked like this

Problem solved!

Simple code highlighter using only CSS

Over the last 10 years, I have learnt that sharing code on websites can be tricky. Just yesterday I was working on a blog post and realized that anything between the <code></code> can look ugly if not styled properly.

For example, after writing some bash code within the post, it looked this ugly:

Now, I just investigated how my CSS looked like. And the CSS to style it was barebones, like this

code,
kbd,
tt,
var {
font: 15px Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace;
}

Clearly, not acceptable and it looked plain and ugly. I didn’t want to use third party JS based highlighter and wanted to use clean CSS approach. I don’t need complex syntax highlighting and basically didn’t want to mess with simplicity and cleanliness of my site. In short, no time for bullshit. So here is what I did

code,
kbd,
tt,
var {
font: 15px Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace;
background: #eee;
color: black;
margin: 20px 0;
display: block;
padding: 20px;
}

Now, that’s more like it and it would simply add some nice greyish background, fix some margins and padding around the code and in a way, highlight it so it’s well separated from the general text. Problem solved! Nice and simple.

My cache wouldn’t clear automatically, so I simply cleaned the browser cache but had already tested with the incognito mode, the best way to test websites while you are developing them for a new customer base or just want to see quick results instead of cleaning the browser cache.  Here is the final result:

This works perfectly on the white background of my site. I am a happy man and all it took was 20 minutes to do that and also write this blog post about it. A quick lesson in usability and user experience 🙂

Uncategorized

Restart apache on CentOS

Recently, I had a friend setup a CentOS server for me as I personally have experience setting up and managing lamp on Ubuntu servers but needed a CentOS expert. Anyhow, the way to manage Apache on CentOS is a bit different than how it’s done on Ubuntu or debian based Linux. So I was trying to open my site and it wouldn’t connect. After ssh-ing into my box, I realized apache is not working and I needed to restart. Usually on Ubuntu you’d do

httpd restart

but it doesn’t really work, so after a couple minutes of googling, I found it

apachectl start

And, here is the error I got


Syntax error on line 295 of /etc/httpd/conf/httpd.conf:
DocumentRoot '/var/www/html' is not a directory, or is not readable

Now issue was, I deleted the directory without checking if it’s used by apache as I usually remove the default config of apache using `html` directory for default site config. I know, noob mistake. Anyhow, I created that director again and this time


apachectl start

worked like a charm. But I didn’t give up on the httpd command just yet. So tried it again


# httpd restart
Usage: httpd [-D name] [-d directory] [-f file]
[-C "directive"] [-c "directive"]
[-k start|restart|graceful|graceful-stop|stop]
[-v] [-V] [-h] [-l] [-L] [-t] [-S]
Options:
-D name : define a name for use in directives
-d directory : specify an alternate initial ServerRoot
-f file : specify an alternate ServerConfigFile
-C "directive" : process directive before reading config files
-c "directive" : process directive after reading config files
-e level : show startup errors of level (see LogLevel)
-E file : log startup errors to file
-v : show version number
-V : show compile settings
-h : list available command line options (this page)
-l : list compiled in modules
-L : list available configuration directives
-t -D DUMP_VHOSTS : show parsed settings (currently only vhost settings)
-S : a synonym for -t -D DUMP_VHOSTS
-t -D DUMP_MODULES : show all loaded modules
-M : a synonym for -t -D DUMP_MODULES
-t : run syntax check for config files

This time I realized I was doing it without the extra params I had to give to httpd command, so here we go:


[-k start|restart|graceful|graceful-stop|stop]

Now I just wanted to try it


# httpd -k stop
# httpd -k restart

So the first one stops it, I checked after and the site won’t load. That means it worked. Then I simply used restart ( I could have used -k start to start as well) to get it up and running.

This time, above command works perfectly. So a little but of learning today. Moral of the story, just try a little harder before googling it.

Hope this helps 🙂

Link to official CentOS page regarding starting and stopping apache. https://www.centos.org/docs/5/html/Deployment_Guide-en-US/s1-apache-startstop.html

Uncategorized

Javascript: Copy object or variable from console into clipboard

While I was doing some debugging, I badly needed to compare two Javascript objects that I could easily print into console but then was having a hard time remembering all of the differences from one object to the other one. This was a major API change and I couldn’t just get everything off my memory. So I just needed a quick way of copying the JS object into clipboard. With chrome dev tools, I printed both the objects to console with console.log and then used Sublime comparison tool to compare them both and easily note the differences when I needed to.

Here is how to do that:

Right click on the variable or object and then click on “Store as Global Variable”. Since I had two variables that I needed to compare. I saved them both in the same manner.

Chrome Dev Tools – Save console log object into global variable

Chrome Dev Tools – Objects after being saved as Global Variables

Now for the final step, I used copy(temp1) and copy(temp2) to get the variables stored in the clipboard and then subsequently copied them into different files to compare. You can use any file comparison tool for the visual difference which helps with quickly noticing what changed and modify whatever code changes are need for new object in the application. In my case, I used, ‘Compare Side-By-Side‘ package for Sublime Text. As you can see, I can quickly able to see the differences between the properties of object as we changed the API from V1 to V2.

Side-by-side file comparison & difference tool for ST2/3

Uncategorized

React – Lets start with a ‘Hello world’

Skip to real stuff. 

My mom always says, just do it! Or was it Nike? Anyhow, I plan on actually just doing it. Like this guy!

So I am going to challenge myself everyday. It’s 6:35 AM in the morning and I have been up all night. I just want to reinvent myself in the best possible may. May be I just need some new learning. My day job involves Angular 1 so I am kinda bored and want to learn new skills. So here we go:

I am starting with installing and getting a basic “Hello World” app with react. The idea is to spend 30 minutes everyday and share my experiences with you.

All you need to know for this is a little bit about node and what is npm. That’s all. Then simply go into the terminal and type as follows


npm install -g create-react-app
create-react-app hello-world
cd hello-world
npm start

Now after that, you should have a working app which you can open in your browser and have fun looking at it. I’d post more tomorrow. Stay tuned.

Note: This is my personal journey with the react learning and I’d keep posting everyday.

Uncategorized

Hello world!

OK, so here is hoping I blog for the next 365 days. Amen to that!

Right now, it feels like in the process of making a real catapult, I’d end up with something like that

catapult

 

Image stolen from: http://www.instructables.com/id/Mini-Siege-Engines/