Startup : Some global advice from books

So, I’m starting a Startup and I need to understand the process, to have a big picture. This article is intended to be a roadmap from the books I’ve read and the info I gathered on the field of honor.

As Startup we don’t have the luxury to make big mistakes, but we also don’t have the luxury to deliver a polished product on their first trial. So we should focus on making a product that makes what it’s made for, and make it well. Also, catch errors before they grow.

But how do I know what my product should do ?

There is 2 sources of input :

  • Internal ideas from everybody in the startup
  • Clients

With all those ideas there is a TODO list big enough to fill the next years, so : How do I choose? (because, yes, apparently I have to choose !)

  • Have authentic core values to help prioritize.
  • Have written mission statement.
  • Know which phase of the process I am in.
  • Validate proof of ideas with A-B Testing.

Then make a plan !

Internal ideas from everybody in the startup

Brainstorm like the life of the startup depends on it !

Need lots of space for creativity !

Good sleep !

Everybody should be trusted and have the opportunity to implement new ideas.

Ideas from clients

Know the customers, know who they are, know how they use the app/product, know their problems, hopes, know when they are happy and when they are not.

And concentrate on doing everything to make them happy !

The core values

A simple sentence that will show the goal of the company (yes we see long term so : company)

I found this is a good read on the subject : https://foundr.com/define-core-values

The mission Statement

A set of Statements that helps foster what the previous article called “company culture”.

On the same note here is a good read : https://www.thebalancesmb.com/how-to-write-a-mission-statement-2948001

The phases of the startup

The idea

I have an idea ?!? That’s Great !

Now it needs to mature, we need to take some time to look around, speak around, compare, read, make it better.

The educated guess

Now let’s transform it into a project. Find a pitch, a strategy, look for money, make a plan.

Next step is proving the concept(s) with a simple showcase website or any experiment that has value. If it fails it is mandatory to pivot and try again, this is crucial.

The early adopters

With the concept in mind, let’s focus on the MVP (Minimum Viable Product). We need early adapters to understand that it might not be a perfect product but we are counting on them to improve the product, they are a part of it and for that we will be forever grateful !

Growth

Now we have a good enough product and customers are starting to pile up, so the word in mind is : GROWTH. We need to attract ever more customers. And we need a new strategy !

The strategies are :

  • Use the early adopters to act as cheerleaders.
  • Use industry experts, bloggers, leaders in the industry to spread the word.
  • Advertisement (social media, magazines, ad mob, flyers etc…)

The tools :

  • Create/refine your slogan.
  • Communicate clearly and smartly.

Projectchunk : Ionic4 – Debuging on Android

I am setting up my app to be a PWA and an android app currently so I wanted to to debug on my real Android device.

It turned out to be extremely easy !

Run the app on your device

This command is the command you are looking for :

ionic cordova run android --device --livereload --debug

The options are :

–device : [cordova/native-run] Deploy build to a
device

–livereload : Spin up dev server to live-reload www files

–debug : [cordova] Mark as a debug build

Debug

Simply use Chrome or Chromium

Go to the dev tools (either F12, Ctrl+alt+i or Cmd+option+i).

The following tab will appear :

You can now access the full debug mode as if the app was running on your chrome browser ! Including the console as you can see

Troubleshooting

https://developers.google.com/web/tools/chrome-devtools/remote-debugging

Projectchunk : Ionic4/Angular8/PWA – Kickstart project

This article is a part of the series of articles about ionic4 and Angular8.

To kickstart the project :

Update ionic

npm install -g ionic

Create the structure

ionic start y.projectchunk blank --type=ionic-angular
ionic cordova platform add android    ionic build

Firebase

create the firebase project

Go to the Firebase console and start a new project

https://console.firebase.google.com

project name : y.projectchunk

add a web application because we’ll want to publish the app as an PWA

application name : y.projectchunk.web

Kubuntu : Add new swap

Version of Kubuntu : 18.04

First check the status of the swap

swapon --show

	NAME       TYPE SIZE USED PRIO
	/swapfile file   8G 7,7G   -2

display information about the current state of the swap

From here create a new swap file with an other name

sudo fallocate -l 16G /swapfile2
sudo chmod 600 /swapfile2
sudo mkswap /swapfile2

Create a new swapfile

And activate it

sudo swapon /swapfile2
sudo vim /etc/fstab

Activate the new swap

/swapfile2 none swap sw 0 0

add this line to /etc/fstab

You should not have to restart your system

Remove the old swap

First deactivate your old swap (this can take some time !)

sudo swapoff /swapfile

Deactivate the old swap

Then delete the old swap file

sudo rm -rf /swapfile

Change changes in the for future

sudo vim /etc/fstab

edit the file system table and remove the reference to the old swap

