├── 2016 ├── 10 │ ├── 16 │ │ └── how-to-create-simple-rest-api-in-php-and-call-them-in-js │ │ │ ├── checkIfUsernameExist.php │ │ │ ├── checkIfUsernameExistAngular.html │ │ │ ├── checkIfUsernameExistJquery.html │ │ │ └── checkIfUsernameExistXML.html │ ├── 17 │ │ └── how-to-automatically-send-welcome-email-to-user-when-they-sign-up-in-wp │ │ │ └── functions.php │ ├── 18 │ │ └── how-to-build-a-simple-chat-bot-using-hubot-that-determine-gender-based-on-name │ │ │ └── chatbotThatDetermineGenderBasedOnName.coffee │ ├── 19 │ │ └── how-to-set-up-a-node.js-application-for-production-on-ubuntu-14.04 │ │ │ ├── 000-default.conf │ │ │ ├── commands.sh │ │ │ └── server.js │ ├── 22 │ │ └── how-to-programmatically-register-an-account-in-wordpress │ │ │ ├── tryRegisterAnAccount.php │ │ │ └── tryRegisterAnAccountJquery.html │ ├── 27 │ │ └── how-to-login-to-wordpress-site-using-casperjs │ │ │ └── loginToWordpressSite.js │ ├── 28 │ │ └── how-to-pass-php-data-to-your-script-in-wordpress │ │ │ ├── audioPlaylist.php │ │ │ ├── createPlaylist.js │ │ │ └── showPlaylistToUser.php │ └── 29 │ │ └── is-it-possible-to-host-two-website-with-different-domain-on-one-server │ │ ├── commands.sh │ │ ├── www-example-com.conf │ │ └── www-example-net.conf ├── 11 │ ├── 12 │ │ └── how-to-take-screenshots-at-different-screen-sizes-using-casperjs │ │ │ ├── screenshots.js │ │ │ └── urls.json │ ├── 15 │ │ └── how-to-add-background-music-in-processing-3.0 │ │ │ └── backgroundMusic.pde │ ├── 17 │ │ └── how-to-play-mp4-video-using-hls │ │ │ ├── commands.sh │ │ │ ├── playM3u8UsingHlsJs.html │ │ │ └── sample.m3u8 │ └── 20 │ │ └── how-to-enable-cross-origin-resource-sharing-on-an-apache-server │ │ ├── 000-default-le-ssl.conf │ │ └── commands.sh └── 12 │ ├── 06 │ └── how-to-build-a-search-page-in-django-with-amazon-dynamodb-and-react-p1-back-end │ │ ├── search.html │ │ ├── urls.py │ │ └── views.py │ └── 09 │ └── how-to-build-a-search-page-in-django-with-amazon-dynamodb-and-react-p2-front-end │ ├── combined-ReactDOM-code-for-both-dropdown.html │ ├── filter-in-react-way-full-code.html │ ├── filter-location-in-react-way.html │ ├── hello-world-in-react-way.html │ └── modified-views.py ├── 2017 ├── 10 │ ├── 19 │ │ └── How-to-replace-a-git-submodules-in-a-repository │ │ │ └── .gitmodules │ ├── 20 │ │ └── How-to-run-a-single-test-or-all-tests-in-a-class-with-gradlew │ │ │ ├── BlogControllerTests.groovy │ │ │ └── commands.sh │ └── 31 │ │ └── Installing-Marsyas-with-Python-bindings-on-Ubuntu-14.04.3-LTS-64-bits │ │ ├── commands.sh │ │ ├── sample.mrs │ │ └── sample.py ├── 04 │ ├── 10 │ │ └── how-to-check-if-an-image-already-existed-in-wp-content-upload-directory │ │ │ └── does-file-exists-sample.php │ └── 02 │ │ └── how-to-setup-pretty-url-in-wordpress-through-lamp-stack │ │ ├── 000-default-le-ssl.conf │ │ └── commands.sh ├── 05 │ └── 07 │ │ └── how-to-set-up-password-authentication-with-apache-on-ubuntu-1404 │ │ ├── 000-default-le-ssl.conf │ │ └── commands.sh ├── 06 │ └── 13 │ │ └── mutable-vs-Immutable-object-in-JavaScript │ │ ├── immutable-sample.js │ │ └── mutation-sample.js └── 07 │ ├── 24 │ └── how-to-use-gulp.js-to-deploy-your-site-to-live-through-github │ │ ├── gulpfile.js │ │ └── prod │ │ └── index.html │ ├── 27 │ └── how-to-add-disqus-to-your-jekyll-site │ │ ├── _includes │ │ └── disqus.html │ │ └── src │ │ └── js │ │ └── disqus.js │ └── 01 │ └── how-to-recover-all-your-deleted-cron-jobs │ └── commands.sh ├── 2018 ├── 11 │ └── 23 │ │ └── how-to-calculate-time-complexity-of-an-algorithm │ │ ├── constantTime.java │ │ ├── cubicTime.java │ │ ├── exponentiationTime.java │ │ ├── linearTime.java │ │ ├── logarithmicTime.java │ │ ├── quadraticNestedConstantForLoopTime.java │ │ ├── quadraticTime.java │ │ ├── sqrtTime.java │ │ └── threeLinearTime.java ├── 02 │ └── 09 │ │ └── Solving-the-Fibonacci-problem-using-Dynamic-Programming-in-Java │ │ └── FibonacciNumber.java └── 03 │ └── 07 │ └── How-to-fix-permission-denied-for-relation-some_table_name-in-PostgreSQL │ ├── userAbleToAccess.sql │ └── userUnableToAccess.sql ├── 2019 ├── 06 │ └── 19 │ │ └── The-right-way-to-manage-nested-callbacks │ │ ├── forthSolution.js │ │ ├── originalVersion.js │ │ ├── originalVersionWithComments.js │ │ ├── secondSolution.js │ │ └── thirdSolution.js ├── 07 │ └── 13 │ │ └── The-easiest-way-to-make-Let-s-Encrypt-renewal-automated │ │ ├── commands.sh │ │ └── readmeForLetsEncrypt.sh └── 09 │ ├── 11 │ └── what-is-a-pure-function-and-how-can-it-be-a-good-practice │ │ ├── ImPureFunctionWithGlobalMutation.java │ │ ├── ImPureFunctionWithGlobalReturn.java │ │ ├── ImPureFunctionWithReferenceArgumentMutation.java │ │ └── PureFunction.java │ └── 13 │ └── why-using-a-global-variable-to-solve-Leetcode-problem-can-be-a-bad-idea │ ├── leetcodeTestCase.py │ └── simplePreorderTraversal.py ├── 2020 ├── 10 │ ├── 23 │ │ └── how-to-activate-virtual-environment-in-powershell │ │ │ └── activateVirtualEnvironment.sh │ └── 27 │ │ └── How-to-prepopulate-GitHub-issue-to-make-people-life-easier-in-jekyll │ │ ├── afterrender.txt │ │ └── beforerender.txt └── 09 │ ├── 13 │ └── how-to-make-an-automotive-wi-fi-plant-watering-system-that-is-connected-to-azure-iot-central │ │ ├── 1 channel Plant Watering System with Arduino UNO R3 and ESP8266.pdf │ │ ├── Automotive Wi-Fi Plant Watering System.json │ │ ├── sketch_aug23a.ino │ │ ├── sketch_aug23b.ino │ │ └── sketch_aug23c.ino │ └── 20 │ └── How-to-display-an-Alexa-rank-chart-in-your-website │ ├── addAlexaConfig.py │ ├── addAlexaRank.py │ ├── alexaRank.html │ ├── downloadAlexaRank.py │ ├── getAlexaRank.py │ ├── parseAlexaRank.py │ ├── uploadAlexaConfig.py │ └── uploadAlexaRank.py └── README.md /2016/10/16/how-to-create-simple-rest-api-in-php-and-call-them-in-js/checkIfUsernameExist.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /2016/10/16/how-to-create-simple-rest-api-in-php-and-call-them-in-js/checkIfUsernameExistAngular.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |

{{ return_message }}

4 |
5 | 6 | 7 | -------------------------------------------------------------------------------- /2016/10/16/how-to-create-simple-rest-api-in-php-and-call-them-in-js/checkIfUsernameExistJquery.html: -------------------------------------------------------------------------------- 1 | 2 |

3 | 4 | 5 | -------------------------------------------------------------------------------- /2016/10/16/how-to-create-simple-rest-api-in-php-and-call-them-in-js/checkIfUsernameExistXML.html: -------------------------------------------------------------------------------- 1 | 2 |

3 | 4 | -------------------------------------------------------------------------------- /2016/10/17/how-to-automatically-send-welcome-email-to-user-when-they-sign-up-in-wp/functions.php: -------------------------------------------------------------------------------- 1 | user_email; 5 | // for simplicity, lets assume that user has typed their first and last name when they sign up 6 | $user_full_name = $user->user_firstname . $user->user_lastname; 7 | 8 | // Now we are ready to build our welcome email 9 | $to = $user_email; 10 | $subject = "Hi " . $user_full_name . ", welcome to our site!"; 11 | $body = ' 12 |

Dear ' . $user_full_name . ',


13 |

Thank you for joining our site. Your account is now active.

14 |

Please go ahead and navigate around your account.

15 |

Let me know if you have further questions, I am here to help.

16 |

Enjoy the rest of your day!

17 |

Kind Regards,

18 |

poanchen

19 | '; 20 | $headers = array('Content-Type: text/html; charset=UTF-8'); 21 | if (wp_mail($to, $subject, $body, $headers)) { 22 | error_log("email has been successfully sent to user whose email is " . $user_email); 23 | }else{ 24 | error_log("email failed to sent to user whose email is " . $user_email); 25 | } 26 | } 27 | 28 | add_action('user_register', 'send_welcome_email_to_new_user'); 29 | ?> -------------------------------------------------------------------------------- /2016/10/18/how-to-build-a-simple-chat-bot-using-hubot-that-determine-gender-based-on-name/chatbotThatDetermineGenderBasedOnName.coffee: -------------------------------------------------------------------------------- 1 | module.exports = (robot) -> 2 | robot.hear /check gender for (.*)/i, (res) -> 3 | personName = escape(res.match[1]) 4 | res.http("https://api.genderize.io/?name=" + personName) 5 | .get() (error, response, body) -> 6 | try 7 | json = JSON.parse(body) 8 | res.send "Probability of " + "#{json.probability}" + " that " + personName + " is a " + "#{json.gender}.\n" 9 | catch error 10 | res.send "something went wrong..." -------------------------------------------------------------------------------- /2016/10/19/how-to-set-up-a-node.js-application-for-production-on-ubuntu-14.04/000-default.conf: -------------------------------------------------------------------------------- 1 | 2 | ServerAdmin webmaster@localhost 3 | ServerName THIS_IS_WHERE_YOU_PUT_YOUR_DOMAIN_NAME_HERE 4 | 5 | ProxyRequests off 6 | 7 | 8 | Order deny,allow 9 | Allow from all 10 | 11 | 12 | 13 | ProxyPass http://PRIVATE_IP_ADDRESS:PORT_THAT_Node_JS_APP_LISTEN/ 14 | ProxyPassReverse http://PRIVATE_IP_ADDRESS:PORT_THAT_Node_JS_APP_LISTEN/ 15 | 16 | -------------------------------------------------------------------------------- /2016/10/19/how-to-set-up-a-node.js-application-for-production-on-ubuntu-14.04/commands.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | curl http://PRIVATE_IP_ADDRESS:PORT_THAT_Node_JS_APP_LISTEN 4 | sudo pm2 install pm2 -g 5 | sudo pm2 YOUR_NODE_JS_SERVER_NAME_FILE.js 6 | sudo pm2 list 7 | sudo pm2 startup ubuntu 8 | sudo apt-get update 9 | sudo apt-get install apache2 10 | sudo service apache2 status 11 | sudo service apache2 start 12 | cd /etc/apache2/sites-enabled/ 13 | sudo vi 000-default.conf 14 | sudo service apache2 restart -------------------------------------------------------------------------------- /2016/10/19/how-to-set-up-a-node.js-application-for-production-on-ubuntu-14.04/server.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var app = express(); 3 | 4 | app.get('/', function (request, response) { 5 | response.send("Hello World"); 6 | }); 7 | 8 | app.listen(8080); -------------------------------------------------------------------------------- /2016/10/22/how-to-programmatically-register-an-account-in-wordpress/tryRegisterAnAccount.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /2016/10/22/how-to-programmatically-register-an-account-in-wordpress/tryRegisterAnAccountJquery.html: -------------------------------------------------------------------------------- 1 | 2 |

