├── README.md ├── pics ├── architecture │ ├── architecture_c4model_maps.jpg │ ├── architecture_c4model_scope.jpg │ └── architecture_web_101.png ├── arduino_led.jpg ├── breadboard.png ├── database │ ├── database_1nf.jpg │ ├── database_2nf.jpg │ ├── database_3nf.jpg │ ├── database_denormalization.jpg │ ├── database_many_to_many_1.jpg │ ├── database_many_to_many_2.jpg │ ├── database_normalization.jpg │ ├── database_one_to_many_1.jpg │ ├── database_one_to_many_2.jpg │ ├── database_one_to_one_1.jpg │ └── database_one_to_one_2.jpg ├── electronics │ ├── khan_current.jpg │ └── khan_voltage.jpg ├── elm │ ├── TEA.png │ └── elm_arch.png ├── express │ └── express_middleware.jpg ├── git │ └── git_workflow.jpg ├── grid.jpg ├── inherit.jpg ├── js_event_loop.png ├── mvc_full_stack.jpg ├── networking │ ├── OSI.png │ ├── OSI_vs_TCPIP.jpg │ ├── TCPIP.jpg │ ├── data_flow.jpg │ ├── http.jpg │ └── ping.jpg ├── product │ ├── market_fit │ │ └── market_fit_startup_stages.jpg │ ├── mvp │ │ ├── mvp_airbnb.jpg │ │ ├── mvp_stripe.jpg │ │ └── mvp_twitch.jpg │ ├── pricing │ │ ├── pricing_billion_formula.jpg │ │ ├── pricing_optimization.jpg │ │ ├── pricing_quadrants.jpg │ │ ├── pricing_rule.jpg │ │ ├── pricing_sales_stages.jpg │ │ └── pricing_thermometer.jpg │ └── sales │ │ ├── sales_conversations_phone.jpg │ │ ├── sales_cycle.jpg │ │ ├── sales_expectations.jpg │ │ ├── sales_follow_up.jpg │ │ └── sales_reality.jpg ├── react │ └── react_components.jpg ├── rfid_wiegand_arduino.jpg └── sql │ └── pivot_unpivot.png └── topics ├── algos.md ├── ansible.md ├── architecture.md ├── arduino.md ├── assembly.md ├── async.md ├── babel.md ├── base.md ├── bash.md ├── bitwise.md ├── brainjs.md ├── caching.md ├── compression.md ├── config.md ├── cron.md ├── css.md ├── dbdesign.md ├── docker.md ├── dom.md ├── dotnet.md ├── electricity.md ├── electron.md ├── electronics.md ├── elm.md ├── es6.md ├── excel.md ├── express.md ├── filesystem.md ├── fp.md ├── git.md ├── googleapi.md ├── graphql.md ├── javascript.md ├── linux.md ├── logging.md ├── middleware.md ├── mobile.md ├── mssql.md ├── mvc.md ├── mysql.md ├── networking.md ├── nginx.md ├── node.md ├── nodemcu.md ├── oop.md ├── productMVP.md ├── productMarketFit.md ├── productPricing.md ├── productSales.md ├── puppeteer.md ├── raspberrypi.md ├── react.md ├── restful.md ├── rfid.md ├── security.md ├── ssh.md ├── ssl.md ├── stats.md ├── systemd.md ├── tabulator.md ├── testing.md ├── tmux.md ├── users.md ├── vagrant.md ├── vim.md ├── vm.md ├── vscode.md ├── vue.md ├── wasm.md └── webpack.md /README.md: -------------------------------------------------------------------------------- 1 | # Programming 2 | 3 | ### Javascript 4 | 5 | - [Javascript](./topics/javascript.md) 6 | - [ES6](./topics/es6.md) 7 | - [OOP](./topics/oop.md) 8 | - [DOM](./topics/dom.md) 9 | - [Async](./topics/async.md) 10 | - [FP](./topics/fp.md) 11 | 12 | ### Frontend 13 | 14 | - [CSS](./topics/css.md) 15 | - [React](./topics/react.md) 16 | - [Vue](./topics/vue.md) 17 | - [Electron](./topics/electron.md) 18 | - [Elm](./topics/elm.md) 19 | - [Tabulator](./topics/tabulator.md) 20 | 21 | ### Backend 22 | 23 | - [Node](./topics/node.md) 24 | - [Express](./topics/express.md) 25 | - [Middleware](./topics/middleware.md) 26 | - [nginx](./topics/nginx.md) 27 | - [GraphQL](./topics/graphql.md) 28 | - [Caching](./topics/caching.md) 29 | - [Logging](./topics/logging.md) 30 | - [SSL](./topics/ssl.md) 31 | - [Puppeteer](./topics/puppeteer.md) 32 | 33 | ### Database 34 | 35 | - [Design](./topics/dbdesign.md) 36 | - [MySQL](./topics/mysql.md) 37 | - [SQL Server](./topics/mssql.md) 38 | 39 | ### Tooling 40 | 41 | - [Git](./topics/git.md) 42 | - [Babel](./topics/babel.md) 43 | - [Webpack](./topics/webpack.md) 44 | - Typescript 45 | - [VS Code](./topics/vscode.md) 46 | 47 | ### Architecture 48 | 49 | - [MVC](./topics/mvc.md) 50 | - [Architecture](./topics/architecture.md) 51 | - Use Cases 52 | - [RESTful](./topics/restful.md) 53 | 54 | ### Concepts 55 | 56 | - File Organization 57 | - Authentication 58 | - [Security](./topics/security.md) 59 | - [Testing](./topics/testing.md) 60 | - [Bitwise](./topics/bitwise.md) 61 | - [Binary base](./topics/base.md) 62 | 63 | ### Useful 64 | 65 | - [Algorithms](./topics/algos.md) 66 | - [Google API](./topics/googleapi.md) 67 | - [Assembly](./topics/assembly.md) 68 | - [WebAssembly](./topics/wasm.md) 69 | - [.NET](./topics/dotnet.md) 70 | - [Excel](./topics/excel.md) 71 | - [Statistics](./topics/stats.md) 72 | 73 | ### Mobile 74 | 75 | - [Overview](./topics/mobile.md) 76 | 77 | # Linux 78 | 79 | ### Administration 80 | 81 | - [basics](./topics/linux.md) 82 | - [filesystem](./topics/filesystem.md) 83 | - [users](./topics/users.md) 84 | - [config](./topics/config.md) 85 | - [systemd](./topics/systemd.md) 86 | 87 | ### Tools 88 | 89 | - [bash](./topics/bash.md) 90 | - [tmux](./topics/tmux.md) 91 | - [vim](./topics/vim.md) 92 | - [ssh](./topics/ssh.md) 93 | - [compression](./topics/compression.md) 94 | - [cron](./topics/cron.md) 95 | 96 | # DevOps 97 | 98 | ### Virtualization 99 | 100 | - [VM](./topics/vm.md) 101 | - [Vagrant](./topics/vagrant.md) 102 | 103 | ### Containerization 104 | 105 | - [Docker](./topics/docker.md) 106 | 107 | ### Configuration Management 108 | 109 | - [Ansible](./topics/ansible.md) 110 | 111 | # Networking 112 | 113 | - [Networking](./topics/networking.md) 114 | 115 | # Electronics 116 | 117 | ### General 118 | 119 | - [Electronics](./topics/electronics.md) 120 | - Terminology 121 | - Communication Protocols 122 | - Components 123 | - [RFID](./topics/rfid.md) 124 | 125 | ### Gadgets 126 | 127 | - [Raspberry Pi](./topics/raspberrypi.md) 128 | - [Arduino](./topics/arduino.md) 129 | - [NodeMCU](./topics/nodemcu.md) 130 | 131 | ### Electricity 132 | 133 | - [Electricity](./topics/electricity.md) 134 | 135 | # Machine Learning 136 | 137 | - [Brain.js](./topics/brainjs.md) 138 | 139 | # Product 140 | 141 | - [MVP](./topics/productMVP.md) 142 | - [Pricing](./topics/productPricing.md) 143 | - [Sales](./topics/productSales.md) 144 | - [Product Market Fit](./topics/productMarketFit.md) 145 | 146 | # Googling 147 | 148 | ``` 149 | "exact query" - Search for the exact phrase 150 | website.com: query - Search only in the website 151 | query 2017..2018 - Seach in the date range 152 | filetype:pdf query - Search just for file type 153 | ``` 154 | -------------------------------------------------------------------------------- /pics/architecture/architecture_c4model_maps.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/architecture/architecture_c4model_maps.jpg -------------------------------------------------------------------------------- /pics/architecture/architecture_c4model_scope.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/architecture/architecture_c4model_scope.jpg -------------------------------------------------------------------------------- /pics/architecture/architecture_web_101.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/architecture/architecture_web_101.png -------------------------------------------------------------------------------- /pics/arduino_led.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/arduino_led.jpg -------------------------------------------------------------------------------- /pics/breadboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/breadboard.png -------------------------------------------------------------------------------- /pics/database/database_1nf.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/database/database_1nf.jpg -------------------------------------------------------------------------------- /pics/database/database_2nf.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/database/database_2nf.jpg -------------------------------------------------------------------------------- /pics/database/database_3nf.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/database/database_3nf.jpg -------------------------------------------------------------------------------- /pics/database/database_denormalization.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/database/database_denormalization.jpg -------------------------------------------------------------------------------- /pics/database/database_many_to_many_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/database/database_many_to_many_1.jpg -------------------------------------------------------------------------------- /pics/database/database_many_to_many_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/database/database_many_to_many_2.jpg -------------------------------------------------------------------------------- /pics/database/database_normalization.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/database/database_normalization.jpg -------------------------------------------------------------------------------- /pics/database/database_one_to_many_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/database/database_one_to_many_1.jpg -------------------------------------------------------------------------------- /pics/database/database_one_to_many_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/database/database_one_to_many_2.jpg -------------------------------------------------------------------------------- /pics/database/database_one_to_one_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/database/database_one_to_one_1.jpg -------------------------------------------------------------------------------- /pics/database/database_one_to_one_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/database/database_one_to_one_2.jpg -------------------------------------------------------------------------------- /pics/electronics/khan_current.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/electronics/khan_current.jpg -------------------------------------------------------------------------------- /pics/electronics/khan_voltage.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/electronics/khan_voltage.jpg -------------------------------------------------------------------------------- /pics/elm/TEA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/elm/TEA.png -------------------------------------------------------------------------------- /pics/elm/elm_arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/elm/elm_arch.png -------------------------------------------------------------------------------- /pics/express/express_middleware.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/express/express_middleware.jpg -------------------------------------------------------------------------------- /pics/git/git_workflow.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/git/git_workflow.jpg -------------------------------------------------------------------------------- /pics/grid.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/grid.jpg -------------------------------------------------------------------------------- /pics/inherit.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/inherit.jpg -------------------------------------------------------------------------------- /pics/js_event_loop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/js_event_loop.png -------------------------------------------------------------------------------- /pics/mvc_full_stack.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/mvc_full_stack.jpg -------------------------------------------------------------------------------- /pics/networking/OSI.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/networking/OSI.png -------------------------------------------------------------------------------- /pics/networking/OSI_vs_TCPIP.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/networking/OSI_vs_TCPIP.jpg -------------------------------------------------------------------------------- /pics/networking/TCPIP.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/networking/TCPIP.jpg -------------------------------------------------------------------------------- /pics/networking/data_flow.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/networking/data_flow.jpg -------------------------------------------------------------------------------- /pics/networking/http.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/networking/http.jpg -------------------------------------------------------------------------------- /pics/networking/ping.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/networking/ping.jpg -------------------------------------------------------------------------------- /pics/product/market_fit/market_fit_startup_stages.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/product/market_fit/market_fit_startup_stages.jpg -------------------------------------------------------------------------------- /pics/product/mvp/mvp_airbnb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/product/mvp/mvp_airbnb.jpg -------------------------------------------------------------------------------- /pics/product/mvp/mvp_stripe.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/product/mvp/mvp_stripe.jpg -------------------------------------------------------------------------------- /pics/product/mvp/mvp_twitch.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/product/mvp/mvp_twitch.jpg -------------------------------------------------------------------------------- /pics/product/pricing/pricing_billion_formula.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/product/pricing/pricing_billion_formula.jpg -------------------------------------------------------------------------------- /pics/product/pricing/pricing_optimization.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/product/pricing/pricing_optimization.jpg -------------------------------------------------------------------------------- /pics/product/pricing/pricing_quadrants.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/product/pricing/pricing_quadrants.jpg -------------------------------------------------------------------------------- /pics/product/pricing/pricing_rule.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/product/pricing/pricing_rule.jpg -------------------------------------------------------------------------------- /pics/product/pricing/pricing_sales_stages.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/product/pricing/pricing_sales_stages.jpg -------------------------------------------------------------------------------- /pics/product/pricing/pricing_thermometer.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/product/pricing/pricing_thermometer.jpg -------------------------------------------------------------------------------- /pics/product/sales/sales_conversations_phone.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/product/sales/sales_conversations_phone.jpg -------------------------------------------------------------------------------- /pics/product/sales/sales_cycle.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/product/sales/sales_cycle.jpg -------------------------------------------------------------------------------- /pics/product/sales/sales_expectations.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/product/sales/sales_expectations.jpg -------------------------------------------------------------------------------- /pics/product/sales/sales_follow_up.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/product/sales/sales_follow_up.jpg -------------------------------------------------------------------------------- /pics/product/sales/sales_reality.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/product/sales/sales_reality.jpg -------------------------------------------------------------------------------- /pics/react/react_components.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/react/react_components.jpg -------------------------------------------------------------------------------- /pics/rfid_wiegand_arduino.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/rfid_wiegand_arduino.jpg -------------------------------------------------------------------------------- /pics/sql/pivot_unpivot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petasittek/notes/449206b4416145810d31c1468c33e0b5b3c7cfb5/pics/sql/pivot_unpivot.png -------------------------------------------------------------------------------- /topics/algos.md: -------------------------------------------------------------------------------- 1 | # Useful Algorithms 2 | 3 | ```javascript 4 | let data = [ 5 | { id: 1, name: "a" }, 6 | { id: 2, name: "b" }, 7 | { id: 3, name: "c" }, 8 | { id: 4, name: "d" }, 9 | { id: 5, name: "e" } 10 | ] 11 | ``` 12 | 13 | ## Shuffle array 14 | ```javascript 15 | function shuffleArray(array) { 16 | for (var i = array.length - 1; i > 0; i--) { 17 | var j = Math.floor(Math.random() * (i + 1)); 18 | var temp = array[i]; 19 | array[i] = array[j]; 20 | array[j] = temp; 21 | } 22 | return array; 23 | } 24 | 25 | let shuffled = shuffleArray(data); 26 | console.log(shuffled); 27 | ``` 28 | 29 | ## Sort array 30 | ```javascript 31 | // true desc, false asc 32 | let dynamicSort = function(field, reverse, primer){ 33 | 34 | let key = primer ? 35 | function(x) {return primer(x[field])} : 36 | function(x) {return x[field]}; 37 | 38 | reverse = !reverse ? 1 : -1; 39 | 40 | return function (a, b) { 41 | return a = key(a), b = key(b), reverse * ((a > b) - (b > a)); 42 | }; 43 | } 44 | 45 | let sorted = data.sort(dynamicSort("id", false)); 46 | console.log(sorted); 47 | ``` 48 | 49 | -------------------------------------------------------------------------------- /topics/ansible.md: -------------------------------------------------------------------------------- 1 | # Ansible 2 | 3 | What should the server look like vs How to make it that way. 4 | 5 | We configure the state of a server, rather than the installation process with scripts, or god forbid manual installation by typing each command. 6 | 7 | More importantly, it offers built-in monitoring and alerting after deployment, instead of configuring our own for each machine. Ex. Which servers are running which version? 8 | 9 | The configuration scripts serve as documentation compared to reading cryptic bash scripts. 10 | 11 | Ansible is a **declarative** system. Instead of saying **Install something**, we say **I want something to be installed** i.e. if it's already isntalled, do nothing... Otherwise install it. 12 | 13 | Ansible commands are idempotent, meaning they always result in the same, no matter how many times they run. 14 | 15 | Ansible does not require anything to run on the remote servers, aside from SSH access with private/public RSA keys. 16 | 17 | Ansible uses the `jinja2` templating engine to inject variables with `{{variable}}`. 18 | 19 | ## Things needed 20 | 21 | #### Inventory 22 | 23 | A list of machines to do things on. Can be a simple text file. 24 | 25 | ```ansible 26 | server1.company.com 27 | server2.company.com 28 | ``` 29 | 30 | Machines can be grouped by using `[group]`. Machines can belong to several groups. 31 | 32 | ```ansible 33 | [database] 34 | db1.company.com 35 | db2.company.com 36 | ``` 37 | ## Commands 38 | 39 | `ansible database -i invetory -m ping` - Run the ping module (-m) on all the machines in the database group, located in the inventory (-i) list. 40 | 41 | `ansible database -i inventory -m apt -a "name=mysql-server state=present"` - If mysql is not installed, install it on all machines missing it in the database group. 42 | 43 | ## Playbook 44 | 45 | Instead of running commands one by one, we can define a playbook(.yml) with all the commands in one place. 46 | 47 | Each task should have a name, so that it's printed in the output as it runs, as well as serve as documentation. 48 | 49 | ```yml 50 | -- 51 | - hosts: all 52 | tasks: 53 | - name: Update package list 54 | apt: update_cache=yes cache_valid_time=36000 # last 10 hours. 55 | 56 | - hosts: database 57 | tasks: 58 | - name: Install MySQL 59 | apt: name=mysql-server state=present 60 | - name: Copy fixtures 61 | template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf 62 | ``` 63 | 64 | `ansible-playbook -i inventory playbook.yml` - Run the playbook. 65 | 66 | #### Variables 67 | 68 | To prevent repetition, we can define variables and inject them where needed. 69 | 70 | ```yml 71 | -- 72 | - hosts: database 73 | vars: 74 | fixture_name: fixtures.sql # Variable 75 | tasks: 76 | - name: Install MySQL 77 | apt: name=mysql-server state=present 78 | - name: Copy fixtures 79 | copy: src={{fixture_name}} dest=/tmp/{{fixture_name}} 80 | ``` 81 | 82 | #### Loops 83 | 84 | ```yml 85 | -- 86 | - hosts: all 87 | tasks: 88 | - name: Install packages 89 | apt: name={{item}} state=present 90 | with_items: # Loop 91 | - python 92 | - python-pip 93 | - vim 94 | ``` 95 | 96 | #### Loops with Variables 97 | 98 | ```yml 99 | -- 100 | - hosts: all 101 | vars: 102 | packages: # Variable 103 | - python 104 | - python-pip 105 | - vim 106 | tasks: 107 | - name: Install packages 108 | apt: name={{item}} state=present 109 | with_items: packages # Variable 110 | ``` 111 | 112 | ## File Organization Convention 113 | -------------------------------------------------------------------------------- /topics/architecture.md: -------------------------------------------------------------------------------- 1 | "Software Architecture" is just a fancy way of saying "how code is organised" and/or how "data flows" through a system. Whenever you see the word "pattern" it just means "a bunch of experienced people have concluded that this works well, so as beginners, we don't have to think too hard (up-front)." 2 | 3 | # Web App Example 4 | 5 | ![Web 101](../pics/architecture/architecture_web_101.png) 6 | 7 | [Source](https://engineering.videoblocks.com/web-architecture-101-a3224e126947) 8 | 9 | # C4 Model 10 | 11 | [Source](https://www.youtube.com/watch?v=1zYK615kepE) 12 | 13 | The model prevents unstandardized drawings of architectures due to the lack of common vocabulary. A common set of abstractions is more important than a common notation i.e. **"Abstraction first, notation second"**. 14 | 15 | Very often the code does not match the architecture diagrams. The diagrams are maps that help developers navigate a large and complex codebase. 16 | 17 | ![C4](../pics/architecture/architecture_c4model_maps.jpg) 18 | 19 | ## Abstraction 20 | 21 | ![Abstraction](../pics/architecture/architecture_c4model_scope.jpg) 22 | 23 | A **software system** is made up of one or more **containers**, each of which contains one or more **components**, which in turn are implemented by one or more **code elements**. It's basically zooming in or out. 24 | 25 | - Context of the System 26 | - Containers 27 | - Components 28 | - Code 29 | 30 | #### Example 31 | 32 | - **[Context]** Customer uses CRM 33 | - **[Container]** Front End - Single Page App 34 | - **[Component]** Login component 35 | - **[Component]** Leads component 36 | - **[Code]** HTML 37 | - **[Code]** CSS 38 | - **[Code]** Javascript functions 39 | - **[Container]** Back End - RESTful API 40 | - **[Component]** Login endpoints 41 | - **[Component]** Leads endpoints 42 | - **[Code]** GET api/leads 43 | - **[Code]** GET api/lead/1 44 | - **[Code]** POST api/leads 45 | - **[Container]** Database 46 | - **[Component]** Login tables 47 | - **[Component]** Leads tables 48 | - **[Code]** lead table 49 | - **[Code]** lead_item table 50 | - **[Code]** lead_type table 51 | 52 | ## Notation 53 | 54 | Use shape, color and size to **complement** a diagram that already makes sense. 55 | 56 | ### Titles 57 | Short and meaningful. Include the diagram type. Ex. [System Context] Financial Risk System 58 | 59 | ### Acronyms 60 | 61 | Avoid using them as much as possible. At least provide the full meaning when using them. 62 | 63 | ### Elements 64 | 65 | Start with simple boxes containing the element's: 66 | - Name 67 | - Type 68 | - Technology 69 | - Description/Responsibility 70 | 71 | #### Example 72 | 73 | - [Person] **Anonymous User** - Anybody on the web. 74 | - [Software System] **acmeCRM** - Easy to use generic CRM. 75 | - [Container: Node + Express] **Back End API** - Returns JSON data to the Front End applications. 76 | - [Component: Node + Express] **Lead Routes** - Retrieved lead data from the database and returns it to the client. 77 | 78 | ### Lines 79 | 80 | Favor uni-directional lines showing the most important dependencies or data flow, with an annotation to be explicit about the purpose of the line and direction. Read the relationships out loud. 81 | 82 | Instead of: 83 | 84 | [Software System] Trade Data System ---> trade data ---> [Software System] Financial Risk System 85 | [Software System] Trade Data System ---> **sends** trade data **to** ---> [Software System] Financial Risk System 86 | 87 | ### Legend 88 | 89 | Explain the shapes, line styles, colors, borders, acronyms... Even if they are obvious. 90 | -------------------------------------------------------------------------------- /topics/arduino.md: -------------------------------------------------------------------------------- 1 | # Arduino 2 | 3 | **Arduino** is a development board utilizing an **AVR ATMEGA328** MCU (microcontroller). An MCU can't do much unless it's in a circuit. 4 | 5 | The more professional option is to use a separate development board/launchpad for the MCUs. The idea is to plug in the MCU into it, program it, and take it out to be soldered in a circuit, rather than use the whole board like the Arduino. 6 | 7 | Other popular microcontrollers: 8051, PIC, AVR, ARM, MSP 8 | 9 | Microcontrollers have application specific small processing power while microprocessors have general purpose large processing power. 10 | 11 | Microcontrollers have built in RAM, ROM and other peripherals in a single chip. Microprocessors have only the CPU, and other peripherals, RAM, ROM should be connected externally. 12 | 13 | # Programming 14 | 15 | Unlike most previous programmable circuit boards, the Arduino does not need a separate piece of hardware (called a programmer) in order to load new code onto the board – you can simply use a USB cable. 16 | 17 | The Arduino IDE uses a simplified version of C++. 18 | 19 | Arduino basically works by setting something upfront once and then by trapping execution in an infinite loop. 20 | 21 | The code **will not** compile without `setup()` and `loop()`. 22 | 23 | ```c 24 | void setup() { 25 | // Setup code, run once 26 | } 27 | 28 | void loop() { 29 | // Main code, run repeatedly 30 | } 31 | ``` 32 | 33 | # Setup 34 | 35 | We can select the type of board we are working with at tools > board, or add ones with the boards manager. 36 | 37 | We define the way we are connecting to the board via a port at tools > port. It changes each time the board is disconnected. 38 | 39 | # Upload 40 | 41 | The code is compiled and uploaded into the chip via the USB cable. The built-in small LED light will blink in the frequency of the loop to indicate that it's working. 42 | 43 | # Serial Monitor 44 | 45 | We can see what Arduino outputs via tools > serial monitor. If we are getting weird characters, we need to set the **baud** value to the correct one. 46 | 47 | # Pull-up resistor 48 | 49 | Instead of adding resistors manually, we can use the built-in functionality. 50 | 51 | ```c 52 | pinMode(button, INPUT_PULLUP) 53 | ``` 54 | 55 | # digitalWrite vs analogWrite 56 | 57 | `digitalWrite` will set the specified pin to one of two states - HIGH/LOW, which equate to 5v (3.3v on some boards) and ground respectively. 58 | 59 | `analogWrite` can vary by the type of output used. It will set the pin to a periodic high/low signal, where the percentage of the signal spent high is proportional to the value written. Ex. `analogWrite(PIN, 255)`. 60 | 61 | pinMode(buzzerPin, OUTPUT); 62 | 63 | # Simple blinking LED example 64 | 65 | ```c 66 | int LED = 12; 67 | 68 | void setup() { 69 | pinMode(LED, OUTPUT); 70 | } 71 | 72 | void loop() { 73 | digitalWrite(LED, HIGH); 74 | delay(100); 75 | digitalWrite(LED, LOW); 76 | delay(100); 77 | } 78 | ``` 79 | 80 | ![Arduino LED](../pics/arduino_led.jpg) 81 | 82 | # Cop Car 83 | 84 | ```c 85 | int LED_RED = 12; 86 | int LED_BLUE = 13; 87 | int BUZZER = 10; 88 | 89 | void setup() { 90 | pinMode(LED_RED, OUTPUT); 91 | pinMode(LED_BLUE, OUTPUT); 92 | pinMode(BUZZER, OUTPUT); 93 | } 94 | 95 | void loop() { 96 | tone(BUZZER, 200, 250); 97 | digitalWrite(LED_RED, HIGH); 98 | delay(500); 99 | digitalWrite(LED_RED, LOW); 100 | 101 | tone(BUZZER, 400, 250); 102 | digitalWrite(LED_BLUE, HIGH); 103 | delay(500); 104 | digitalWrite(LED_BLUE, LOW); 105 | } 106 | ``` 107 | -------------------------------------------------------------------------------- /topics/assembly.md: -------------------------------------------------------------------------------- 1 | C is pretty much a macro language for assembly. 2 | 3 | Assembly languages are low-level programming languages where you are giving instructiins like 4 | 5 | "load from memory location 123" "load from memory location 124" "add those together" "store the result at memory location 124" "compare to memory 77" "if that location equals 4, jump to instruction 60" 6 | 7 | Different processors have different assembly languages, so you can't run the same assembly programs on, say, x86 and ARM machines. 8 | 9 | 10 | But which assembly to choose? 11 | 12 | Whatever processor you're writing for? Different architectures use different instruction sets 13 | 14 | Let’s say I want one for an amd rizen 3200. Should I pick masm? Gas? Nasm? Yasm? 15 | 16 | They’re all x86_64 assemblers. There isn’t “assembly language” so much as a whole family of assembly languages. It’s not like saying it’s programmed in C is all I’m saying. 17 | 18 | For x86 there are two main dialects of assembly: AT&T and Intel. Personally I prefer Intel, I think it looks cleaner with less sigils, and putting the destination operator first makes more sense with instructions like `sub` and especially with comparison and jump. `sub eax 4` computes eax-4 and stores the result in eax, on AT&T syntax this is written `sub $4 %eax` so you have to read "subtract 4 from eax". And `cmp 4 eax; jl label` is simply "jump if 4 < eax" on Intel syntax, but in AT&T syntax the comparison is swapped to `cmp %eax $4`, but `jl` still means "jump if 4 < eax". It's very easy to get confused. 19 | 20 | Beyond this, the assemblers are mostly different in whether they support macros and what kind. So the choice isn't too important. -------------------------------------------------------------------------------- /topics/babel.md: -------------------------------------------------------------------------------- 1 | Babel is a transpiler (translator + compiler) and it converts modern code into old code, able to run in older browsers. 2 | 3 | ```bash 4 | npm install babel-cli babel-core babel-preset-env 5 | ``` 6 | 7 | `babel-cli` - Command line interface. Takes a js file and returns a transpiled one. 8 | `babel-core` - The transpiling logic. 9 | `babel-preset-env` - Each new javascript feature has a **separate** plugin. Intead of installing them one by one, we can install a preset containing all of them. 10 | 11 | To run the transpiler we can use: 12 | ```bash 13 | # Use the env preset to transpile index.js and put the output in the build folder in index.js. 14 | babel --presets env index.js -o build/index.js 15 | ``` 16 | This command is for one file. In order to transpile many files, a bundler like Webpack is needed. Here, every file is transpiler first, before being added to the bundle. 17 | 18 | We can add this in `package.json` for convenience: 19 | ```json 20 | { 21 | "scripts": { 22 | "babel": "babel --presets env index.js -o build/index.js" 23 | } 24 | } 25 | ``` -------------------------------------------------------------------------------- /topics/base.md: -------------------------------------------------------------------------------- 1 | base = how bytes are represented 2 | 3 | # base-2 - Binary 4 | 5 | Most basic representation. 1 byte is 8 binary characters or bits. 6 | 7 | | 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 | Number | 8 | | :------------ | :------------ | :------------ | :------------ | :------------ | :------------ | :------------ | :------------ | -----: | 9 | | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | 231 | 10 | | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 11 | 12 | 231 = 128 + 64 + 32 + 4 + 2 + 1 13 | 14 | 231 in binary is 1110 0111 15 | 16 | # base-10 - Decimal 17 | 18 | | 102 | 101 | 100 | Number | 19 | | :------------- | :------------- | :------------- | -----: | 20 | | 2 | 3 | 1 | 231 | 21 | 22 | 231 = 200 + 30 + 1 23 | 24 | # base-16 - Hexadecimal 25 | 26 | Encodes 1 byte (8 bits) into 2 hex characters. 27 | 28 | | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | 29 | | :-- | :-- | :-- | :-- | :-- | :-- | :-- | :-- | :-- | :-- | :-- | :-- | :-- | :-- | :-- | :-- | 30 | | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 31 | 32 | 231 in hexadecimal is `E7`. 33 | 34 | | 161 | 160 | Number | 35 | | :------------- | :------------- | -----: | 36 | | E | 7 | 231 | 37 | 38 | E7 = 14 x 161 + 7 x 160 39 | E7 = 14 x 16 + 7 x 1 40 | E7 = 224 + 7 = 231 41 | E7 = 1110 0111 42 | 43 | Hexadecimal numbers have either a `0x` prefix or an `h` suffix. So either `0xE7` or `E7h`. 44 | 45 | # base-64 46 | 47 | Encodes 3 source bytes (24 bits) into 4 base-64 characters. 48 | 49 | I was curious how on EARTH base64 can convert 3 input bytes into 4 output bytes for just 33% space growth (whereas hex converts 1 input byte into 2 output bytes for 100% space growth). Why specifically 3 input bytes? 50 | 51 | The answer is: 52 | 53 | 3 bytes = 3 x 8 bits = 24 bits. 54 | 55 | Why that magic "24 bits" number? Well, base 64 represents the numbers 0 to 63. How are those represented in binary? With 000000 (0) to 111111 (63). 56 | 57 | Bingo! Each base64 character represents 6 bits of input data using a single output byte (a single character such as "Z", etc). 58 | 59 | So 24 bits (3 full bytes of input) / 6 bits (base64 alphabet) = 4 bytes of base64. That's it! 60 | 61 | You may think "Why not base128 (7 bits of input = 8 bits of output), at just 14% size growth when encoding?". The answer for that is that base64 is the best we can find, since the lower 128 ASCII characters aren't all printable. Many are control characters such as NULL etc. 62 | 63 | There are obviously ways to create other systems such as perhaps "base81" etc, since you can do anything you want if you create a custom encoding algorithm. But the beauty of base64 is how it encodes data so cleanly in chunks of 6 bits. So that encoding scheme became popular. 64 | -------------------------------------------------------------------------------- /topics/bash.md: -------------------------------------------------------------------------------- 1 | # Variables 2 | 3 | Setting a command's output into a variable. 4 | ```bash 5 | all="$(ls ./all | wc -l)" && echo "all: ${all}" && resampled="$(ls ./resampled | wc -l)" && echo "resampled: ${resampled}" 6 | ``` 7 | 8 | # Logical 9 | `&&` - AND 10 | `||` - OR 11 | 12 | # Redirection 13 | `>` - Redirect standard output and **overwrite**. 14 | `>>` - Redirect standard output and **append**. 15 | `<` - Redirect input to another command. Ex. `mail mike@somewhere.org < to_do.txt` 16 | 17 | # Piping 18 | `|` - Uses the **output** of one command as the **input** of another. 19 | 20 | # Command Substitution 21 | `$(PROGRAM_PATH)` - Use program output as variable. Ex. `echo "$(/bin/date) - Hi" >> logfile.log` 22 | 23 | # grep 24 | Only works for searching files or standard outputs. 25 | 26 | `grep ` - Returns all the lines containing the search criteria. 27 | 28 | # File movement 29 | 30 | ```bash 31 | # Navigate to D: 32 | cd /mnt/d 33 | 34 | # List all files WITH new line. Pasted in Excel gives one name per cell vertically. 35 | ls -1 > ../pics.txt 36 | 37 | # A && B – Run B only if A succeeded 38 | # One command from main folder 39 | cd 1 && ls -1 > ../pics.txt && cd ../2 && ls -1 >> ../pics.txt && cd .. 40 | 41 | # Wihtout .jpg extension. 42 | cd 1 && ls -1 | tr -d ".jpg" > ../pics.txt && cd ../2 && ls -1 | tr -d ".jpg" >> ../pics.txt && cd .. 43 | 44 | # Navigate to folder with files. List all files and replace new line with comma (,) and export one folder up into .csv file. 45 | ls -1 | tr "\\n" "," > ../pics.csv 46 | 47 | # Append (>>) files from other folder 48 | ls -1 | tr "\\n" "," >> ../pics.csv 49 | 50 | # List the different files from folder 1 vs folder 2 51 | diff <(ls -1a folder1) <(ls -1a folder2) 52 | 53 | # Check for different files not present in folder2 from folder1, and MOVE those in folder3 54 | rsync -rcC --compare-dest=folder2/ folder1/ folder3/ 55 | 56 | # Find all the files with a space in the name 57 | find ./ -name "* *" 58 | 59 | # Find all the files with a space in the name AND move them 60 | find ./ -name "* *" -exec mv -t ../folder {} + 61 | 62 | # Find all the files with a dash - in the name AND move them 63 | find ./ -name "*-*" -exec mv -t ../temp {} + 64 | 65 | # Find all files with 4 characters 66 | find ./ -name "????.jpg" 67 | 68 | # Find all files with 4 characters AND move them 69 | find ./ -name "????.jpg" -exec mv -t ../folder {} + 70 | 71 | # Count number of files in folder 72 | ls | wc -l 73 | 74 | # Count number of files in folder with 6 characters. 75 | find ./ -name "??????.jpg" | wc -l 76 | 77 | # List just the names of the images (without the extension). 78 | ls -1 | sed -e 's/\..*$//' > ../pics.txt 79 | ``` 80 | 81 | # Image manipulation 82 | Requires the `imagemagick` package 83 | ```bash 84 | sudo apt-get install imagemagick 85 | ``` 86 | ### Resizing 87 | ```bash 88 | # Resize image to specific dimensions, while trying to keep aspect ratio. 89 | convert image.jpg -resize 492x492 resized_image.jpg 90 | 91 | # Bulk resizing of images in a folder with conversion statuses, saved in a specified folder. 92 | for file in *.jpg; do convert $file -resize 492x492 ../resized/$file && echo $file converted; done 93 | ``` 94 | 95 | ### Resampling 96 | ```bash 97 | sudo apt install imagemagick 98 | 99 | # Reduce the image quality. Adjust the quality parameter 1-100. 100 | convert image.jpg -sampling-factor 4:2:0 -strip -quality 1 -interlace JPEG -colorspace RGB resampled_image.jpg 101 | 102 | # Bulk resampling of images in a folder with conversion statuses, saved in a specified folder. 103 | for file in *.jpg; do convert $file -sampling-factor 4:2:0 -strip -quality 1 -interlace JPEG -colorspace RGB ../resampled/$file && echo $file resampled; done 104 | ``` 105 | 106 | ### Watermarking 107 | ```bash 108 | # Watermarking 109 | composite -dissolve 30% -gravity center watermark2.jpg image.jpg watermarked_image.jpg 110 | 111 | # Bulk Watermarking (Save in a specific folder) 112 | for file in *.jpg; do composite -dissolve 30% -gravity center ../watermark.jpg $file ./watered/$file && echo $file watermarked; done 113 | ``` -------------------------------------------------------------------------------- /topics/bitwise.md: -------------------------------------------------------------------------------- 1 | 2 | # Bitwise OR 3 | 4 | Sets each bit to 1 if one of two bits is 1. 5 | 6 | ```javascript 7 | // 1 = 00000001 8 | // 2 = 00000010 9 | 10 | console.log(1 | 2) 11 | // 3 = 00000011 12 | ``` 13 | 14 | # Bitwise AND 15 | 16 | Sets each bit to 1 if both bits are 1. 17 | 18 | ```javascript 19 | // 1 = 00000001 20 | // 2 = 00000010 21 | 22 | console.log(1 & 2) 23 | // 0 = 00000000 24 | ``` 25 | 26 | # Bitwise XOR 27 | 28 | Sets each bit to 1 if only one of two bits is 1. 29 | 30 | ```javascript 31 | // 10 = 00001010 32 | 33 | console.log(1 ^ 2) 34 | // 6 = 000000110 35 | ``` 36 | 37 | # Bitwise NOT 38 | 39 | Inverts all the bits. 40 | 41 | # Shift Left 42 | 43 | Add n zeros to the right i.e. remove n bits from the left. (binary to number) 44 | 45 | ``` 46 | 00000 111 (7) << 1 = 0000 111 0 (14) 47 | 00000 101 (5) << 3 = 00 101 000 (40) 48 | ``` 49 | 50 | # Shift Right 51 | 52 | Add n zeros to the left i.e. remove n bits from the right. (binary to number) 53 | 54 | ``` 55 | 00 101010 (42) >> 4 = 000000 10 (2) 56 | 00000 111 (7) >> 1 = 000000 11 (3) 57 | 00 110011 (51) >> 3 = 00000 110 (6) 58 | ``` 59 | -------------------------------------------------------------------------------- /topics/brainjs.md: -------------------------------------------------------------------------------- 1 | Forward propagation = Prediction 2 | Back propagation = Measuring i.e. learning -------------------------------------------------------------------------------- /topics/caching.md: -------------------------------------------------------------------------------- 1 | # Memcached 2 | 3 | It stores key-value pairs in memory for quick access. It doesn't persist data to disk as a database. 4 | 5 | Can be run on a separate machine, but usually it's on the app server. 6 | 7 | When an HTTP request hits the server, it first checks if memcached has the response stored and returns that. If not, it retireves the data from the database, generates the reposnse, and saves it in the cache for future use. 8 | 9 | ```bash 10 | sudo apt-get install memcached 11 | ``` 12 | 13 | ```bash 14 | # key (string) - value (string) 15 | set(key, value) 16 | get(key) 17 | delete(key) 18 | ``` -------------------------------------------------------------------------------- /topics/compression.md: -------------------------------------------------------------------------------- 1 | # gzip 2 | 3 | This package creates a `.gz` compressed file, much like `.rar` or `.zip`. 4 | 5 | ## Compression 6 | `gzip ` - Compress a file. *Deletes original file*. 7 | `gzip -k ` - Compress without deletion. 8 | 9 | `gzip -9 ` - Compression quality 1-9. *Default is 5*. 10 | 11 | 12 | ## Extraction 13 | `gzip -d ` or `gunzip `- Extract. 14 | -------------------------------------------------------------------------------- /topics/config.md: -------------------------------------------------------------------------------- 1 | # Configuration 2 | 3 | **Make a BACKUP before any edits** with `cp file file.ORIGINAL` 4 | 5 | All config files are located in `/etc/`. They are plain text files. 6 | 7 | Use the `less` program to view configuration files, instead of an editor. Ex. `less /etc/ssh/sshd_config`. 8 | 9 | `/`+`string` - Search inside **less** (case sensitive). 10 | `q` - Exit. 11 | -------------------------------------------------------------------------------- /topics/cron.md: -------------------------------------------------------------------------------- 1 | Each user has his own crontab i.e. cron table i.e table of scheduled processes. 2 | 3 | ```bash 4 | # List of tasks 5 | crontab -l 6 | 7 | # Edit crontabs i.e Add a cron job that runs as root. Opens editor. 8 | sudo crontab -e 9 | 10 | # List of crontabs 11 | sudo less /var/spool/cron/crontabs 12 | 13 | # Systemwide crontab 14 | sudo less /etc/crontab 15 | ``` 16 | 17 | # Format 18 | 19 | ```bash 20 | # minute, hour, day-of-month, month-of-year, day-of-week, command 21 | # * = Every 22 | # , = List of values 23 | # x-y = Range of values 24 | # /x = Recurring i.e. every x times 25 | 26 | # Append hello every minute. 27 | * * * * * echo "hello" >> home/user/log.txt 28 | 29 | # At 03:00 on Sunday. 30 | 0 3 * * 0 echo "hello" >> home/user/log.txt 31 | 32 | # At every 20th minute past hour 22 on day-of-month 1 and 15. 33 | */20 22 1,15 * * echo "hello" >> home/user/log.txt 34 | 35 | # At 10:15 on every 2nd day-of-month from 1 through 10 and on Friday. 36 | 15 10 1-10/2 * 5 echo "hello" >> home/user/log.txt 37 | ``` 38 | The timing doesn't overlap meaning it happens in both cases, not a combination of the two. -------------------------------------------------------------------------------- /topics/css.md: -------------------------------------------------------------------------------- 1 | # Grid 2 | 3 | Grid works pretty much like a table i.e. you define a grid with columns and rows, and then assign each child element a position in the grid. 4 | 5 | The positions are the lines at which the elements start or end. A grid with 5 columns and 5 rows is actually 6 lines across (5 columns) and 6 lines over (rows). 6 | 7 | ```html 8 |
9 |
Lorem ipsum dolor sit amet
10 |
11 |
Lorem
12 |
Lorem
13 |
Lorem
14 |
Lorem
15 |
Lorem
16 |
Lorem
17 |
Lorem
18 |
Lorem ipsum dolor sit amet
19 |
20 | ``` 21 | 22 | ```css 23 | #container { 24 | display: grid; 25 | grid-template-columns: 1fr 1fr 1fr 1fr 1fr; /* 5 columns, 6 lines */ 26 | grid-template-rows: repeat(5, 1fr); /* shorthand for 5 rows, 6 lines */ 27 | } 28 | #box1 { 29 | background: red; 30 | grid-column-start: 1; /* start at column line 1 */ 31 | grid-column-end: 2; /* end at column line 1 */ 32 | grid-row-start: 1; /* start at row line 1 */ 33 | grid-row-end: 2; /* end at rown line 1 */ 34 | } 35 | #box2 { 36 | grid-column: 3/-1; /* start at column line 3, end at -1 (last) */ 37 | grid-row: 2/-1; /* start at row line 2, end at -1 (last) */ 38 | display: grid; /* Nested grid */ 39 | grid-template-columns: repeat(3, 1fr); /* With separate columns */ 40 | grid-gap: 10px; /* Space between columns and rows */ 41 | padding: 10px; 42 | background: blue; 43 | } 44 | #box3 { 45 | background: rgba(0, 255, 0, 0.8); 46 | grid-column: 2/4; /* start at column line 2, end at 4 */ 47 | grid-row: 3/5; /* start at row line 3, end at 5 */ 48 | } 49 | .box { 50 | background: yellow; 51 | } 52 | ``` 53 | 54 | This CSS would result in: 55 | ![CSS Grid](../pics/grid.jpg) 56 | 57 | # Flexbox 58 | 59 | This is for 1 dimension only, unlike the 2 dimensional grid. Flexbox can either make a row, or a column. 60 | 61 | It's not a choice of either flex or grid, but rather about combining them. Ex. A login form can be placed in the grid, but the inputs in it can flow with flex. 62 | 63 | ```css 64 | .class { 65 | display: flex; 66 | flex-direction: column; 67 | } 68 | ``` 69 | 70 | # Selectors 71 | 72 | ```CSS 73 | #menuItem:hover .menuSubItems { 74 | /* On the menu item hover, change all elements with the menuSubItems class. */ 75 | } 76 | 77 | #categories > ul > li { 78 | /* Change the lis only if they belong to the ul belonging to #categories. */ 79 | } 80 | 81 | .menuItem ul, li { 82 | /* Change all uls and lis belonging to the menuItem class. */ 83 | } 84 | ``` 85 | 86 | # Animation 87 | 88 | The animations work by flowing from a set of CSS rules, to the ones from the animation. 89 | 90 | ```css 91 | .fadeInOut { 92 | opacity: 0; 93 | /* Use the effect, and last for 2 sec. The effect name can be anything*/ 94 | animation: fadeInOut 2s linear forwards; 95 | -webkit-animation: fadeInOut linear forwards; 96 | } 97 | 98 | /* Fast fade in, long display, fast fade out */ 99 | @keyframes fadeInOut { 100 | 20% { opacity: 1 } /* @ 20% of 2 sec be fully visible */ 101 | 80% { opacity: 1 } /* @ After 80% of 2 sec start fading */ 102 | } 103 | 104 | @-webkit-keyframes fadeInOut { 105 | 20% { opacity: 1 } 106 | 80% { opacity: 1 } 107 | } 108 | ``` 109 | 110 | # Fixed table header 111 | 112 | ```html 113 |
114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 |
Header 1Header 2
Data 1
Data 2
Data 3
125 |
126 | ``` 127 | 128 | #### CSS only 129 | 130 | ```css 131 | th { 132 | position: sticky; /* This makes a header fixed/sticky */ 133 | top: 0px; /* Won't work without this */ 134 | } 135 | ``` 136 | 137 | #### Javascript only 138 | 139 | ```javascript 140 | document.getElementById("table").addEventListener( 141 | "scroll", 142 | function() { 143 | var translate = "translate(0," + this.scrollTop + "px)"; 144 | this.querySelector("thead").style.transform = translate; 145 | }, 146 | false 147 | ); 148 | ``` -------------------------------------------------------------------------------- /topics/dbdesign.md: -------------------------------------------------------------------------------- 1 | # Table Relationships 2 | 3 | **Look both ways (From each perspective) when trying to determine the relationship.** 4 | 5 | 6 | ## One to Many - 90% 7 | 8 | ![One to Many](../pics/database/database_one_to_many_1.jpg) 9 | 10 | ![One to Many](../pics/database/database_one_to_many_2.jpg) 11 | 12 | ## Many to Many - 10% 13 | 14 | ![Many to One](../pics/database/database_many_to_many_1.jpg) 15 | 16 | ![Many to One](../pics/database/database_many_to_many_2.jpg) 17 | 18 | 19 | ## One to One - 0% 20 | 21 | Not a thing.If one row points to only one row, you might as well join the tables. 22 | 23 | 24 | ![One to One](../pics/database/database_one_to_one_1.jpg) 25 | 26 | 27 | Sometimes you think you have a one-to-one relationship, but you don’t. Look both ways (from each perspective) to avoid this. 28 | 29 | ![One to One](../pics/database/database_one_to_one_2.jpg) 30 | 31 | # Normalization 32 | 33 | Taking your database design through these 3 steps will vastly improve the quality of your data. 34 | 35 | There are more than 3 Normal Forms, but usually 3 is the norm. There are more than 6. 36 | 37 | ## First Normal Form (1NF) 38 | 39 | Each of the columns and tables should contain one and only one value without it repeating. 40 | 41 | Usually every 1NF problem is solved by creating a new table. One of the signs for the need is when columns start having the same name with a number differentiating them. Computer1, Computer2… 42 | 43 | ![1NF](../pics/database/database_1nf.jpg) 44 | 45 | 46 | ## Second Normal Form (2NF) 47 | 48 | Any non-key field should be dependent on the entire primary key i.e. “Can I figure out any of the values in the row from just part of the composite key?”. Only a problem when dealing with composite keys. 49 | 50 | ![2NF](../pics/database/database_2nf.jpg) 51 | 52 | ## Third Normal Form (3NF) 53 | 54 | No non-key field is dependent on any other non-key field i.e. “Can I figure out any of the values in this row from any of the other values?”. 55 | 56 | ![3NF](../pics/database/database_3nf.jpg) 57 | 58 | ## Denormalization 59 | 60 | Sometimes tables intentionally break normalization, and some only seem like they do. 61 | 62 | Creating a new table for phones and emails would complicate things needlessly. The same goes for the area codes. 63 | 64 | ![Denormalization](../pics/database/database_denormalization.jpg) -------------------------------------------------------------------------------- /topics/docker.md: -------------------------------------------------------------------------------- 1 | # Docker 2 | 3 | Docker is used to run apps/processes without actually installing them. This is useful because it ensures the same environment is running on all the machines using the images that make the containers. 4 | 5 | **Container** is a running instance of an **image**, which is a template for an environment, a snapshot of a system at a certain time. It has the OS, software and application code all bundled in one file. Images are built via a **Dockerfile**, a list of steps to perform to build the image. List of steps like configure the OS, install packages, copy project files into the right places... 6 | 7 | Dockerfile > (build) Image > (run) Container. 8 | 9 | There should be **only one** process per container. 10 | 11 | Localhost (127.0.0.1) for a container is itself. Containers can access each other by using their names as the domain. 12 | 13 | Docker uses a `unix socket` which means that it runs as `root` and asks for `sudo`. 14 | 15 | ## Installing Docker 16 | 17 | Add the GPG key. 18 | `curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -` 19 | 20 | Add the Docker repository to APT sources. 21 | `sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"` 22 | 23 | Update the package list to include Docker. 24 | `sudo apt-get update` 25 | 26 | Install Docker. 27 | `sudo apt-get install -y docker-ce` 28 | 29 | ## Basic Commands 30 | 31 | `docker run ` - Build a container from an image and run it. Each usage creates a new container. 32 | `docker start ` - Start an existing container by name or id. 33 | `docker stop ` - Stop a container by name or id. 34 | `docker ps` - List all running containers. `-a` for stopped ones. 35 | `docker rm ` - Delete a container by name or id. 36 | `docker exec -it bash` - Enter a container. 37 | 38 | ## Flags 39 | 40 | `--name ` - Name the container. 41 | `-p 8080:80` - Map the container's `80` port, to the webserver's `8080` port i.e. the container can be accessed via `8080`. 42 | `-d` - Run as daemon i.e. background process. 43 | `-v :` - Volume. Mount a local directory as a container directory. Used when not specified in Dockerfile. 44 | 45 | `sudo docker rm $(sudo docker ps -aq)` - Remove all containers. 46 | 47 | ## Build Container with Dockerfile 48 | 49 | #### Dockerfile 50 | `FROM ` - Always at top. Uses an image as a base. 51 | `RUN ` - Run commands on image **build**. Can be chained with &&. 52 | `CMD ["">]` - Run a command on container **start**. 53 | `COPY ` - Copy from local directory to container directory. 54 | `WORKDIR ` - Set work directory. Default is `/`. 55 | `EXPOSE ` - Expose a specific port. 56 | `#` - Comment. 57 | 58 | #### Build 59 | `docker build -t ` - Build an image by running all commands in the Dockerfile. 60 | 61 | ###### nginx Container Example 62 | ```Dockerfile 63 | FROM nginx 64 | COPY ./nginx.conf /etc/nginx/conf.d/default.conf 65 | COPY /src /www 66 | ``` 67 | 68 | ``` 69 | # ./nginx.conf - Bare minimum needed to run nginx. 70 | server { 71 | root /www; 72 | } 73 | ``` 74 | 75 | `sudo docker build -t nginx-static .` - Build the container. 76 | 77 | `sudo docker run -d -p 8080:80 --name nginx-static nginx-static` - For this to work, a port forwarding rule is needed on the VM with host `3000` and guest `8080`. Container `80` > VM `8080` > Host `3000`. 78 | 79 | Visit the website in the host via `127.0.0.1:3000`. 80 | 81 | ## Docker Compose 82 | 83 | `sudo apt-get install docker-compose` or get it from https://github.com/docker/compose/releases. 84 | 85 | After a while, running, starting and stopping containers gets very tedious. Instead of manually typing the docker commands one by one, we can define a `docker-compose.yml` configuration file to do it for us. 86 | 87 | We can either use pre-made Dockerfiles, or we can write their content directly in the compose file. 88 | 89 | All the locations are relative to the docker-compose file. 90 | 91 | ```yml 92 | version: '3' # Version of compose file format. 93 | 94 | services: 95 | products-service: # This can be named anyway. Used for connecting containers. 96 | build: ./products # Folder containing Dockerfile. 97 | volumes: # List of volumes to be mounted. 98 | - ./products:/usr/src/app # Source:Container 99 | ports: # List of ports. 100 | - 5001:80 # Host:Container port forwarding. 101 | ``` 102 | 103 | `sudo docker-compose build` - Recreate image. 104 | `--no-cache` - Recreate without cache. 105 | 106 | `sudo docker-compose up` - Run container. 107 | `sudo docker-compose dowm` - Stop and remove container. 108 | 109 | #### Container Networking 110 | 111 | ```yml 112 | version: "3" 113 | services: 114 | web: 115 | build: . 116 | ports: 117 | - "8000:8000" 118 | db: 119 | image: postgres 120 | ports: 121 | - "8001:5432" 122 | ``` 123 | 124 | When you run docker-compose up, the following happens: 125 | - A network called `myapp_default` is created. 126 | - A container is created using web’s configuration. It joins the network `myapp_default` under the name `web`. 127 | - A container is created using db’s configuration. It joins the network `myapp_default` under the name `db`. 128 | 129 | Each container can now look up the hostname web or db and get back the appropriate container’s IP address. For example, web’s application code could connect to the URL postgres://db:5432 and start using the Postgres database. 130 | 131 | It is important to note the distinction between HOST_PORT and CONTAINER_PORT. In the above example, for db, the HOST_PORT is 8001 and the container port is 5432 (postgres default). Networked service-to-service communication use the CONTAINER_PORT. When HOST_PORT is defined, the service is accessible outside the swarm as well. 132 | 133 | Within the web container, your connection string to db would look like postgres://db:5432, and from the host machine, the connection string would look like postgres://{DOCKER_IP}:8001. 134 | -------------------------------------------------------------------------------- /topics/dom.md: -------------------------------------------------------------------------------- 1 | Instead of using JQuery for simple DOM manipulation, we can use Vanilla JS to achieve the same. JQuery is simply an abstraction library. 2 | 3 | # Select 4 | ```javascript 5 | // By ID 6 | document.getElementById('id'); 7 | 8 | // By class 9 | document.getElementsByClassName('class-name'); // Returns an array 10 | 11 | // By tag 12 | document.getElementsByTagName('li'); // Returns an array 13 | ``` 14 | 15 | ### Query Selector 16 | Can select any element with the same command, but it grabs **only the first one**. This is pretty much JQuery if we replace `document.querySelector` with `$`. 17 | 18 | ```javascript 19 | document.querySelector('#id'); // ID 20 | document.querySelector('.class-name'); // Class 21 | document.querySelector('li'); // Tag 22 | 23 | // Select specific element by Class 24 | document.querySelector('.class-name:nth-child(2)'); // Just the 2nd one. 25 | 26 | // Select all elements 27 | document.querySelectorAll('.class-name'); 28 | 29 | // Select all elements by Class 30 | document.querySelectorAll('.class-name:nth-child(odd)'); // Every other one. Returns array. 31 | 32 | // Examples 33 | document.querySelector("header .container"); 34 | document.querySelector("header h1"); 35 | ``` 36 | ### Display 37 | ```javascript 38 | // Show the class. 39 | element.className; 40 | 41 | // Return an array of classes. The array can be modified with .add or .remove 42 | element.classList; 43 | ``` 44 | 45 | ### Parent/Child 46 | ```javascript 47 | var element = document.getElementById('id'); 48 | 49 | // Parent 50 | element.parentNode // Selects the parent element. 51 | element.parentNode.parentNode // Ad infinitum 52 | 53 | // Child 54 | element.children // Returns an array. 55 | element.firstElementChild 56 | element.lastElementChild 57 | 58 | // Bad child. These include blank elements in the returned array. 59 | element.childNode 60 | element.firstChild 61 | element.lastChild 62 | 63 | // Sibling 64 | element.nextElementSibling // Not nextSibling. 65 | element.previousElementSibling // Not previousSibling. 66 | ``` 67 | 68 | # Change 69 | ```javascript 70 | var element = document.getElementById('id'); 71 | 72 | // Text 73 | element.textContent = "New text"; 74 | element.innerText = "New text"; 75 | 76 | // HTML 77 | element.innerHtml = "
Text
"; 78 | 79 | // CSS 80 | element.style.borderBottom = "solid 1px red"; 81 | ``` 82 | 83 | ### Common Elements 84 | `document` - Whole DOM. 85 | `document.domain` - The domain name. 86 | `document.URL` - The URL. 87 | `document.title` - The title. 88 | `document.doctype` - The document type. 89 | `document.head` - The head object. 90 | `document.body` - The body object. 91 | `document.forms` - Array of all forms. 92 | `document.links` - Array of all links. 93 | `document.images` - Array of all images. 94 | 95 | # Create / Remove 96 | ```javascript 97 | // Element 98 | var element = document.createElement("div"); 99 | 100 | // Class 101 | element.className = "class-name"; 102 | 103 | // classList 104 | element.classList.add("class-name"); 105 | element.classList.remove("class-name"); 106 | 107 | // ID 108 | element.id = "id"; 109 | 110 | // Attribute 111 | element.setAttribute("title", "Hello World!"); 112 | 113 | // Text Node 114 | var text = document.createTextNode("Hello World!"); 115 | 116 | // Add text to div 117 | element.appendChild(text); 118 | 119 | // Remove the child element 120 | element.removeChild(text); 121 | ``` 122 | 123 | ### Bulk 124 | ```javascript 125 | let elements = document.querySelectorAll('.class el') 126 | elements.forEach(el => { 127 | el.className = "" 128 | }); 129 | ``` 130 | 131 | # Events 132 | 133 | ### Old way 134 | 135 | ```html 136 | 137 | ``` 138 | ```javascript 139 | function buttonClick(){ 140 | console.log("Button clicked."); 141 | } 142 | ``` 143 | 144 | ### Event Listener 145 | ```html 146 | 147 | ``` 148 | ```javascript 149 | var button = document.getElementById("button"); 150 | 151 | button.addEventListener("click", buttonClick); 152 | 153 | function buttonClick(){ 154 | console.log("Button clicked."); 155 | } 156 | ``` 157 | We can pass in the event and do all kinds of things with it, as it contains information such as the event type, mouse coordinates etc. 158 | ```javascript 159 | function buttonClick(e){ 160 | console.log(e); // Logs the event. 161 | console.log(e.target); // The clicked element. 162 | console.log(e.target.id); // Clicked element id. 163 | console.log(e.target.className); // Clicked element class. 164 | 165 | console.log(e.ctrlkey); // Is control pressed boolean. altkey, shiftkey... 166 | } 167 | ``` 168 | 169 | ### Bulk Event Listeners 170 | ```javascript 171 | document.querySelectorAll('#myTable td') 172 | .forEach(el => el.addEventListener("click", (e) => { 173 | // Here, `this` refers to the element the event was hooked on 174 | console.log("clicked", e.target.value) 175 | })); 176 | ``` 177 | Thit creates a separate function for each cell; **instead, you could share one function without losing any functionality.** 178 | 179 | ```javascript 180 | function clickHandler(e) { 181 | // Here, `this` refers to the element the event was hooked on 182 | console.log("clicked", e.target.value) 183 | } 184 | 185 | document.querySelectorAll('#myTable td') 186 | .forEach(el => el.addEventListener("click", clickHandler)); 187 | ``` 188 | 189 | **Example** 190 | ```javascript 191 | var hover = document.querySelectorAll('.hover'); 192 | 193 | // The functions are cointained inside another one to prevent execution on load. 194 | hover.forEach(e => e.addEventListener("mouseover", () => mouseOver(e))); 195 | hover.forEach(e => e.addEventListener("mouseout", () => mouseOut(e))); 196 | 197 | function mouseOver(e) { 198 | e.classList.remove("w3-black"); 199 | e.classList.add("w3-teal"); 200 | } 201 | 202 | function mouseOut(e) { 203 | e.classList.remove("w3-teal"); 204 | e.classList.add("w3-black"); 205 | } 206 | ``` 207 | 208 | ### Mouse 209 | ```javascript 210 | element.addEventListener("click", runEvent); 211 | ``` 212 | 213 | `click`- On click. 214 | `dblclick`- On double click. 215 | `mousedown` - On mouse button press. 216 | `mouseup` - On mouse button release. 217 | `mouseenter` - On hover over the element (parent) itself. 218 | `mouseover` - On hover over the child elements. 219 | `mouseleave` - On blur out of the element (parent) itself. 220 | `mouseout` - On blur out of child elements. 221 | `mousemove` - Any mouse movement. 222 | 223 | ### Input 224 | ```javascript 225 | var itemInput = document.querySelector('input[type="text"]'); 226 | var form = document.querySelector('form'); 227 | var select = document.querySelector('select'); // A selector with options. 228 | 229 | itemInput.addEventListener("keydown", runEvent); // Input events. 230 | select.addEventListener("change", runEvent); // Selector events. "input" works the same. 231 | 232 | function runEvent(e){ 233 | console.log(e.target.value); // Logs out the input value. Or selector value. 234 | } 235 | ``` 236 | `focus` - On input click event. 237 | `blur` - Click outside of input event. 238 | `copy, cut, paste` - Input action events. 239 | `input` - Any interaction with the input. 240 | 241 | ### Submit 242 | Submitting a form registers an event for a split second and it vanishes. In order to prevent that and make it persistent, we need to use the event method `preventDefault()` i.e. it stops the normal form submission to a file. 243 | 244 | ```javascript 245 | form.addEventListener("submit", runEvent); 246 | 247 | function runEvent(e){ 248 | e.preventDefault(); 249 | console.log(e.target.value); // Logs out the input value. Or selector value. 250 | } 251 | ``` 252 | 253 | ### Keyboard 254 | `keydown` - Any keyboard button press and release. 255 | `keyup` - Button release. 256 | `keypress` - Button press. 257 | 258 | ### Custom Events 259 | 260 | ```javascript 261 | function send(channel, payload){ 262 | let event = new CustomEvent(channel, { 263 | detail: payload 264 | }) 265 | dispatchEvent(event); 266 | } 267 | 268 | function on(channel){ 269 | addEventListener(channel, (e) => { 270 | console.log(e.detail) 271 | }, false); // bubbles 272 | } 273 | 274 | on("foo"); // Register listener 275 | 276 | send("foo", "bar"); // Catch event and print "bar" 277 | ``` 278 | -------------------------------------------------------------------------------- /topics/dotnet.md: -------------------------------------------------------------------------------- 1 | # .NET Framework 2 | 3 | It's a computing framework for building applications on Windows, and it serves as an environment in which computer programs can run. 4 | 5 | It is composed of: 6 | - **Assemblies**, which are typically `.exe` or `.dll` files that contain compiled code which requires .NET to run. 7 | - **The Common Language Runtime (CLR)**. This is a set of Windows libraries whose job is to run assemblies. It's essentially a Virtual Machine. 8 | - **Class libraries**. A set of object-oriented APIs which can be used by assemblies. 9 | 10 | It's possible for anyone to create a compiler that compiles a language for .NET, but the most common languages that use .NET are C# and VB.NET. 11 | 12 | If you write your code to the framework, you can be sure it will work on anything that the framework says it can run on. In the case of Windows .NET, that means 'any' version of Windows. In the case of .NET Core, that's starting to mean 'any' modern device. 13 | 14 | ### CLR 15 | 16 | It's an application sitting in memory, whose job is to translate IL Code (Intermediate Language) into Machine Code i.e. JIT (Just-in-time-compilation). 17 | 18 | Java's "CLR" is called "JVM". 19 | 20 | C/C++ > Machine Code 21 | Java > ByteCode (JVM) > Machine Code 22 | C# > IL Code (CLR) > Machine Code 23 | 24 | ### .dll 25 | 26 | Basically a module i.e. a collection of reusable code for other programs to call. 27 | 28 | ### .bat 29 | 30 | A script file, equivalent to a Linux shell/bash script. 31 | 32 | ### Class Library 33 | 34 | Applications consist of the building block classes. 35 | 36 | Related classes are organized in containers called Namespaces. 37 | 38 | Namespaces are organized in an Assembly, either an EXE (Executable) or DLL (Dynamically Linked Library) 39 | 40 | When the application is compiled, one or more Assemblies are made. 41 | 42 | # For Development 43 | 44 | 1. .NET contains a large set of programs which you can call through your program. These are the programs which contain simple functions like join two arrays to complex functions like translate voice to text /or recognize red object in a image(image analyses) etc, Provide functionality to make a internet application, mobile application etc, alot of them are provided(you can call those functions from your program). The .NET libraries are soo vast that you can program Robots/Arduino etc to develop signal processing, image analysis, large set of web application frameworks, etc. 45 | 46 | 2. It maintains a common language underneath and allows you to program in different higher level languages like C#, VB, IronPython etc. When you compile it convert to a common language. It provides different set of build tools to develop applications, integrate, add other frameworks, allow others to easily write frameworks, etc. 47 | 48 | # For End User: 49 | 50 | When you develop a program in .NET (or you can say using .NET) to run this program on many other computers you need to have a corresponding .NET framework available on that computer. So you have to install the .NET framework before you run your program. The .NET framework which you install on different computers have all the functionality your program needs but it wont have the tools for compile/build/develop .NET applications (because those are not needed on the end user machines. They also ported this framework to Linux so you can run .NET applications on Linux platform. -------------------------------------------------------------------------------- /topics/electronics.md: -------------------------------------------------------------------------------- 1 | # Terminology 2 | 3 | #### Circuit 4 | 5 | Your circuit is the collection of all the connections you’ve made, using wires, resistors, LEDs, buttons, GPIO and other pins, etc. 6 | 7 | It can be closed (like when you press a button, and a signal is able to traverse from one end to the other), or it can be open (a button is not pressed, or there’s some other break in the circuit). 8 | 9 | An open circuit is like a long train of dominos, where you've removed 4 or 5 from the middle. You can try sending a signal from one end, but it's never going to bridge the gap. 10 | 11 | #### Firmware 12 | 13 | A set of programs and routines that are built into the device running them. They are typically essential for the basic operation of the device and are not usually accessible by the user. 14 | 15 | #### Serial 16 | 17 | Data sent over time, most often one single bit after another. All the protocols are serial protocols. 18 | 19 | #### Bus 20 | 21 | A set of wires which transfer data. One wire can carry one bit: a 0 (low voltage) or 1 (high voltage). A bus is just a collection of wires, so a 4-bit bus has four wires and can carry four bits. 22 | 23 | #### Relay 24 | 25 | It's an electronic switch. Instead of manually flipping it, it's done via a 5V signal. It can be open (NO) or closed (NC) by default, so the signal would od the opposite. Ex. Arduino sends a signal to the relay to close the circuit for turning on a lamp. 26 | 27 | #### Abbreviations 28 | 29 | **Baud** - Measure for communication speed over a data channel. Equivalent to bits per second. 30 | 31 | **VIN** - Voltage that is currently supplied to the board. 32 | 33 | **VCC** - Input pin on the board if you want to power it from a pin instead of a port. 34 | 35 | **COM** - Common connection for relay or transistor outputs. When the output is activated, the PLC will energize the relay or transistor, effectively connecting the NO (normally open) pin to the COM (common) pin.. 36 | **NO** - Normally open relay. 37 | **NC** - Normally closed relay. 38 | 39 | #### PWM 40 | 41 | Pulse Width Modulation, or PWM, is a technique for getting analog results with digital means. Digital control is used to create a square wave, a signal switched between on and off. This on-off pattern can simulate voltages in between full on (5 Volts) and off (0 Volts) by changing the portion of the time the signal spends on versus the time that the signal spends off. 42 | 43 | # GPIO - General Purpose Input Output 44 | 45 | Used to interact with the real world. 46 | 47 | Each GPIO pin has two states. You can call them on or off, high or low, 1 or 0, etc. A pin is set "high" when it's outputting 3.3v or reading in 3.3v, and "low" when it's off. 48 | 49 | Output pins are like switches that the Raspberry Pi can turn on or off (like turning on/off a LED light). But it can also send a signal to another device. 50 | 51 | Input pins are like switches that you can turn on or off from the outside world (like a on/off light switch). But it can also be a data from a sensor, or a signal from another device. 52 | 53 | ## Floating 54 | 55 | The pins receive surrounding noise from other electronic devices, which interferes with the regular signals. This is called a **floating pin**. 56 | 57 | This also happens with with other modules such as a switch on a breadboard. 58 | 59 | To prevent this, we need to use a **pull-up resistor** i.e. pull the pin up to a voltage when nothing happens (switch is off) 60 | 61 | Micro-controllers have built-in pull-up resistors. 62 | 63 | ### Pull Down 64 | 65 | When you have a circuit that connects 3.3v to a GPIO pin, it'll read HIGH when the circuit is closed. When it's open, it could read anything. You need a "pull down" resistor connecting your circuit to ground, so that it reads LOW when the circuit is open. (I'll show this in effect later.) 66 | 67 | ### Pull Up 68 | 69 | Similarly, if you have a circuit connecting your GPIO pin to ground when it's closed, it'll read LOW. You need a "pull up" resistor so that, when it's open, it defaults to the HIGH state. 70 | 71 | # Communication Protocols 72 | 73 | **I2C** - Easiest and most expandable bus. Raspberry has two I2C buses, bus 0 and bus 1. Capable of expanding the Rpi to thousands of output ports. Programming is very easy. 74 | 75 | **SPI** - Only 2 chip select lines so max number of devices is very limited. Bus is faster and can be driven over longer cable runs than I2C. Programming more difficult. Device selection very limited unless you are willing to solder SMD. 76 | 77 | **UART (RS-232)** - Welcome to the 1970s. Lever shifters are a must. No intelligence at all. Pretty boring stuff actually. 78 | 79 | ## I2C - Inter-Integrated Circuit 80 | 81 | It's a bus that allows easy communication between components which reside on the same circuit board. 82 | 83 | It's a synchronous protocol, and it's the first we see which has some "intelligence" in it; the other ones dumbly shifted bits in and out, and that was that. 84 | 85 | I2C uses only 2 wires, one for the clock (SCL) and one for the data (SDA). That means that master and slave send data over the same wire, again controlled by the master who creates the clock signal. 86 | 87 | I2C doesn't use separate Slave Selects to select a particular device, but has addressing. The first byte sent by the master holds a 7 bit address (so that you can use 127 devices on the bus) and a read/write bit, indicating whether the next byte(s) will also come from the master or should come from the slave. 88 | 89 | After each byte, the receiver must send a "0" to acknowledge the reception of the byte, which the master latches with a 9th clock pulse. 90 | 91 | If the master wants to write a byte, the same process repeats: the master puts bit after bit on the bus and each time gives a clock pulse to signal that the data is ready to be read. 92 | 93 | If the master wants to receive data it only generates the clock pulses. The slave has to take care that the next bit is ready when the clock pulse is given. 94 | 95 | This protocol is patented by NXP (formerly Phillips), to save licensing cost, Atmel using the word TWI (2-wire interface) which exactly same as I2C, so any AVR device will not have I2C but it will have TWI. 96 | 97 | Two or more signals on the same wire may cause conflicts, and you would have a problem if one device sends a "1" while the other sends a "0". Therefore the bus is wired-OR'd: two resistors pull the bus to a high level, and the devices only send low levels. If they want to send a high level they simply release the bus. 98 | 99 | - SDA - Serial data 100 | - SCL - Serial clock 101 | 102 | ## SPI - Serial Peripheral Interface 103 | 104 | The SPI bus is a serial communication protocol for controlling and communicating with almost any digital electronic device that accepts a clocked serial stream of bits. SPI is typically used for short distance communication and most commonly found in embedded devices. 105 | 106 | A master sends a clock signal, and upon each clock pulse it shifts one bit out to the slave, and one bit in, coming from the slave. Signal names are therefore SCK for clock, MOSI for Master Out Slave In, and MISO for Master In Slave Out. 107 | 108 | By using SS (Slave Select) signals the master can control more than one slave on the bus. There are two ways to connect multiple slave devices to one master, one is mentioned above i.e. using slave select, and other is daisy chaining, it uses fewer hardware pins (select lines), but software gets complicated. 109 | 110 | - MISO - Master Input, Slave Output 111 | - MOSI - Master Output, Slave Input 112 | - SCLK - Serial Clock 113 | - SS - Slave Select 114 | 115 | ## UART - Universal Asynchronous Receiver-Transmitter (Serial) 116 | 117 | A computer microchip used for translation between parallel and serial data. 118 | 119 | The UART functions to convert parallel data from PC bus lines to serial data for transmission via line drivers to RS-232, RS-422, and RS-485 devices. 120 | 121 | UART is responsible for sending and receiving a sequence of bits. At the output of a UART these bits are usually represented by logic level voltages. These bits can become RS-232, RS-422, RS-485, or perhaps some proprietary spec. 122 | 123 | This is, essentially, a serial communications interface. The "universal" part means that it can be configured to support many different specific serial protocols. The term is generic, and does not represent a specific standard. At minimum it means that it has a TX and an RX line, which sends a serial data stream and receives a serial data stream. 124 | 125 | It's one of the most used serial protocols. Most controllers have a hardware UART on board. It uses a single data line for transmitting and one for receiving data. 126 | 127 | Most often 8-bit data is transferred, as follows: 128 | - 1 start bit (low level) 129 | - 8 data bits 130 | - 1 stop bit (high level) 131 | 132 | The low level start bit and high level stop bit mean that there's always a high to low transition to start the communication. That's what describes UART. No voltage level, so you can have it at 3.3 V or 5 V, whichever your microcontroller uses. 133 | 134 | Note that the microcontrollers which want to communicate via UART have to agree on the transmission speed, the bit-rate, as they only have the start bits falling edge to synchronize. That's called asynchronous communication. 135 | 136 | - TxD - Transmitter, carries data from DTE to DCE. 137 | - RxD - Receiver, carries data from DCE to DTE. 138 | 139 | **TTL** (Transistor Transistor Logic) is not a protocol. It's an older technology for digital logic, but the name is often used to refer to the 5 V supply voltage, often incorrectly referring to what should be called UART. 140 | 141 | ### RS-232 142 | 143 | A standard defining the signals (serial communication transmission of data) between two devices, defining the signal names, their purpose, voltage levels, connectors and pinouts. 144 | 145 | - DTE (data terminal equipment) ex. computer terminal. 146 | - DCE (data communication equipment) ex. modem. 147 | 148 | # Breadboard 149 | 150 | Red - Power 151 | Blue - Ground 152 | Green - Tie-points (Do not cross the trench) 153 | Trench - Middle 154 | 155 | ![TEA](../pics/breadboard.png) 156 | 157 | # Components 158 | 159 | #### Resistor 160 | 161 | #### Capacitor 162 | 163 | #### Diode 164 | 165 | #### Transistor 166 | -------------------------------------------------------------------------------- /topics/elm.md: -------------------------------------------------------------------------------- 1 | # Elm 2 | 3 | Elm code can be tested in the [sandbox app](http://elm-lang.org/examples/hello-html) without installation. 4 | 5 | # Install 6 | ```bash 7 | sudo npm install -g elm # Normal install 8 | sudo npm install --unsafe-perm -g elm # If npm gives you permission errors. 9 | ``` 10 | 11 | `elm-package install elm-lang/PACKAGE_NAME` - Install dependencies. 12 | 13 | #### Alternative 14 | Install yarn 15 | ```bash 16 | curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - 17 | echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list 18 | sudo apt-get update && sudo apt-get install yarn 19 | ``` 20 | 21 | Install Elm 22 | ```bash 23 | export PATH="$PATH:`yarn global bin`" # Add in order to use Elm commands. 24 | yarn global add elm 25 | ``` 26 | # Elm "Hello World!" 27 | Create the `Main.elm` file. This, along with all the dependecies will transpile into Javascript in step 3. 28 | 29 | ```elm 30 | import Html exposing (text) 31 | 32 | main = 33 | text "Hello, World!" 34 | ``` 35 | Create the `index.html` file, which will load the javascript file created in step 3. 36 | 37 | ```html 38 | 39 | 40 | 41 |
42 | 43 | 46 | 47 | 48 | ``` 49 | 50 | Compile/transpile the elm code into javascript. 51 | ```bash 52 | elm-make Main.elm --output=main.js # Locations are relative. 53 | ``` 54 | 55 | The result from this is the creation of: 56 | - `elm-stuff` - Holds the dependecies, like `node_modules`. 57 | - `elm-package.json` - Lists the dependecies, like `package.json`. 58 | - `main.js` - The transpiled elm code, to be used in `index.html`. 59 | 60 | # Build/Compile 61 | `elm-make Main.elm --output=../public/main.js` - Build 62 | 63 | # App Build Order 64 | 65 | 1. Connect modules / Navigation 66 | 2. Login 67 | 3. Saving Token 68 | 4. Logout 69 | 5. Lock/Control Access to Pages 70 | 6. Individual Pages (Modules) 71 | 72 | # The Elm Architecture 73 | 74 | ![TEA](../pics/elm/TEA.png) 75 | 76 | There are 3 main wiring parts between modules. They happen in the `Model`, `Update` and `View`. 77 | 78 | ![TEA](../pics/elm/elm_arch.png) 79 | 80 | # ChildModule.elm 81 | 82 | ```elm 83 | module ChildModule exposing(..) 84 | ``` 85 | 86 | **Note:** In order to import a module in `Main`, the source folder (where all the modules are) needs to be added in the `elm-package.json` file under `source-directories` like so: 87 | 88 | ```json 89 | "source-directories": [ 90 | ".", 91 | "src" 92 | ] 93 | ``` 94 | 95 | # Main.elm 96 | 97 | ## 1. Model 98 | 99 | The `Main` module doesn't need to know the details of `ChildModule`'s model. It just needs to know that the `ChildModule` has a model, which is exposed and can be referenced by using `ChildModule.Model`. The initial value can be referenced as well with `ChildModule.initModel`. 100 | 101 | So we just need to create a `childModule` field of type `ChildModule.Model`. 102 | 103 | ```elm 104 | import ChildModule 105 | 106 | type alias Model = 107 | { page : Page, 108 | , childModule : ChildModule.Model 109 | } 110 | 111 | initModel : Model 112 | initModel = 113 | { page = ChildModulePage 114 | , childModule = ChildModule.initModel 115 | } 116 | ``` 117 | 118 | ## 2. Update 119 | 120 | When the message is of type `ChildModuleMsg` i.e. originating from an outside module, we pull out the included message and put it into the identifier `cmMsg`. 121 | 122 | The `Main` module doesn't know how to handle this message directly, but the `ChildModule`'s **update function** does (for any message in that module), so we just call it to deal with the `ChildModule`'s **model**. 123 | 124 | To do this, we update the model by setting the `childModule` field to the value returned by calling the `ChildModule`'s **update function** and passing it the two parameters, the **message** `cmMsg` and the **current model** for the child module `model.childModule` 125 | 126 | ```elm 127 | type Msg 128 | = ChangePage Page 129 | | ChildModuleMsg ChildModule.messages 130 | 131 | update : Msg -> Model -> Model 132 | update msg model = 133 | case msg of 134 | ChangePage page -> 135 | { model | page = page } 136 | 137 | ChildModuleMsg cmMsg -> 138 | { model | childModule = ChildModule.update cmMsg model.childModule } 139 | ``` 140 | ## 3. View 141 | 142 | This is a **GOTCHA** part due to the different `Html Msg` types. We need to transform the html capable of generating `ChildModule` messages into `Html` capable of generating `Main` messages by using `map`. 143 | 144 | The first parameter for the `map` function is a transformation function, which is the `ChildModuleMsg`'s type constructor that acts as a function. 145 | 146 | The second parameter is the `ChildModule`'s view function with the **current model** as an argument, hence the tuple. 147 | 148 | **In other words, we are transforming any message coming from the child view, into main messages by using map.** 149 | 150 | ```elm 151 | view : Model -> Html Msg 152 | view model = 153 | let 154 | page = 155 | case model.page of 156 | ChildModulePage -> 157 | Html.map ChildModuleMsg (ChildModule.view model.childModule) 158 | in 159 | div [] [ page ] 160 | 161 | ``` 162 | 163 | # Coonection and Navigation 164 | 165 | After creating a `ChildModule`, exposing it and adding it to `elm-package.json`'s `source-directories`, we need to connect the module and navigate between them. 166 | 167 | The connection is explained in **The Elm Architecture** above. 168 | 169 | To use the navigation, we need to install the package with `elm-package install elm-lang/navigation` along with th dependencies and import the package with `include Navigation`. 170 | 171 | After that, in the `main` function, we change the `Html.program` function call into `Navigation.program location`. 172 | 173 | ```elm 174 | main : Program Never Model Msg 175 | main = 176 | -- Html.program 177 | Navigation.program locationToMsg 178 | { init = init 179 | , update = update 180 | , view = view 181 | , subscriptions = subscriptions 182 | } 183 | ``` 184 | 185 | `Navigation.program` takes a function as a parameter, which takes a location as a parameter. 186 | 187 | The `locationToMsg` is called every time the URL changes. The function takes a `Navigation.Location` and returns a `Msg`. 188 | 189 | This function needs to: 190 | 1. Transform the URL hash into a `Page`. 191 | 2. Return the page as part of a `Msg`. 192 | 3. The message is fed back into the `update` function. 193 | -------------------------------------------------------------------------------- /topics/excel.md: -------------------------------------------------------------------------------- 1 | # Insert pictures from URL 2 | 3 | This code gets images from URLs and inserts them in the column to the right of the URL. 4 | 5 | 1. Have a column with the image URLs, usually in range `A:A`. Leave an empty column on the right i.e. `B:B`. 6 | 2. Open the Developer/Visual Basic tab. 7 | 3. Paste the below code in a new module. (Insert/Module) 8 | 4. Edit the `Rng` value in the code i.e. the range with image URLs ex. `A1:A100`. 9 | 5. Click run and wait for the images to be populated in the adjacent column i.e. column `B:B`. 10 | 11 | It takes around 2 seconds per image. 12 | 13 | ```vbnet 14 | Sub URLPictureInsert() 15 | Dim xCol As Long 16 | Dim xRg As Range 17 | Dim w As Integer 18 | Dim h As Integer 19 | On Error Resume Next 20 | Set Rng = ActiveSheet.Range("A1:A100") 21 | w = 100 22 | h = 100 23 | For Each cell In Rng 24 | xCol = cell.Column + 1 25 | Set xRg = Cells(cell.Row, xCol) 26 | xRg.ColumnWidth = 20 27 | xRg.RowHeight = 100 28 | ActiveSheet.Shapes.AddPicture Filename:=cell, LinkToFile:=msoFalse, SaveWithDocument:=msoCTrue, Left:=xRg.Left + (xRg.Width - w) / 2, Top:=xRg.Top + (xRg.Height - h) / 2, Width:=w, Height:=h 29 | Next 30 | End Sub 31 | ``` 32 | 33 | # Google Sheets Cell Update Timestamp 34 | 35 | 1. Modify code with corresponding sheet, cells and update cells. 36 | 2. Go to Tools/Script Editor. 37 | 3. Paste the code and click save. 38 | 39 | ```javascript 40 | function onEdit(e) { 41 | var sh = e.source.getActiveSheet(); 42 | var sheets = ['Sheet1']; // Which sheets to run the code. 43 | 44 | // Columns with the data to be tracked. 1 = A, 2 = B... 45 | var ind = [1, 2, 3].indexOf(e.range.columnStart); 46 | 47 | // Which columns to have the timestamp, related to the data cells. 48 | // Data in 1 (A) will have the timestamp in 4 (D) 49 | var stampCols = [4, 5, 6] 50 | 51 | if(sheets.indexOf(sh.getName()) == -1 || ind == -1) return; 52 | 53 | // Insert/Update the timestamp. 54 | var timestampCell = sh.getRange(e.range.rowStart, stampCols[ind]); 55 | timestampCell.setValue(typeof e.value == 'object' ? null : new Date()); 56 | } 57 | ``` -------------------------------------------------------------------------------- /topics/express.md: -------------------------------------------------------------------------------- 1 | # npm mssql 2 | 3 | Connections are expensive. Use them for one time open/close operations. Otherwise, use a pool when executing a series of queries. 4 | 5 | ```Javascript 6 | // Async/Await 7 | router.get("/api", function (req, res) { 8 | 9 | (async function () { 10 | 11 | let id = req.query.id; 12 | 13 | try { 14 | const connection = await sql.connect(db); 15 | const request = await connection.request() 16 | 17 | request.input("id", sql.Int, id); 18 | 19 | let query = ` 20 | select * 21 | from products 22 | where id = @id 23 | ` 24 | 25 | let result = await request.query(query) 26 | 27 | res.send(result) 28 | 29 | } catch (err) { 30 | console.log("Error: " + err); 31 | } finally { 32 | sql.close(); 33 | }; 34 | })() 35 | }) 36 | 37 | // Promise 38 | new sql.ConnectionPool(db).connect().then(pool => { 39 | return pool.request().query("SELECT * FROM product") 40 | }).then(result => { 41 | let rows = result.recordset 42 | res.setHeader('Access-Control-Allow-Origin', '*') 43 | res.status(200).json(rows); 44 | sql.close(); 45 | }).catch(err => { 46 | res.status(500).send({ message: "${err}"}) 47 | sql.close(); 48 | }); 49 | 50 | // Callback 51 | sql.connect(db, function (err) { 52 | if (err) console.log(err); 53 | var request = new sql.Request(); 54 | request.query("SELECT * FROM product", function (err, recordset) { 55 | if (err) console.log(err) 56 | 57 | let rows = recordset.recordsets[0]; 58 | res.send(rows); 59 | sql.close(); // Important 60 | }); 61 | }); 62 | ``` 63 | 64 | # JSON 65 | 66 | JSON is used to transfer data via a string. 67 | 68 | An object from one programming language can be transferred to another by encoding it in JSON and then decoding it, even though they cannot understand each others' objects. 69 | 70 | ```Javascript 71 | // Javascript object literal. 72 | var personObject = { 73 | firstName:"John", 74 | lastName:"Doe", 75 | age:50, 76 | eyeColor:"blue" 77 | }; 78 | 79 | // Convert object to JSON. 80 | var personJSON = JSON.stringify(personObject); 81 | 82 | // personJSON. 83 | { 84 | "firstName":"John", 85 | "lastName":"Doe", 86 | "age":50, 87 | "eyeColor":"blue" 88 | } 89 | 90 | // Convert JSON to object. 91 | JSON.stringify(personJSON); 92 | ``` 93 | -------------------------------------------------------------------------------- /topics/filesystem.md: -------------------------------------------------------------------------------- 1 | # Filesystem 2 | 3 | #### Directories 4 | 5 | **root** has the following directories: 6 | - **etc**. Configuration files. 7 | - **proc**. System information. 8 | - **home**. All the users. 9 | - **boot**. Operating system lives here. 10 | - **dev**. Where devices are mounted. `sda` is main disk, `sdaX` are partitions (Mounted as block files). 11 | 12 | `tree DIRECTORY` - Show directory tree. `tree .` for current. Needs to be donwloaded with `sudo apt-get install tree`. 13 | 14 | #### Files 15 | 16 | Plain text file > Compilation > Binary (.exe) i.e. package. Ubuntu is simply a collection (repository) of pre-compiled packages, running over a kernel (Big pile of software that knows how to make the hardware do stuff). 17 | 18 | **"On a UNIX system, everything is a file; if something is not a file, it is a process."** (directory is a file containing names of other files) 19 | 20 | File extensions are meaningless. They are there for the user's sake. 21 | 22 | There are 7 types of files, which can be recognized by using `ls -l` and looking at the first bit: 23 | 1. **Normal**. Images, text, config... 24 | 2. **Directory**. File pointing to files. 25 | 3. **Link**. Shortcut/Redirect. 26 | 4. **Pipe**. Use a process output as input for another. 27 | 5. **Character Device**. Input/Output files Ex. Teminal. 28 | 6. **Block**. Used for block devices. Ex. Hard Disk. 29 | 7. **Socket**. Used for Interprocess Communication. 30 | - **Unix Socket**. Local machine only (Superfast). Ex. Nginx communicates with a PHP interpreter. 31 | - **TCP Socket**. Exposed to network (Slower). Ex. Nginx communicates with a website visitor. 32 | 33 | #### Interprocess Communication (IPC) 34 | 35 | In Linux, **everything is a file**. There are special files like **sockets** that allow processes to communicate with each other without dangerously sharing memory. 36 | 37 | **Sockets** are files where processes can write stuff, and other processes can listen in real time. 38 | -------------------------------------------------------------------------------- /topics/fp.md: -------------------------------------------------------------------------------- 1 | # Functional Programming 2 | 3 | Simple **is not** easy. Simple software is beautiful, and worth the effort. 4 | 5 | For `objects`, we add properties with the `...spread` operator, and remove them with `...spread destructuring`. 6 | 7 | For arrays, we add items also with the `...spread` operator, transform the array with `.map`, and remove items with `.filter`. 8 | 9 | In both objects and arrays, we summarize info with `.reduce`. 10 | 11 | # virtual-dom 12 | 13 | The view part won't work with HTML strings. The elements have to be proper DOM nodes. Using strings gives this error `Uncaught TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'.` 14 | 15 | ```javascript 16 | // Won't work 17 | var el = "