Projectchunk : Ionic4/Angular8 – RxJS tutorial – Observables and Subjects

RxJS is a library for dealing with streams.

Before we even start, here is the Stackblitz of the code I am using in this article

Observable

An Observable is a wrapper for dynamic data that allows ONE subscriber to be notified whenever the data changes.

Create an Observable

const elephant = Observable.create(observer => {
  observer.next('trump');
  observer.next('eyes');
  observer.complete();
  observer.next('tail'); // will not be broadcasted
});

elephant.subscribe(console.log);

const tiger = of('tiger');
hello.subscribe(console.log);// tiger

const giraphe = from('giraphe', asyncScheduler);
giraphe.subscribe(console.log); // g, i, r, a, p, h, e

const clickObservable = fromEvent(document, 'click');
clickObservable.subscribe(console.log);

const comingBackObservable = interval(500);
comingBackObservable.subscribe(console.log); // 0, 1, 2, 3 ...

Cold Observable

The default behavior : Whenever a new subscriber subscribes, the create method is played again.

Hot Observable

Hot Observables allows more than one subscriber to listen to the same Observable without repeating the call to the create method.

hot = cold.pipe(share());

The problem is that Hot Observables just mean “all subscribers subscribe to the same data source”. But the first subscriber still calls the create method and all future subscribers will be notified of FUTURE updates.

Hot Observable with replay

Most likely this is not the desired outcome because you still want to get the last emitted values when someone new subscribes. This is the job of “`shareReplay“` and “`publishReplay“`

hot=cold.pipe(shareReplay());
hot=cold.pipe(publishReplay());
hot=cold.pipe(publishReplay().refCount());

The (main?) difference between both is that publishReplay will automatically stop after the last subscriber unsubscribes if used with refCount.

nb: Don’t forget that you may want to subscribe later so shareReplay is a safer option as long as you don’t forget to close the stream manually.

Will I get all the last datas or just the previous one ?

Good question !

By default you will get ALL the datas from the stream (they have been stored in memory for you and all the future subscribers).

hot=cold.pipe(shareReplay(1));
hot=cold.pipe(publishReplay(1));

In most cases you just want the last one.

Subject

Most of the times you don’t want to create an hot observable from a cold one but create a Subject.

Subject behaves like hot observables (with the share method so they don’t store the history) but they do not have a create method, the messages are pushed .

BehaviorSubject

This is the holyGrail of Observables/Sujbects.

It is a Subject that works like it has a shareReplay(1) so it will give you the “current” value of the stream.

Close the pipes

unsubscribe

if you subscribe, then you should unsubscribe later

take()

take takes a number in agrument and closes the stream after.

takeWhile()

use the function to determine if it should close or not

takeUntil()

use an Observable to cancel the current stream when the Observable in parameters emits anything.

Operators

Pipe

Pipe is the function that you apply to a function in order to use operators on each value that “runs” in the operator.

const myNewObservable = myObservable.pipe(operator(), operator());

Pseudo code to use pipe

It is interesting to note that when a new value is emited, each observer will run through the stack of pipe for that value.

Deal with the datas

map()

map takes a function as argument, that function has the current value as a parameter and should return a new value that will replace it.

(oldValue) => {/* ... */return newValue}

tap()

tap is just like map but you can’t change the value by returning the new value. Basically it is used to DO something at that point of the pipe.

scan()

scan takes a function as argument, that function is like “reduce” in JS, it builds an accumulator (the last value) through the values.

(accumulator, oldvalue) => {return theNewValueThatWillBeTheNextAccumulator}

filter()

filter takes a function as argument, that function has the current value in parameter and should return true or false, only true values will be keps in the stream

(value) => {/* ... */return trueIfWeWantToKeepTheValue}

Too many data

debounceTime()

takes an number of ms in argument. It will filter out every value and if, after the number of ms in argument no value arrived, it will give the last value that passed.

Use case : search function where you don’t want to have a new value at every key stroke, but only a search when he stopped typing for some ms.

throttleTime()

takes an number of ms in argument. It will return AT MOST one value every “X ms”

bufferCount()

takes an integer and will aggregate chunk of that amount.

switchmap()

Switchmap is so important that it has it’s own category 🙂

Switchmap is a little like map but when you want to change the NATURE of the flow, it maps values to observable. Cancels the previous inner observable.

Use case : You have an Observable of the user and you want to use it’s ID to get a list of it’s posts.

posts$ = user$.pipe(switchMap(user => {return queryUserPostsReturnsObservable(user.ID))});

Combining Observables

The following functions

merge

Merge combines the Observables they receive as input parameters (spread) into a single Observable.

It just merge the observables and emits any new data from any source

combineLatest

Merge combines the Observables they receive as input parameters (in an array) into a single Observable.