3 | 4 |

5 | 6 |

7 | 8 | 9 | -------------------------------------------------------------------------------- /2016/10/27/how-to-login-to-wordpress-site-using-casperjs/loginToWordpressSite.js: -------------------------------------------------------------------------------- 1 | var page = require('webpage').create(); 2 | var casper = require('casper').create(); 3 | 4 | var urlBeforeLoggedIn = "https://www.jenrenalcare.com/wp-login.php"; 5 | var urlAfterLoggedIn = "https://www.jenrenalcare.com/wp-admin/"; 6 | 7 | casper.start(urlBeforeLoggedIn); 8 | 9 | casper.waitForSelector('form[method="post"]', function() { 10 | casper.fillSelectors('form[method="post"]', { 11 | 'input[name="log"]': 'put_your_username_or_email_address_here', 12 | 'input[name="pwd"]': 'put_your_password_here' 13 | }, true); 14 | }); 15 | 16 | casper.waitForUrl(urlAfterLoggedIn, function() { 17 | this.viewport(3000, 1080); 18 | this.capture('./screenshot.png', {top: 0,left: 0,width: 3000, height: 1080}); 19 | }); 20 | 21 | casper.run(); -------------------------------------------------------------------------------- /2016/10/28/how-to-pass-php-data-to-your-script-in-wordpress/audioPlaylist.php: -------------------------------------------------------------------------------- 1 | 'AEHelp', 11 | 'title' => 'CD1-T-1: Listening Section 1 (Demo)', 12 | 'mp3' => $basePath . 'ielts-sample-audio/CD1-Track-01.mp3' 13 | ), 14 | array( 15 | 'artist' => 'AEHelp', 16 | 'title' => 'CD1-T-1: Listening Section 3 (Demo)', 17 | 'mp3' => $basePath . 'ielts-sample-audio/CD1-Track-03.mp3' 18 | ), 19 | array( 20 | 'artist' => 'AEHelp', 21 | 'title' => 'CD1-T-5: Reading Passage 1 (Demo)', 22 | 'mp3' => $basePath . 'ielts-sample-audio/CD1-Track-05.mp3' 23 | ), 24 | array( 25 | 'artist' => 'AEHelp', 26 | 'title' => 'CD1-T-7: Reading Passage 3 (Demo)', 27 | 'mp3' => $basePath . 'ielts-sample-audio/CD1-Track-07.mp3' 28 | ), 29 | array( 30 | 'artist' => 'AEHelp', 31 | 'title' => 'CD1-T-8: Speaking Part 1 (Demo)', 32 | 'mp3' => $basePath . 'ielts-sample-audio/CD1-Track-08.mp3' 33 | ) 34 | ); 35 | ?> -------------------------------------------------------------------------------- /2016/10/28/how-to-pass-php-data-to-your-script-in-wordpress/createPlaylist.js: -------------------------------------------------------------------------------- 1 | document.addEventListener("DOMContentLoaded", function(event) { 2 | for (var i = 0; i < audio_array.length; i++) { 3 | addAudioToHTML(audio_array[i].artist, audio_array[i].title, audio_array[i].mp3, i); 4 | } 5 | 6 | function addAudioToHTML (artist, title, source, position) { 7 | var parentDiv = document.createElement("div"); 8 | var firstP = document.createElement("p"); 9 | var artistForP1 = document.createTextNode("Artist: " + artist); 10 | 11 | firstP.appendChild(artistForP1); 12 | parentDiv.appendChild(firstP); 13 | 14 | var secondP = document.createElement("p"); 15 | var artistForP2 = document.createTextNode("Title: " + title); 16 | 17 | secondP.appendChild(artistForP2); 18 | parentDiv.appendChild(secondP); 19 | 20 | var audio = new Audio(source); 21 | audio.controls = true; 22 | // add warning message for web browser that does not support audio tag 23 | audio.innerHTML = "Your browser does not support the audio element."; 24 | 25 | parentDiv.appendChild(audio); 26 | 27 | var audioDiv = document.getElementById('audio'); 28 | document.querySelector('#audio').insertBefore(parentDiv, audioDiv.childNodes[position]); 29 | } 30 | }); -------------------------------------------------------------------------------- /2016/10/28/how-to-pass-php-data-to-your-script-in-wordpress/showPlaylistToUser.php: -------------------------------------------------------------------------------- 1 | section, which will enqueue the js file. Without this, the js file will not be 13 | // included in this specific page 14 | wp_head(); 15 | ?> 16 | 17 |
-------------------------------------------------------------------------------- /2016/10/29/is-it-possible-to-host-two-website-with-different-domain-on-one-server/commands.sh: -------------------------------------------------------------------------------- 1 | sudo service apache2 restart -------------------------------------------------------------------------------- /2016/10/29/is-it-possible-to-host-two-website-with-different-domain-on-one-server/www-example-com.conf: -------------------------------------------------------------------------------- 1 | 2 | ServerName www.example.com 3 | ServerAdmin webmaster@localhost 4 | DocumentRoot /var/www/example.com 5 | 6 | ErrorLog /var/www/example.com/log/error.log 7 | CustomLog /var/www/example.com/log/access.log combined 8 | -------------------------------------------------------------------------------- /2016/10/29/is-it-possible-to-host-two-website-with-different-domain-on-one-server/www-example-net.conf: -------------------------------------------------------------------------------- 1 | 2 | ServerName www.example.net 3 | ServerAdmin webmaster@localhost 4 | DocumentRoot /var/www/example.net 5 | 6 | ErrorLog /var/www/example.net/log/error.log 7 | CustomLog /var/www/example.net/log/access.log combined 8 | -------------------------------------------------------------------------------- /2016/11/12/how-to-take-screenshots-at-different-screen-sizes-using-casperjs/screenshots.js: -------------------------------------------------------------------------------- 1 | var casper = require("casper").create(); 2 | var fs = require('fs'); 3 | var urls = []; 4 | var inputFile; 5 | var contents; 6 | var contentsToJSON; 7 | var viewports = [ 8 | { 9 | 'name': 'Apple-iPhone-4s-portrait', 10 | 'viewport': {width: 320, height: 480} 11 | }, 12 | { 13 | 'name': 'Apple-iPhone-4s-landscape', 14 | 'viewport': {width: 480, height: 320} 15 | }, 16 | { 17 | 'name': 'Apple-iPhone-5-portrait', 18 | 'viewport': {width: 320, height: 568} 19 | }, 20 | { 21 | 'name': 'Apple-iPhone-5-landscape', 22 | 'viewport': {width: 568, height: 320} 23 | }, 24 | { 25 | 'name': 'Apple-iPhone-6-portrait', 26 | 'viewport': {width: 540, height: 960} 27 | }, 28 | { 29 | 'name': 'Apple-iPhone-6-landscape', 30 | 'viewport': {width: 960, height: 540} 31 | }, 32 | { 33 | 'name': 'Apple-iPad-mini-4-portrait', 34 | 'viewport': {width: 768, height: 1024} 35 | }, 36 | { 37 | 'name': 'Apple-iPad-mini-4-landscape', 38 | 'viewport': {width: 1024, height: 768} 39 | }, 40 | { 41 | 'name': 'Desktop-720p-HD', 42 | 'viewport': {width: 1280, height: 720} 43 | }, 44 | { 45 | 'name': 'Desktop-1080p-HD', 46 | 'viewport': {width: 1920, height: 1080} 47 | } 48 | ]; 49 | 50 | if (casper.cli.has(0)) { 51 | inputFile = casper.cli.get(0).toLowerCase(); 52 | }else{ 53 | casper.echo("No file passed, aborting...").exit(); 54 | } 55 | 56 | contents = fs.read(inputFile); 57 | contentsToJSON = JSON.parse(contents); 58 | 59 | var listOfLinks = contentsToJSON.links; 60 | listOfLinks.forEach(function (currentValue, index, arr) { 61 | urls.push({url: currentValue.url}); 62 | }); 63 | 64 | casper.start().each(urls, function(self, link) { 65 | self.thenOpen(link.url, function() { 66 | var folderPath = 'screenshots/' + link.url.split('//')[1].split('/')[0] + '/'; 67 | console.log("Taking screenshot for the url " + link.url + "...") 68 | viewports.forEach(function (currentValue) { 69 | console.log('Screenshot for ' + currentValue.name + ' (' + currentValue.viewport.width + 'x' + currentValue.viewport.height + ')', 'info'); 70 | self.viewport(currentValue.viewport.width, currentValue.viewport.height); 71 | self.capture(folderPath + currentValue.name + '-' + currentValue.viewport.width + 'x' + currentValue.viewport.height + '.png', { 72 | top: 0, 73 | left: 0, 74 | width: currentValue.viewport.width, 75 | height: currentValue.viewport.height 76 | }); 77 | }); 78 | }); 79 | }); 80 | 81 | casper.run(); -------------------------------------------------------------------------------- /2016/11/12/how-to-take-screenshots-at-different-screen-sizes-using-casperjs/urls.json: -------------------------------------------------------------------------------- 1 | { 2 | "links": [ 3 | { 4 | "url": "http://www.example.com" 5 | }, 6 | { 7 | "url": "http://www.example.net" 8 | } 9 | ] 10 | } -------------------------------------------------------------------------------- /2016/11/15/how-to-add-background-music-in-processing-3.0/backgroundMusic.pde: -------------------------------------------------------------------------------- 1 | import processing.sound.*; 2 | 3 | SoundFile file; 4 | //put your audio file name here 5 | String audioName = "sample.mp3"; 6 | String path; 7 | 8 | //runs once when the app first starts 9 | void setup() { 10 | // for more info about sketchPath, go to https://processing.org/discourse/beta/num_1229443269.html 11 | path = sketchPath(audioName); 12 | file = new SoundFile(this, path); 13 | file.play(); 14 | } 15 | 16 | //runs all the time, this is the main app loop 17 | void draw() { 18 | } -------------------------------------------------------------------------------- /2016/11/17/how-to-play-mp4-video-using-hls/commands.sh: -------------------------------------------------------------------------------- 1 | ffmpeg -i sample.mp4 -profile:v baseline -level 3.0 -s 840x560 -start_number 0 -hls_list_size 0 -f hls sample.m3u8 -------------------------------------------------------------------------------- /2016/11/17/how-to-play-mp4-video-using-hls/playM3u8UsingHlsJs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /2016/11/17/how-to-play-mp4-video-using-hls/sample.m3u8: -------------------------------------------------------------------------------- 1 | #EXTM3U 2 | #EXT-X-VERSION:3 3 | #EXT-X-TARGETDURATION:11 4 | #EXT-X-MEDIA-SEQUENCE:0 5 | #EXTINF:10.023222, 6 | sample0.ts 7 | #EXTINF:10.000000, 8 | sample1.ts 9 | #EXTINF:10.000000, 10 | sample2.ts 11 | #EXTINF:10.000000, 12 | sample3.ts 13 | #EXTINF:10.000000, 14 | sample4.ts 15 | #EXTINF:10.000000, 16 | sample5.ts 17 | #EXTINF:10.000000, 18 | sample6.ts 19 | #EXTINF:10.000000, 20 | sample7.ts 21 | #EXTINF:10.000000, 22 | sample8.ts 23 | #EXTINF:7.800000, 24 | sample9.ts 25 | #EXT-X-ENDLIST -------------------------------------------------------------------------------- /2016/11/20/how-to-enable-cross-origin-resource-sharing-on-an-apache-server/000-default-le-ssl.conf: -------------------------------------------------------------------------------- 1 | # remember to replace /var/www with your directory root 2 | 3 | # some other apache code here, if any 4 | # replace the url to the one you wanted 5 | Header set Access-Control-Allow-Origin "https://s.codepen.io" 6 | # some other apache code here, if any 7 | -------------------------------------------------------------------------------- /2016/11/20/how-to-enable-cross-origin-resource-sharing-on-an-apache-server/commands.sh: -------------------------------------------------------------------------------- 1 | cd /etc/apache2/sites-enabled 2 | sudo vi [name of your conf file].conf 3 | sudo a2enmod headers 4 | sudo service apache2 restart -------------------------------------------------------------------------------- /2016/12/06/how-to-build-a-search-page-in-django-with-amazon-dynamodb-and-react-p1-back-end/search.html: -------------------------------------------------------------------------------- 1 | {% for billionaire in billionaires %} 2 | {{ billionaire.first_name }} {{ billionaire.last_name }}
3 | {{ billionaire.source_of_wealth }}
4 | {{ billionaire.current_location }}
5 | {{ billionaire.net_worth }}
6 |
7 | {% endfor %} -------------------------------------------------------------------------------- /2016/12/06/how-to-build-a-search-page-in-django-with-amazon-dynamodb-and-react-p1-back-end/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import url 2 | 3 | urlpatterns = [ 4 | # http://127.0.0.1:8000/search 5 | # http://127.0.0.1:8000/search/ 6 | url(r'^search/?', views.search, name='search'), 7 | ] -------------------------------------------------------------------------------- /2016/12/06/how-to-build-a-search-page-in-django-with-amazon-dynamodb-and-react-p1-back-end/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | from django.template import loader 3 | from django.http import HttpResponse 4 | from boto3.dynamodb.conditions import Key, Attr 5 | import boto3 6 | import botocore 7 | 8 | # dynamodb configuration 9 | dynamodb = boto3.resource( 10 | 'dynamodb', 11 | aws_access_key_id='put_your_aws_access_key_here', 12 | aws_secret_access_key='put_your_aws_secret_access_key_here', 13 | region_name='puy_your_amazon_dynamodb_region_here') 14 | 15 | # http://127.0.0.1:8000/search 16 | # http://127.0.0.1:8000/search/ 17 | def search(request): 18 | template = loader.get_template('search.html') 19 | params = retrieve_all_get_parameters(request) 20 | billionaires = get_list_of_billionaires(params) 21 | context = { 22 | 'billionaires' : billionaires 23 | } 24 | 25 | return HttpResponse(template.render(context, request)) 26 | 27 | def get_list_of_billionaires(param): 28 | filter_expression = [] 29 | expression_attribute_names = {} 30 | expression_attribute_values = {} 31 | 32 | try: 33 | net_worth_under = param['net_worth_under'] 34 | filter_expression.append('(#net_worth <= :net_worth_under)') 35 | expression_attribute_names['#net_worth'] = 'net_worth' 36 | expression_attribute_values[':net_worth_under'] = net_worth_under 37 | except KeyError: 38 | pass 39 | try: 40 | current_residence = param['current_residence'] 41 | filter_expression.append('(#l = :current_residence)') 42 | expression_attribute_names['#l'] = 'current_location' 43 | expression_attribute_values[':current_residence'] = current_residence 44 | except KeyError: 45 | pass 46 | try: 47 | table = dynamodb.Table('put_your_amazon_dynamodb_table_name_here') 48 | except botocore.exceptions.ClientError as e: 49 | # http://stackoverflow.com/questions/33068055/boto3-python-and-how-to-handle-errors 50 | return 'failed' 51 | else: 52 | filtered_string = filter_expression_to_string(filter_expression) 53 | if filtered_string != '' and expression_attribute_names and expression_attribute_values: 54 | response = table.scan( 55 | FilterExpression = filtered_string, 56 | ExpressionAttributeNames = expression_attribute_names, 57 | ExpressionAttributeValues = expression_attribute_values, 58 | ) 59 | else: 60 | response = table.scan( 61 | ReturnConsumedCapacity = 'TOTAL', 62 | ) 63 | if response['ResponseMetadata']['HTTPStatusCode'] == 200: 64 | try: 65 | item = response['Item'] 66 | except KeyError: 67 | return None 68 | return item 69 | 70 | def retrieve_all_get_parameters(request): 71 | param = {} 72 | net_worth_under = request.GET.get('net_worth_under') 73 | current_residence = request.GET.get('current_residence') 74 | 75 | if net_worth_under != None and net_worth_under != '': 76 | param['net_worth_under'] = net_worth_under 77 | if current_residence != None and current_residence != '': 78 | param['current_residence'] = current_residence 79 | 80 | return param 81 | 82 | def filter_expression_to_string(filter_expression): 83 | if not filter_expression: 84 | return '' 85 | length_of_filter_expression = len(filter_expression) 86 | filter_expression_to_string = '' 87 | for x in range(length_of_filter_expression): 88 | filter_expression_to_string += filter_expression[x] 89 | if x + 1 != length_of_filter_expression: 90 | filter_expression_to_string += ' and ' 91 | return filter_expression_to_string -------------------------------------------------------------------------------- /2016/12/09/how-to-build-a-search-page-in-django-with-amazon-dynamodb-and-react-p2-front-end/combined-ReactDOM-code-for-both-dropdown.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | -------------------------------------------------------------------------------- /2016/12/09/how-to-build-a-search-page-in-django-with-amazon-dynamodb-and-react-p2-front-end/filter-in-react-way-full-code.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | -------------------------------------------------------------------------------- /2016/12/09/how-to-build-a-search-page-in-django-with-amazon-dynamodb-and-react-p2-front-end/filter-location-in-react-way.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | -------------------------------------------------------------------------------- /2016/12/09/how-to-build-a-search-page-in-django-with-amazon-dynamodb-and-react-p2-front-end/hello-world-in-react-way.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | -------------------------------------------------------------------------------- /2016/12/09/how-to-build-a-search-page-in-django-with-amazon-dynamodb-and-react-p2-front-end/modified-views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | from django.template import loader 3 | from django.http import HttpResponse 4 | from boto3.dynamodb.conditions import Key, Attr 5 | import json 6 | import boto3 7 | import botocore 8 | 9 | # dynamodb configuration 10 | dynamodb = boto3.resource( 11 | 'dynamodb', 12 | aws_access_key_id='put_your_aws_access_key_here', 13 | aws_secret_access_key='put_your_aws_secret_access_key_here', 14 | region_name='puy_your_amazon_dynamodb_region_here') 15 | 16 | # http://127.0.0.1:8000/search 17 | # http://127.0.0.1:8000/search/ 18 | def search(request): 19 | template = loader.get_template('search.html') 20 | params = retrieve_all_get_parameters(request) 21 | billionaires = get_list_of_billionaires(params) 22 | context = { 23 | 'billionaires' : billionaires 24 | } 25 | 26 | return HttpResponse(template.render(context, request)) 27 | 28 | def get_list_of_billionaires(param): 29 | filter_expression = [] 30 | expression_attribute_names = {} 31 | expression_attribute_values = {} 32 | 33 | try: 34 | net_worth_under = param['net_worth_under'] 35 | filter_expression.append('(#net_worth <= :net_worth_under)') 36 | expression_attribute_names['#net_worth'] = 'net_worth' 37 | expression_attribute_values[':net_worth_under'] = net_worth_under 38 | except KeyError: 39 | pass 40 | try: 41 | current_residence = param['current_residence'] 42 | filter_expression.append('(#l = :current_residence)') 43 | expression_attribute_names['#l'] = 'current_location' 44 | expression_attribute_values[':current_residence'] = current_residence 45 | except KeyError: 46 | pass 47 | try: 48 | table = dynamodb.Table('put_your_amazon_dynamodb_table_name_here') 49 | except botocore.exceptions.ClientError as e: 50 | # http://stackoverflow.com/questions/33068055/boto3-python-and-how-to-handle-errors 51 | return 'failed' 52 | else: 53 | filtered_string = filter_expression_to_string(filter_expression) 54 | if filtered_string != '' and expression_attribute_names and expression_attribute_values: 55 | response = table.scan( 56 | FilterExpression = filtered_string, 57 | ExpressionAttributeNames = expression_attribute_names, 58 | ExpressionAttributeValues = expression_attribute_values, 59 | ) 60 | else: 61 | response = table.scan( 62 | ReturnConsumedCapacity = 'TOTAL', 63 | ) 64 | if response['ResponseMetadata']['HTTPStatusCode'] == 200: 65 | try: 66 | item = response['Item'] 67 | except KeyError: 68 | return None 69 | return json.dumps(items, indent=4) 70 | 71 | def retrieve_all_get_parameters(request): 72 | param = {} 73 | net_worth_under = request.GET.get('net_worth_under') 74 | current_residence = request.GET.get('current_residence') 75 | 76 | if net_worth_under != None and net_worth_under != '': 77 | param['net_worth_under'] = net_worth_under 78 | if current_residence != None and current_residence != '': 79 | param['current_residence'] = current_residence 80 | 81 | return param 82 | 83 | def filter_expression_to_string(filter_expression): 84 | if not filter_expression: 85 | return '' 86 | length_of_filter_expression = len(filter_expression) 87 | filter_expression_to_string = '' 88 | for x in range(length_of_filter_expression): 89 | filter_expression_to_string += filter_expression[x] 90 | if x + 1 != length_of_filter_expression: 91 | filter_expression_to_string += ' and ' 92 | return filter_expression_to_string -------------------------------------------------------------------------------- /2017/04/02/how-to-setup-pretty-url-in-wordpress-through-lamp-stack/000-default-le-ssl.conf: -------------------------------------------------------------------------------- 1 | # remember to replace /var/www with your directory root 2 | 3 | # some other apache code here, if any 4 | # replace the url to the one you wanted 5 | AllowOverride All 6 | # some other apache code here, if any 7 | -------------------------------------------------------------------------------- /2017/04/02/how-to-setup-pretty-url-in-wordpress-through-lamp-stack/commands.sh: -------------------------------------------------------------------------------- 1 | sudo a2enmod rewrite 2 | cd /etc/apache2/sites-enabled 3 | sudo vi [name of your conf file].conf 4 | sudo service apache2 restart -------------------------------------------------------------------------------- /2017/04/10/how-to-check-if-an-image-already-existed-in-wp-content-upload-directory/does-file-exists-sample.php: -------------------------------------------------------------------------------- 1 | get_var( "SELECT post_id FROM {$wpdb->postmeta} WHERE meta_value LIKE '%/$filename'" ) ); 6 | } 7 | 8 | if ( null == ( $thumb_id = does_file_exists( 'example.png' ) ) ) { 9 | // hummm....seems like we have never seen this file name before, let's do an upload 10 | } else { 11 | // nice...the image already exist!!! 12 | } 13 | ?> -------------------------------------------------------------------------------- /2017/05/07/how-to-set-up-password-authentication-with-apache-on-ubuntu-1404/000-default-le-ssl.conf: -------------------------------------------------------------------------------- 1 | 2 | Options Indexes FollowSymLinks 3 | AllowOverride All 4 | Require all granted 5 | -------------------------------------------------------------------------------- /2017/05/07/how-to-set-up-password-authentication-with-apache-on-ubuntu-1404/commands.sh: -------------------------------------------------------------------------------- 1 | sudo apt-get update 2 | sudo apt-get install apache2 apache2-utils 3 | sudo htpasswd -c /etc/apache2/.htpasswd username 4 | cat /etc/apache2/.htpasswd 5 | sudo vi /etc/apache2/sites-enabled/000-default.conf 6 | sudo service apache2 restart -------------------------------------------------------------------------------- /2017/06/13/mutable-vs-Immutable-object-in-JavaScript/immutable-sample.js: -------------------------------------------------------------------------------- 1 | function immutable(originalArray) { 2 | // Instead of mutating/modifying the original array, 3 | // we first make a copy of the original array 4 | // In this way, the original array stay unchanged. 5 | var newArray = [...originalArray]; 6 | newArray[0] = "new value"; 7 | return newArray; 8 | } 9 | 10 | var array = ["some value", "another value"]; 11 | alert("Return from immutable " + immutable(array)); 12 | alert("Array: " + array + " (original array stay unchanged)."); -------------------------------------------------------------------------------- /2017/06/13/mutable-vs-Immutable-object-in-JavaScript/mutation-sample.js: -------------------------------------------------------------------------------- 1 | function mutation(originalArray) { 2 | // directly mutating/modifying the original array 3 | originalArray[0] = "new value"; 4 | return originalArray; 5 | } 6 | 7 | var array = ["some value", "another value"]; 8 | alert("Return from mutation " + mutation(array)); 9 | alert("Array: " + array + " (original array has been altered)."); -------------------------------------------------------------------------------- /2017/07/01/how-to-recover-all-your-deleted-cron-jobs/commands.sh: -------------------------------------------------------------------------------- 1 | wget https://github.com/poanchen/recover-crontab/archive/x.x.x.zip 2 | wget https://github.com/poanchen/recover-crontab/archive/x.x.x.tar.gz 3 | unzip x.x.x.zip 4 | tar xvzf x.x.x.tar.gz 5 | ./recover-crontab.sh -u [PUT YOUR USERNAME HERE] -------------------------------------------------------------------------------- /2017/07/24/how-to-use-gulp.js-to-deploy-your-site-to-live-through-github/gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var deploy = require('gulp-gh-pages'); 3 | 4 | gulp.task('deploy', function () { 5 | return gulp.src("./prod/**/*") 6 | .pipe(deploy({ 7 | remoteUrl: "https://github.com/your_github_username_here/your_github_username_here.github.io.git", 8 | branch: "master" 9 | })) 10 | }); -------------------------------------------------------------------------------- /2017/07/24/how-to-use-gulp.js-to-deploy-your-site-to-live-through-github/prod/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Page Title 5 | 6 | 7 |

Hello world

8 | 9 | -------------------------------------------------------------------------------- /2017/07/27/how-to-add-disqus-to-your-jekyll-site/_includes/disqus.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 20 | 23 | 24 | 25 |
26 | 27 | -------------------------------------------------------------------------------- /2017/07/27/how-to-add-disqus-to-your-jekyll-site/src/js/disqus.js: -------------------------------------------------------------------------------- 1 | var disqus_config = function () { 2 | // we are using document.location.* here because Jekyll code does not work well in JS code. 3 | this.page.url = document.location.href; 4 | this.page.identifier = document.location.pathname; 5 | }; 6 | 7 | // You should be able to get the following lines of code from your Disqus admin. 8 | // https://disqus.com/admin/universalcode 9 | (function() { // DON'T EDIT BELOW THIS LINE 10 | var d = document, s = d.createElement('script'); 11 | s.src = '//[your_username].disqus.com/embed.js'; 12 | s.setAttribute('data-timestamp', +new Date()); 13 | (d.head || d.body).appendChild(s); 14 | })(); -------------------------------------------------------------------------------- /2017/10/19/How-to-replace-a-git-submodules-in-a-repository/.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "path/to/your-submodules"] 2 | path = path/to/your-submodules 3 | url = https://www.github.com/poanchen/your-submodules-name -------------------------------------------------------------------------------- /2017/10/20/How-to-run-a-single-test-or-all-tests-in-a-class-with-gradlew/BlogControllerTests.groovy: -------------------------------------------------------------------------------- 1 | package io.github.poanchen.projectName.api 2 | class BlogControllerTests { 3 | void testCreate_BlogWithoutTitle() { 4 | // some test code 5 | } 6 | void testUpdate_BlogWithInvalidAuthorEmail() { 7 | // some test code 8 | } 9 | } -------------------------------------------------------------------------------- /2017/10/20/How-to-run-a-single-test-or-all-tests-in-a-class-with-gradlew/commands.sh: -------------------------------------------------------------------------------- 1 | ./gradlew :projectName-api:unitTest --tests io.github.poanchen.projectName.api.BlogControllerTests.testCreate_BlogWithoutTitle 2 | ./gradlew :projectName-api:unitTest --tests io.github.poanchen.projectName.api.BlogControllerTests -------------------------------------------------------------------------------- /2017/10/31/Installing-Marsyas-with-Python-bindings-on-Ubuntu-14.04.3-LTS-64-bits/commands.sh: -------------------------------------------------------------------------------- 1 | sudo apt install git 2 | sudo apt install cmake 3 | sudo apt install cmake-curses-gui 4 | sudo apt install libasound2-dev 5 | 6 | wget https://github.com/poanchen/marsyas/archive/version-0.5.1.tar.gz 7 | tar xvzf version-0.5.1.tar.gz 8 | cd marsyas-version-0.5.1/ 9 | mkdir build 10 | cd build 11 | ccmake ../ #(First, select c to configure. And then, select g to generate and exit.) 12 | make -j 3 #(or higher if you have more cores) (This will take quite a bit of time to build it) 13 | 14 | cd bin 15 | ./HelloWorld #(Ctrl+C to force shut down or similar) 16 | cd .. 17 | 18 | sudo apt install swig 19 | sudo apt install python-dev (the python headers) 20 | sudo apt install python-matplotlib 21 | sudo apt install ipython 22 | sudo apt install libfreetype6-dev 23 | 24 | ccmake ../ #(First, press enter with up and down arrow to enable the WITH_SWIG and WITH_PNG option to be ON. And then, select g to generate and exit.) 25 | make -j 3 #(or higher if you have more cores) (This will take quite a bit of time to build it) 26 | sudo make install #(Install the Marsyas python bindings so that Python can find them globally) 27 | sudo ldconfig /usr/local/lib #(Add /usr/local/lib to the path searched for libraries) 28 | 29 | cd src/marsyas_python 30 | python windowing.py -------------------------------------------------------------------------------- /2017/10/31/Installing-Marsyas-with-Python-bindings-on-Ubuntu-14.04.3-LTS-64-bits/sample.mrs: -------------------------------------------------------------------------------- 1 | Series { 2 | inSamples = 2048 3 | -> input: SoundFileSource { filename = "sample.wav" } 4 | -> Windowing { size = 2048 } 5 | -> Spectrum 6 | -> PowerSpectrum { spectrumType = "magnitude" } 7 | -> selection: Selector { disable = 0 } 8 | -> sink: CsvSink { filename = "output.csv" } 9 | + done = (input/hasData == false) 10 | } -------------------------------------------------------------------------------- /2017/10/31/Installing-Marsyas-with-Python-bindings-on-Ubuntu-14.04.3-LTS-64-bits/sample.py: -------------------------------------------------------------------------------- 1 | from pylab import * 2 | import sys 3 | from matplotlib import pyplot 4 | from marsyas import * 5 | from marsyas_util import * 6 | y_data = [] 7 | system = marsyas.system_from_script_file("sample.mrs") 8 | while (system.getControl("SoundFileSource/input/mrs_bool/hasData").to_bool()): 9 | system.tick() 10 | y_data.extend(system.getControl("Selector/selection/mrs_realvec/processedData").to_realvec()) 11 | y_data[-1] *= 44100 / 1025 # Sampling Rate / FFT Size 12 | plot(range(0, len(y_data)), y_data) 13 | savefig('sample.png') -------------------------------------------------------------------------------- /2018/02/09/Solving-the-Fibonacci-problem-using-Dynamic-Programming-in-Java/FibonacciNumber.java: -------------------------------------------------------------------------------- 1 | public class FibonacciNumber { 2 | public int getFibonacciNumberRecursively(int n) { 3 | if(n == 0) return 0; 4 | if(n == 1) return 1; 5 | return getFibonacciNumberRecursively(n - 1) + getFibonacciNumberRecursively(n - 2); 6 | } 7 | public HashMap hm = new HashMap(); 8 | public int getFibonacciNumberTopDown(int n) { 9 | if(hm.containsKey(n)) return hm.get(n); 10 | if(n == 0) return 0; 11 | if(n == 1) return 1; 12 | int nthValue = getFibonacciNumberTopDown(n - 1) + getFibonacciNumberTopDown(n - 2); 13 | hm.put(n, nthValue); 14 | return nthValue; 15 | } 16 | public int getFibonacciNumberBottomUpWithCache(int n) { 17 | hm.put(0, 0); 18 | hm.put(1, 1); 19 | for(int i = 2; i <= n; i++) { 20 | hm.put(i, hm.get(i - 1) + hm.get(i - 2)); 21 | } 22 | return hm.get(n); 23 | } 24 | public int getFibonacciNumberBottomUpWithoutCache(int n) { 25 | if (n == 0 || n == 1) return n; 26 | int fnMin2 = 0; 27 | int fnMin1 = 1; 28 | int sum = 0; 29 | for(int i = 2; i <= n; i++) { 30 | sum = fnMin1 + fnMin2; 31 | fnMin2 = fnMin1; 32 | fnMin1 = sum; 33 | } 34 | return sum; 35 | } 36 | public static void main(String [] args) { 37 | getFibonacciNumberRecursively(8); // 21 38 | getFibonacciNumberTopDown(8); // 21 39 | getFibonacciNumberBottomUpWithCache(8); // 21 40 | getFibonacciNumberBottomUpWithoutCache(8); // 21 41 | } 42 | } -------------------------------------------------------------------------------- /2018/03/07/How-to-fix-permission-denied-for-relation-some_table_name-in-PostgreSQL/userAbleToAccess.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE "database"; 2 | CREATE USER someuser WITH PASSWORD 'securepassword'; 3 | CREATE TABLE "some_table_name"( 4 | "id" int NOT NULL, 5 | "data" text NOT NULL 6 | ); 7 | INSERT INTO "some_table_name" values(0, "some text"); 8 | GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO someuser; 9 | -------------------------------------------------------------------------------- /2018/03/07/How-to-fix-permission-denied-for-relation-some_table_name-in-PostgreSQL/userUnableToAccess.sql: -------------------------------------------------------------------------------- 1 | CREATE DATABASE "database"; 2 | CREATE USER someuser WITH PASSWORD 'securepassword'; 3 | GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO someuser; 4 | CREATE TABLE "some_table_name"( 5 | "id" int NOT NULL, 6 | "data" text NOT NULL 7 | ); 8 | INSERT INTO "some_table_name" values(0, "some text"); -------------------------------------------------------------------------------- /2018/11/23/how-to-calculate-time-complexity-of-an-algorithm/constantTime.java: -------------------------------------------------------------------------------- 1 | public class constantTime { 2 | 3 | // Time complexity: O(1) 4 | // Space complexity: O(1) 5 | public static void main(String [] args) { 6 | int x = 15; 7 | x += 6; 8 | System.out.print(x); // should print 21 9 | } 10 | } -------------------------------------------------------------------------------- /2018/11/23/how-to-calculate-time-complexity-of-an-algorithm/cubicTime.java: -------------------------------------------------------------------------------- 1 | public class cubicTime { 2 | 3 | // Time complexity: O(n^3) 4 | // Space complexity: O(1) 5 | public static void print2DArray(int [][] m) { 6 | for(int i = 0; i < m.length; i++) { 7 | for(int j = 0; j < m[0].length; j++) { 8 | for(int k = 0; k < m[0].length; k++) { 9 | System.out.print(m[i][j] + ","); 10 | } 11 | } 12 | System.out.println(); 13 | } 14 | } 15 | public static void main(String[] args) { 16 | int [][] m = new int[3][3]; 17 | m[0][0] = 1; 18 | m[0][1] = 2; 19 | m[0][2] = 3; 20 | m[1][0] = 4; 21 | m[1][1] = 5; 22 | m[1][2] = 6; 23 | m[2][0] = 7; 24 | m[2][1] = 8; 25 | m[2][2] = 9; 26 | print2DArray(m); 27 | } 28 | } -------------------------------------------------------------------------------- /2018/11/23/how-to-calculate-time-complexity-of-an-algorithm/exponentiationTime.java: -------------------------------------------------------------------------------- 1 | public class exponentiationTime { 2 | 3 | // Time complexity: O(4^n) 4 | // Space complexity: O(1) 5 | public static void getMaxAnswer(double res, int [] arr, int index) { 6 | if(index == arr.length) { 7 | System.out.println(res); 8 | } else { 9 | getMaxAnswer(res + arr[index], arr, index + 1); 10 | getMaxAnswer(res - arr[index], arr, index + 1); 11 | getMaxAnswer(res * arr[index], arr, index + 1); 12 | getMaxAnswer(res / arr[index], arr, index + 1); 13 | } 14 | } 15 | public static void main(String[] args) { 16 | int [] arr = new int[]{1, 12, 3}; 17 | getMaxAnswer(arr[0] * 1.0, arr, 1); 18 | } 19 | } -------------------------------------------------------------------------------- /2018/11/23/how-to-calculate-time-complexity-of-an-algorithm/linearTime.java: -------------------------------------------------------------------------------- 1 | public class linearTime { 2 | 3 | // Time complexity: O(n) 4 | // Space complexity: O(1) 5 | public static void printArray(int [] arr) { 6 | for(int i = 0; i < arr.length; i++) { 7 | System.out.println(arr[i]); 8 | } 9 | } 10 | public static void main(String[] args) { 11 | int [] arr = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 12 | printArray(arr); 13 | } 14 | } -------------------------------------------------------------------------------- /2018/11/23/how-to-calculate-time-complexity-of-an-algorithm/logarithmicTime.java: -------------------------------------------------------------------------------- 1 | public class logarithmicTime { 2 | 3 | // Time complexity: O(log(n)) 4 | // Space complexity: O(1) 5 | public static int binarySearch(int [] arr, int target) { 6 | int low = 0, high = arr.length - 1; 7 | while(low <= high) { 8 | int mid = low + ((high - low) / 2); 9 | if(arr[mid] == target) return mid; 10 | if(arr[mid] < target) low = mid + 1; 11 | else high = mid - 1; 12 | } 13 | return -(low + 1); 14 | } 15 | public static void main(String[] args) { 16 | int [] arr = new int[]{2, 3, 5, 7, 9, 19, 25}; 17 | System.out.println(binarySearch(arr, 2) == 0); // true 18 | System.out.println(binarySearch(arr, 19) == 5); // true 19 | System.out.println(binarySearch(arr, 1) == -1); // true 20 | System.out.println(binarySearch(arr, 20) == -7); // true 21 | System.out.println(binarySearch(arr, 18) == -6); // true 22 | } 23 | } -------------------------------------------------------------------------------- /2018/11/23/how-to-calculate-time-complexity-of-an-algorithm/quadraticNestedConstantForLoopTime.java: -------------------------------------------------------------------------------- 1 | public class quadraticNestedConstantForLoopTime { 2 | 3 | // Time complexity: O(n^2) 4 | // Space complexity: O(1) 5 | public static void print2DArray(int [][] m) { 6 | for(int i = 0; i < m.length; i++) { 7 | for(int j = 0; j < m[0].length; j++) { 8 | for(int k = 0; k <= 10; k++) { 9 | System.out.print(m[i][j] + ","); 10 | } 11 | } 12 | System.out.println(); 13 | } 14 | } 15 | public static void main(String[] args) { 16 | int [][] m = new int[3][3]; 17 | m[0][0] = 1; 18 | m[0][1] = 2; 19 | m[0][2] = 3; 20 | m[1][0] = 4; 21 | m[1][1] = 5; 22 | m[1][2] = 6; 23 | m[2][0] = 7; 24 | m[2][1] = 8; 25 | m[2][2] = 9; 26 | print2DArray(m); 27 | } 28 | } -------------------------------------------------------------------------------- /2018/11/23/how-to-calculate-time-complexity-of-an-algorithm/quadraticTime.java: -------------------------------------------------------------------------------- 1 | public class quadraticTime { 2 | 3 | // Time complexity: O(n^2) 4 | // Space complexity: O(1) 5 | public static void print2DArray(int [][] m) { 6 | for(int i = 0; i < m.length; i++) { 7 | for(int j = 0; j < m[0].length; j++) { 8 | System.out.print(m[i][j] + ","); 9 | } 10 | System.out.println(); 11 | } 12 | } 13 | public static void main(String[] args) { 14 | int [][] m = new int[3][3]; 15 | m[0][0] = 1; 16 | m[0][1] = 2; 17 | m[0][2] = 3; 18 | m[1][0] = 4; 19 | m[1][1] = 5; 20 | m[1][2] = 6; 21 | m[2][0] = 7; 22 | m[2][1] = 8; 23 | m[2][2] = 9; 24 | print2DArray(m); 25 | } 26 | } -------------------------------------------------------------------------------- /2018/11/23/how-to-calculate-time-complexity-of-an-algorithm/sqrtTime.java: -------------------------------------------------------------------------------- 1 | import java.lang.Math; 2 | 3 | public class sqrtTime { 4 | 5 | // Time complexity: O(sqrt(n)) 6 | // Space complexity: O(1) 7 | public static boolean isPrime(int n) { 8 | boolean isPrime = true; 9 | for(int i = 2; Math.sqrt(n) > i && isPrime; i++) { 10 | if(n % i == 0) isPrime = false; 11 | } 12 | return isPrime; 13 | } 14 | public static void main(String[] args) { 15 | System.out.println(isPrime(2) == true); 16 | System.out.println(isPrime(5) == true); 17 | System.out.println(isPrime(7) == true); 18 | System.out.println(isPrime(12) == false); 19 | System.out.println(isPrime(20) == false); 20 | } 21 | } -------------------------------------------------------------------------------- /2018/11/23/how-to-calculate-time-complexity-of-an-algorithm/threeLinearTime.java: -------------------------------------------------------------------------------- 1 | public class threeLinearTime { 2 | 3 | // Time complexity: O(n) 4 | // Space complexity: O(1) 5 | public static void printArray(int [] arr) { 6 | for(int i = 0; i < arr.length; i++) { 7 | System.out.println(arr[i]); 8 | } 9 | } 10 | public static void main(String[] args) { 11 | int [] arr = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 12 | printArray(arr); 13 | printArray(arr); 14 | printArray(arr); 15 | } 16 | } -------------------------------------------------------------------------------- /2019/06/19/The-right-way-to-manage-nested-callbacks/forthSolution.js: -------------------------------------------------------------------------------- 1 | const beginToAddSongsToPlaylist = async () => { 2 | let response = await retrieveAccessToken(tab.url); 3 | response = await retrieveUserInfo(response); 4 | response = await createAPlaylist(response); 5 | response = await getAllSongsInfo(response); 6 | response = await prepareToaddAllSongsToPlaylist(response); 7 | response = await addAllSongsToPlaylist(response); 8 | }; 9 | 10 | beginToAddSongsToPlaylist(); 11 | 12 | const retrieveAccessToken = url => { 13 | return new Promise(resolve => { 14 | post("https://accounts.spotify.com/api/token", {}, urlencode({ 15 | grant_type: 'authorization_code', 16 | code: getParam(url, 'code'), 17 | redirect_uri: "https://www.jenrenalcare.com/upload/thank-you.html", 18 | client_id: "3aa81ba3bbea466ba09fef04a5feea41", 19 | client_secret: "c47f40315044462d8b52bf747e8b2e1f" 20 | }), response => { 21 | resolve(response); 22 | }); 23 | }) 24 | }; 25 | 26 | const retrieveUserInfo = response => { 27 | var tokenType = response.token_type; 28 | var accessToken = response.access_token; 29 | return new Promise(resolve => { 30 | get("https://api.spotify.com/v1/me", { 31 | Authorization: tokenType + ' ' + accessToken 32 | }, null, response => { 33 | response['token_type'] = tokenType 34 | response['access_token'] = accessToken; 35 | return resolve(response); 36 | }); 37 | }); 38 | }; 39 | 40 | const createAPlaylist = response => { 41 | var tokenType = response.token_type; 42 | var accessToken = response.access_token; 43 | var userId = response.id; 44 | return new Promise(resolve => { 45 | post("https://api.spotify.com/v1/users/" + userId + "/playlists", { 46 | Authorization: tokenType + ' ' + accessToken, 47 | "Content-type": "application/json" 48 | }, JSON.stringify({ 49 | name: localStorage.playlistTitle 50 | }), response => { 51 | response['token_type'] = tokenType 52 | response['access_token'] = accessToken; 53 | response['userId'] = userId; 54 | return resolve(response); 55 | }); 56 | }); 57 | }; 58 | 59 | const searchASong = response => { 60 | return new Promise(resolve => { 61 | get("https://api.spotify.com/v1/search", { 62 | Authorization: response.token_type + ' ' + response.access_token 63 | }, buildSearchQuery(response.song), responseFromSearch => { 64 | resolve(responseFromSearch.tracks.items[0]); 65 | }); 66 | }); 67 | }; 68 | 69 | 70 | const getAllSongsInfo = response => { 71 | var tokenType = response.token_type; 72 | var accessToken = response.access_token; 73 | var playlistId = response.id; 74 | var userId = response.userId; 75 | var songs = JSON.parse(localStorage.songs); 76 | var allSearchPromises = []; 77 | for (key in songs) { 78 | response['song'] = songs[key]; 79 | allSearchPromises.push(searchASong(response)); 80 | } 81 | return Promise.all(allSearchPromises).then(function(response) { 82 | response['token_type'] = tokenType; 83 | response['access_token'] = accessToken; 84 | response['playlistId'] = playlistId; 85 | response['userId'] = userId; 86 | return response; 87 | }); 88 | }; 89 | 90 | const prepareToaddAllSongsToPlaylist = response => { 91 | var songs = []; 92 | for (key in response) { 93 | if (isNumeric(key)) { 94 | songs.push(response[key].uri); 95 | } 96 | } 97 | return new Promise(resolve => { 98 | response['songs'] = songs; 99 | resolve(response); 100 | }); 101 | }; 102 | 103 | const addAllSongsToPlaylist = response => { 104 | var tokenType = response.token_type; 105 | var accessToken = response.access_token; 106 | var playlistId = response.playlistId; 107 | var userId = response.userId; 108 | var songs = response.songs; 109 | return new Promise(resolve => { 110 | post("https://api.spotify.com/v1/users/" + userId + "/playlists/" + playlistId + "/tracks", { 111 | Authorization: tokenType + ' ' + accessToken, 112 | "Content-type": "application/json" 113 | }, JSON.stringify({ 114 | uris: songs 115 | }), function(response) { 116 | resolve(response); 117 | }); 118 | }); 119 | }; 120 | 121 | function isNumeric(n) { 122 | return !isNaN(parseFloat(n)) && isFinite(n); 123 | } 124 | 125 | function buildSearchQuery(song) { 126 | return "q=" + song.title + 127 | "%20album:" + song.album + 128 | "%20artist:" + song.artist + 129 | "&type=track"; 130 | } -------------------------------------------------------------------------------- /2019/06/19/The-right-way-to-manage-nested-callbacks/originalVersion.js: -------------------------------------------------------------------------------- 1 | // function get(url, header, param, success) {...} 2 | // function post(url, header, param, success) {...} 3 | 4 | post("https://accounts.spotify.com/api/token", {}, urlencode({ 5 | grant_type: 'authorization_code', 6 | code: getParam(tab.url, 'code'), 7 | redirect_uri: "https://www.jenrenalcare.com/upload/thank-you.html", 8 | client_id: "3aa81ba3bbea466ba09fef04a5feea41", 9 | client_secret: "c47f40315044462d8b52bf747e8b2e1f" 10 | }), function(response) { 11 | var tokenType = response.token_type; 12 | var accessToken = response.access_token; 13 | get("https://api.spotify.com/v1/me", { 14 | Authorization: tokenType + ' ' + accessToken 15 | }, null, function(response) { 16 | var userId = response.id; 17 | post("https://api.spotify.com/v1/users/" + userId + "/playlists", { 18 | Authorization: tokenType + ' ' + accessToken, 19 | "Content-type": "application/json" 20 | }, JSON.stringify({ 21 | name: localStorage.playlistTitle 22 | }), function(response) { 23 | var playlistId = response.id; 24 | var songs = JSON.parse(localStorage.songs); 25 | var i = 0; 26 | for (key in songs) { 27 | get("https://api.spotify.com/v1/search", { 28 | Authorization: tokenType + ' ' + accessToken 29 | }, "q=" + songs[key].title + "%20album:" + songs[key].album + "%20artist:" + songs[key].artist + "&type=track", function(response) { 30 | if (response.tracks.items.length) { 31 | var uri = response.tracks.items[0].uri; 32 | post("https://api.spotify.com/v1/users/" + userId + "/playlists/" + playlistId + "/tracks", { 33 | Authorization: tokenType + ' ' + accessToken, 34 | "Content-type": "application/json" 35 | }, JSON.stringify({ 36 | uris: [uri] 37 | }), function(response) { 38 | // song has been added to the playlist 39 | }); 40 | } 41 | }); 42 | }; 43 | }); 44 | }); 45 | }); -------------------------------------------------------------------------------- /2019/06/19/The-right-way-to-manage-nested-callbacks/originalVersionWithComments.js: -------------------------------------------------------------------------------- 1 | // function get(url, header, param, success) {...} 2 | // function post(url, header, param, success) {...} 3 | 4 | // Retrieve temporary access token 5 | post("https://accounts.spotify.com/api/token", {}, urlencode({ 6 | grant_type: 'authorization_code', 7 | code: getParam(tab.url, 'code'), 8 | redirect_uri: "https://www.jenrenalcare.com/upload/thank-you.html", 9 | client_id: "3aa81ba3bbea466ba09fef04a5feea41", 10 | client_secret: "c47f40315044462d8b52bf747e8b2e1f" 11 | }), function(response) { 12 | var tokenType = response.token_type; 13 | var accessToken = response.access_token; 14 | // Retrieve user’s id using the access token that we just got 15 | get("https://api.spotify.com/v1/me", { 16 | Authorization: tokenType + ' ' + accessToken 17 | }, null, function(response) { 18 | var userId = response.id; 19 | // Create a brand new empty playlist 20 | post("https://api.spotify.com/v1/users/" + userId + "/playlists", { 21 | Authorization: tokenType + ' ' + accessToken, 22 | "Content-type": "application/json" 23 | }, JSON.stringify({ 24 | name: localStorage.playlistTitle 25 | }), function(response) { 26 | var playlistId = response.id; 27 | var songs = JSON.parse(localStorage.songs); 28 | var i = 0; 29 | // Try to look for the song on Spotify for every song on the list 30 | for (key in songs) { 31 | get("https://api.spotify.com/v1/search", { 32 | Authorization: tokenType + ' ' + accessToken 33 | }, "q=" + songs[key].title + "%20album:" + songs[key].album + "%20artist:" + songs[key].artist + "&type=track", function(response) { 34 | if (response.tracks.items.length) { 35 | var uri = response.tracks.items[0].uri; 36 | // Since we got the user’s id from step 2 as well as the playlist’s id from step 3, we should now be able to add songs to the playlist on Spotify 37 | post("https://api.spotify.com/v1/users/" + userId + "/playlists/" + playlistId + "/tracks", { 38 | Authorization: tokenType + ' ' + accessToken, 39 | "Content-type": "application/json" 40 | }, JSON.stringify({ 41 | uris: [uri] 42 | }), function(response) { 43 | // song has been added to the playlist 44 | }); 45 | } 46 | }); 47 | }; 48 | }); 49 | }); 50 | }); -------------------------------------------------------------------------------- /2019/06/19/The-right-way-to-manage-nested-callbacks/secondSolution.js: -------------------------------------------------------------------------------- 1 | // function get(url, header, param, success) {...} 2 | // function post(url, header, param, success) {...} 3 | 4 | var tokenType, accessToken, userId, playlistId, songs = JSON.parse(localStorage.songs); 5 | 6 | retrieveAccessToken(function(response) { 7 | retrieveUserId(response, function(response) { 8 | createANewPlaylist(response, function(response) { 9 | addAllSongsToPlayList(response, function(total) { 10 | console.log("There are " + total + " out of " + songs.length + " songs been added to the playlist!!!"); 11 | }); 12 | }); 13 | }); 14 | }); 15 | 16 | function retrieveAccessToken(callback) { 17 | post("https://accounts.spotify.com/api/token", {}, urlencode({ 18 | grant_type: 'authorization_code', 19 | code: getParam(tab.url, 'code'), 20 | redirect_uri: "https://www.jenrenalcare.com/upload/thank-you.html", 21 | client_id: "3aa81ba3bbea466ba09fef04a5feea41", 22 | client_secret: "c47f40315044462d8b52bf747e8b2e1f" 23 | }), function(response) { 24 | callback(response); 25 | }); 26 | } 27 | 28 | function retrieveUserId(response, callback) { 29 | tokenType = response.token_type; 30 | accessToken = response.access_token; 31 | get("https://api.spotify.com/v1/me", { 32 | Authorization: tokenType + ' ' + accessToken 33 | }, null, function(response) { 34 | callback(response); 35 | }); 36 | } 37 | 38 | function createANewPlaylist(response, callback) { 39 | userId = response.id; 40 | post("https://api.spotify.com/v1/users/" + userId + "/playlists", { 41 | Authorization: tokenType + ' ' + accessToken, 42 | "Content-type": "application/json" 43 | }, JSON.stringify({ 44 | name: localStorage.playlistTitle 45 | }), function(response) { 46 | callback(response); 47 | }); 48 | } 49 | 50 | function searchASong(key, callback) { 51 | get("https://api.spotify.com/v1/search", { 52 | Authorization: tokenType + ' ' + accessToken 53 | }, "q=" + songs[key].title + "%20album:" + songs[key].album + "%20artist:" + songs[key].artist + "&type=track", function(response) { 54 | callback(response); 55 | }); 56 | } 57 | 58 | function addASongToThePlaylist(uri, callback) { 59 | post("https://api.spotify.com/v1/users/" + userId + "/playlists/" + playlistId + "/tracks", { 60 | Authorization: tokenType + ' ' + accessToken, 61 | "Content-type": "application/json" 62 | }, JSON.stringify({ 63 | uris: [uri] 64 | }), function(response) { 65 | callback(response); 66 | }); 67 | } 68 | 69 | function addAllSongsToPlayList(response, callback) { 70 | playlistId = response.id; 71 | var i = 0; 72 | for (key in songs) { 73 | searchASong(key, function(response) { 74 | if (response.tracks.items.length) { 75 | addASongToThePlaylist(response.tracks.items[0].uri, function(response) { 76 | i++; 77 | }); 78 | } 79 | }); 80 | } 81 | callback(i); 82 | } -------------------------------------------------------------------------------- /2019/06/19/The-right-way-to-manage-nested-callbacks/thirdSolution.js: -------------------------------------------------------------------------------- 1 | retrieveAccessToken(tab.url) 2 | .then(retrieveUserInfo) 3 | .then(createAPlaylist) 4 | .then(getAllSongsInfo) 5 | .then(prepareToaddAllSongsToPlaylist) 6 | .then(addAllSongsToPlaylist) 7 | .catch(error => { 8 | progress.innerHTML += "[WARNING] " + error + "
"; 9 | }); 10 | 11 | const retrieveAccessToken = url => { 12 | return new Promise(resolve => { 13 | post("https://accounts.spotify.com/api/token", {}, urlencode({ 14 | grant_type: 'authorization_code', 15 | code: getParam(url, 'code'), 16 | redirect_uri: "https://www.jenrenalcare.com/upload/thank-you.html", 17 | client_id: "3aa81ba3bbea466ba09fef04a5feea41", 18 | client_secret: "c47f40315044462d8b52bf747e8b2e1f" 19 | }), response => { 20 | resolve(response); 21 | }); 22 | }) 23 | }; 24 | 25 | const retrieveUserInfo = response => { 26 | var tokenType = response.token_type; 27 | var accessToken = response.access_token; 28 | return new Promise(resolve => { 29 | get("https://api.spotify.com/v1/me", { 30 | Authorization: tokenType + ' ' + accessToken 31 | }, null, response => { 32 | response['token_type'] = tokenType 33 | response['access_token'] = accessToken; 34 | return resolve(response); 35 | }); 36 | }); 37 | }; 38 | 39 | const createAPlaylist = response => { 40 | var tokenType = response.token_type; 41 | var accessToken = response.access_token; 42 | var userId = response.id; 43 | return new Promise(resolve => { 44 | post("https://api.spotify.com/v1/users/" + userId + "/playlists", { 45 | Authorization: tokenType + ' ' + accessToken, 46 | "Content-type": "application/json" 47 | }, JSON.stringify({ 48 | name: localStorage.playlistTitle 49 | }), response => { 50 | response['token_type'] = tokenType 51 | response['access_token'] = accessToken; 52 | response['userId'] = userId; 53 | return resolve(response); 54 | }); 55 | }); 56 | }; 57 | 58 | const searchASong = response => { 59 | return new Promise(resolve => { 60 | get("https://api.spotify.com/v1/search", { 61 | Authorization: response.token_type + ' ' + response.access_token 62 | }, buildSearchQuery(response.song), responseFromSearch => { 63 | resolve(responseFromSearch.tracks.items[0]); 64 | }); 65 | }); 66 | }; 67 | 68 | 69 | const getAllSongsInfo = response => { 70 | var tokenType = response.token_type; 71 | var accessToken = response.access_token; 72 | var playlistId = response.id; 73 | var userId = response.userId; 74 | var songs = JSON.parse(localStorage.songs); 75 | var allSearchPromises = []; 76 | for (key in songs) { 77 | response['song'] = songs[key]; 78 | allSearchPromises.push(searchASong(response)); 79 | } 80 | return Promise.all(allSearchPromises).then(function(response) { 81 | response['token_type'] = tokenType; 82 | response['access_token'] = accessToken; 83 | response['playlistId'] = playlistId; 84 | response['userId'] = userId; 85 | return response; 86 | }); 87 | }; 88 | 89 | const prepareToaddAllSongsToPlaylist = response => { 90 | var songs = []; 91 | for (key in response) { 92 | if (isNumeric(key)) { 93 | songs.push(response[key].uri); 94 | } 95 | } 96 | return new Promise(resolve => { 97 | response['songs'] = songs; 98 | resolve(response); 99 | }); 100 | }; 101 | 102 | const addAllSongsToPlaylist = response => { 103 | var tokenType = response.token_type; 104 | var accessToken = response.access_token; 105 | var playlistId = response.playlistId; 106 | var userId = response.userId; 107 | var songs = response.songs; 108 | return new Promise(resolve => { 109 | post("https://api.spotify.com/v1/users/" + userId + "/playlists/" + playlistId + "/tracks", { 110 | Authorization: tokenType + ' ' + accessToken, 111 | "Content-type": "application/json" 112 | }, JSON.stringify({ 113 | uris: songs 114 | }), function(response) { 115 | resolve(response); 116 | }); 117 | }); 118 | }; 119 | 120 | function isNumeric(n) { 121 | return !isNaN(parseFloat(n)) && isFinite(n); 122 | } 123 | 124 | function buildSearchQuery(song) { 125 | return "q=" + song.title + 126 | "%20album:" + song.album + 127 | "%20artist:" + song.artist + 128 | "&type=track"; 129 | } -------------------------------------------------------------------------------- /2019/07/13/The-easiest-way-to-make-Let-s-Encrypt-renewal-automated/commands.sh: -------------------------------------------------------------------------------- 1 | cd letsencrypt/; ./letsencrypt-auto renew -------------------------------------------------------------------------------- /2019/07/13/The-easiest-way-to-make-Let-s-Encrypt-renewal-automated/readmeForLetsEncrypt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | now="$(date)" 3 | printf "Current date and time %s\n" "$now" 4 | cd letsencrypt/; ./letsencrypt-auto renew -------------------------------------------------------------------------------- /2019/09/11/what-is-a-pure-function-and-how-can-it-be-a-good-practice/ImPureFunctionWithGlobalMutation.java: -------------------------------------------------------------------------------- 1 | public class ImPureFunctionWithGlobalMutation { 2 | public static int accessAddFunctionCount = 0; 3 | public static int add(int a, int b) { 4 | accessAddFunctionCount++; 5 | return a + b; 6 | } 7 | public static void main(String [] args) { 8 | int c = add(10, 5); 9 | System.out.println(c); // 15 10 | c = add(5, 20); 11 | System.out.println(c); // 25 12 | } 13 | } -------------------------------------------------------------------------------- /2019/09/11/what-is-a-pure-function-and-how-can-it-be-a-good-practice/ImPureFunctionWithGlobalReturn.java: -------------------------------------------------------------------------------- 1 | public class ImPureFunctionWithGlobalReturn { 2 | public static int accessImpureAddFunctionCount = 0; 3 | public static int impureAdd(int a, int b) { 4 | accessImpureAddFunctionCount++; 5 | return a + b; 6 | } 7 | public static int getAccessImpureAddFunctionCount() { 8 | return accessImpureAddFunctionCount; 9 | } 10 | public static void main(String [] args) { 11 | int c = impureAdd(10, 5); 12 | System.out.println(c); // 15 13 | c = impureAdd(5, 20); 14 | System.out.println(c); // 25 15 | System.out.println(getAccessImpureAddFunctionCount()); // 2 16 | } 17 | } -------------------------------------------------------------------------------- /2019/09/11/what-is-a-pure-function-and-how-can-it-be-a-good-practice/ImPureFunctionWithReferenceArgumentMutation.java: -------------------------------------------------------------------------------- 1 | public class ImPureFunctionWithReferenceArgumentMutation { 2 | public static void append(ArrayList list, Integer a) { 3 | list.add(a); 4 | } 5 | public static void main(String [] args) { 6 | ArrayList list = new ArrayList<>(Arrays.asList(1, 3, 5, 7, 9)); 7 | System.out.println(list.size()); // 5 8 | append(list, 11); 9 | System.out.println(list.size()); // 6 10 | } 11 | } -------------------------------------------------------------------------------- /2019/09/11/what-is-a-pure-function-and-how-can-it-be-a-good-practice/PureFunction.java: -------------------------------------------------------------------------------- 1 | public class PureFunction { 2 | public static int add(int a, int b) { 3 | return a + b; 4 | } 5 | public static void main(String [] args) { 6 | int c = add(10, 5); 7 | System.out.println(c); // 15 8 | } 9 | } -------------------------------------------------------------------------------- /2019/09/13/why-using-a-global-variable-to-solve-Leetcode-problem-can-be-a-bad-idea/leetcodeTestCase.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode: 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.left = None 6 | # self.right = None 7 | 8 | class Solution: 9 | ans = [] 10 | def helper(self, root: TreeNode): 11 | if root is None: 12 | return 13 | self.ans.append(root.val) 14 | self.helper(root.left) 15 | self.helper(root.right) 16 | def preorderTraversal(self, root: TreeNode) -> List[int]: 17 | self.helper(root) 18 | return self.ans 19 | def evulateAnswer(result: List[int], correctAnswer: List[int]) -> bool: 20 | # ... 21 | def main(): 22 | testCases = [...] 23 | testCasesAnswer = [...] 24 | i = 0 25 | correctness = True 26 | for test in testCases: 27 | result = self.preorderTraversal(test) 28 | if evulateAnswer(result, testCasesAnswer[i]) is False: 29 | correctness = False 30 | break 31 | i = i + 1 32 | return correctness 33 | if __name__ == "__main__": 34 | main() -------------------------------------------------------------------------------- /2019/09/13/why-using-a-global-variable-to-solve-Leetcode-problem-can-be-a-bad-idea/simplePreorderTraversal.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode: 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.left = None 6 | # self.right = None 7 | 8 | class Solution: 9 | ans = [] 10 | def helper(self, root: TreeNode): 11 | if root is None: 12 | return 13 | self.ans.append(root.val) 14 | self.helper(root.left) 15 | self.helper(root.right) 16 | def preorderTraversal(self, root: TreeNode) -> List[int]: 17 | self.helper(root) 18 | return self.ans -------------------------------------------------------------------------------- /2020/09/13/how-to-make-an-automotive-wi-fi-plant-watering-system-that-is-connected-to-azure-iot-central/1 channel Plant Watering System with Arduino UNO R3 and ESP8266.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/poanchen/code-for-blog/6ed4bee910ff35fcf4e28c4fe80f5273b72c886f/2020/09/13/how-to-make-an-automotive-wi-fi-plant-watering-system-that-is-connected-to-azure-iot-central/1 channel Plant Watering System with Arduino UNO R3 and ESP8266.pdf -------------------------------------------------------------------------------- /2020/09/13/how-to-make-an-automotive-wi-fi-plant-watering-system-that-is-connected-to-azure-iot-central/Automotive Wi-Fi Plant Watering System.json: -------------------------------------------------------------------------------- 1 | { 2 | "@id": "urn:IoTProject:AutomotiveWiFiPlantWateringSystemV4_51y:1", 3 | "@type": "CapabilityModel", 4 | "implements": [ 5 | { 6 | "@id": "urn:IoTProject:AutomotiveWiFiPlantWateringSystemV4_51y:u09vydk92:1", 7 | "@type": "InterfaceInstance", 8 | "displayName": { 9 | "en": "Interface" 10 | }, 11 | "name": "AutomotiveWiFiPlantWateringSystemV4_3dv", 12 | "schema": { 13 | "@id": "urn:IoTProject:AutomotiveWiFiPlantWateringSystemV4_3dv:1", 14 | "@type": "Interface", 15 | "displayName": { 16 | "en": "Interface" 17 | }, 18 | "contents": [ 19 | { 20 | "@id": "urn:IoTProject:AutomotiveWiFiPlantWateringSystemV4_3dv:MoisturePercentage:1", 21 | "@type": "Telemetry", 22 | "displayName": { 23 | "en": "Moisture Percentage" 24 | }, 25 | "name": "MoisturePercentage", 26 | "schema": "integer", 27 | "unit": "percent" 28 | }, 29 | { 30 | "@id": "urn:IoTProject:AutomotiveWiFiPlantWateringSystemV4_3dv:PlantJustWatered:1", 31 | "@type": "Telemetry", 32 | "displayName": { 33 | "en": "Plant Just Watered" 34 | }, 35 | "name": "PlantJustWatered", 36 | "schema": "integer" 37 | } 38 | ] 39 | } 40 | } 41 | ], 42 | "displayName": { 43 | "en": "Automotive Wi-Fi Plant Watering System" 44 | }, 45 | "@context": [ 46 | "http://azureiot.com/v1/contexts/IoTModel.json" 47 | ] 48 | } -------------------------------------------------------------------------------- /2020/09/13/how-to-make-an-automotive-wi-fi-plant-watering-system-that-is-connected-to-azure-iot-central/sketch_aug23a.ino: -------------------------------------------------------------------------------- 1 | const int AirValue = 640; // you might need to calibrate this number, instruction is down below 2 | const int WaterValue = 353; // you might need to calibrate this number, instruction is down below 3 | const int SoilMoisturePin = A0; 4 | int soilMoistureValue = 0; 5 | int soilmoisturepercent = 0; 6 | 7 | void setup() { 8 | Serial.begin(115200); 9 | pinMode(SoilMoisturePin, INPUT); 10 | } 11 | 12 | void loop() { 13 | soilMoistureValue = analogRead(SoilMoisturePin); 14 | soilmoisturepercent = map(soilMoistureValue, AirValue, WaterValue, 0, 100); 15 | Serial.print(soilmoisturepercent); 16 | Serial.println("%"); 17 | delay(60000); 18 | } -------------------------------------------------------------------------------- /2020/09/13/how-to-make-an-automotive-wi-fi-plant-watering-system-that-is-connected-to-azure-iot-central/sketch_aug23b.ino: -------------------------------------------------------------------------------- 1 | const int AirValue = 640; // you might need to calibrate this number, instruction is down below 2 | const int WaterValue = 353; // you might need to calibrate this number, instruction is down below 3 | const int DrySoilMoisturePercentage = 50; 4 | const int SoilMoisturePin = A0; 5 | const int RelayPin = D2; 6 | int soilMoistureValue = 0; 7 | int soilmoisturepercent = 0; 8 | 9 | void setup() { 10 | Serial.begin(115200); 11 | pinMode(SoilMoisturePin, INPUT); 12 | pinMode(RelayPin, OUTPUT); 13 | digitalWrite(RelayPin, HIGH); 14 | } 15 | 16 | void loop() { 17 | soilMoistureValue = analogRead(SoilMoisturePin); 18 | soilmoisturepercent = map(soilMoistureValue, AirValue, WaterValue, 0, 100); 19 | Serial.print(soilmoisturepercent); 20 | Serial.println("%"); 21 | if (soilmoisturepercent <= DrySoilMoisturePercentage) { 22 | Serial.println("Water pumps running..."); 23 | digitalWrite(RelayPin, LOW); 24 | delay(5000); 25 | } 26 | Serial.println("Water pumps stopped..."); 27 | digitalWrite(RelayPin, HIGH); 28 | delay(60000); 29 | } -------------------------------------------------------------------------------- /2020/09/13/how-to-make-an-automotive-wi-fi-plant-watering-system-that-is-connected-to-azure-iot-central/sketch_aug23c.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | const int AirValue = 640; // you might need to calibrate this number, instruction is down below 5 | const int WaterValue = 353; // you might need to calibrate this number, instruction is down below 6 | const int DrySoilMoisturePercentage = 50; 7 | const int SoilMoisturePin = A0; 8 | const int RelayPin = D2; 9 | int soilMoistureValue = 0; 10 | int soilmoisturepercent = 0; 11 | int plantJustWatered = 0; 12 | 13 | void setup() { 14 | Serial.begin(115200); 15 | WiFi.begin("Wi-Fi name", "Wi-Fi password"); 16 | pinMode(SoilMoisturePin, INPUT); 17 | pinMode(RelayPin, OUTPUT); 18 | digitalWrite(RelayPin, HIGH); 19 | while (WiFi.status() != WL_CONNECTED) { 20 | delay(1000); 21 | Serial.println("Waiting for connection..."); 22 | } 23 | } 24 | 25 | void loop() { 26 | soilMoistureValue = analogRead(SoilMoisturePin); 27 | soilmoisturepercent = map(soilMoistureValue, AirValue, WaterValue, 0, 100); 28 | Serial.print(soilmoisturepercent); 29 | Serial.println("%"); 30 | plantJustWatered = 0; 31 | if (soilmoisturepercent <= DrySoilMoisturePercentage) { 32 | Serial.println("Water pumps running..."); 33 | digitalWrite(RelayPin, LOW); 34 | delay(3500); 35 | plantJustWatered = 1; 36 | } 37 | Serial.println("Water pumps stopped..."); 38 | digitalWrite(RelayPin, HIGH); 39 | if (WiFi.status() == WL_CONNECTED) { 40 | HTTPClient http; 41 | // get the Azure Functions url by following this doc, https://docs.microsoft.com/azure/azure-functions/functions-create-first-azure-function#test-the-function 42 | http.begin("http://iotc-fnce72a5dmyl4xs.azurewebsites.net/api/IoTCIntegration?code=1v//IKFDfdJKOdfdsoMKlkpJNOfdoOrpIWuystxtBHJUds=="); 43 | http.addHeader("Content-Type", "application/json"); 44 | // you can get your deviceId by going over this doc, https://docs.microsoft.com/azure/iot-central/core/concepts-get-connected#connect-a-single-device 45 | String moistureData = "{\"device\": {\"deviceId\": \"1wc1sdkminp\"},\"measurements\": {\"MoisturePercentage\": \"" + String(soilmoisturepercent) + "\", \"PlantJustWatered\": \"" + String(plantJustWatered) + "\"}}"; 46 | int httpCode = http.POST(moistureData); 47 | if (httpCode == 200) { 48 | Serial.println("Moisture data sent successfully..."); 49 | } else { 50 | Serial.println("Moisture data failed to send..."); 51 | } 52 | http.end(); 53 | } 54 | delay(60000); 55 | } -------------------------------------------------------------------------------- /2020/09/20/How-to-display-an-Alexa-rank-chart-in-your-website/addAlexaConfig.py: -------------------------------------------------------------------------------- 1 | import os 2 | config = {} 3 | 4 | # config for your site 5 | config["website"] = "https://poanchen.github.io" 6 | 7 | # config for your ifttt 8 | config["iftttApiEndpoint"] = "https://maker.ifttt.com/trigger/%s/with/key/%s" 9 | config["iftttEventName"] = "add_alexa_rank" 10 | config["iftttApiMakerKey"] = os.environ['IFTTTAPIMAKERKEY'] # get the key from https://ifttt.com/maker_webhooks/settings 11 | 12 | # config for alexa site 13 | config["alexaCli"] = 10 14 | config["alexaApiEndpoint"] = "http://data.alexa.com/data" -------------------------------------------------------------------------------- /2020/09/20/How-to-display-an-Alexa-rank-chart-in-your-website/addAlexaRank.py: -------------------------------------------------------------------------------- 1 | import requests, xml.etree.ElementTree as ET, sys 2 | execfile("config.py") 3 | CLI = config["alexaCli"] 4 | 5 | def getDefaultAlexaParams(url, cli=CLI): 6 | return """?cli=%d&url=%s""" % (cli, url) 7 | def getDefaultAlexaPostParams(gr, cn, cr): 8 | return {"value1": gr, "value2": cn, "value3": cr} 9 | def getGlobalRankIfAny(xml): 10 | try: 11 | return xml[0].find("POPULARITY").get("TEXT") 12 | except: 13 | pass 14 | def getCountryNameIfAny(xml): 15 | try: 16 | return xml[0].find("COUNTRY").get("NAME") 17 | except: 18 | pass 19 | def getCountryRankIfAny(xml): 20 | try: 21 | return xml[0].find("COUNTRY").get("RANK") 22 | except: 23 | pass 24 | 25 | if __name__ == "__main__": 26 | # getting site rank from Alexa api 27 | r = requests.get(config["alexaApiEndpoint"] + 28 | getDefaultAlexaParams(config["website"])) 29 | if r.status_code != requests.codes.ok: 30 | print "Alexa api end-point went wrong. Please try again later" 31 | sys.exit(0) 32 | 33 | # reading the xml and retrieve the rank 34 | xml = ET.fromstring(r.content) 35 | 36 | # trigger the ifttt api 37 | payload = getDefaultAlexaPostParams(getGlobalRankIfAny(xml), 38 | getCountryNameIfAny(xml), 39 | getCountryRankIfAny(xml)) 40 | r = requests.post(config["iftttApiEndpoint"] % \ 41 | (config["iftttEventName"], config["iftttApiMakerKey"]), 42 | data=payload) 43 | if r.status_code != requests.codes.ok: 44 | print "Ifttt api end-point went wrong. Please try again later" 45 | sys.exit(0) 46 | print "yaa, entry has been added to your Google spreadsheet" 47 | -------------------------------------------------------------------------------- /2020/09/20/How-to-display-an-Alexa-rank-chart-in-your-website/alexaRank.html: -------------------------------------------------------------------------------- 1 |

Alexa rank

2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /2020/09/20/How-to-display-an-Alexa-rank-chart-in-your-website/downloadAlexaRank.py: -------------------------------------------------------------------------------- 1 | import requests, csv, re 2 | execfile("config.py") 3 | 4 | # Download the sheets 5 | print "Beginning to download the CSV from Google Sheets" 6 | r = requests.get(config['excelDownloadUrl']) 7 | open(config['excelFileName'], 'wb').write(r.content) 8 | print "Finished downloading the sheets..." -------------------------------------------------------------------------------- /2020/09/20/How-to-display-an-Alexa-rank-chart-in-your-website/getAlexaRank.py: -------------------------------------------------------------------------------- 1 | import requests, xml.etree.ElementTree as ET, sys 2 | execfile("config.py") 3 | CLI = config["alexaCli"] 4 | 5 | def getDefaultAlexaParams(url, cli=CLI): 6 | return """?cli=%d&url=%s""" % (cli, url) 7 | def getGlobalRankIfAny(xml): 8 | try: 9 | return xml[0].find("POPULARITY").get("TEXT") 10 | except: 11 | pass 12 | def getCountryNameIfAny(xml): 13 | try: 14 | return xml[0].find("COUNTRY").get("NAME") 15 | except: 16 | pass 17 | def getCountryRankIfAny(xml): 18 | try: 19 | return xml[0].find("COUNTRY").get("RANK") 20 | except: 21 | pass 22 | 23 | if __name__ == "__main__": 24 | # getting site rank from Alexa api 25 | r = requests.get(config["alexaApiEndpoint"] + 26 | getDefaultAlexaParams(config["website"])) 27 | if r.status_code != requests.codes.ok: 28 | print "Alexa api end-point went wrong. Please try again later" 29 | sys.exit(0) 30 | 31 | # reading the xml and retrieve the rank 32 | xml = ET.fromstring(r.content) 33 | 34 | print(getGlobalRankIfAny(xml)) # for example, 523849 35 | print(getCountryNameIfAny(xml)) # for example, United States 36 | print(getCountryRankIfAny(xml)) # for example, 359604 37 | -------------------------------------------------------------------------------- /2020/09/20/How-to-display-an-Alexa-rank-chart-in-your-website/parseAlexaRank.py: -------------------------------------------------------------------------------- 1 | # Convert CSV to JSON (Including Data Decimation) 2 | import json 3 | print "Converting CSV to JSON format..." 4 | months = ['March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December', 'January', 'February'] 5 | i = 0 6 | json_data = [] 7 | been_throughed_months = set() 8 | with open(config['excelFileName']) as csvDataFile: 9 | csvReader = csv.reader(csvDataFile) 10 | for row in csvReader: 11 | matchDate = re.match(r'^(%s) (\d*),\s(\d*)\sat\s\d\d:\d\d[AP]M' % months[i % 12], row[0]) 12 | if matchDate and int(matchDate.group(2)) >= 10: 13 | date_and_time = matchDate.group(1) + ', ' + matchDate.group(3) 14 | if (date_and_time not in been_throughed_months and row[1] != '' and row[2] != '' and row[3] != '') or int(matchDate.group(2)) == 28: 15 | json_data.append({ 16 | "Date and Time" : date_and_time, 17 | "Global Rank" : int(row[1]), 18 | "Top Ranked Country" : row[2] if row[2] != '' else "", 19 | "Country Rank" : int(row[3]) if row[3] != '' else "", 20 | }) 21 | been_throughed_months.add(date_and_time) 22 | i = i + 1 23 | print "Finished converting...Time to write to a file and save as JSON" 24 | full_file_name = config['excelFileName'] +\ 25 | "." +\ 26 | config['excelFileExtension'] 27 | open(full_file_name, 'wb').write(json.dumps(json_data)) 28 | print "Finished writing." -------------------------------------------------------------------------------- /2020/09/20/How-to-display-an-Alexa-rank-chart-in-your-website/uploadAlexaConfig.py: -------------------------------------------------------------------------------- 1 | import os 2 | config = {} 3 | 4 | config['excelDownloadUrl'] = "urlToYourGoogleSheet" # for example, "https://docs.google.com/spreadsheets/d/XXXXXXXXXXXXX/export?format=csv" 5 | config['excelFileName'] = "poanchen - alexa" 6 | config['excelFileExtension'] = "json" 7 | config['excelFilePath'] = "./" 8 | 9 | # Azure Portal 10 | config['accountName'] = "poanchengithubio" 11 | config['accountKey'] = os.environ['AZUREPORTALACCOUNTKEY'] # get the key from https://portal.azure.com 12 | 13 | # Azure Blob Storage 14 | config['containerName'] = "poanchen" 15 | -------------------------------------------------------------------------------- /2020/09/20/How-to-display-an-Alexa-rank-chart-in-your-website/uploadAlexaRank.py: -------------------------------------------------------------------------------- 1 | # Upload the JSON file to my Azure Blob Storage 2 | from azure.storage.blob import BlockBlobService 3 | print "Beginning to upload the JSON file" 4 | blob_service = BlockBlobService(config['accountName'], config['accountKey']) 5 | full_path_to_file = config['excelFilePath'] +\ 6 | full_file_name 7 | blob_service.create_blob_from_path( 8 | config['containerName'], 9 | full_file_name, 10 | full_path_to_file) 11 | print "Finished uploading the JSON file" -------------------------------------------------------------------------------- /2020/10/23/how-to-activate-virtual-environment-in-powershell/activateVirtualEnvironment.sh: -------------------------------------------------------------------------------- 1 | .\.venv\Scripts\Activate -------------------------------------------------------------------------------- /2020/10/27/How-to-prepopulate-GitHub-issue-to-make-people-life-easier-in-jekyll/afterrender.txt: -------------------------------------------------------------------------------- 1 | Hey poanchen, 2 | 3 | I found an issue where [Enter feedback here]. 4 | 5 | --- 6 | 7 | Blog title: How to prepopulate GitHub issue to make people's life easier in Jekyll? 8 | Site URL: https://poanchen.github.io/blog/2020/10/27/How-to-prepopulate-GitHub-issue-to-make-people-life-easier-in-jekyll 9 | Blog Date: 2020-10-27 01:30:30 -0700 -------------------------------------------------------------------------------- /2020/10/27/How-to-prepopulate-GitHub-issue-to-make-people-life-easier-in-jekyll/beforerender.txt: -------------------------------------------------------------------------------- 1 | Hey {{ page.author }}, 2 | 3 | I found an issue where [Enter feedback here]. 4 | 5 | --- 6 | 7 | Blog title: {{ page.title }} 8 | Site URL: {{ site.url }}{{ page.url }} 9 | Blog Date: {{ page.date }} -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # code-for-blog 2 | 3 | This repository collects code samples linked from my [blog](https://poanchen.github.io/blog/). 4 | 5 | [![ko-fi](https://www.ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/J3J3ZC9H) 6 | 7 | 8 | --------------------------------------------------------------------------------