test satu dua tiga

"; // is a string 18 | document.body.appendChild(el); 19 | 20 | // Works 21 | var el = document.createElement("p"); // is a node 22 | el.innerHTML = "test satu dua tiga"; 23 | document.body.appendChild(el); 24 | ``` 25 | 26 | # hyperscript-helpers 27 | 28 | This small library helps make the code cleaner. 29 | 30 | ```javascript 31 | // instead of writing 32 | h("div"); 33 | 34 | // write 35 | div(); 36 | 37 | // instead of writing 38 | h("section#main", mainContents); 39 | 40 | // write 41 | section("#main", mainContents); 42 | ``` 43 | 44 | ### API 45 | 46 | ```javascript 47 | tagName(selector); 48 | tagName(attrs); 49 | tagName(children); 50 | tagName(attrs, children); 51 | tagName(selector, children); 52 | tagName(selector, attrs, children); 53 | Where; 54 | ``` 55 | 56 | - `selector` is string, starting with "." or "#". 57 | - `attrs` is an object of attributes. 58 | - `children` is a hyperscript node, an array of hyperscript nodes, a string or an array of strings. 59 | 60 | # Simple app 61 | 62 | 1. When we click the increment button, the `dispatch` function, defined in the `app` function is called, with the `MSGS.ADD` payload. 63 | 2. The `update` function, a switch statement, then uses the payload to match the behavior, in this case to add 1 to the current `model`. 64 | 3. The `view` function then uses the latest model to generate the DOM tree, but only with the changes parts, thanks to the `virtual-dom`. 65 | 66 | ```javascript 67 | const hh = require("hyperscript-helpers"); // Create HTML element functions 68 | const { h, diff, patch } = require("virtual-dom"); 69 | const createElement = require("virtual-dom/create-element"); 70 | 71 | // const { div, button } = require('hyperscript-helpers')(h); 72 | const { div, button } = hh(h); 73 | 74 | const initModel = 0; 75 | 76 | const MSGS = { 77 | ADD: "ADD", 78 | SUBTRACT: "SUBTRACT" 79 | }; 80 | 81 | // Updates the model after a view action. 82 | function update(msg, model) { 83 | switch (msg) { 84 | case MSGS.ADD: 85 | return model + 1; 86 | case MSGS.SUBTRACT: 87 | return model - 1; 88 | default: 89 | return model; 90 | } 91 | } 92 | 93 | // The dispatch reloads the view. Defined in app. 94 | function view(dispatch, model) { 95 | return div([ 96 | div({ className: "counter" }, `Count: ${model}`), 97 | button( 98 | { 99 | className: "button", 100 | onclick: () => dispatch(MSGS.ADD) 101 | }, 102 | "+" 103 | ), 104 | button( 105 | { 106 | className: "button", 107 | onclick: () => dispatch(MSGS.SUBTRACT) 108 | }, 109 | "-" 110 | ) 111 | ]); 112 | } 113 | 114 | // impure code contained inside app function 115 | function app(initModel, update, view, node) { 116 | // Initial view 117 | let model = initModel; 118 | let currentView = view(dispatch, model); 119 | let rootNode = createElement(currentView); 120 | node.appendChild(rootNode); 121 | 122 | function dispatch(msg) { 123 | model = update(msg, model); 124 | const updatedView = view(dispatch, model); 125 | const patches = diff(currentView, updatedView); 126 | rootNode = patch(rootNode, patches); 127 | currentView = updatedView; 128 | } 129 | } 130 | 131 | // Load app div 132 | const rootNode = document.getElementById("app"); 133 | 134 | app(initModel, update, view, rootNode); 135 | ``` 136 | 137 | # HTTP effects 138 | 139 | HTTP requests are triggered in a similar way to how the app performs state updates. 140 | 141 | Normal updates: 142 | 143 | - view generates a message. 144 | - update is called with the new message and current model. 145 | - update returns the new model. 146 | - view uses the new model to re-render the view. 147 | 148 | HTTP updates: 149 | 150 | - view generates a message. 151 | - update is called with the new message and current model. 152 | - update returns the new model, a url, and a message generating function. 153 | - the app function makes a server request with the url. 154 | - when the server responds, the message generating function returned from update, creates a new message that includes the server data. 155 | - update is called with the newly generated message. 156 | - update returns the new model. 157 | - view uses the new model to re-render the view. 158 | -------------------------------------------------------------------------------- /topics/googleapi.md: -------------------------------------------------------------------------------- 1 | # Sheets API 2 | 3 | 1. Go to console.developers.google.com 4 | 2. Create a project. 5 | 3. Go to console.developers.google.com/apis/credentials and create API key for the project. 6 | 4. Set the sheet to public for the request to work. 7 | 8 | The sheet can be public i.e. `Anyone who has the link can view`, and be only editable privately. This avoids the OAuth part. 9 | 10 | 11 | ```javascript 12 | let sheet = "c750833d5021f60a1b8ff8bf0a21bb9dc74cff12" 13 | let range = "Sheet1" 14 | let apiKey = "6e0ece719a48d5334369bd881b4324aa957e4407" 15 | 16 | let url = `https://sheets.googleapis.com/v4/spreadsheets/${sheet}/values/${range}?key=${apiKey}` 17 | 18 | fetch(url) 19 | .then(res => res.json()) 20 | .then(data => { 21 | console.log(data) 22 | }) 23 | .catch(err => err); 24 | ``` 25 | 26 | ### Private sheet 27 | 28 | With private user data you would need to use OAuth. 29 | 30 | 1. Go to console.developers.google.com/apis/library and pick Sheets. 31 | 2. Configure OAuth. 32 | 33 | -------------------------------------------------------------------------------- /topics/graphql.md: -------------------------------------------------------------------------------- 1 | GraphQL is an alternative to REST API. It's a typed query language. 2 | 3 | It allows flexible querying from the front-end i.e. client. 4 | 5 | It solves the problem of needing **just** a piece of data, without getting all the data from an end-point. 6 | 7 | REST API would handle this for a `GET /user` request with: 8 | - `GET /user-slim` - Lots of routes and updating. 9 | - `GET /user?data=slim` - The API becomes complex 10 | 11 | GraphQL would handle this with `POST /user` by sending this query expression in the body. 12 | 13 | ```js 14 | { 15 | query { // operation type 16 | user { // operation end-point 17 | name // requested field 18 | age 19 | } 20 | } 21 | } 22 | ``` 23 | 24 | GraphQL **always** uses `POST` because it sends the query expression. 25 | 26 | | REST API | GraphQL | 27 | | ------------- |-------------| 28 | | GET | `query` operation type | 29 | | POST, PUT, PATCH, DELETE | `mutation` operation type | 30 | | Routes | Query definitions | 31 | | Controllers | Resolvers | -------------------------------------------------------------------------------- /topics/javascript.md: -------------------------------------------------------------------------------- 1 | # Language 2 | 3 | The complete JavaScript implementation is made up of three distinct parts: 4 | 5 | - The Core (based on ECMAScript spec) 6 | - The Document Object Model (DOM) 7 | - The Browser Object Model (BOM) 8 | 9 | ## ECMAScript 10 | 11 | ECMA-262 describes it like this: 12 | 13 | ``` 14 | ECMAScript can provide core scripting capabilities for a variety of host environments, and therefore the core scripting language is specified... apart from any particular host environment. 15 | ``` 16 | 17 | A Web browser is considered a host environment for ECMAScript, but it is not the only host environment. A list of other host environments listed here. 18 | 19 | Apart from DOM and BOM, each browser has its own implementation of the ECMAScript interface. 20 | 21 | ## Document Object Model (DOM) 22 | 23 | The Document Object Model (DOM) is an application programming interface (API) for HTML as well as XML. 24 | 25 | The DOM maps out an entire page as a document composed of a hierarchy of nodes like a tree structure and using the DOMAPI nodes can be removed, added, and replaced. 26 | 27 | ### DOM level 1 28 | 29 | Consisted of two modules: the DOM Core, which provided a way to map the structure of an XML-based document to allow for easy access to and manipulation of any part of a document, and the DOM HTML, which extended the DOM Core by adding HTML-specific objects and methods. 30 | 31 | ### DOM Level 2 32 | 33 | Introduced several new modules of the DOM to deal with new types of interfaces: 34 | 35 | - DOM Views — describes interfaces to keep track of the various views of a document (that is, the document before CSS styling and the document after CSS styling) 36 | - DOM Events — describes interfaces for events 37 | - DOM Style — describes interfaces to deal with CSS-based styles 38 | - DOM Traversal and Range — describes interfaces to traverse and manipulate a document tree 39 | 40 | ### DOM Level 3 41 | 42 | Further extends the DOM with the introduction of methods to load and save documents in a uniform way (contained in a new module called DOM Load and Save) as well as methods to validate a document (DOM Validation). In Level 3, the DOM Core is extended to support all of XML 1.0, including XML Infoset, XPath, and XML Base. 43 | 44 | Note that the DOM is not JavaScript-specific, and indeed has been implemented in numerous other languages. For Web browsers, however, the DOM has been implemented using ECMAScript and now makes up a large part of the JavaScript language. 45 | 46 | Other DOMs 47 | 48 | - Scalable Vector Graphics (SVG) 49 | - Mathematical Markup Language (MathML) 50 | - Synchronized Multimedia Integration Language (SMIL) 51 | 52 | ## Browser Object Model (BOM) 53 | 54 | Browsers feature a Browser Object Model (BOM) that allows access and manipulation of the browser window. Using the BOM, developers can move the window, change text in the status bar, and perform other actions that do not directly relate to the page content. 55 | 56 | Because no standards exist for the BOM, each browser has its own implementation. 57 | 58 | # Event Loop 59 | 60 | ![TEA](../pics/js_event_loop.png) 61 | 62 | Based on [Philip Roberts' talk](https://www.youtube.com/watch?v=8aGhZQkoFbQ). 63 | 64 | The Javascript runtime only knows of the `heap` and `call stack`. 65 | 66 | The rest of the functionality, like async stuff, is provided in the form of `WebAPIs` by the browser/Node. 67 | 68 | For async operations, the `callback` is offloaded into a separate `queue`, which is emptied by the `event loop` one by one as soon as the `stack` becomes empty. 69 | 70 | Without the `event loop` the stack would be blocked during the whole duration of the async operaiton, basically freezing the app. 71 | 72 | # Hoisting 73 | 74 | Both variable and function declarations are hoisted to the top on code execution, meaning that their order is irrelevant i.e functions can be called before they are declared. 75 | 76 | # Variables 77 | 78 | ```javascript 79 | var a; // Regular. 80 | let c; // Block scoped. 81 | const b; // Immutable. 82 | ``` 83 | 84 | # Functions 85 | 86 | Functions are first class objects - a function is a regular object of type `function`. The function object type has a constructor: `Function`. 87 | 88 | There are several ways to declare a function. 89 | 90 | The difference is how the function interacts with the external components (the outer scope, the enclosing context, object that owns the method, etc) and the invocation type (regular function invocation, method invocation, constructor call, etc). 91 | 92 | ## Function declaration 93 | 94 | **Hoisted**. Available immediately after parsing, before any code is executed. 95 | 96 | The function declaration creates a variable in the current scope with the identifier equal to function name. This variable holds the function object. 97 | 98 | ```javascript 99 | function foo() {} 100 | foo(); 101 | ``` 102 | 103 | Use them when a function expression is not appropriate or when it is important that that a function is hoisted. 104 | 105 | ## Function expression 106 | 107 | **Not hoisted.** Available only after the variable assignment is executed. 108 | 109 | ```javascript 110 | // Named 111 | let bar = function foo() {}; 112 | bar(); 113 | foo(); // undefined 114 | ``` 115 | 116 | Use them when you are doing recursion or want to see the function name in the debugger. 117 | 118 | ```javascript 119 | // Anonymous 120 | let foo = function() {}; 121 | foo(); 122 | 123 | let bar = foo(); 124 | bar(); // Error: not a function. 125 | ``` 126 | 127 | Use them when you want to pass a function as an argument to another function or you want to form a closure. 128 | 129 | ## IIFE - immediately Invoked Function Expression 130 | 131 | ```javascript 132 | (function() { 133 | // ... 134 | })(); 135 | ``` 136 | 137 | Use them for the module pattern. 138 | 139 | ## ES6 140 | 141 | Binds `this` automatically. 142 | 143 | ```javascript 144 | let foo = () => {}; 145 | ``` 146 | 147 | Use them when you want to lexically bind the `this` value. 148 | 149 | ## Function constructor (Avoid this) 150 | 151 | ```javascript 152 | let foo = new Function(); 153 | ``` 154 | 155 | ## Other 156 | 157 | - Use function declaration generators `function* foo(){}` when you want to exit and then re-enter a function. 158 | - Use function expression generators `let foo = function* [name](){}` when you want to exit and then re-enter a nested function. 159 | 160 | ## Function parameters vs arguments 161 | 162 | An argument is the value supplied to the parameter. 163 | 164 | ```javascript 165 | function foo(bar) { 166 | // bar is a parameter 167 | console.log(bar); 168 | } 169 | 170 | foo("baz"); // baz is an argument. 171 | ``` 172 | 173 | # Useful 174 | 175 | ## Truthy / Falsy 176 | 177 | Strings with at least one letter and numbers larger than zero are `truthy`. 178 | 179 | ```javascript 180 | console.log(true && "foo"); // foo 181 | console.log(true && "foo" && 1); // 1 182 | ``` 183 | 184 | # Debugging 185 | 186 | ```javascript 187 | // Write to console 188 | console.log(); 189 | 190 | // Show DOM element 191 | console.dir(); 192 | 193 | // Display the call stack of a function 194 | console.trace(); 195 | 196 | // Track execution time 197 | console.time("point"); // undefined 198 | console.timeEnd("point"); // point: 1337.42 ms 199 | 200 | // Count the number of executions 201 | console.count("foo"); // foo: 1 202 | console.count("foo"); // foo: 2 203 | console.countReset("foo"); // undefined 204 | console.count("foo"); // foo: 1 205 | 206 | // Avoid if-else statements 207 | function greaterThan(a, b) { 208 | console.assert(a > b, { message: "a is not greater than b", a: a, b: b }); 209 | } 210 | greaterThan(2, 1); // a is not greater than b, a: 2, b: 1 211 | 212 | // Heap size 213 | console.memory; 214 | 215 | // Display a table. Takes an array of objects. 216 | console.table(array); 217 | ``` 218 | -------------------------------------------------------------------------------- /topics/linux.md: -------------------------------------------------------------------------------- 1 | # Terminal 2 | 3 | `/` - Root directory 4 | `~` - Home directory 5 | 6 | `^` - Control key. 7 | `M` - Alt key. 8 | 9 | `CTRL` + `C` - Stop running command. 10 | `CTRL` + `D` - Close current shell session. 11 | `CTRL` + `L` - Clear screen. (Scrolls you down in reality) 12 | 13 | `CTRL` + `A` - Go to beginning of line. 14 | `CTRL` + `E` - Go to end of line. 15 | `CTRL` + `F` - Next word. 16 | `CTRL` + `B` - Previous word. 17 | 18 | `ALT` + `Backspace` - Delete last word. 19 | `ALT` + `Left` / `Right` - Go to previous / next word. 20 | `CTRL` + `U` - Delete whole line. 21 | 22 | `man COMMAND` - Command help. 23 | `history` - Lists all the commands used. 24 | `CTRL` + `R` - Search command history. Hit again for previous command. 25 | 26 | # Information 27 | 28 | ```bash 29 | cat /etc/os-release # Linux version 30 | df -h # Show disk space in readable format 31 | ``` 32 | 33 | # Install 34 | 35 | `dpkg` is a backend for `apt-get`, which is a backend for `aptitude` (GUI). 36 | 37 | ## Packages 38 | 39 | ```bash 40 | apt-cache search PACKAGE # Search packages. 41 | apt-cache madison PACKAGE # List versions. 42 | 43 | apt-get update # Update the packages list. 44 | apt-get install PACKAGE # Install specified package. 45 | apt-get upgrade # Actually update the packages. 46 | 47 | apt list --installed # A list of installed packages. 48 | 49 | apt-get remove PACKAGE # Remove a specified package. 50 | add-apt-repository REPO # Add 3rd party repository or PPA (Personal Package Archive). 51 | 52 | curl URL # Output the URL content. 53 | wget "URL" # Download from URL. 54 | sudo dpkg –i FILE_NAME # Install downloaded file. 55 | ``` 56 | 57 | ## .deb 58 | 59 | Install `.deb` packages from the terminal. 60 | 61 | ```bash 62 | sudo dpkg -i 63 | sudo apt-get install -f 64 | ``` 65 | 66 | # Find 67 | 68 | ```bash 69 | grep -r 'string' directory_to_search # List occurences of string in all files. 70 | find / # List root directory's content. 71 | find / | grep FILE # Search the output. 72 | 73 | sudo find / -iname FOLDER/FILE.ext # Find case insensitive. 74 | which PROGRAM # Find path to program. 75 | ``` 76 | 77 | # Count 78 | ```bash 79 | # Number of files 80 | ls | wc -l 81 | 82 | # Find all files with the given extensions 83 | # in the specified folders, and count the number of lines. 84 | find folder1 folder2 -name '*.js' -o -name '*.sql' | xargs wc -l 85 | ``` 86 | 87 | 88 | # Utility 89 | 90 | ```bash 91 | # Navigation 92 | cd FOLDER # Change directory 93 | cd .. # Go back one up 94 | cd - # Go back to last working directory 95 | pwd # Current path 96 | 97 | # List 98 | ls -a # List all files, including hidden 99 | ls -l # List in a list format 100 | ll # Shorthand for ls -l 101 | ls -lh # Show file size 102 | 103 | # Read 104 | cat FILE # Show the file content in terminal 105 | less FILE # View file content in the less program 106 | head FILE # Show first 10 lines 107 | tail FILE # Show last 10 lines 108 | tail -f FILE # Log in real time 109 | 110 | # Create 111 | mkdir FOLDER # Create a folder 112 | touch FILE # Create a file 113 | 114 | # Copy/Paste 115 | cp PATH/FILE PATH/FILE # Create a copy 116 | mv PATH/FILE PATH/FILE # Rename or Cut & Paste a file 117 | 118 | # Delete 119 | rm FOLDER/FILE # Delete folder or file 120 | rm -r FOLDER # Delete a directory and its files 121 | 122 | # Printing 123 | echo TEXT # print text 124 | printf TEXT # print formatted text 125 | ``` 126 | 127 | ```bash 128 | \n # new line 129 | \r # carriage return, i.e. bring carret (cursor) to start of line 130 | ``` 131 | 132 | # Processes 133 | 134 | ```bash 135 | ps -ef # List all running processes. 136 | ps -ef | grep # Find a specific process. 137 | kill -9 # Kill a process by id. 138 | ``` 139 | 140 | # Environment Variables 141 | 142 | PATH is an enviroment variable. It tells your machine where to search for program executables, so when you run your **picc** program you can just do `picc` instead of `/usr/hitech/picc/9.82/bin/picc`. 143 | 144 | Add them to `~/.profile` to make them permanent. Paths require the `bin`, while variables don't. 145 | 146 | The variable is not in the environment until you export it. Otherwise it's just a shell variable. 147 | 148 | ```bash 149 | env # List all variables. 150 | echo "$HOME" # Specific variable, in this case **$PATH**. 151 | ``` 152 | 153 | Paths are delimited with `:`. 154 | 155 | ```bash 156 | # Method 1 157 | vim ~/.profile # Edit this file. 158 | PATH="$HOME/bin:$PATH" # Find this line. 159 | PATH="$HOME/bin:$PATH:/usr/hitech/picc/9.82/bin" # Change it into this. 160 | # It appends the new path to the existing system ones, just for this user. 161 | 162 | # Method 2 - Shorthand to avoid editing manually. 163 | export PATH="$PATH:/usr/hitech/picc/9.82/bin" # export ="" 164 | ``` 165 | 166 | # Password Generator 167 | 168 | Generate a random 14 character password by using the linux `/dev/urandom` file, a stream of mashed system data. 169 | 170 | `cat /dev/urandom | env LC_CTYPE=C tr -dc a-zA-Z0-9 | head -c 14` 171 | 172 | # Ubuntu on Windows 173 | 174 | `C:\Users\User\AppData\Local\lxss\home\user` - Filesystem location. 175 | 176 | `cd /mnt/` - Navigate to My Computer (C:, D:). 177 | 178 | # How to Compile and Run a C Program 179 | 180 | ```bash 181 | # Create file 182 | touch hello.c 183 | 184 | # Edit file 185 | vim hello.c 186 | ``` 187 | Paste this C code in the file. 188 | ```c 189 | #include 190 | 191 | main() { 192 | printf("Hello World\n"); 193 | } 194 | ``` 195 | 196 | ``` bash 197 | # Compile the code into hello program 198 | gcc -o hello hello.c 199 | 200 | # Run the program 201 | ./hello 202 | ``` -------------------------------------------------------------------------------- /topics/logging.md: -------------------------------------------------------------------------------- 1 | Winston, log4js, bunyan are logging libraries. 2 | 3 | The act of persisting the log is called: 4 | 5 | - Winston: Transports 6 | - Bunyan: Streams 7 | - Log4js: Appenders 8 | 9 | In Winston 3, a "transport" is a storage device for your logs, a writable stream i.e. carrying the data from the app to the console or file. 10 | 11 | **Don't go crazy with logging. Use it to know what came in and out of the system. You can figure out almost everything with those two.** 12 | 13 | # Winston 14 | 15 | ```js 16 | ``` 17 | -------------------------------------------------------------------------------- /topics/middleware.md: -------------------------------------------------------------------------------- 1 | _A stack of functions, executed before the final request handler is made._ 2 | 3 | **Middleware functions** are functions with access to the `req` and `res` objects. They can... 4 | 5 | - Execute any code. 6 | - Make changes to the `req` and `res` objects. 7 | - End the response cycle. 8 | - Call the next middleware in the stack, by using `next()`. 9 | 10 | The functions do something, then pass the results to the next middleware in the chain. 11 | 12 | Express has built-in ones, but we can also make custom ones. 13 | 14 | ```js 15 | // Loggin middleware 16 | function log(req, res, next) { 17 | console.log(new Date(), req.method, req.url); 18 | next(); // MUST USE THIS 19 | } 20 | ``` 21 | 22 | ```js 23 | // This will make a log before EACH request in the app. 24 | app.use(log); 25 | 26 | app.get("/", (req, res) => { 27 | res.write("Hello World!"); 28 | res.end; 29 | }); 30 | ``` 31 | 32 | ```js 33 | // This will make a log before THIS request ONLY. 34 | app.get("/", log, (req, res) => { 35 | res.write("Hello World!"); 36 | res.end; 37 | }); 38 | ``` 39 | 40 | ### Authentication example 41 | 42 | ```js 43 | app.post("/upload", auth.isAuthenticated(), controller.upload); 44 | ``` 45 | 46 | !["Middleware"](../pics/express/express_middleware.jpg) 47 | 48 | # App Setup 49 | 50 | **app.js** 51 | 52 | ```js 53 | let express = require("express"); 54 | let middleware = require("./middleware.js"); 55 | let api = require("./api"); 56 | 57 | let app = express(); 58 | 59 | // Allow requests from all domains and localhost 60 | app.all("/*", function (req, res, next) { 61 | res.header("Access-Control-Allow-Origin", "*"); 62 | res.header("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, Accept"); 63 | res.header("Access-Control-Allow-Methods", "POST, GET"); 64 | next(); 65 | }); 66 | 67 | app.use(bodyParser.urlencoded({ extended: false })) 68 | .use(express.static("./app/public")) 69 | .use(api); 70 | 71 | module.exports = app; 72 | ``` 73 | 74 | **server.js** 75 | 76 | ```js 77 | const app = require("./app.js"); 78 | 79 | const PORT = process.env.PORT || 3000; 80 | 81 | app.listen(PORT, () => { 82 | console.log(`listening on port: ${PORT}`); 83 | }); 84 | ``` 85 | 86 | # Error Handling 87 | 88 | **middleware.js** 89 | 90 | ```js 91 | let errorHandler = (err, req, res, next) => { 92 | // Log error message in our server's console 93 | console.error("ERROR:", err); 94 | 95 | // If err has no specified error code, set error code to 'Internal Server Error (500)' 96 | if (!err.statusCode) err.statusCode = 500; 97 | 98 | // All HTTP requests must have a response, so let's send back an error with its status code and message 99 | res.status(err.statusCode).send(err); 100 | }; 101 | 102 | module.exports = { errorHandler }; 103 | ``` 104 | 105 | **server.js** 106 | 107 | ```js 108 | app.use(middleware.errorHandler); 109 | ``` 110 | 111 | # 404 112 | 113 | **middleware.js** 114 | 115 | ```js 116 | let wrongRoute = (req, res, next) => { 117 | let error = new Error("404 Not found."); 118 | error.status = 404; 119 | next(error); 120 | }; 121 | 122 | module.exports = { wrongRoute }; 123 | ``` 124 | 125 | **server.js** 126 | 127 | ```js 128 | app.use(middleware.wrongRoute); 129 | ``` 130 | 131 | # MySQL Pool 132 | 133 | `createConnection` creates a single connection lasting until you close it. You can pass that connection around by reference and re-use it, or you can close it on demand. 134 | 135 | `createPool` creates a place where connections get stored. When you request a connection from a pool, you are either given a connection that is currently not being used or a new connection. If you’re at the connection limit, it will wait until a connection is available before it continues. Pooled connections do not need to be manually closed, they can remain open and be re-used. 136 | 137 | this library ensures that connections are auto-released after each query. 138 | 139 | In fact, `pool.query()` is a shortcut for `pool.getConnection()` + `connection.query()` + `connection.release()`. 140 | 141 | ```js 142 | let mysql = require("mysql"); 143 | let pool = mysql.createPool({ 144 | connectionLimit: 10, 145 | host: "localhost", 146 | user: "matt", 147 | password: "password", 148 | database: "my_database", 149 | }); 150 | 151 | // This is just for checking the connection. Can be completely avoided. 152 | pool.getConnection((err, connection) => { 153 | if (err) { 154 | if (err.code === "PROTOCOL_CONNECTION_LOST") { 155 | console.error("Database connection was closed."); 156 | } 157 | if (err.code === "ER_CON_COUNT_ERROR") { 158 | console.error("Database has too many connections."); 159 | } 160 | if (err.code === "ECONNREFUSED") { 161 | console.error("Database connection was refused."); 162 | } 163 | } 164 | // We also ensure that the connection we’ve just created is released back into the pool. 165 | if (connection) connection.release(); 166 | return; 167 | }); 168 | module.exports = pool; 169 | ``` 170 | 171 | Perform queries with the database like so: 172 | 173 | ```js 174 | const express = require("express"); 175 | const router = express.Router(); 176 | const pool = require("../pool.js"); 177 | 178 | // note the async keyword 179 | router.get("/api/endpoint", async function (req, res) { 180 | try { 181 | let query = ` 182 | select * from product 183 | `; 184 | 185 | var rows = await pool.query(query); 186 | res.status(200).send(rows); 187 | } catch (err) { 188 | throw new Error(err); 189 | } 190 | }); 191 | ``` 192 | -------------------------------------------------------------------------------- /topics/mobile.md: -------------------------------------------------------------------------------- 1 | # Mobile development 2 | 3 | ## Native 4 | 5 | No compilation needed, as the app is written in the native language. 6 | 7 | - Java (Android) 77% share 8 | - Swift (iPhone) 19% share 9 | 10 | ## Hybrid 11 | 12 | Like Electron, but for mobile devices. 13 | 14 | - PhoneGap - Same as Cordova, vanilla JS, paid version. 15 | - Cordova - Same as PhoneGap, vanilla JS, open source. 16 | - Ionic - Angular UI library on top of Cordova that gives a native look. 17 | 18 | ## Compiled 19 | 20 | **Only** the UI components are compiled to their native equivalents. The rest runs in the language runtime. 21 | 22 | - React Native (Javascript) Have to build your own components. 23 | - Native Script (Javascript) Less popular 24 | - Flutter (Dart) 25 | 26 | # Android 27 | 28 | ## Setup Overview 29 | 30 | - JDK 31 | - SDK 32 | - Packages 33 | - Environment Variables 34 | - NodeJS 35 | - Cordova 36 | 37 | ## API Level 38 | 39 | The Android platform provides a framework API that applications can use to interact with the underlying Android system. Updates to the framework API are designed so that the new API remains compatible with earlier versions of the API. 40 | 41 | | Codename | Version | API | Distribution | 42 | | ----------- | ------- | --- | ------------ | 43 | | Oreo | 8.0.0 | 26 | 11% | 44 | | Nougat | 7.0.0 | 24 | 20% | 45 | | Marshmallow | 6.0.0 | 23 | 22% | 46 | 47 | ### Java Development Kit (JDK) 48 | 49 | The JDK (Java Development Kit) contains the JRE (Java Runtime Environment). 50 | 51 | Open JDK = open-source variant of the JRE and JDK. 52 | 53 | Java version 1.8.0_5 = JDK 8 update 5 54 | 55 | ```bash 56 | sudo apt update 57 | sudo apt install openjdk-8-jdk 58 | 59 | java -version # java version "1.8.0_181" 60 | 61 | # Add this line to ~/.profile 62 | export JAVA_HOME="/usr/lib/jvm/java-1.8.0-openjdk-amd64" 63 | 64 | export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 65 | export PATH=$PATH:/usr/lib/jvm/java-8-openjdk-amd64/bin 66 | 67 | # Reload configuration 68 | source ~/.profile 69 | ``` 70 | 71 | ## Gradle 72 | 73 | As of Cordova-Android 6.4.0, Gradle is now required to be installed to build Android. Gradle requires Java Development Kit (JDK) 7 or higher in order to work. 74 | 75 | ```bash 76 | wget https://services.gradle.org/distributions/gradle-4.9-bin.zip 77 | sudo unzip -d /opt/gradle gradle-4.9-bin.zip 78 | ``` 79 | 80 | ## Android SDK 81 | 82 | By default, the Android SDK does not include everything you need to start developing. 83 | 84 | The Android SDK can be broken down into several components. These include: 85 | 86 | - SDK-tools 87 | - Platform-tools 88 | - Build-tools 89 | - The Android Debug Bridge (ADB) 90 | - Android Emulator 91 | 92 | Arguably the most important parts of this package are in the SDK-tools. You will need these tools regardless of which version of Android you are targeting. 93 | 94 | These are what will actually compile your code along with any data and resource files into an APK, an Android package, which is an archive file with an `.apk` suffix. 95 | 96 | One APK file contains all the contents of an Android app and is the file that Android-powered devices use to install the app. 97 | 98 | **From the SDK you really only need sdk-tools, platform-tools, build-tools and the latest API.** 99 | 100 | ```bash 101 | sudo apt-get install android-sdk 102 | ``` 103 | 104 | ```bash 105 | wget https://dl.google.com/android/repository/sdk-tools-linux-4333796.zip 106 | sudo unzip -d /home sdk-tools-linux-4333796.zip 107 | 108 | # Add this line to ~/.profile 109 | export PATH=/opt/pradip/tools:/opt/pradip/tools/bin:$PATH 110 | 111 | # Reload configuration 112 | source ~/.profile 113 | ``` 114 | 115 | After installing the Android SDK, you must also install the packages for whatever API level you wish to target. It is recommended that you install the highest SDK version that your version of cordova-android supports. 116 | 117 | ```bash 118 | sdkmanager --list 119 | ``` 120 | 121 | Android Platform SDK for your targeted version of Android 122 | Android SDK build-tools version 19.1.0 or higher 123 | Android Support Repository (found under "Extras") 124 | 125 | ## Environment Variables 126 | 127 | We need to configure and export the environment variables so that the executables can be run directly from anywhere. Add them to `~/.bashrc` to make them permanent. 128 | 129 | ```bash 130 | sudo vim ~/.profile 131 | ``` 132 | 133 | add following code to the end of the file... 134 | 135 | ```bash 136 | # Gradle 137 | PATH=$PATH:/opt/gradle/gradle-4.9/bin 138 | 139 | # Android SDK 140 | ANDROID_HOME="/usr/lib/android-sdk/" 141 | PATH="${PATH}:${ANDROID_HOME}tools/:${ANDROID_HOME}platform-tools/" 142 | ``` 143 | 144 | save, exit and run source to relad the configuration. 145 | 146 | ```bash 147 | source ~/.profile 148 | ``` 149 | 150 | ## SDK Manager 151 | 152 | https://www.androidauthority.com/android-sdk-tutorial-beginners-634376/ 153 | https://www.androidauthority.com/how-to-install-android-sdk-software-development-kit-21137/ 154 | 155 | ## Android Virtual Device Manager (AVD) 156 | 157 | Create a virtual device where you set the desired device with the system image downloaded via the SDK manager, as well as the target API. 158 | 159 | ## Build Process 160 | 161 | https://developer.android.com/studio/build 162 | 163 | # Apache Cordova 164 | 165 | Mobile apps can be created with HTML, CSS and Javascript. 166 | 167 | The mobile app is a website running in a webview, like Electron for desktop. A webview is a wrapper i.e. a shell browser, without the menus, tabs etc. 168 | 169 | The native device features can be accessed through the wrapper, not directly. Also, The UI components automatically adjust to the platform. 170 | 171 | ## History 172 | 173 | - PhoneGap was previously a product of Adobe. 174 | - To keep it open-source always and follow standards, PhoneGap codebase was handed over to Apache. 175 | - At Apache, it got a name change as Cordova. 176 | - And now it’s better known as Apache Cordova. 177 | - Ionic sits on top of Cordova as a UI library with Angular, to give the web app a native feel. 178 | 179 | PhoneGap is paid. 180 | Cordova is open source. 181 | The codebase is the same. 182 | 183 | If you use phonegap/Cordova you are using plain JavaScript (and can therefore choose to add any framework, including Angular, to that) whereas if you're using ionic then you're an AngularJs developer. 184 | 185 | ## Install 186 | 187 | To run Cordova, node is required. NPM is used for intalling Cordova, along with the plarforms and plugins. 188 | 189 | ```bash 190 | sudo npm i cordova -g 191 | ``` 192 | 193 | When the app is compiled, the target platform SDK is required. 194 | 195 | - Adroid Stuido for Android SDK. 196 | - Xcode for iPhone SDK. 197 | 198 | ## Create app 199 | 200 | ```bash 201 | #cordova folder_name package_name app_name 202 | cordova create myApp com.domain.app AppName 203 | ``` 204 | 205 | This will create the following: 206 | 207 | - `config.xml` - Old configuration (Don't use) 208 | - `hooks` - Special build tools go here. 209 | - `package.json` - Configuration 210 | - `platforms` - SKDs are stored here. 211 | - `plugins` - Like node_modules 212 | - `res` - Additional resources, like icons. 213 | - `www` - The web app lives here. 214 | - css 215 | - img 216 | - js 217 | - index.html 218 | 219 | The phone doesn't call the apps by name. It uses a special internal name to reference them. 220 | 221 | Reverse domain name notation is used as the naming convention for the packages. They are based on registered domain names, and are only reversed for sorting purposes. 222 | 223 | For example, if a company making a product called `MyProduct` has the registered domain name `example.com`, they could use the reverse-DNS string `com.example.MyProduct` to describe it. 224 | 225 | Reverse-DNS names are a simple way of reducing name-space collisions, since any domain name is registered by only one party at a time. 226 | 227 | ## Add platform 228 | 229 | ```bash 230 | cordova platform add android 231 | ``` 232 | 233 | ## Emulate app 234 | 235 | This will load the app inside the emulator. You first need to create it with a system image for the target platform with AVD. 236 | 237 | ```bash 238 | cordova emulate android 239 | ``` 240 | 241 | ## Build app 242 | 243 | This will build the app i.e. `.apk` file, which can be installed on an android device. 244 | 245 | ```bash 246 | cordova build android 247 | ``` 248 | -------------------------------------------------------------------------------- /topics/mvc.md: -------------------------------------------------------------------------------- 1 | ![mvc](../pics/mvc_full_stack.jpg) -------------------------------------------------------------------------------- /topics/networking.md: -------------------------------------------------------------------------------- 1 | # Setup 2 | 3 | Tools used for networking. 4 | 5 | ```bash 6 | sudo apt-get update && sudo apt-get upgrade 7 | sudo apt-get install netcat-openbsd tcpdump traceroute mtr 8 | ``` 9 | 10 | # Theory 11 | 12 | Create a basic program that sends a string to the specified ip/port. 13 | 14 | Create a second program that listens on that ip/port and prints out any received strings. 15 | 16 | Congratulations you now know how every network works. The rest is security, data verification/validation, optimization. 17 | 18 | ## HTTP / TCP Model 19 | 20 | Each of these depends on the one below. Some of these don't belong on a specific layer. 21 | 22 | ![TEA](../pics/networking/TCPIP.jpg) 23 | 24 | HTTP = Hypertext Transfer Protocol 25 | TCP = Transmission Control Protocol 26 | 27 | All traffic is split up into messages called packets, sent between two computers in a stream, with the addresses of the sender and recipient in each one. 28 | 29 | HTTP is needed so that communicating systems can understand each other. TCP just provides "envelopes" that can transfer bytes around the network. 30 | 31 | An application protocol assigns structure and meaning to the contents of the envelopes. 32 | 33 | **If you speak English and I send you a letter written in French, you'll still get the letter, but you won't understand it.** 34 | 35 | HTTP is implemented in browsers and web servers, while TCP in the operating system. 36 | 37 | #### Simple HTTP Request 38 | 39 | ```bash 40 | # HTTP header 41 | GET /posts/1 HTTP/1.1 42 | Host: jsonplaceholder.typicode.com 43 | 44 | # Manual request - Returns header and body 45 | printf 'GET /posts/1 HTTP/1.1\r\nHost:jsonplaceholder.typicode.com\r\n\r\n' | nc jsonplaceholder.typicode.com 80 46 | 47 | # Just the body 48 | curl jsonplaceholder.typicode.com/posts/1 49 | ``` 50 | 51 | ## Ports 52 | 53 | Listening on a port is like waiting for a phone call on a specific phone number. 54 | 55 | Ports let servers distinguish one service from another on the same host and wait for someone to connect. 56 | 57 | Normally a server has well known ports for it's applications. ex. HTTP uses `port 80` and SSH uses `port 22`. The client initiates a connection, and it's associated with an arbitrary port on its end. 58 | 59 | Only one program can listen to a port in a given moment. Once started, the program can start child processes to listen for multiple connections on the same port i.e. a web server. 60 | 61 | The port range that a normal (non-root) user can listen on is `1024` through `65535`. Root access (including sudo) can listen on ports down to 1. 62 | 63 | If the other side doesn't pick up, an RST (Reset packet) error message is sent back. 64 | 65 | # DNS 66 | 67 | It's basically a phonebook for IP addresses. 68 | 69 | An `A Record` is matched with an IP address, so when someone looks for `www.google.com`, the A record is referenced and the IP address is sent back to the user. 70 | 71 | The DNS resolver i.e. client code is built into the OS. 72 | 73 | **CNAME** - Canonical Name i.e. alias for a domain. 74 | **AAAA** - IPv6 equivalent to an A record. 75 | **NS** - DNS Name server. The NS record for a particular domain specifies which DNS has the records. 76 | 77 | # Tools 78 | 79 | ## ping 80 | 81 | It sends individual packets to test if traffic can get from one address to another, and back. 82 | 83 | ```bash 84 | ping 8.8.8.8 85 | 86 | # send 5 packets 87 | ping -c 5 google.com 88 | ``` 89 | 90 | #### unknown host 91 | 92 | ```bash 93 | sudo vim /etc/resolv.conf 94 | # Add nameserver 8.8.8.8 95 | ``` 96 | 97 | ## lsof 98 | 99 | The `lsof` utility lists open files, including network sockets (listening or connected). 100 | 101 | ```bash 102 | # List only network sockets 103 | lsof -i 104 | ``` 105 | 106 | ## nc / netcat 107 | 108 | `netcat` is a tool for manually talking to servers, by connecting to a port and sending a string over it. It's a thin wrapper over TCP. 109 | 110 | ```bash 111 | nc en.wikipedia.org 80 112 | nc localhost 22 113 | nc gmail-smtp-in.l.google.com 80 114 | ``` 115 | 116 | To illustrate, we can use two terminals to talk to each other. Anything typed at the second console will be concatenated to the first, and vice-versa. This is a simple TCP server. The connection is ended with `CTRL` + `d`. 117 | 118 | ```bash 119 | # terminal 1 120 | nc -l 3456 # listen for an incoming connection on port 3456 121 | # typed text 122 | 123 | # terminal 2 124 | nc 127.0.0.1 3456 # connect to the machine and port being listened on 125 | # typed text 126 | ``` 127 | 128 | Commands can be sent via a `pipe`. 129 | 130 | ```bash 131 | echo 'message' | netcat server 80 132 | ``` 133 | 134 | `netcat` doesn't know anything about forming HTTP request, but in combination with `printf` and `piping`, it can be done. 135 | 136 | ```bash 137 | printf 'HEAD / HTTP/1.1\r\nHost: google.com\r\n\r\n' | nc google.com 80 138 | 139 | printf 'GET /posts/1 HTTP/1.1\r\nHost:jsonplaceholder.typicode.com\r\n\r\n' | nc jsonplaceholder.typicode.com 80 140 | ``` 141 | 142 | ## host 143 | 144 | Used for looking up records in the DNS. 145 | 146 | ```bash 147 | # Returns all the records 148 | host google.com 149 | 150 | # Returns just the A record 151 | host -t a google.com 152 | ``` 153 | 154 | ## dig 155 | 156 | Similar to `host` in showing DNS records, but in a way more readable for scripts and closer to the way they are stored in the DNS configuration files. 157 | 158 | ```bash 159 | dig google.com 160 | ``` 161 | 162 | # Static server 163 | 164 | This will start a static web server on port `8000`. The command has to be run in the directory with the `index.html` file. 165 | 166 | ```bash 167 | python -m SimpleHTTPServer 8080 168 | ``` 169 | 170 | # Networking 171 | 172 | **Gateway** is the router address we are talking to in order to connect to the rest of the network/internet. 173 | 174 | `127.x.x.x` - Your computer. 175 | `192.168.0.x` - Local address created by a router. 176 | 177 | `ifconfig` - Check IP address. 178 | `ping 8.8.8.8` - Ping IP address. 179 | `netstat -tupln` - Check open ports. 180 | 181 | `cat etc/network/interfaces` - Shows the interfaces brought up after booting. 182 | 183 | `/etc/hosts` is used to simulate a domain for an IP address. Add `127.0.0.1 domain.com` to avoid typing the IP address. 184 | 185 | # The following notes are from the book Networking for System Administrators - Michael W. Lucas 186 | 187 | # Roles 188 | 189 | Every sysadmin, database admin, web admin, developer, and IT professional should understand the basics of networking. 190 | 191 | It's **much** easier to teach a system administrator the basics of networking, than to teach a network administrator the basics of system administration. 192 | 193 | ## System Administrators 194 | 195 | Responsible for managing servers i.e. computers, running an OS, whose main task is providing services to other servers or users, rather than the network. 196 | 197 | They should: 198 | 199 | - Learn the basics of networking 200 | 201 | ## Network Administrators 202 | 203 | Responsible for managing network equipment, such as routers. 204 | 205 | They should: 206 | 207 | - Learn basics of how servers operate. 208 | - Understand the basics of: 209 | - user access control and privileges 210 | - processes 211 | - services and daemons 212 | - install/remove software 213 | 214 | # Basic tools 215 | 216 | | unix | windows | use | 217 | | ---------------- | -------- | ----------------------------------------------------------- | 218 | | ifconfig / route | ifconfig | View the system's network configuration | 219 | | grep | findstr | Search for specific text | 220 | | netstat | netstat | Display established network connections and statistics | 221 | | lsof | | What processes open which files | 222 | | route | | Display where and change how traffic is sent | 223 | | tcpdump | | Display traffic to and from a server, view network activity | 224 | | traceroute | tracert | Show the route the traffic takes | 225 | | host | nslookup | Explore the Domain Name System (DNS) | 226 | 227 | # Network Layers 228 | 229 | Each layer handles a very specific task and interacts only with layers directly above or below. When a layer breaks, it takes all the above with it. Always try to specify the problematic layer for better support. 230 | 231 | - Textbook 7 layer model - Open Systems Interconnect (OSI) 232 | - Real-world 5 layer model - Modified TCP/IP 233 | - Physical 234 | - Datalink 235 | - Network 236 | - Transport 237 | - Application 238 | 239 | ## 1. Physical layer 240 | 241 | This is mostly Ethnernet cables i.e. "The wire". It has no intelligence, as the datalink determines how it's used. 242 | 243 | ## 2. Datalink layer 244 | 245 | Transforms the layers above into signals transmitter over the wire, called `frames`. Most environments use Ethernet as the datalink layer. 246 | 247 | IPv4: 248 | 249 | - Media Access Control (MAC) 250 | - Address Resolution Protocol (ARP) 251 | 252 | IPv6: 253 | 254 | - MAC 255 | - Neighbor Discovery (ND) 256 | 257 | ## 3. Network layer 258 | 259 | Maps connectivity between hosts. i.e. "Can I and how do I get to this other host?" 260 | 261 | Provides a consistent interface to network programs. 262 | 263 | A single chunk of network data is called a `packet`. 264 | 265 | The Internet uses the `Internet Protocol (IP)` which gives each host one or more unique IP addresses, so other hosts can find it. 266 | 267 | Network Address Translation (NAT) screws around with the "unique address" rule, but ultimately, you have a globally unique IP address on your or provider's network. 268 | 269 | ## 4. Transport layer 270 | 271 | The data you care about, called `segments`, flows here. 272 | 273 | ### ICMP - Internet Control Message Protocol 274 | 275 | Low-level connectivity messages between hosts i.e. `ping`, re-routing traffic, Datalink layer errors... 276 | 277 | ### TCP - Transmission Control Protocol 278 | 279 | Rich (reliable) transmission of application data between hosts. Has error checking, congestion control, retransmission of lost data. 280 | 281 | ### UDP - User Diagram Protocol 282 | 283 | Simple (unreliable) transmission of application data between hosts. Reliability is handled in the application, rather than layer. Usually video games. 284 | 285 | ## 5. Application layer 286 | 287 | For simplicity and more realistic use, it bundles the actual higher layers: 288 | 289 | - **Session layer** - open/close transport layer connections. 290 | - **Presentation layer** - Lets programs exchange data. 291 | - **Application layer** - Actual protocol spoken over these connections. 292 | 293 | The `TCP/IP` model calls everything above the transport layer the application layer. It includes protocols like HTTP, SMTP, LDAP... 294 | -------------------------------------------------------------------------------- /topics/node.md: -------------------------------------------------------------------------------- 1 | # Install 2 | 3 | ```bash 4 | sudo apt install nodejs -y 5 | 6 | # Check install 7 | node -v 8 | npm -v 9 | ``` 10 | 11 | # Import / Export 12 | 13 | - **CommonJS (CJS) format**. Used in Node.js and uses `require` and `module.exports` to define dependencies and modules. *The npm ecosystem is built upon this format*. `exports = module.exports` 14 | 15 | ```javascript 16 | // lib.js 17 | 18 | // Export the function 19 | function sayHello(){ 20 | console.log('Hello'); 21 | } 22 | 23 | // Do not export the function 24 | function somePrivateFunction(){ 25 | // ... 26 | } 27 | 28 | module.exports.sayHello = sayHello; 29 | ``` 30 | ```javascript 31 | let sayHello = require('./lib').sayHello; 32 | 33 | sayHello(); 34 | // => Hello 35 | ``` 36 | 37 | - **ES Module (ESM) format**. As of ES6 (ES2015), JavaScript supports a native module format. It uses an `export` keyword to export a module’s public API and an `import` keyword to import it. 38 | 39 | ```javascript 40 | // lib.js 41 | 42 | // Export the function 43 | export function sayHello(){ 44 | console.log('Hello'); 45 | } 46 | 47 | // Do not export the function 48 | function somePrivateFunction(){ 49 | // ... 50 | } 51 | ``` 52 | ```javascript 53 | import { sayHello } from './lib'; 54 | // import * as lib from './lib'; 55 | 56 | sayHello(); 57 | // => Hello 58 | ``` 59 | 60 | # Modules 61 | 62 | Instead of writing all the code in one giant file, we can split the code into multiple files called `modules`. Only things that are highly related should go in a module. 63 | 64 | This increases maintainability, code reuse and abstraction (blackbox). 65 | 66 | **CommonJS** (old) - Synchronous 67 | ```javascript 68 | // foo.js module 69 | function foo() { 70 | return 'bar'; 71 | } 72 | module.exports.foo = foo; 73 | 74 | // index.js use 75 | const { foo } = require('foo'); 76 | ``` 77 | 78 | **ES6** - Must use Babel, can be asynchronous 79 | ```javascript 80 | // foo.js module 81 | export function foo() { 82 | return 'bar'; 83 | } 84 | 85 | // index.js use 86 | import { foo } from 'foo'; 87 | ``` 88 | 89 | Every file in Node is considered a module. Everything declared inside is scoped to the file i.e. they are private. 90 | 91 | Node does not give access to the global scope. In order to use the content of a module, we need to export it i.e. make it public. 92 | 93 | ```javascript 94 | var message = "hello"; 95 | console.log(global.message); // undefined 96 | ``` 97 | 98 | ## ES6 Modules 99 | 100 | A proper format, unlike the CommonJS convention. 101 | 102 | ```javascript 103 | // add.js 104 | export function add(a, b) { 105 | return a + b; 106 | } 107 | 108 | // index.js 109 | import { add } from "./add"; 110 | ``` 111 | 112 | Modules are exported with `export` and imported with `import`. We can export one or more objects from a module. 113 | 114 | There are `default` and `named` exports. We use a default export if there is a single object we want to export. 115 | 116 | **module** 117 | 118 | ```javascript 119 | import { Person } from "./person"; 120 | 121 | // Named export 122 | export function promote() {} 123 | 124 | // Default export 125 | export default class Teacher extends Person { 126 | constructor(name, degree) { 127 | super(name); 128 | this.degree = degree; 129 | } 130 | 131 | teach() { 132 | console.log("teach"); 133 | } 134 | } 135 | ``` 136 | 137 | **import** 138 | 139 | ```javascript 140 | import Teacher, { promote } from "./teacher"; 141 | 142 | // Default -> import ... from ""; 143 | // Named -> import { ... } from ""; 144 | 145 | const teacher = new Teacher("John", "MSc"); 146 | teacher.teach(); 147 | ``` 148 | 149 | ### Browsers 150 | 151 | Must include the `.js` file extension during import. 152 | 153 | **circle.js** 154 | 155 | ```javascript 156 | // Implementation detail, not exported 157 | const _radius = new WeakMap(); // private property 158 | 159 | // Public interface i.e. exported part 160 | export class Circle { 161 | constructor(radius) { 162 | _radius.set(this, radius); 163 | } 164 | 165 | draw() { 166 | console.log("Circle with radius" + _radius.get(this)); 167 | } 168 | } 169 | ``` 170 | 171 | **index.js** 172 | 173 | ```javascript 174 | import { Circle } from "./circle.js"; // Must include the .js file extension 175 | 176 | const c = new Circle(10); 177 | c.draw(); // Circle with radius 10 178 | ``` 179 | 180 | **index.html** 181 | 182 | We need to add the module type in order to avoid the `Uncaught SyntaxError: Unexpected token {` error, caused by the `import` curly brace. 183 | 184 | ```html 185 | 186 | ``` 187 | 188 | ## Old formats 189 | 190 | Conventions/syntax for defining modules. ES6 natively supports them. 191 | 192 | - **CommonJS** - Loads files synchronously. 193 | 194 | Since ES5 doesn't support modules, developers came up with different syntaxes to define them. These are only used in legacy applications. 195 | 196 | - **AMD** (Browser) - Asynchronous Module Definition. 197 | - **UMD** (Browser / Node)- Universal Module Definition. 198 | 199 | ### CommonJS (Node) 200 | 201 | Two problems: 202 | 203 | 1. Browsers cannot load files synchronously. This is solved via bundling a huge file including everything, even unused things. 204 | 2. JS engine cannot tell what a module exports until it runs it. 205 | 206 | ```javascript 207 | // add.js 208 | function add(a, b) { 209 | return a + b; 210 | } 211 | module.exports = add; 212 | 213 | // index.js 214 | const add = require("./add"); // Loads synchronously 215 | add(2, 3); // 5 216 | ``` 217 | 218 | CommonJS defines the: 219 | 220 | - `module.exports` for exporting modules. It represents the object that is exported from a module. 221 | - `module` refers to the current module (file). 222 | - `exports` is an object and property of `module`. 223 | - `require("./module")` for importing modules. 224 | 225 | #### Single class export 226 | 227 | When we import the `foo.js` module, we directly get the `Foo` class. 228 | 229 | ```javascript 230 | class Foo {} 231 | 232 | module.exports = Foo; 233 | ``` 234 | 235 | #### Multiple class exports 236 | 237 | We can import the `exports` objects and access its properties. 238 | 239 | ```javascript 240 | class Foo {} 241 | class Bar {} 242 | 243 | module.exports.Foo = Foo; 244 | module.exports.Bar = Bar; 245 | ``` 246 | 247 | #### Example 248 | 249 | **circle.js** 250 | 251 | ```javascript 252 | // Implementation detail, not exported 253 | const _radius = new WeakMap(); // private property 254 | 255 | // Public interface i.e. exported part 256 | class Circle { 257 | constructor(radius) { 258 | _radius.set(this, radius); 259 | } 260 | 261 | draw() { 262 | console.log("Circle with radius" + _radius.get(this)); 263 | } 264 | } 265 | 266 | module.exports = Circle; 267 | ``` 268 | 269 | **index.js** 270 | 271 | ```javascript 272 | const Circle = require("./circle"); 273 | 274 | const c = new Circle(10); 275 | c.draw(); // Circle with radius 10 276 | ``` 277 | -------------------------------------------------------------------------------- /topics/nodemcu.md: -------------------------------------------------------------------------------- 1 | # NodeMCU/ ESP28266 2 | 3 | NodeMCU is a firmware that allows you to program the ESP8266 chip with a LUA script, or C/C++ via the Arduino IDE. 4 | 5 | The NodeMCU programming model is similar to that of Node.js, only in Lua. It is asynchronous and event-driven. Many functions, therefore, have parameters for callback functions. 6 | 7 | While the ESP8266 is often used as a ‘dumb’ Serial-to-WiFi bridge, it’s a very powerful microcontroller on its own, as it's basically an Arduino. 8 | 9 | # Power 10 | 11 | The chip itself uses 3.3v, but if the board has a usb port, then it knows that usb comes with a 5v supply, so it probably has a regulator built-in to convert the 5v to the 3.3v the chip needs. 12 | 13 | A phone charger or power bank should work just fine. 14 | 15 | https://tttapa.github.io/ESP8266/Chap04%20-%20Microcontroller.html 16 | 17 | # Setup 18 | 19 | 1. Start Arduino IDE and open Preferences window. 20 | 21 | 2. Enter http://arduino.esp8266.com/stable/package_esp8266com_index.json into Additional Board Manager URLs field. You can add multiple URLs, separating them with commas. 22 | 23 | 3. Open Boards Manager from Tools > Board menu and install esp8266 platform (and don't forget to select your ESP8266 board from Tools > Board menu after installation). 24 | 25 | # GPIO 26 | 27 | NodeMCU Development kit provides access to the GPIOs of ESP8266. **The NodeMCU Dev kit pins are numbered differently than internal GPIO notations of ESP8266**. For example, the D0 pin on the NodeMCU Dev kit is mapped to the internal GPIO pin 16 of ESP8266. 28 | 29 | ```c 30 | // Pins can be assigned like this 31 | int PIN_A = D7 // GPIO13 32 | int PIN_A = 13 // D7 33 | 34 | // This can also be used. Takes less RAM. 35 | #define PIN_A 13 36 | ``` 37 | 38 | # LED example 39 | 40 | ```c 41 | int LED = D7; 42 | 43 | void setup() { 44 | pinMode(LED, OUTPUT); 45 | } 46 | 47 | void loop() { 48 | digitalWrite(LED, LOW); 49 | delay(1000); 50 | digitalWrite(LED, HIGH); 51 | delay(2000); 52 | } 53 | ``` 54 | 55 | # Remote LED light 56 | 57 | Upload the code into NodeMCU, and go to the local address specified in the serial monitor in order to toggle the LED light, connected in a classic GPIO way. 58 | 59 | ```c 60 | #include 61 | 62 | const char* ssid = "WIFI_NAME"; 63 | const char* password = "WIFI_PASSWORD"; 64 | 65 | int ledPin = 13; // GPIO13---D7 of NodeMCU 66 | WiFiServer server(80); 67 | 68 | void setup() { 69 | Serial.begin(115200); 70 | delay(10); 71 | 72 | pinMode(ledPin, OUTPUT); 73 | digitalWrite(ledPin, LOW); 74 | 75 | // Connect to WiFi network 76 | Serial.println(); 77 | Serial.println(); 78 | Serial.print("Connecting to "); 79 | Serial.println(ssid); 80 | 81 | WiFi.begin(ssid, password); 82 | 83 | while (WiFi.status() != WL_CONNECTED) { 84 | delay(500); 85 | Serial.print("."); 86 | } 87 | Serial.println(""); 88 | Serial.println("WiFi connected"); 89 | 90 | // Start the server 91 | server.begin(); 92 | Serial.println("Server started"); 93 | 94 | // Print the IP address 95 | Serial.print("Use this URL to connect: "); 96 | Serial.print("http://"); 97 | Serial.print(WiFi.localIP()); 98 | Serial.println("/"); 99 | 100 | } 101 | 102 | void loop() { 103 | // Check if a client has connected 104 | WiFiClient client = server.available(); 105 | if (!client) { 106 | return; 107 | } 108 | 109 | // Wait until the client sends some data 110 | Serial.println("new client"); 111 | while(!client.available()){ 112 | delay(1); 113 | } 114 | 115 | // Read the first line of the request 116 | String request = client.readStringUntil('\r'); 117 | Serial.println(request); 118 | client.flush(); 119 | 120 | // Match the request 121 | 122 | int value = LOW; 123 | if (request.indexOf("/LED=ON") != -1) { 124 | digitalWrite(ledPin, HIGH); 125 | value = HIGH; 126 | } 127 | if (request.indexOf("/LED=OFF") != -1) { 128 | digitalWrite(ledPin, LOW); 129 | value = LOW; 130 | } 131 | 132 | // Set ledPin according to the request 133 | //digitalWrite(ledPin, value); 134 | 135 | // Return the response 136 | client.println("HTTP/1.1 200 OK"); 137 | client.println("Content-Type: text/html"); 138 | client.println(""); // do not forget this one 139 | client.println(""); 140 | client.println(""); 141 | 142 | client.print("Led is now: "); 143 | 144 | if(value == HIGH) { 145 | client.print("On"); 146 | } else { 147 | client.print("Off"); 148 | } 149 | client.println("