From the moment there is some data in all the streams, whenever a new data comes in, the observer will receive all the latest data of all the streams.

Error handling

catchError

catches error and replace it with new value given as an Observable

retry

Automatically retries when error

Inspirations

http://reactivex.io/ -> https://rxjs.dev/

Kubuntu : use mouse shortcuts

Version of Kubuntu : 18.04

Guide to setup mouse shortcuts to control the UI on Kubuntu.

Prerequisites

Install xbindkeys and qdbus

sudo apt-get install xbindkeys
sudo apt-get install qdbus

Create a default xbindkeys config file

xbindkeys --defaults-guile > /home/<HOME_FOLDER>/.xbindkeysrc.scm

Which mouse event

To get the mous events description you can use the xev utilities

xev | grep button

You will get output like

    state 0x10, button 1, same_screen YES
    state 0x110, button 1, same_screen YES
    state 0x10, button 8, same_screen YES
    state 0x10, button 8, same_screen YES
    state 0x10, button 9, same_screen YES
    state 0x10, button 9, same_screen YES
    state 0x10, button 10, same_screen YES
    state 0x10, button 10, same_screen YES

the corresponding events will be b:1 for button 1, b:10 for button 10 etc…

Which script

Get a full list of the KDE Kwin desktop shortcut with

qdbus org.kde.kglobalaccel /component/kwin org.kde.kglobalaccel.Component.shortcutNames

they are to be used with the command (you can try them in the terminal)

qdbus org.kde.kglobalaccel /component/kwin org.kde.kglobalaccel.Component.invokeShortcut "<YOUR SHORTCUT>"

Stitch all of that into shortcut

Edit the .xbindkeysrc.scm file that we created earlier with your prefered editor

v ~/.xbindkeysrc.scm
(xbindkey '(Control "b:9") "/home/<HOME_FOLDER>/Documents/dev/conf/scripts/ctrl_mouse_arrow_next.sh")
(xbindkey '(Control "b:8") "/home/<HOME_FOLDER>/Documents/dev/conf/scripts/ctrl_mouse_arrow_previous.sh")

(xbindkey '("b:10") "/home/sephah/<HOME_FOLDER>/dev/conf/scripts/mouse_thumb.sh")
(xbindkey '(Control "b:10") "/home/<HOME_FOLDER>/Documents/dev/conf/scripts/ctrl_mouse_thumb.sh")
(xbindkey '("b:13") "/home/<HOME_FOLDER>/Documents/dev/conf/scripts/mouse_zoom.sh")

Here is the content of those files

WARNING : DO NOT FORGET TO MAKE THEM EXECUTABLE

#!/bin/bash

# Loop through the x axis of windows
qdbus org.kde.kglobalaccel /component/kwin org.kde.kglobalaccel.Component.invokeShortcut 'Switch One Desktop to the Right'

# Or use "go to next desktop"
# qdbus org.kde.KWin /KWin nextDesktop

ctrl_mouse_arrow_next.sh

#!/bin/bash

# Loop through the y axis of windows
qdbus org.kde.kglobalaccel /component/kwin org.kde.kglobalaccel.Component.invokeShortcut 'Switch One Desktop Up'

# Or use "go to previous desktop"
# qdbus org.kde.KWin /KWin previousDesktop

ctrl_mouse_arrow_previous.sh

#!/bin/bash

# key binding to Control F8
# Which is binded to show all desktops
xte 'keydown Control_L' 'key F8' 'keyup Control_L'

ctrl_mouse_thumb.sh

#!/bin/bash

# Show all app "Expose" style (like in mac)
qdbus org.kde.kglobalaccel /component/kwin org.kde.kglobalaccel.Component.invokeShortcut Expose

mouse_thumb.sh

#!/bin/bash

# Show desktop script
# ref : https://askubuntu.com/a/399280

current_mode="$(wmctrl -m | grep 'showing the desktop')"

if [[ "${current_mode##* }" == ON ]]; then
    wmctrl -k off
else
    wmctrl -k on
fi

mouse_zoom.sh

Start the script

With the command :

xbindkeys
# Or if you already started the xbindkey and want to update the key bidings
killall xbindkeys && xbindkeys

References

Some inspiration for xbindkeys : https://pryp.in/blog/19/zoom-the-screen-with-alt-scroll-in-kde.html

The script for “showing desktop” : https://askubuntu.com/a/399280

More shortcut ideas and xev command : https://blog.hanschen.org/2009/10/13/mouse-shortcuts-with-xbindkeys/

Improve it

Shortcut for zoom : https://bbs.archlinux.org/viewtopic.php?id=106494

More shortcut ideas : https://martinovic.blog/post/kdeconnect_commands/

Other idea for looping through desktops : https://www.reddit.com/r/kde/comments/8h92z0/command_line_command_to_switch_virtual_desktop/