On the phackers slack #careeradvice channel, a recurring theme seems to be the higher salaries that developers overseas are paid.
It always starts out with a developer -- usually a novice but not always -- discovering that developers in some other country with the same skillset as him are getting paid 5x (or whatever multiple) he is getting here. Other developers will then helpfully remind him of the greater cost-of-living, higher taxes, etc. in those countries. Invariably someone will say that Pinoy developers are worth more than what they're getting now.
Well, here's an important concept that I have had to explain multiple times:
You're worth whatever the market determines you're worth.
People often forget or ignore the fact that it's not just them and the employer that are negotiating. It's other employers, AND other workers. If you're negotiating with company, do you honestly think you're the only candidate they're considering? Other candidates or applicants may have the same skillset as you, but offer to work for a lower salary (for whatever reason). Other workers competing for the same jobs determine what you'll end up getting as well.
The real way to command a higher rate, regardless of whether it's local employment or remote, is to be as @mparaz and @radeinla put it, the special snowflake. If you're a commodity programmer, you get the commodity programmer rate because there are so many other candidates with the same or similar skillset.
If you have, or can signal that you have a particular set of skills and there is a demand for those skills, then congrats, special snowflake, you can command a higher rate. The more difficult to obtain those skills (or signals) are, and the greater the demand, the better able you will be to command a higher rate whether here or abroad.
For developers unable to make it to the annual Google I/O conference, Google holds I/O Extended events in cities around the world. This year Google Developer Group Philippines went all out and held I/O Extended events in five major cities, demonstrating their new APIs and services available to developers.
For the Manila leg, I ran a workshop for Google Cloud Platform's Natural Language API, for an audience of mostly students. In retrospect, NLP is too advanced and specialized field for undergrads or novice developers, unless they have a specific application or are using NLP already.
A number of the students couldn't get past signing up with GCP, which requires a credit card.
In the future, I'll need to be more upfront with the prerequisites and level of experience needed to get the most out of my workshops.
Yesterday morning at Microsoft Philippines, I gave a short talk introducing AI and machine learning to software engineers. Instead of walking through my usual R or Python code, I did a demo using Microsoft's own ML Studio, which was helpful for visualizing the machine learning process.
Most of the Q&A was about the possible impact of AI on jobs, inequality and security/privacy.
This is a quick reference to installing kerasR, a slim wrapper around Keras starting with the required Python packages.
Create a virtualenv:
$ virtualenv pydata --python=/usr/bin/python3 Running virtualenv with interpreter /usr/bin/python3 Using base prefix '/usr' New python executable in /home/brian/pydata/bin/python3 Also creating executable in /home/brian/pydata/bin/python Installing setuptools, pip, wheel...done. $ source pydata/bin/activate (pydata) $
Install keras. This will also install the other prerequisites for doing any sort of datasciency stuff in Python (numpy, pandas) as well as Theano. Tensorflow will be installed in the next step.
(pydata) $ pip install keras Collecting keras Collecting six (from keras) Using cached six-1.10.0-py2.py3-none-any.whl Collecting theano (from keras) Collecting pyyaml (from keras) Collecting scipy>=0.14 (from theano->keras) Downloading scipy-0.19.0-cp35-cp35m-manylinux1_x86_64.whl (47.9MB) 100% |████████████████████████████████| 47.9MB 27kB/s Collecting numpy>=1.9.1 (from theano->keras) Downloading numpy-1.13.0-cp35-cp35m-manylinux1_x86_64.whl (16.9MB) 100% |████████████████████████████████| 16.9MB 66kB/s Installing collected packages: six, numpy, scipy, theano, pyyaml, keras Successfully installed keras-2.0.4 numpy-1.13.0 pyyaml-3.12 scipy-0.19.0 six-1.10.0 theano-0.9.0
(pydata) $ pip install tensorflow
In R, install the kerasR package:
> install.packages("kerasR") Installing package into ‘/home/brian/R/x86_64-pc-linux-gnu-library/3.4’ ... ** testing if installed package can be loaded successfully loaded keras * DONE (kerasR)
This may also install the reticulate package, which is an interface to Python objects and methods.
A guide to using kerasR is provided as a vignette.
If you get an error message when executing library(kerasR) saying:
> library(kerasR) keras not available See reticulate::use_python() to set python path, then use kerasR::keras_init() to retry
this means kerasR (or more specifically, reticulate) can't find the keras python package, you need to start R after loading your virtualenv:
$ source pydata/bin/activate (pydata) $ R > library(kerasR) Using TensorFlow backend. successfully loaded keras >
import pandas as pd from nltk.tokenize import word_tokenize from nltk.corpus import stopwords from string import punctuation
raw = pd.read_csv("../files/Philippine Startups - Sheet1.csv")
descriptions = raw['Long Description'] descriptions.head()
0 Arthrologic designs and develops a TKA (Total ... 1 BluLemons Gaming Studio is an all-Filipino th... 2 Croo enables people to swiftly send informatio... 3 The Company has the opportunity to create the ... 4 Despite current transponder technologies avail... Name: Long Description, dtype: object
raw_words = word_tokenize(" ".join(descriptions))
stop_words = set(stopwords.words('english') + list(punctuation)) words = [w.lower() for w in raw_words if w.lower() not in stop_words and not w.isdigit() and len(w) > 3]
['arthrologic', 'designs', 'develops', 'total', 'knee', 'arthroplasty', 'system', 'simple', 'evidence-based', 'utilizing', 'successful', 'clinical', 'data', 'improve', 'surgical', 'skills', 'easy-to-use', 'surgeon-friendly', 'instrumentation', 'assure']
word_str = " ".join(words) word_str[:1000]
'arthrologic designs develops total knee arthroplasty system simple evidence-based utilizing successful clinical data improve surgical skills easy-to-use surgeon-friendly instrumentation assure successful predictable results offer competitive cost provide greater majority patients access technology improve living \u200bthe product asian-fit 2-component total knee arthroplasty system definitive surgical treatment severe end-stage osteoarthritic knees \u200bblulemons gaming studio all-filipino theme mobile gaming studio develop games based filipino culture \u200bthey believe creating mobile games great avenue showcase philippines offer globally vision create games impact filipino youth across cultures croo enables people swiftly send information loved ones need arises without typing anything calling anyone button accessory clicked sent predetermined emergency contacts smartphone application text message contains important information person’s current location nearby landmarks person’s contacts equipped '
with open("../files/phstartupwords.txt","w") as f: f.write(word_str)
Find the Atmel touchscreen device:
$ xinput --list ⎡ Virtual core pointer id=2 [master pointer (3)] ⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)] ⎜ ↳ FocalTechPS/2 FocalTech FocalTech Touchpad id=17 [slave pointer (2)] ⎜ ↳ Logitech USB Optical Mouse id=20 [slave pointer (2)] ⎜ ↳ Atmel id=10 [slave pointer (2)] ⎣ Virtual core keyboard id=3 [master keyboard (2)] ↳ Virtual core XTEST keyboard id=5 [slave keyboard (3)] ↳ Power Button id=6 [slave keyboard (3)] ↳ Sleep Button id=9 [slave keyboard (3)] ↳ USB2.0 UVC HD Webcam id=13 [slave keyboard (3)] ↳ Video Bus id=7 [slave keyboard (3)] ↳ AT Translated Set 2 keyboard id=16 [slave keyboard (3)] ↳ Video Bus id=8 [slave keyboard (3)] ↳ Asus WMI hotkeys id=15 [slave keyboard (3)]
The Atmel device is our touchscreen.
Use the xinput disable and enable commands to turn the touchscreen off or on again.:
$ xinput disable Atmel $ xinput enable Atmel
Both commands are silent, unless you specify a device that doesn't exist.