"); 150 | client.println(""); 151 | client.println("
"); 152 | client.println(""); 153 | 154 | delay(1); 155 | Serial.println("Client disonnected"); 156 | Serial.println(""); 157 | } 158 | ``` 159 | -------------------------------------------------------------------------------- /topics/productMVP.md: -------------------------------------------------------------------------------- 1 | # Building Product 2 | 3 | MVP = You've made something bad, the most desperate want. 4 | 5 | [Building Product - Michael Seibel](https://youtu.be/C27RVio2rOs) 6 | 7 | Justin.tv later Twitch 8 | 9 | Things that allowed us to survive (All were essential): 10 | - Founding team was extremely technical. This allowed them to break a lot of rules. 11 | - Didn't spend a lot of money. 12 | - Ego was highly tied to the startup. Failing = Fail in life. 13 | 14 | ## What problem are you solving? 15 | 16 | - Can you state the problem clearly in 1 sentence? 17 | - Have you experienced the problem yourself? 18 | - Can you describe the problem narrowly? 19 | - Is the problem solvable? Ex. Uber for babysitting. Very hard to solve. 20 | 21 | ## Who is your customer? 22 | 23 | - Everyone? **NO!** 24 | - How often do you have the problem? 25 | 26 | - Ex. Car selling app. The customer is not the buyer, but the seller! The buyer comes back after 7 years, the seller has the problem everyday. 27 | 28 | - How intense is the problem? 29 | - Are they willing to pay? 30 | 31 | - *I need to give it away for free, it's the only way I'll get users*. **WRONG!** If you want to know if you have a good product it's a lot easier to make it harded for the user to use it, and see if they use it anyway. If they have an extremely intense problem, and you ask for $100, they'll see a deal. If you charge $0, you'll get people trying something out, without a real problem. **Starting with a price is always better than free**. 32 | 33 | - How easy are they to find? 34 | 35 | ## Does your MVP solve the problem? 36 | 37 | Usually you end up with a completely differnt product by the end. 38 | 39 | The longer you build it, the more it drifts away from the initial idea. 40 | 41 | The answer to this question hurts. 42 | 43 | ## Which customers should you go after first? 44 | 45 | Go after the easiest first! The instinct is to go after the hardest first, almost as a proof. 46 | 47 | If you're trying to sell a simple $1,000 / month software, and you're engaged in a 6 month conversation with them, that's not a desperate company, MOVE ON! 48 | 49 | *Whose business is gonna go out of business without using you?* 50 | 51 | Find the people screaming for the product! 52 | 53 | Ignore investors, friends, other founders... They will 100% lead you astray. Talk to customers. 54 | 55 | ## Which customers should you run away from? 56 | 57 | The hard ones! 58 | 59 | Customers blasting your support, constantly complaining... Exploiting your value. 60 | 61 | You can FIRE a customer. 62 | 63 | ## Should you discount or start with a super low price? 64 | 65 | **NO!** 66 | 67 | You can structure discounts and incentives into your sales pitch, if you understand what value you're getting back. 68 | 69 | Ex. We've made a deal with AWS to have 40% discount, and we can pass that onto you, but only for the first 30 days. I'd love for you to take as much time as you want to make a decision, but I really would hate you buying it on the 31st day. 70 | 71 | It's a structured discount. Also, the price is simply set higher from the start. 72 | 73 | This is the way to do it, not by giving it for free because no one will use it. 74 | 75 | ## How to setup metrics 76 | 77 | Google Analytics is bad for this. 78 | 79 | - How many people visited the website. 80 | - How many pages they viewed. 81 | - Where they came from. 82 | 83 | You need an events based metrics product i.e. what their actions were. 84 | 85 | - Did they click this button? 86 | - Did they see this screen? 87 | - How long were they on a page before doing something else? 88 | - Did they leave something in their cart? 89 | 90 | Ex. Mixpanel, Amplitude, Heap... 91 | 92 | Pick 5-10 important stats. 93 | 94 | Ex. Instagram: 95 | 96 | - Open the app 97 | - Create an account 98 | - Took a photo 99 | - Applied effects 100 | - Shared he photo 101 | 102 | Make measurements a part of the product spec i.e. strart tracking with the release. 103 | 104 | ## Product Development Cycle (v1) 105 | 106 | Have **ONE** brainstorming meeting every week. In order to prevent hating it, make it the only one during the cycle. 107 | 108 | 1. KPI goal - A number that you track, that reflects how well the company is doing. 109 | 110 | - If you charge money, it's revenue. 111 | - If not, it's usage. 112 | 113 | 2. Brainstorm. Any stated idea, is writted on a board. 114 | 115 | - New features / Reitereation on existing ones. 116 | - Bug fixes. 117 | - Tests. A/B testing. 118 | 119 | 3. Easy / Medium / Hard, time for one engineer to build. 120 | 121 | - Easy. 1-2 hours. 122 | - Medium. 1-2 days. 123 | - Hard. While dev cycle. 124 | 125 | Most hard ideas can be restated as an easy idea, if you undrestand what bits of the hard idea are both useless and hard. Most of the time, these can be removed. 126 | 127 | 4. Decide 128 | 129 | Decide which features would impact the KPI the most. Hard first, medium second, easy last. 130 | 131 | 5. Writte spec. Everyone fuck up here, and no one likes this step. 132 | 133 | Go through the brainstorm ideas, and write down the selected on in **DETAIL**. This is **EXTREMELY IMPORTANT** 134 | 135 | ## Pivot vs Iterate 136 | 137 | If you are expecting to build something significant under two years, you are doing it wrong. 138 | 139 | Pivot = Changing the customer and/or the problem (rare) Means start a new company. 140 | Iterate = Changing the solution (common) 141 | 142 | Many make the mistake by thinkin the solution is the genius part, and they look for different customers for their solution. Actually, identifying the problem that other's haven't figured out how to solve is the genius part. Facebook and Google weren't first. 143 | 144 | ## Fake vs Real Steve Jobs (how not to be a product dictator) 145 | 146 | Fake Steve Jobs = The product has to be this way, because I said so. Fuck the customer, fuck everyone else, fuck you... Dreams and creates art. 147 | 148 | Real Steve Jobs = Release a shitty MVP and every year reiterate. Iterates and talks to customers. 149 | 150 | # How to Plan an MVP (Minimum Viable Product) 151 | 152 | [How to Plan an MVP - Michael Seibel](https://www.youtube.com/watch?v=1hHMwLxN6EM) 153 | 154 | When you think about MVP, you should think about something ridiculously simple. It's the first think you can give, to the very first users, in order to see if you can deliver any value at all. 155 | 156 | **THE THING THAT GETS PEOPLE REALLY SCREWED UP WITH THEIR MVP, IS THAT THEY HAVE A VISION THAT'S BIG, AND ARE NOT WILLING TO HAVE A SMALL MVP** 157 | 158 | Talk yo your users before writing code, to understand the problem! 159 | 160 | You can be your own first user. 161 | 162 | ## Goal of a pre-launch startup 163 | 164 | - Launch something bad quickly! 165 | - Get initial customers, anyone. 166 | - Talk to customers and get feedback. 167 | - Iterate i.e. continue improving the solution. 168 | 169 | Most founders have an idea what to build, so they think that having not built the full thing, it's not worth getting feddback on the shitty initial thing. This is a mistake, because the final product might not be what your customers want at all. 170 | 171 | Holt the problem tightly, the customer tightly, but the solution loosely. 172 | 173 | On iteration, it's like your making a screwdriver, and the mechanic tells you it doesn't screw anything, so you go looking for uses of the screwdriver if it can cook. Fix the product, rather than look for a customer for the broken one. 174 | 175 | ## Lean MVP (most cases) 176 | 177 | - Very fast to build (weeks, not months) 178 | - **Extremely** limited functionality. 179 | - Appeal to a small set of users. Have a vision of everyone, make an MVP for a few. 180 | - Base to iterate from. Your MVP is not special. 181 | 182 | ![MVP](../pics/product/mvp/mvp_airbnb.jpg) 183 | 184 | ![MVP](../pics/product/mvp/mvp_twitch.jpg) 185 | 186 | ![MVP](../pics/product/mvp/MVP_stripe.jpg) 187 | 188 | ## Heavy MPV (very few cases) 189 | 190 | - Significant regulation (banking, insurance) 191 | - Hardtech (rockets) 192 | - Biotech 193 | - Moonshot (bore tunnels under cities) 194 | 195 | ## Launching 196 | 197 | **It's not important to "launch"** i.e. do you remember Google, Facebook, Twitter launches? 198 | 199 | Launch simply means to start getting customers. 200 | 201 | Learning from customers is easier with an MVP, than without. 202 | 203 | ## Hacks for building an MVP quickly 204 | 205 | - Time box your spec (list of stuff to build) 206 | - Write your spec (Most fuck it up) 207 | - Cut your spec (unimportant stuff) 208 | - Don't fall in love with your MVP 209 | 210 | The goal is to get ANYTHING in front of a customer. 211 | 212 | If you think your MPV is special, you think it has to be perfect, you then spend a lot of time messing with it. 213 | 214 | You must assume it **HAS TO BE SHITTY**. 215 | 216 | If you are looking for a shirt to paint with and destroy, you woudln't spend time tailoring it. 217 | 218 | **NEVER ASK USERS FOR FEATURES** 219 | 220 | It's no their job to come up with features. Their job is to come up with problems. 221 | 222 | - How often do they have it? 223 | - How intense is it? 224 | - Are they willing to pay for it? 225 | - Do they know others that have it? 226 | 227 | Any feature request should be converted into problem dissection. 228 | 229 | Do I have product market fit? If you have to ask, you don't. You know you have it if you start spending the whole time just keeping servers alive to meet demand, rather than making new features. "We're gonna die because we have too many users!" 230 | 231 | Almost no one achieves product market fit. You may have some users, but that's not product market fit. 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | -------------------------------------------------------------------------------- /topics/productMarketFit.md: -------------------------------------------------------------------------------- 1 | # Product Market Fit - David Rusenko 2 | 3 | [David Rusenko - How To Find Product Market Fit](https://www.youtube.com/watch?v=0LNQxT9LvM0) 4 | 5 | Product Market Fit = Make something **a lot** of people want. 6 | 7 | Startup Stages 8 | 9 | ![Startup Stages](../pics/product/market_fit/market_fit_startup_stages.jpg) 10 | 11 | Top early challenges at a startup: 12 | 13 | - Finding product market fit. 14 | - Hiring and building a world-class team. 15 | - Making money (distant 3rd) 16 | - Build an organization that scalably and repeatedly launches great products. 17 | 18 | *It's a lot harder yo build a product a lot of people really really want, that it is to figure out how to make money from that product.* 19 | 20 | **The best companies create a market** 21 | 22 | Market research won't help, as you need to find the hidden need. If it's obvious, then everyone would be doing it. 23 | 24 | Everyone is going to tell you that the idea sucks. 25 | 26 | What are your customers trying to do, and what substitues are there? Ex. For a website builder, substitues are coding, facebook page, agency... 27 | 28 | "They are not trying to build a website... They're trying to grow their business." 29 | 30 | Where are you customer pulling you? You shouldn't be pushing them towards a solution. When things are working and your customers are telling you non-stop "You need to do this", and you say "It's not our vision" and they hack it to do it anyway... 31 | 32 | When you find people hacking your product to do something it wasn't meant to, pay attention and double down on that. 33 | 34 | ## Building a remarkable product 35 | 36 | 1. Have a great idea. 37 | 2. Talk to customers. 38 | 3. ??? 39 | 4. PROFIT! 40 | 41 | ### Step 3 42 | 43 | 1. Talk to customers. Develop a market thesis. 44 | 2. Listen to their problems, not solutions. 45 | 46 | - "If you ask customers what they want, they'd say a faster horse. They don't know what they want until you show it to them" - Henry Ford 47 | - It's absolutely critical to talk to customers and understand their pain. Listen to their proposed solutions, but dig deeper. What underlying job are they trying to accomplish? 48 | 49 | 3. Rapid prototyping and user testing. 50 | 51 | - Building a fully functional product is the most expensive possible way to test your hypothesis. 52 | - Focus on getting toa functional prototype as quickly as possible that you ca get in front of users. 53 | - Don't worry about scaling, monetizing... It comes later. 54 | - Expect it will that 10x the number of iterations: 55 | - Keep your burn low. 56 | - Build a team that can do this quickly. (Outsourcing is difficult in the early days) 57 | 58 | 4. Build the solution to their problems. 59 | 5. Test the solution with them. 60 | 61 | - Make sure you're talking to your target customer. (Be open to change who they are) 62 | - Don't overthink it. Anecdotal is ok. 63 | - Most helpful tools: 64 | - Customer interviews (5-10) 65 | - UX testing sessions (3-5) **MOST IMPORTANT** 66 | 67 | 1. Get someone to use your app in front of you. 68 | 2. Encourage them to give honest feedback. 69 | 3. Ask them to perform a task. (You can't touch the phone/keyboard) 70 | 4. DO NOT SAY OR DO ANYTHING. 71 | 5. Watch in extreme agony as they struggle to figure it out. 72 | 73 | - Metrics (Beware, never enough data to support behavior) 74 | 75 | 6. Did it work? If not, GOTO 1. 76 | 7. By the time you've reached this step, you've likely looped ~27 times. 77 | 78 | ## When to launch 79 | 80 | Minimum ~~Viable~~ Remarkable Product 81 | 82 | *Launch when your product is better than what's out there* - Paul Buchheit 83 | 84 | ## Prioritization 85 | 86 | 1. Only one thing matters. 87 | 88 | - Focus only on the things that get you to your next stage. Don't go to conferences, don't write blog posts, don't read the news... 89 | 90 | 2. Optimize for learning. 91 | 92 | - Most people prioritize by creating a list sorted by cost x benefit. Instead, ask yourself *"What is our biggest unknown that would rewrite our priority list?"* 93 | 94 | ## When is product market fit achieved 95 | 96 | By tracking 3 metrics 97 | 98 | 1. Returning usage. How many people go back on day 1, 3, 7, 30? 99 | 2. Track NPS (Would you recommend our product? 1 - 10). Should be > 50. 100 | - 9, 10 is plus. ex. 88% 101 | - 7, 8 is discarded. ex. 8% 102 | - 0 - 6 is minus. ex. 12% 103 | - Total NPS is 80. 104 | 3. Paying customer renewal rates. 105 | 106 | Don't pay much attention to: 107 | 108 | 1. Sign-ups. 109 | 2. Conversion rate. 110 | 111 | You'll know when you've achieved it when customers start beating a path to your door. When you don't have it, everything feels hard. When you have it, everything is easy and every move works - you're a genius. (The reality is somewhere in between) 112 | 113 | ## Scaling the team 114 | 115 | **Don't scale the team past ~20 before product market fit.** Everything breaks at 23-25 people. 116 | 117 | - A moderate amount of micromanagement is healthy at this stage. You should be involved in everything important and know all there is to know about your customers, product, market, channels... 118 | - This helps make fast and quality decisions which is a huge advantage over larger orgs where this is distributed across many roles. 119 | - Don't delegate anything important - yet! 120 | 121 | **Once you've achieved it, scale aggressively** 122 | 123 | - You've found/created a new market, but you're likely not the only one. 124 | - You're in a race to capture this new market. Advantages accrue to #1 - be that company. 125 | - Build the team aggressively, but thoughtfully. 126 | - You'll need to completely change the way you operate including doing a lot more delegating. 127 | - No more micromanagement! 128 | 129 | **Never more than double the size of the company in any year** 130 | 131 | # Product Market Fit - Michael Seibel 132 | 133 | [The Real Product Market Fit by Michael Seibel](https://www.youtube.com/watch?v=FBOLk9s9Ci4) 134 | 135 | Product Market Fit - Finding out what needs to be built 136 | 137 | You've achieved it when customers are buying as fast as you can provide. Money is piling up, you're hiring like crazy... 138 | 139 | 140 | Company building starts AFTER you've figured out how to solve a problem. 141 | 142 | The only way you know you've made something customers want, is because they are using it in an explosive and destructive way. 143 | 144 | Once you find product market fit, it's your company to fuck up. 145 | 146 | -------------------------------------------------------------------------------- /topics/productPricing.md: -------------------------------------------------------------------------------- 1 | [Kevin Hale - Startup Pricing 101](https://www.youtube.com/watch?v=jwXlo9gy_k4) 2 | 3 | ![Pricing](../pics/product/pricing/pricing_thermometer.jpg) 4 | 5 | There are two ways to get to the price: 6 | 1. Cost based 7 | 2. Value based - strive for this one 8 | 9 | # 4 common mistakes 10 | 11 | 1. Prices are too low 12 | 13 | 2. Underestimate costs 14 | 15 | 3. Don't understand your value 16 | - Either they don't understand your value, or you're unable to convince them. 17 | 18 | 4. Focus on wrong customers 19 | - *"If I build a better product, and half charge half the competition, I win..."* You are looking for people that won't base their decision on price alone. 20 | 21 | # Product lifecycle 22 | 23 | ![Pricing](../pics/product/pricing/pricing_sales_stages.jpg) 24 | 25 | Startups live in the 1st and 2nd stage, and the customers there are not mainstream, they're early adopters. 26 | 27 | *"Studies indicated that demand does not begin to accelerate untils the first 2%-5% of potential buyers adopt the product"* 28 | 29 | # Price optimization 30 | 31 | ![Pricing](../pics/product/pricing/pricing_optimization.jpg) 32 | 33 | Red = Lost opportunities (Happens at discount/tiered pricing) 34 | 35 | ![Pricing](../pics/product/pricing/pricing_billion_formula.jpg) 36 | 37 | What would the business look like if you're a billion dollar company i.e. $100M in sales **annually**, or $8M **monthly**. 38 | 39 | SMB = The *danger zone*, where a lot of companies are in and they struggle, where the customer treats their money like consumers but they kinda look like an enterprise. 40 | 41 | | Annual | Monthly | 42 | |---|---| 43 | | $100 | $8 | 44 | | $1K | $83 | 45 | | $10K | $833 | 46 | | $100K | $8,333 | 47 | 48 | 49 | 50 | ![Pricing](../pics/product/pricing/pricing_quadrants.jpg) 51 | 52 | **The numbers are ANNUAL** 53 | 54 | The price determines the acquisition strategy. 55 | 56 | - Self-serve (Same day conversions) 57 | - All marketing is inbound. No ads. 58 | - Support is self-serve. 59 | - No sales team. 60 | 61 | - Transactional (1 - 3 months sales cycle) 62 | - Marketing generates leads. 63 | - Support SLAs for training/onboarding. 64 | - Inside sales, SDR, demo presenter. 65 | 66 | - Enterprise (6 - 12 months sales cycle) 67 | - Branding. 68 | - Phone support, customer support. 69 | - Sales managers, territories. 70 | 71 | ![Pricing](../pics/product/pricing/pricing_rule.jpg) 72 | 73 | Charge $100 for customer's percieved value of $1,000. Raise prices by 5% until you start losing 20% of customers. -------------------------------------------------------------------------------- /topics/productSales.md: -------------------------------------------------------------------------------- 1 | # How to Sell - Tyler Bosemy 2 | 3 | [How to Sell - Tyler Bosemy](https://www.youtube.com/watch?v=xZi4kTJG-LE) 4 | 5 | ![Sales](../pics/product/sales/sales_expectations.jpg) 6 | 7 | ![Sales](../pics/product/sales/sales_reality.jpg) 8 | 9 | _You should be spending every moment, of every day, doing one of two things... Bulding product or talking to users_ - Paul Graham 10 | 11 | You have 2 HUGE advantages: passion + deep expertize 12 | 13 | Ideally, there should be a sales dedicated co-founder, doing it full-time. 14 | 15 | ## They almighty funnel 16 | 17 | 1. Prospecting - Who might be interested? 18 | 2. Conversations - Is this the right product for them? 19 | 3. Closing - How to not lose the deal. 20 | 4. Revenue 21 | 22 | ## Prospecting 23 | 24 | Figure out who will even take your call. 25 | 26 | - Find the innovators (2.5%) 27 | - It's a numbers game! You have to find the innovators. 28 | - Reach out to > 100 companies. 29 | - Top 3 methods: 30 | - Your network 31 | - Conferences 32 | - Cold emails 33 | 34 | **You're gonna hear a lot of NO!** 35 | 36 | ### Conferences 37 | 38 | - Figure out what's out there. 39 | - Go to a few. 40 | - Get the list! 41 | - Find out who's going to be there in advance. 42 | - Do it with as many as possible. 43 | - Email people in advance to setup a pitch. 44 | - Schedule entire days in 30 min increments. 45 | 46 | ### Cold Emails 47 | 48 | All you're trying to do is get a call or meet them i.e. move out of prospecting and start a converstaion 49 | 50 | - Short 51 | - To the point 52 | - Personalized 53 | - Actionable 54 | - Don't be to salesy. 55 | 56 | ``` 57 | John, 58 | 59 | My name is Tyler and I'm the CEO of Clever. 60 | 61 | My company has developed new technology that reduces the time spent doing SIS integrations by 80%. 62 | 63 | I figured this might be of interest to you given the new middle school reading software Scholastic just released. 64 | 65 | I'd love to get your feedback even if you're not in the market for this right now. 66 | 67 | Do you have 20 minutes this week? I'm open Tuesday at 1 or 2pm ET if either may work. 68 | 69 | Tyler 70 | ``` 71 | 72 | ## Conversations 73 | 74 | ![Converstaions](../pics/product/sales/sales_conversations_phone.jpg) 75 | 76 | When you get them on the phone, remember to **SHUT UP AND LISTEN!**. 77 | 78 | Number 1 sales tip: Sales is about listening. 79 | 80 | Listening is what sales is at its core. If you can do that, the rest is easy. People think it's about being a battering ram and forcing someone to buy. Rather, it's about building relationships with people, understanding their problems and needs, and seeing if you can help them with your solution. 81 | 82 | Ask questions: 83 | 84 | - Tell me about the problem you're having. 85 | - How do you solve it today? 86 | - What does your ideal solution look like? 87 | 88 | ### Religious Follow Up 89 | 90 | ![Converstaions](../pics/product/sales/sales_follow_up.jpg) 91 | _This is 2 months of work for closing a \$100,000/year customer_ 92 | 93 | ...And this is for someone that wants to buy the product! It's not over till they say no. 94 | 95 | The potential client has a lot on their mind that's not you. Being persistent is not rude if done the right way. 96 | 97 | **In order to not be push, follow up a little under a week (5-6 days)**... As long as it's thoughful and personalized. 98 | 99 | It's a lot of work to do sales well and it takes a lot of follow up. You have to have an inhumane willingness to just keep going. 100 | 101 | **There's a lot of value in driving conversations towards yes/no quickly.** - In order to not waste time on "no-s". 102 | 103 | Until you hear a no, you can follow up within reason. 8 unanswered emails... take a hint. 104 | 105 | ## Closing Traps 106 | 107 | ### Redlines 108 | 109 | - Final step is to send them an agreement. **HAVE IT READY!** 110 | - Use the open source YC contract template. 111 | - Don't waste time on minor legal points. 112 | 113 | Redlining = Changes to an agreement 114 | 115 | Usually when you send the contract, companies will want to change things. 116 | 117 | Early customers are like mana from heaven, do not lose them by draggin on the process! Obviously don't sign something stupid. 118 | 119 | ### 1 more feature 120 | 121 | "I want to buy, but only if you had this feature..." 122 | 123 | - Usually a polite pass. 124 | - Building it will not get you the sale! 125 | 126 | Either sign a conditional agreement, or wait to hear demand from more customers. 127 | 128 | ### Free trials 129 | 130 | "We want to try it for a month before buying" 131 | 132 | - Early on you need **commitment**, **validation** and **revenue**. 133 | - Free trial gets you **none** of these. 134 | 135 | Instead, offer a first 30 days cancellation period on an annual contract. 136 | 137 | ## Looking forward 138 | 139 | ![Cycle](../pics/product/sales/sales_cycle.jpg) 140 | 141 | 5 ways to build a big business: 142 | 143 | - Flea / Mice / Rabbits - Marketing 144 | - Deer - Inside Sales 145 | - Elephants - Field Sales 146 | 147 | How much you're able to charge determines your approach on sales. 148 | 149 | Prioritize the easiest sells i.e the most in need. Don't look for references, but rather for product validation. 150 | 151 | Low pricing ex. \$50/month: Demand generation, Email campaigns, self-service sign-up flows, referral codes... 152 | 153 | ## Pricing 154 | 155 | It's a really tough question. 156 | 157 | Just start with something and iterate, as the market will respond. 158 | 159 | More startups need to charge more. 160 | 161 | Guess a reasonable number for you, if you close that sale, try doubling it next time and so on... 162 | 163 | Be bold and confident about the price, but iterate in private. 164 | 165 | # How to Get Users and Grow - Gustaf Alstromer 166 | 167 | [How to Get Users and Grow - Gustaf Alstromer](https://www.youtube.com/watch?v=T9ikpoF2GH0) 168 | 169 | # Startups = Growth 170 | 171 | Some people think that if you build a product, and you put it out on the market, people will come and start using it. Not really. 172 | 173 | **Don't have a growth team if you don't have product market fit** - It's super dangerous as it will kill the business. 174 | -------------------------------------------------------------------------------- /topics/puppeteer.md: -------------------------------------------------------------------------------- 1 | # Install 2 | 3 | ```bash 4 | npm i puppeteer --save 5 | 6 | # This is needed for the dependencies 7 | sudo apt install chromium-browser 8 | ``` 9 | 10 | # Scraping 11 | 12 | 13 | # PDF 14 | 15 | ```javascript 16 | const express = require("express"); 17 | const puppeteer = require('puppeteer') 18 | 19 | var app = express(); 20 | 21 | // Allow requests from all domains and localhost 22 | app.all("/*", function (req, res, next) { 23 | res.header("Access-Control-Allow-Origin", "*"); 24 | res.header( 25 | "Access-Control-Allow-Headers", 26 | "X-Requested-With, Content-Type, Accept" 27 | ); 28 | res.header("Access-Control-Allow-Methods", "POST, GET"); 29 | next(); 30 | }); 31 | 32 | app.get('/pdf/:id', function (req, res) { 33 | 34 | let id = req.params.id; 35 | 36 | async function printPDF() { 37 | const browser = await puppeteer.launch({ headless: true, args: ['--no-sandbox', '--disable-setuid-sandbox'] }); 38 | const page = await browser.newPage(); 39 | await page.goto(`http://localhost:4000/${id}`, { waitUntil: 'networkidle0' }); 40 | const pdf = await page.pdf({ format: 'A4' }); 41 | 42 | await browser.close(); 43 | return pdf 44 | } 45 | 46 | printPDF().then(pdf => { 47 | res.set({ 'Content-Type': 'application/pdf', 'Content-Length': pdf.length }) 48 | res.send(pdf) 49 | }) 50 | 51 | }); 52 | 53 | app.get('/offer', function (req, res) { 54 | 55 | html = `

Hello World!

` 56 | res.send(html) 57 | 58 | }); 59 | 60 | var server = app.listen(4000, function () { 61 | var host = server.address().address; 62 | var port = server.address().port; 63 | console.log("app listening at http://%s:%s", host, port); 64 | }); 65 | ``` 66 | 67 | -------------------------------------------------------------------------------- /topics/raspberrypi.md: -------------------------------------------------------------------------------- 1 | # Raspberry Pi 2 | 3 | It's a micro-computer. 4 | -------------------------------------------------------------------------------- /topics/rfid.md: -------------------------------------------------------------------------------- 1 | # Standards 2 | 3 | | Family | Frequency | Protocol| Storage | Writable | Reader 4 | |---|---|---|---|---|---| 5 | Low Frequency (LF) | 125/134 kHz | EM4100 | UID 4 bytes | No | RDM-6300 (Coil antenna) 6 | High Frequency (HF) | 13.56 MHz | Mifare Classic | UID 4 bytes | 1 KB | MFRC-522 (Loop antenna) 7 | Ultra High Frequency (UHF) | 868 MHz | 1386.00 | 8 | 9 | The UIDs are hard-coded by the manufacturer and cannot be changed. 10 | 11 | All cards contain a chip and an antenna. They are passive i.e. get the energy from the reader. 12 | 13 | # Wiegand 14 | 15 | This is a transmission protocol which connects the RFID reader with a controller. 16 | 17 | The Wiegand interface has two data lines, DATA0 and DATA1. These lines are normally held high at 5V. 18 | - When a 0 is sent, DATA0 drops to 0V for a few µs. 19 | - When a 1 is sent, DATA1 drops to 0V for a few µs. 20 | 21 | There are a few ms between the pulses. 22 | 23 | It transmits the UID in 2 formats: 24 | 25 | - W26 - Transports only first 3 bytes of the UID. 26 | - W34 - Transports the whole UID (4 bytes). Connect brown wire to ground to get this format. 27 | 28 | If the correct UIDs are not transported via serial, the D0 and D1 may need to be swapped. 29 | 30 | ![Sketch](../pics/rfid_wiegand_arduino.jpg) 31 | 32 | # Read Wiegand 33 | 34 | ```javascript 35 | function bitCount(int_type){ 36 | let count = 0 37 | while(int_type){ 38 | int_type &= int_type - 1 39 | count += 1 40 | } 41 | return count 42 | } 43 | 44 | let raw = 0x21a6616; // 10000110100110011000010110 45 | 46 | let FAC_PAR_MASK = 0x2000000; // 10000000000000000000000000 47 | let FACILITY_MASK = 0x1FE0000; // 01111111100000000000000000 48 | let CARD_MASK = 0x1FFFE; // 00000000011111111111111110 49 | let CARD_PAR_MASK = 1; // 00000000000000000000000001 50 | 51 | let facility = (raw & FACILITY_MASK) >> 17 52 | let card = (raw & CARD_MASK) >> 1 53 | 54 | let fac_par = (raw & FAC_PAR_MASK) >> 25 ; 55 | // even parity 56 | let fac_par_ok = (bitCount(facility) + fac_par) % 2 == 0; 57 | 58 | let card_par = raw & CARD_PAR_MASK 59 | // odd parity 60 | let card_par_ok = (bitCount(card) + card_par) % 2 == 1 61 | 62 | if (fac_par_ok && card_par_ok){ 63 | console.log("Both parity bits ok, successful read.") 64 | console.log("Facility:", facility) 65 | console.log("Card:", card) 66 | } else { 67 | if (!fac_par_ok) console.log("Facility parity check failed!") 68 | if (!card_par_ok) console.log("Card parity check failed!") 69 | } 70 | ``` -------------------------------------------------------------------------------- /topics/security.md: -------------------------------------------------------------------------------- 1 | # Attacks 2 | 3 | ### XSS - Cross Site Scripting 4 | 5 | Handling special characters properly by preventing them from being parsed as code. 6 | 7 | - Input validation 8 | - Limit allowed user inputs by blacklisting `>`, `<`, `"`, ` 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 76 | 77 | ``` 78 | 79 | # Input Form 80 | 81 | [Prototype](https://jsbin.com/yabegevada/edit?html,js,console,output) for adding and updating data via an input form. 82 | 83 | **HTML** 84 | ```html 85 | 86 | 87 | 88 | 89 | 90 | TODO 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 |
101 | 102 | 103 | ``` 104 | **Javascript** 105 | ```javascript 106 | // Initial data and table 107 | fetch("https://jsonplaceholder.typicode.com/todos?&_limit=5") 108 | .then(res => res.json()) 109 | .then(data => { 110 | renderTable(data); 111 | }) 112 | .catch(err => console.log(err)); 113 | 114 | // Used for resetting state 115 | let initState = { 116 | id: null, 117 | userId: null, 118 | title: null, 119 | completed: false, 120 | } 121 | 122 | let state = initState; 123 | 124 | // Used for populating inputs in setState 125 | let inputPropertyMapping = [ 126 | {property: "title", inputId: "todo-input"} 127 | ] 128 | 129 | function setState(newDataObject){ 130 | // Updates state with new data 131 | state = {...state, ...newDataObject}; 132 | 133 | // Populate inputs 134 | inputPropertyMapping.map(inputPropertyMappingItem => { 135 | let value = newDataObject[inputPropertyMappingItem.property] 136 | let input = document.getElementById(inputPropertyMappingItem.inputId); 137 | if(input) input.value = value; 138 | }) 139 | } 140 | 141 | // Update state on all input changes 142 | document 143 | .querySelectorAll('input') 144 | .forEach(e => e.addEventListener("input", () => { 145 | // console.dir(e); 146 | setState({[e.name]: e.value}) 147 | console.log(state) 148 | }) 149 | ); 150 | 151 | function clearInputs(){ 152 | inputPropertyMapping.map(item => { 153 | let input = document.getElementById(item.inputId); 154 | if(input) input.value = ""; 155 | }) 156 | } 157 | 158 | // Table generation 159 | function renderTable(data){ 160 | let table = new Tabulator("#example-table", { 161 | height:500, 162 | data: data, 163 | addRowPos:"top", 164 | layout:"fitColumns", 165 | columns:[ 166 | {title:"Title", field:"title"}, 167 | {title:"Completed", field:"completed"}, 168 | ], 169 | rowClick:function(e, row){ 170 | setState(row.getData()); 171 | console.log(state) 172 | } 173 | }); 174 | 175 | console.log("Initial state: ", state) 176 | 177 | document.getElementById("todo-button-new").addEventListener("click", () => { 178 | setState(initState) 179 | console.log(state) 180 | }); 181 | 182 | // SUBMIT TODO 183 | document.getElementById("todo-button-submit").addEventListener("click", () => { 184 | // POST TODO to server 185 | if(state.id == null){ 186 | fetch('https://jsonplaceholder.typicode.com/todos', { 187 | method: 'POST', 188 | body: JSON.stringify(state), 189 | headers: { 190 | "Content-type": "application/json; charset=UTF-8" 191 | } 192 | }) 193 | .then(response => response.json()) 194 | .then(json => { 195 | console.log("POST Response data:", json); 196 | // Add TODO to table 197 | table.addData(json); 198 | clearInputs(); 199 | }) 200 | } 201 | 202 | // PATCH TODO to server 203 | if(state.id != null){ 204 | fetch(`https://jsonplaceholder.typicode.com/todos/${state.id}`, { 205 | method: 'PATCH', 206 | body: JSON.stringify(state), 207 | headers: { 208 | "Content-type": "application/json; charset=UTF-8" 209 | } 210 | }) 211 | .then(response => response.json()) 212 | .then(json => { 213 | console.log("PATCH Response data:", json); 214 | // Update TODO in table 215 | table.updateData([json]); 216 | clearInputs(); 217 | }) 218 | } 219 | }) 220 | } 221 | ``` -------------------------------------------------------------------------------- /topics/testing.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | The idea is to automate the manual testing of code, with code. 4 | 5 | This requires an initial time investment, which is quickly paid back in the time saved by making sure the application is stable. 6 | 7 | # Test types 8 | 9 | - **Unit tests** 10 | Testing single functions with no dependencies (thousands). 11 | 12 | - **Integration test** 13 | Testing single functions with dependencies i.e. functions that call other functions (couple). Does the combination of single functions work? 14 | 15 | - **End-to-end (E2E) / UI test** 16 | Testing by simulating a literal manual UI interaction (few). 17 | 18 | # Setup 19 | 20 | The following is needed to test code. 21 | 22 | 1. **Test runner** 23 | Executes tests and summarizes results, with `Mocha`. 24 | 25 | 2. **Assertion library** 26 | Define testing logic and conditions, with `Chai`. 27 | 28 | 3. **Headless browser** - E2E testing 29 | Simulate browser interactions, with `Puppeteer`. 30 | 31 | - `Jest` is both a test runner and an assertion library. 32 | 33 | # Jest 34 | 35 | ```bash 36 | npm install --save-dev jest 37 | ``` 38 | 39 | ## Unit test 40 | 41 | **scripts.js** 42 | 43 | ```javascript 44 | exports.addNumbers = function(a, b) { 45 | return `The result is ${a + b}`; 46 | }; 47 | ``` 48 | 49 | **scripts.test.js** / **scripts.spec.js** 50 | 51 | We must name the test files like this, in order to be found. 52 | 53 | ```javascript 54 | const { addNumbers } = require("./scripts"); 55 | 56 | // Task runner 57 | test("should output a sum", () => { 58 | const sum = addNumbers(2, 3); 59 | // Assertion library 60 | expect(sum).toBe("The result is 5"); 61 | }); 62 | ``` 63 | 64 | **package.json** 65 | 66 | ```json 67 | "scripts": { 68 | "test": "jest" 69 | } 70 | ``` 71 | 72 | We can also run the tests automatically with every change we make. 73 | 74 | ```json 75 | "scripts": { 76 | "test": "jest --watch" 77 | } 78 | ``` 79 | 80 | We finally run the test... 81 | 82 | ```bash 83 | npm test 84 | 85 | -- 86 | PASS ./scripts.test.js 87 | ✓ should output a sum (3ms) 88 | 89 | Test Suites: 1 passed, 1 total 90 | Tests: 1 passed, 1 total 91 | Snapshots: 0 total 92 | Time: 1.605s 93 | Ran all test suites. 94 | ``` 95 | 96 | ## E2E UI test 97 | 98 | Puppeteer works with Jest. 99 | 100 | ```bash 101 | npm install --save-dev puppeteer 102 | ``` 103 | 104 | This literally creates a browser window in which the specified actions are simulated. 105 | 106 | **scripts.test.js** 107 | 108 | ```javascript 109 | test("Should insert a todo item", async () => { 110 | const browser = await puppeteer.launch({ 111 | headless: false, // Display the browser 112 | slowMo: 80, // slow down the actions in the browser 113 | args: ["--window-size=1920,1080"] 114 | }); 115 | const page = await browser.newPage(); 116 | 117 | await page.goto("http://domain.com/todo"); 118 | await page.type("input#todo", "Some arbitrary task"); 119 | await page.click("#btn-add-user"); 120 | 121 | const todoItem = await page.$eval(".todo-item", el => el.textContent); 122 | expect(todoItem).toBe("Some arbitrary task"); 123 | }); 124 | ``` 125 | 126 | The test will run much faster without rendering the browser. 127 | 128 | ```javascript 129 | const browser = await puppeteer.launch({ 130 | headless: true 131 | }); 132 | ``` 133 | -------------------------------------------------------------------------------- /topics/tmux.md: -------------------------------------------------------------------------------- 1 | # tmux 2 | 3 | ## Basic 4 | ```bash 5 | tmux # Start tmux. 6 | CTRL + B # Command mode. 7 | ``` 8 | 9 | ## Windows (tabs) 10 | ```bash 11 | c # New window. 12 | numbers # Change window. 13 | , # Name window. 14 | w # List windows. 15 | . # Move window. Asks for a number. 16 | & # Close window. 17 | CTRL + D # Close window. 18 | ``` 19 | 20 | ## Panes (splits) 21 | ```bash 22 | % # Split horizontally (left/right). 23 | \" # Split vertically (top/bottom). 24 | arrows # Change pane. Resize if holding command. 25 | x # Close pane. 26 | q # Show pane numbers 27 | space # Toggle between layouts 28 | ``` 29 | 30 | ## Misc 31 | ```bash 32 | [ # Scrolling mode with arrows or PageUp/PageDown. 33 | CTRL + C # Exit scrolling mode. 34 | ``` 35 | 36 | # Setup 37 | 38 | Create a `tmux.sh` file to automate the setup. 39 | 40 | ```bash 41 | tmux new-session \; \ 42 | send-keys 'echo "Pane 1"' C-m \; \ 43 | send-keys 'cd /mnt/c//lab/posto/app && npm start' C-m \; \ 44 | split-window -h -p 75 \; \ 45 | send-keys 'echo "Pane 2"' C-m \; \ 46 | send-keys 'cd /mnt/c//lab/posto/server && nodemon server.js' C-m \; \ 47 | split-window -h -p 66 \; \ 48 | send-keys 'echo "Pane 3"' C-m \; \ 49 | send-keys 'echo | sudo -S service mysql start && sudo mysql -u root -p' C-m \; \ 50 | split-window -h -p 50 \; \ 51 | send-keys 'echo "Pane 4"' C-m \; \ 52 | send-keys 'cd /mnt/c//lab/posto' C-m \; \ 53 | # split-window -v \; \ 54 | # select-pane -t 0 \; \ 55 | ``` 56 | 57 | # Configuration 58 | In order to configurate tmux, a `tmux.conf` file is needed, as it doesn't exist. We can create this with `sudo touch /etc/tmux.conf`, or `sudo touch ~/.tmux.conf` for a user specific one. 59 | 60 | ```bash 61 | # Reload config file with CTRL + b + r 62 | bind r source-file /etc/tmux.conf 63 | 64 | # Activate mouse (Scrolling, selecting, re-sizing) 65 | set -g mouse on 66 | ``` 67 | 68 | -------------------------------------------------------------------------------- /topics/users.md: -------------------------------------------------------------------------------- 1 | # Create 2 | 3 | ```bash 4 | # Guided user creation 5 | adduser 6 | 7 | # Add sudo access 8 | usermod -aG sudo 9 | 10 | # Scripted user creation 11 | useradd --uid --gid -m -s /usr/bin/zsh -d /var/www/ --password 12 | ``` 13 | 14 | # Login 15 | 16 | ```bash 17 | # Login as user 18 | su - 19 | 20 | # Login as root 21 | sudo -i 22 | 23 | # Logout 24 | CTRL + d # or exit 25 | ``` 26 | 27 | The root account is disabled by default in Ubuntu, so there is no root password, that's why `su` fails with an authentication error. 28 | 29 | # Permissions 30 | 31 | `ls -l` - Show file permissions. 32 | 33 | `chown USER:GROUP FILENAME` - Change file owner. 34 | 35 | `sudo usermod -a -G ` - Add user to a group. Needs a logout. 36 | 37 | `chmod` - Change file mode i.e. `rwx` permissions. 38 | 39 | `r` - Read. 40 | `w` - Write. 41 | `x` - Execute. 42 | 43 | | Permission | File Type | Owner | Group | Other | Meaning | 44 | | :--------: | :-------: | :---: | :---: | :---: | :-------------------------------------------------------------: | 45 | | -rwx------ | - | rwx | --- | --- | File that only the owner can read, write and execute. | 46 | | drw-rw---- | d | rw- | rw- | r-- | Directory that owner and group can read/write, others just read | 47 | 48 | Owner permissions trump group ones. 49 | 50 | `chmod +x FILE` - Add execute permission to owner, group and others. 51 | `chmod u+w FILE` - Add write permission to just the owner. 52 | `chmod o-r FILE` - Remove read permission to other users. 53 | 54 | This can get very tedious for each permission (9 commands), so instead, we can set the permissions by using octal numbers. 55 | 56 | First number is **owner**, second is **group**, and third is **others**. 57 | 58 | `chmod 644 FILE` - Owner read/write, group read, others read. 59 | 60 | | Dec | Permission | 61 | | :-: | -------------------- | 62 | | 7 | Read, write, execute | 63 | | 6 | Read, write | 64 | | 5 | Read, execute | 65 | | 4 | Read | 66 | | 3 | Write, execute | 67 | | 2 | Write | 68 | | 1 | Execute | 69 | | 0 | No permissions | 70 | 71 | `7, 6, 5, 4, 0` - Most used. 72 | 73 | A binary mask is used to determine the numbers. Add the column values for each 1 and the sum is the decimal number. 74 | 75 | | Type | Read (4) | Write (2) | Execute (1) | Decimal | 76 | | :-------: | :------: | :-------: | :---------: | :-----: | 77 | | **User** | 1 | 1 | 1 | 7 | 78 | | **Group** | 1 | 0 | 1 | 5 | 79 | | **Other** | 1 | 0 | 0 | 4 | 80 | 81 | The number `754` would give the owner full permissions, the group read/execute, and just read for the others. 82 | -------------------------------------------------------------------------------- /topics/vagrant.md: -------------------------------------------------------------------------------- 1 | # Vagrant 2 | 3 | Vagrant is used to avoid the tedious provisioning of Virtual Machines. Instead of manually installing the OS for every machine, VMs can be spun up instantly by downloading an image (box) from the hub, and running it. 4 | 5 | Vagrant **is not** like Docker. Vagrant is used to start VMs fast, while Docker is used to containerize packages within the VMs. Vagrant avoids installing an OS, Docker avoids installing packages i.e. they just run them. This significantly speeds things up by allowing to quickly create and destroy whole environments. 6 | 7 | In other words, use Vagrant for just the OS and Docker install, and run everything else as a Docker container. 8 | 9 | **Host** = Main Machine. **Guest** = Virtual Machine. 10 | 11 | ## Install 12 | `wget "URL"` - Download Vagrant. 13 | `sudo dpkg -i FILENAME` - Install Vagrant. 14 | `sudo apt-get install virtualbox` - Download VirtualBox. 15 | 16 | ## Virtual Machine 17 | `vagrant box add BOX_NAME` - Download a box. 18 | `vagrant init BOX_NAME` - Create Vagrantfile i.e. VMs live here. 19 | `vagrant up` - Start a box (VM). 20 | -------------------------------------------------------------------------------- /topics/vim.md: -------------------------------------------------------------------------------- 1 | # Vim 2 | 3 | If a file is read-only and can't be changed, use `sudo vim file` to open it as root. 4 | 5 | ## Modes 6 | 7 | `ESC` or `CTRL` + `[` - Command (Default) 8 | `i` - Insert (Editing) 9 | `v` - Visual (Like Command, but with selection) 10 | 11 | ## General 12 | 13 | `:` - Commands. 14 | `.` - Repeat previous command. 15 | `u` - UNDO. 16 | `CTRL` + `r` - REDO. 17 | `c` + `movement` - Change up to movement. 18 | 19 | # Inside 20 | 21 | `command` + `i` + `character` - Do a command inside characters. 22 | 23 | `vi"` - Select everything inside "". 24 | `xi(` - Delete everything inside (). 25 | `ci{` - Change (Delete and enter insert mode) inside {}. 26 | 27 | ## Tabs 28 | 29 | `:tabe FILEPATH` - Open file in new tab 30 | `:tabn` - Next tab 31 | `:tabp` - Previous tab 32 | 33 | ## Copy & Paste 34 | 35 | Enter **visual mode** and select text. 36 | 37 | `y` - Copy (yank) selected. 38 | `d` - Cut selected. 39 | `p` - Paste after cursor. 40 | 41 | `x` - Delete selected. 42 | 43 | These can be combined with movements. Ex. `x2e` is delete next 2 words. 44 | 45 | `yy` - Copy (yank) line in **normal** mode. 46 | `dd` - Cut line in **normal** mode. 47 | 48 | ## Save & Exit 49 | 50 | `:w` - Save 51 | `:q` - Quit 52 | `:wq` - Save & Quit 53 | `:q!` - Cancel & Quit 54 | 55 | ## Moving 56 | 57 | All of these can be used in **visual** mode for selection. 58 | 59 | `j` - Down 60 | `k` - Up 61 | `h` - Left 62 | `l` - Right 63 | 64 | `w` - Forward one word. 65 | `b` - Back one word. 66 | `e` - End of word. 67 | 68 | Adding a number before a command, will repeat it n times. Ex. `3h` will go up 3 lines, `5dd` will detele 5 lines. 69 | 70 | `0` - Beginning of line. 71 | `$` - End of line. 72 | 73 | `%` - Jump to matching tag i.e. `)`, `}`, `]`. 74 | 75 | `f` + `character` - Jump **to** next character. 76 | `t` + `character` - Jump **before** next character. 77 | 78 | `*` - Next occurrence of word under cursor. 79 | `#` - Previous occurrence of word under cursor. 80 | 81 | `gg` - Beginning of file. 82 | `G` - End of file. 83 | `nG` - Jump to line n. 84 | 85 | ## Search 86 | 87 | `/` + `string` + `Enter` = Search for string **forwards**. 88 | `?` + `string` + `Enter` = Search for string **backwards**. 89 | `n` - Next occurrence. 90 | `N` - Previous occurrence. 91 | 92 | ## Replace 93 | 94 | `:%s/text/replacement/g` - Replace text on every line. 95 | `:s/text/replacement/g` - Replace text on current line. 96 | 97 | ## Insert 98 | 99 | `o` - Create new line **under** cursor and enter **INS** mode. 100 | `O` - Create new line **above** cursor and enter **INS** mode. 101 | 102 | `x` - Delete character. 103 | `X` - Backspace. 104 | 105 | `r` + `new character` - Change character under cursor without INS mode. 106 | 107 | ## Multiple Inserts 108 | 109 | `n times` + `i` + `string` + `ESC` = Multiple inserts. 110 | 111 | Ex. `5ifoo` + `ESC` will result in `foofoofoofoofoo`. 112 | 113 | # vimrc - Customization 114 | 115 | The global `.vimrc` file is located in `/etc/vim/vimrc` or `etc/vimrc`. 116 | 117 | Create a `.vimrc` file in the `home` directory for customizations. 118 | 119 | When vim is opened, it will automatically check the current user’s home directory for a .vimrc file. All settings specified in this file will override the global settings. 120 | 121 | Configurations can be made inside `vim` by using `:set number`. 122 | 123 | ```bash 124 | set nocompatible # Set compatibility to Vim only. 125 | set number # Show line numbers. 126 | set visualbell # Use visual bell (no beeping) 127 | set wrap # Word wrap. 128 | 129 | set autoindent # Auto-indent new lines 130 | set shiftwidth=4 # Number of auto-indent spaces 131 | set smartindent # Enable smart-indent 132 | set smarttab # Enable smart-tabs 133 | set softtabstop=4 # TAB is 4 spaces. 134 | ``` -------------------------------------------------------------------------------- /topics/vm.md: -------------------------------------------------------------------------------- 1 | # Virtualbox 2 | 3 | 1. Create VM. 4 | 2. Mount and install Guest Additions. 5 | 3. **Reboot.** 6 | 4. Add clipboard settings. 7 | 5. Add host shared folder. It is under `/media/user/sf_folder_name`. 8 | 6. `sudo adduser username vboxsf` to access shared folder. 9 | 7. **Reboot.** 10 | 11 | # Environment 12 | 13 | User 14 | ```bash 15 | # Add user 16 | adduser 17 | 18 | # Add sudo access 19 | usermod -aG sudo 20 | 21 | # Switch to user 22 | su - 23 | ``` 24 | 25 | Basic 26 | 27 | ```bash 28 | # Update 29 | sudo apt update && sudo apt upgrade; 30 | 31 | # curl, vim, tmux, git (Usually installed already) 32 | sudo apt install curl vim tmux git -y; 33 | 34 | # Node 35 | sudo apt install nodejs npm -y; 36 | 37 | # Global nodemon 38 | sudo npm i -g nodemon; 39 | 40 | # MySQL (sudo mysql -u root) 41 | sudo apt install mysql-server -y && mysql_secure_installation; 42 | ``` 43 | 44 | Web Server 45 | 46 | ```bash 47 | # nginx (web server) 48 | sudo apt install nginx -y; 49 | 50 | # Global forever 51 | sudo npm i -g forever; 52 | ``` 53 | 54 | # Digital Ocean Update 55 | 56 | To update Ubuntu, the droplet needs to be destroyed i.e. rebuilt with the new Linux distro. 57 | 58 | After this, an email will be sent with the login credentials. -------------------------------------------------------------------------------- /topics/vscode.md: -------------------------------------------------------------------------------- 1 | # Shortcuts 2 | 3 | `CTRL` + `p` - Search files. 4 | `CTRL` + `Shift` + `p` - Commands. 5 | 6 | `CTRL` + `d` - Select duplicate values. 7 | 8 | `ALT` + `Up` or `Down` - Move line up or down. 9 | 10 | `ALT` + `SHIFT` + `Down` - Duplicate line. 11 | `ALT` + `SHIFT` + `Right` - Select everything between brackets. 12 | 13 | # Indentation 14 | Go to settings `CTRL` + `,` and set: 15 | 16 | - Workbench > Tree: indent = 25 17 | - Workbench > Tree: Render Indent Guides = always 18 | 19 | # Zen Coding 20 | 21 | ```html 22 | table.table.small>thead>tr>th*4 23 | ``` 24 | 25 | results in 26 | 27 | ```html 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
38 | ``` 39 | -------------------------------------------------------------------------------- /topics/vue.md: -------------------------------------------------------------------------------- 1 | # Hello World 2 | 3 | ```html 4 | 5 | 6 |
7 |

{{ title }}

8 |
9 | ``` 10 | ```javascript 11 | new Vue({ 12 | el: "#app", 13 | data: { 14 | title: "Hello World!" 15 | } 16 | }); 17 | ``` 18 | `Vue` instances are at the core of every Vue app, as they control their own HTML template rendered to the screen. 19 | 20 | # Component Anatomy 21 | 22 | All the code is encapsulated in the component. 23 | 24 | **Output - HTML** 25 | ```html 26 | 31 | ``` 32 | 33 | **Functionality - Javascript** 34 | 35 | A default object is exported i.e. component with a name of "User". The `data()` method returns the state of the component. 36 | ```html 37 | 47 | ``` 48 | 49 | **Style - CSS** 50 | ```html 51 | 56 | ``` 57 | 58 | The main page served is `index.html` located in the `public` folder. 59 | 60 | The entry point for a vue app is `main.js`, located in `src`. There we import the `Vue` app object (where we mount the instance to the `index.html`), and the `App` component. 61 | 62 | # Install 63 | 64 | ```bash 65 | sudo npm i -g vue 66 | 67 | vue --version 68 | ``` 69 | 70 | The framework can also be referenced with a CDN. 71 | 72 | # Vue-CLI 73 | 74 | Qucik SPA scaffolding. It provides build setups for a modern frontend workflow, with hot-reload, lint-on-save, and production-ready builds. 75 | 76 | ```bash 77 | vue create app-name 78 | 79 | cd app-name 80 | nom run serve 81 | ``` 82 | 83 | Chrome extension for debugging: Vue.js Devtools 84 | VS Code Syntax highlighting: Vetur 85 | 86 | # vue-router 87 | 88 | **Installing it overwrites the `App.vue` file**s 89 | 90 | # vuex 91 | 92 | State management library similar to Redux. -------------------------------------------------------------------------------- /topics/wasm.md: -------------------------------------------------------------------------------- 1 | Native apps, distributed in the browser. 2 | 3 | Run "almost machine" code in the browser. 4 | 5 | Lets browsers compete with app stores and installers. 6 | 7 | Write C++, Rust... Compile it to WebAssembly... Run the code as a "web app". 8 | 9 | You can play video games directly in the browser. 10 | 11 | Ex. Open Photoshop in the browser, and send a link of the current project to someone to continue working. No sharing of files and installations. -------------------------------------------------------------------------------- /topics/webpack.md: -------------------------------------------------------------------------------- 1 | Webpack is a bundler, which combines many javascript files into a single bundle file. 2 | 3 | It also uglifies (shortens identifier names) and minifies (gets rid of whitespace) the code. 4 | 5 | ```bash 6 | sudo npm install webpack webpack-cli --save-dev 7 | ``` 8 | 9 | ## Simple Default Example 10 | 11 | **Webpack needs an `src` directory with the entry `index.js` file.** 12 | 13 | Without this, we get `ERROR in Entry module not found: Error: Can’t resolve ‘./src’ in 'folder'`. The entry point can be changed in a `webpack.config.js` file. 14 | 15 | We need to add a webpack scripts in `package.json`, which gets all the dependencies from `./src/index.js`, and bundles all the code into a `./dist/main.js` file. 16 | 17 | ```json 18 | { 19 | "scripts": { 20 | "build": "webpack" 21 | }, 22 | "devDependencies": { 23 | "webpack": "4.x.x" 24 | } 25 | } 26 | ``` 27 | We then simply run 28 | ```bash 29 | npm run build 30 | ``` 31 | 32 | These can also be used in `package.json`, where production minifies, and development doesn't. 33 | ```json 34 | "scripts": { 35 | "dev": "webpack --mode development", 36 | "build": "webpack --mode production" 37 | } 38 | ``` 39 | 40 | ## Configuration 41 | 42 | Instead of a `package.json` script, we can use a detailed `webpack.config.js` configuration file, which can be generated with the command below and by answering questions. 43 | 44 | ```bash 45 | webpack init 46 | ``` 47 | Example : 48 | 1. Will your application have multiple bundles? **No** 49 | 2. Which module will be the first to enter the application? [example: './src/index.js'] **./src/index.js** 50 | 3. Which folder will your generated bundles be in? [default: dist] **Enter** 51 | 4. Are you going to use this in production? **No** 52 | 5. Will you be using ES2015 (ES6)? **Yes** 53 | 6. Will you use one of the below CSS solutions? **No** 54 | 7. Name your `webpack.[name].js`? [default: 'config'] **Enter** 55 | 56 | This will install: 57 | - webpack-cli 58 | - uglifyjs-webpack-plugin 59 | - babel-core 60 | - babel-loder 61 | - babel-preset-env 62 | - webpack 63 | 64 | It will also generate the `webpack.config.js` file: 65 | ```javascript 66 | const webpack = require("webpack"); 67 | const path = require("path"); 68 | 69 | const UglifyjsJSPlugin = require("uglifyjs-webpack-plugin"); 70 | 71 | module.exports = { 72 | entry: './src/index.js', 73 | output: { 74 | filename: '[name].bundle.js', 75 | path: path.resolve(__dirname, dist) 76 | }, 77 | module: { 78 | rules: [ 79 | { 80 | test: /\.js$/, 81 | exclude: /node_modules/, 82 | loader: 'babel-loader', 83 | options: { 84 | presets: ['env'] 85 | } 86 | } 87 | ] 88 | }, 89 | plugins: [new UglifyJSPlugin()] 90 | }; 91 | ``` 92 | We can add this in `package.json` watch for changes and rebuild: 93 | ```json 94 | { 95 | "scripts": { 96 | "build": "webpack -w" 97 | } 98 | } 99 | ``` --------------------------------------------------------------------------------