Featured Blog Posts - TechHui2024-03-29T13:19:34Zhttp://www.techhui.com/profiles/blog/feed?promoted=1&xn_auth=no#MyCorona (parody of My Sharona)tag:www.techhui.com,2020-05-05:1702911:BlogPost:1589992020-05-05T17:25:49.000ZSherry Lorancehttp://www.techhui.com/profile/SherryLorance
<p>Ooh my little sneaky one, my infections one</p>
<p>When you gonna let me socialize, Corona!</p>
<p>Ohh you make my body ache, my breath shallow</p>
<p>Got to isolate myself- thank you Rona!</p>
<p> </p>
<p>When’s this gonna stop, give it up, such a sneaky one</p>
<p>Gonna take my temp, to see if I’m getting worse</p>
<p>My, my, my, aye-aye- cough!</p>
<p>M-m-m-my Corona!</p>
<p> </p>
<p>Stay six feet away, huh a-will ya, huh?</p>
<p>Far enough away to not catch my Corona</p>
<p>Keeping it…</p>
<p>Ooh my little sneaky one, my infections one</p>
<p>When you gonna let me socialize, Corona!</p>
<p>Ohh you make my body ache, my breath shallow</p>
<p>Got to isolate myself- thank you Rona!</p>
<p> </p>
<p>When’s this gonna stop, give it up, such a sneaky one</p>
<p>Gonna take my temp, to see if I’m getting worse</p>
<p>My, my, my, aye-aye- cough!</p>
<p>M-m-m-my Corona!</p>
<p> </p>
<p>Stay six feet away, huh a-will ya, huh?</p>
<p>Far enough away to not catch my Corona</p>
<p>Keeping it all for me, it’s just for me</p>
<p>Running the length of its course- Corona</p>
<p> </p>
<p>When’s this gonna stop, give it up, such a sneaky one</p>
<p>Gonna take my temp, to see if I’m getting worse</p>
<p>My, my, my, aye-aye- cough!</p>
<p>M-m-m-my Corona!</p>
<p>M-m-m-my Corona!</p>
<p> </p>
<p>When you going to leave me, to leave me</p>
<p>I know it’s just a matter of time Corona</p>
<p>Or will you still be plaguing me, a plaguing me</p>
<p>Or will we find a cure- Corona?</p>
<p> </p>
<p>When’s this gonna stop, give it up, such a sneaky one</p>
<p>Gonna take my temp, to see if I’m getting worse</p>
<p>My, my, my, aye-aye- cough!</p>
<p>M-m-m-my Corona!</p>
<p>M-m-m-my Corona!</p>
<p>M-m-m-my Corona!</p>
<p>M-m-m-my Corona!</p>
<p> </p>
<p>Ooooooooo-ohhh, my Corona!</p>
<p>Ooooooooo-ohhh, my Corona!</p>
<p>Ooooooooo-ohhh, my Corona!</p>Using Touch ID to separate bots from humans in social mediatag:www.techhui.com,2018-04-09:1702911:BlogPost:1497132018-04-09T03:47:38.000ZAugusto Callejashttp://www.techhui.com/profile/AugustoCallejas
<p>Whenever you’re on a social network, like Facebook or Twitter, you know who your friends and family are. However, there are many accounts that you don’t know personally, which can be bots. How can you tell bot from human? This a general issue beyond just social media. Google supports an approach to this called <a href="https://en.wikipedia.org/wiki/ReCAPTCHA">reCAPTCHA</a> which can require a user doing a task that a human can do better than a bot. However, when posting to a social network,…</p>
<p>Whenever you’re on a social network, like Facebook or Twitter, you know who your friends and family are. However, there are many accounts that you don’t know personally, which can be bots. How can you tell bot from human? This a general issue beyond just social media. Google supports an approach to this called <a href="https://en.wikipedia.org/wiki/ReCAPTCHA">reCAPTCHA</a> which can require a user doing a task that a human can do better than a bot. However, when posting to a social network, this process would be tedious and lead to lower engagement. Apple’s Touch ID may be able to help.</p>
<p>Apple introduced <a href="https://en.wikipedia.org/wiki/Touch_ID">Touch ID</a> in 2013 to allow users to quickly unlock their phones and download apps without having to re-enter their password. It was <a href="https://techcrunch.com/2014/06/02/apple-touch-id/">extended</a> to all app developers in 2014 so they could store secure credentials that could only be unlocked with a fingerprint.</p>
<p>The proposal is to use Touch ID (and potentially <a href="https://en.wikipedia.org/wiki/Face_ID">Face ID</a>, which was introduced in 2017) as a way to uniquely confirm a human is behind every social media post. Storing secure credentials would not work because they are known to the user, and hence to a bot developer. Instead, the proposal is to allow an app developer (and hence Twitter and Facebook) the ability to provide a timestamped server-generated message that needs to be encrypted via a hardware key that is only available during a finger press. That encrypted message is then sent back to the app developer’s server, where it is decrypted from a list of public keys based on device model and operating system version. If the decrypted message matches the original server message, then the app developer knows that a genuine human confirmed the operation, and the social media post can be accepted. The whole process would need to occur within a certain amount of time, like 30 seconds, in order to stop malicious users from accumulating many encrypted messages in order to spam the network.</p>
<p>This idea is currently not supported by Touch ID, but would require an upgrade allowing device-specific private keys to be stored on the device and public keys to be made available for app developers to confirm encrypted messages. In order to spur adoption among major social networks, the confirmation mechanism would need to be standardized so other hardware providers can implement it on their own hardware. Initially, this could be an optional feature, allowing accounts with more “Touch ID” confirmed posts to be displayed prominently. In the future, users should be able to display only confirmed posts, to ensure their social media feed is bot-free.</p>
<p><em>This post was originally posted on my <a href="https://www.augustocallejas.com/2018/04/08/touch-id/" target="_blank" rel="noopener">blog</a>.</em></p>About $90,000 in prizes awarded on October 21! Hope you guys can join us.tag:www.techhui.com,2017-09-28:1702911:BlogPost:1465432017-09-28T20:13:51.000ZOlin Lagonhttp://www.techhui.com/profile/OlinLagon123
<p dir="ltr"><iframe allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/MmpEiWsVO_U?wmode=opaque" width="560"></iframe>
</p>
<p dir="ltr"><span><a href="http://storage.ning.com/topology/rest/1.0/file/get/396587800?profile=original" target="_self"><img class="align-right" src="http://storage.ning.com/topology/rest/1.0/file/get/396587800?profile=RESIZE_320x320" width="300"></img></a> Since March there’s been a competition going on, called the Purple Prize, that asks tech developers to team up with cultural practitioners to innovate technologies that serve Hawaiian culture and Hawaiʻi.…</span></p>
<p dir="ltr"><iframe width="560" height="315" src="https://www.youtube.com/embed/MmpEiWsVO_U?wmode=opaque" frameborder="0" allowfullscreen=""></iframe> </p>
<p dir="ltr"><span><a href="http://storage.ning.com/topology/rest/1.0/file/get/396587800?profile=original" target="_self"><img src="http://storage.ning.com/topology/rest/1.0/file/get/396587800?profile=RESIZE_320x320" width="300" class="align-right"></a>Since March there’s been a competition going on, called the Purple Prize, that asks tech developers to team up with cultural practitioners to innovate technologies that serve Hawaiian culture and Hawaiʻi. The winners will be selected in October.</span></p>
<p>The Purple Prize is only two years old and is run by the small team at technology education nonprofit Purple Maiʻa Foundation. But it’s one of the biggest competitions in Hawaiʻi if you measure by how much prize money is given away. This year they say they’ll be giving out $90K or more in prizes (cash and cloud service credits).</p>
<p dir="ltr"><span>The words “technology innovation” usually bring to mind things like flying cars, the latest smartphone, or futuristic space stations, but the Purple Prize encourages participants to think about innovation as working to solve problems faced by your local community and your environment.</span></p>
<p>This year, the 12 competing teams are working on projects that have to do with things like monitoring loko iʻa (traditional Hawaiian fishponds), gathering and visualizing data about ecosystems, connecting consumers to healthy food, and sharing moʻolelo (stories) about significant places. The teams all relate their work to this year’s competition theme: Waiwai (value).</p>
<p>Last year, 6 teams competed with projects inspired by the theme aloha ʻāina (love of the land). The top three winning teams were working on wetland censors, a kid’s game app about the watershed called <a href="https://play.google.com/store/apps/details?id=com.halepili.waiwai&hl=en">Waiwai</a>, and a wearable technology that helps you learn Hawaiian rain names.</p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/396589058?profile=original" target="_self"><img src="http://storage.ning.com/topology/rest/1.0/file/get/396589058?profile=RESIZE_1024x1024" width="750" class="align-center"></a></p>
<p></p>
<p>This year’s winners will be chosen on Oct. 21 at UH West Oʻahu. The public and especially students are welcome to check out all the teams, have lunch, and stay for other programming about innovation taking place throughout the day. There is also a pau hana networking event planned for Oct. 19 in Mōʻiliʻili. Watch <a href="http://www.purpleprize.com">www.purpleprize.com</a> for details.</p>H-1B Visas: Large firms exploit visa system flaw, exclude start-ups and small firmstag:www.techhui.com,2015-11-12:1702911:BlogPost:1375452015-11-12T02:27:15.000ZJohn Robert Eganhttp://www.techhui.com/profile/JohnEgan
<p>The H-1B visa is commonly known as the Professional Worker's Visa and has been heavily used in the finance and tech industries as a tool for recruiting top international talent into information technology, software engineering and other specialized jobs in the information economy. A recent article in the New York Times, headlined <a href="http://www.nytimes.com/2015/11/11/us/large-companies-game-h-1b-visa-program-leaving-smaller-ones-in-the-cold.html" rel="nofollow" target="_blank">"Large…</a></p>
<p>The H-1B visa is commonly known as the Professional Worker's Visa and has been heavily used in the finance and tech industries as a tool for recruiting top international talent into information technology, software engineering and other specialized jobs in the information economy. A recent article in the New York Times, headlined <a href="http://www.nytimes.com/2015/11/11/us/large-companies-game-h-1b-visa-program-leaving-smaller-ones-in-the-cold.html" target="_blank" rel="nofollow">"Large Companies Game H-1B Visa Program"</a> details the process whereby a small number of outsourcing companies have successfully exploited a flaw in the way the visa system is operated to capture a disproportionate share of the annual quota of these visas. The result is that small firms, start-ups and other legitimate applicants are being squeezed out of the program.</p>
<p>This matters very much to business in places like Hawaii, where essentially all of our businesses are small, relatively speaking, and concerted efforts are underway to foster a viable tech business community. Local entrepreneurs find themselves locked out of the international talent pool, and our academic engineering programs, where upwards of 50% of graduating PhD students are foreign students, cannot place their best students into local jobs. This in turn impacts <a href="http://www.civilbeat.com/2013/11/20479-hawaii-loses-money-as-international-student-population-shrinks/" target="_blank" rel="nofollow">the ability of local universities and colleges to recruit foreign students</a>. Places like Hawaii <a href="http://www.kauffman.org/what-we-do/research/2014/03/lessons-for-us-metro-areas-characteristics-and-clustering-of-high-tech-immigrant-entrepreneurs" target="_blank" rel="nofollow">need to be talent magnets to compete in the global marketplace,</a> but need a level playing field to stay in the game.</p>
<p>The visa system flaw is quite simple. Individuals may only submit a single application, duplicates are rejected. Firms on the other hand, may submit as many applications as they wish, as long as each is for a single individual. So the large outsourcing firms working the visa game make job offers to literally thousands of workers, predominately in India, contingent on getting a visa. They know they will receive only third of these, but are able to spread the costs over the whole field of newly visaed workers as they place them in batches into contract labor positions for companies such as Disney and Toy R Us.</p>
<p>Why does this disadvantage small firms? A small innovative start-up is looking for the one "best fit" team member who adds a specific talent or expertise to the enterprise build-out. Each highly skilled tech worker on the start-up team is a key component of the product or service development process. A one-in-three chance of success in obtaining a working visa for your employee of choice introduces additional costs and a frustrating uncertainty and instability into the human resources scaling process. For the outsourcing firms on the other hand, skilled workers are the product itself, and at the level they operate on, are essentially fungible. Functioning as high tech temp agencies, they are renting out a generic skill-set and resume, that just incidentally has a human being attached to it.</p>
<p>The entire U.S. employment visa system is ripe for reform, but the political action needed does not look likely in the near term. With the types of exploitation being practiced by the outsourcing firms, along with the many other negative effects of visa abuse, the whole H-1B visa program is getting a bad name.</p>
<p><em>John Robert Egan is an Immigration Lawyer practicing in Honolulu, and can be reached at <a target="_blank" rel="nofollow">jegan@migrationcounsel.com</a></em></p>Free Developer Tools on Windowstag:www.techhui.com,2015-08-14:1702911:BlogPost:1353462015-08-14T03:30:00.000ZDouglas Chinghttp://www.techhui.com/profile/DouglasChing
<p>It used to be that to develop with Microsoft technologies developers would have to pay up for development tools if they wanted the best experience. These days with all the options developers have, getting someone to pay for tools can be difficult.<br></br> <br></br> Recently I wiped of one of my development machines and realized this is no longer the case while installing various tools. <br></br> <br></br> It's well known that Microsoft has been moving towards open sourcing many of their projects like…</p>
<p>It used to be that to develop with Microsoft technologies developers would have to pay up for development tools if they wanted the best experience. These days with all the options developers have, getting someone to pay for tools can be difficult.<br/> <br/> Recently I wiped of one of my development machines and realized this is no longer the case while installing various tools. <br/> <br/> It's well known that Microsoft has been moving towards open sourcing many of their projects like their .net framework, but beyond that they have also been providing more options for free tools and services. To be clear many of these free tools are aimed toward home users, individuals and small teams. Larger businesses still need to pay for the appropriate licensed product.<br/> <br/> <strong>Windows 10</strong></p>
<p>Microsoft has made Windows 10 a free upgrade (if you upgrade within the offer's time period) for individual users who have Windows 7 or Windows 8. When Windows 8 came out one of the major developer complaints is that in order to develop for Windows 8 and the new Windows Store you needed a machine with Windows 8. That meant buying a new computer or paying for a Windows 8 license. By making Windows 10 free for Windows 7 and 8 users Microsoft is trying to lower the barrier for developers.<br/> <br/> <strong>Visual Studio</strong><br/> <a href="http://www.visualstudio.com">http://www.visualstudio.com</a></p>
<p>I remember having to purchase Visual Studio or MSDN just to get Visual Studio. A free Visual Studio is not new. Ever since 2010 Microsoft has offered Express versions of Visual Studio, but they were always heavily restricted in features. At the end of 2014 Microsoft started offering Visual Studio Community 2013 for free. The Community edition is very close to the Professional version and can be used by "individual developers, open source projects, academic research, training, education and small professional teams". VS.net Community 2015 also includes features that allow developers to create Android and other non-Windows apps as well as Data Tools that have usually been reserved for the higher level versions.<br/> <br/> <strong>Visual Studio Code</strong><br/> <a href="http://www.visualstudio.com/products/code-vs.aspx">http://www.visualstudio.com/products/code-vs.aspx</a></p>
<p>Visual Studio Code is a code editor that is cross platform (Windows, OSX, Linux). It is not like Visual Studio. Instead it is similar to other code editors like Sublime, Atom and Brackets. It is based around the same code that the Atom editor (atom.io) uses. Why would someone use VS Code? The main reason would be because it is built to work well with ASP.NET 5 which is also planned to work on Windows, OSX and Linux when released. That's not to say it doesn't work well with other development frameworks. I've used VS Code to update Node, TypeScript and Python and it plays well with many other languages.<br/> <br/> <strong>SQL Server</strong><br/> <a href="http://www.microsoft.com/en-us/server-cloud/products/sql-server-editions/sql-server-express.aspx">http://www.microsoft.com/en-us/server-cloud/products/sql-server-editions/sql-server-express.aspx</a></p>
<p>SQL Server has always been a tough one to get for free. There has been various free versions available over the years, but they have always been very lacking and it's always been hard to get the management tools without getting your hands on one of the full versions. Over the years the Express version has gotten better and with the current SQL Server Express version developers can get functionality that is close to the full versions, but with restricted database size, CPU and memory utilization. They have also made available the management studio that allows developers to manage SQL databases.<br/> <br/> Of course SQL Server Express isn't going to include many of the advanced features of SQL Server. For developers who do need SQL Server that matches production environments closely Microsoft still sells SQL Server Developer edition <a href="http://www.microsoftstore.com/store/msusa/en_US/pdp/SQL-Server-2014-Developer-Edition/productID.298540400">http://www.microsoftstore.com/store/msusa/en_US/pdp/SQL-Server-2014-Developer-Edition/productID.298540400</a><br/> <br/> <strong>Azure</strong><br/> <a href="http://azure.microsoft.com">http://azure.microsoft.com</a></p>
<p>For developers who build web apps or services Microsoft offers some free Azure services. In particular you can publish 10 web sites to Azure for free. It's a good service to use for web site development if you don't want to pay for hosting.<br/> <br/> <strong>Other Great Tools</strong><br/> Besides the Microsoft backed tools above there are a lot of other free tools that I use.<br/> <br/> <strong>GitHub Desktop</strong><br/> <a href="https://desktop.github.com/">https://desktop.github.com/</a></p>
<p>Git has become the source control of choice for many developers. I like GitHub Destkop because it's easy to install and easy to use. If you are someone that doesn't like the command line this one is a good Git client, however it would still benefit you to learn the git command line commands.<br/> <br/> <strong>Atom</strong><br/> <a href="https://atom.io/">https://atom.io/</a></p>
<p>Atom has become my favorite code editor that is not a full fledged IDE.<br/> <br/> <strong>Notepad++</strong><br/> <a href="https://notepad-plus-plus.org/">https://notepad-plus-plus.org/</a></p>
<p>Every developer who has used Windows has probably downloaded Notepad++. It's the app I install to avoid having to use Notepad. Even though I don't use it for coding I like it as a quick editor.</p>
<p></p>
<p>I'd be interested in hearing if anyone has any other good developer tools for Windows or what tools developers on OSX and Linux love to use.</p>Our Immigration System Sucks – Is There a Tech Fix?tag:www.techhui.com,2015-08-07:1702911:BlogPost:1353392015-08-07T20:19:51.000ZJohn Robert Eganhttp://www.techhui.com/profile/JohnEgan
<p>Sooner or later, everyone who is in the tech field for the long run bumps up against the U.S. immigration system. The tech talent pool is global, our engineering schools have plenty of international grads looking to be placed into U.S. jobs, and smart international investors are looking for U.S. tech entrepreneurs to back. And the unanimous reaction to the immigration encounter is “the U.S. immigration system really sucks!”</p>
<p>A …</p>
<p>Sooner or later, everyone who is in the tech field for the long run bumps up against the U.S. immigration system. The tech talent pool is global, our engineering schools have plenty of international grads looking to be placed into U.S. jobs, and smart international investors are looking for U.S. tech entrepreneurs to back. And the unanimous reaction to the immigration encounter is “the U.S. immigration system really sucks!”</p>
<p>A <a href="http://www.wired.com/2015/07/us-digital-service-immigration/http://" target="_blank">recent article in Wired</a> skips over the convoluted politics of immigration reform (it’s really going nowhere) and looks at recent attempts by the federal <a href="https://playbook.cio.gov/" target="_blank">U.S. Digital Service</a> to tech-up the process itself. On first glance, they were floored by the amount of paper (yes, ground-up dead trees are still the foundational mode of communication in the immigration system) being shuffled from office to office. And then they looked at the heavily silo-ed transactional processes that prevent effective collaboration and information sharing, and began to recognize just how entrenched and calcified existing bad practices have become.</p>
<p>So have the engineers got a fix for all this? Let’s hope so, but I’m not holding my breath. The <a href="https://www.whitehouse.gov/blog/2015/07/15/bringing-our-immigration-system-digital-age" target="_blank">report delivered to the White House</a> sums up the present state of affairs pretty accurately - “currently, applicants face unnecessary ambiguity and confusion around how each step in the application process fits into the process as a whole, and lack of awareness of how to succeed.” I think if the Digital Service succeeds in their task of rationalizing and digitizing the immigration system there will be a whole lot less need for immigration lawyers like me to lead clients through the maze. Which, truth be told, would be a very good thing for everyone involved. Higher productivity, increased transparency, better predictability for innovative start-ups, and lower transactional costs overall can’t be bad. And I expect to be retired by then.</p>Continuous Delivery with WordPresstag:www.techhui.com,2015-08-03:1702911:BlogPost:1322492015-08-03T18:48:50.000ZDavid Chunghttp://www.techhui.com/profile/DavidChung
<p>As a continuation of my blog posts regarding continuous delivery, I shall explore the continuous delivery options for WordPress websites since I was recently been involved in such a project.</p>
<p>One changing component of a WordPress website is its templates, which are written in PHP. This PHP source can be version controlled quite easily and integrated with a continuous delivery system.</p>
<p>However, another changing component of a WordPress website is its plugins and their…</p>
<p>As a continuation of my blog posts regarding continuous delivery, I shall explore the continuous delivery options for WordPress websites since I was recently been involved in such a project.</p>
<p>One changing component of a WordPress website is its templates, which are written in PHP. This PHP source can be version controlled quite easily and integrated with a continuous delivery system.</p>
<p>However, another changing component of a WordPress website is its plugins and their configurations, which are stored in the database. Version control of these configurations will require managing the data.</p>
<h1>WordPress Hurdles</h1>
<p>Continuous delivery with WordPress is made difficult with the fact that its configuration is done through the database exclusively with the exception of the configuration of connecting to the database itself.</p>
<p>Another hurdle is that the content is not easily manageable.</p>
<p>For continuous delivery, you will rebuild the WordPress website using a specified core version, a specified list of plugins to install, a version-controlled database, and a maintained uploaded content directory.</p>
<h1>Version Control</h1>
<p>The branching strategy here would be similar to that mentioned in <a href="http://www.techhui.com/profiles/blogs/continuous-delivery-with-ruby-on-rails-and-heroku/" target="_blank">my continuous delivery post with Ruby on Rails and Heroku</a>.</p>
<p>Since the WordPress website is being built from scratch and WordPress is unfortunately configured via database entries, the following should be in version control:</p>
<ul>
<li>the MySQL database dump</li>
<li>list of plugins need</li>
<li>URL to desired WordPress core to install</li>
</ul>
<p><br/> The MySQL database dump should also include DROP TABLE statements. Simply run mysqldump with default settings to generate such a dump.<br/> <br/> The plugins list is simply a text file containing the URLs to the plugin zip file separated by newlines. Unless a specific version is needed, the plugins need to point to the URL that contains the latest plugin zip file. For example, use “<a href="https://downloads.wordpress.org/plugin/some-plugin.zip">https://downloads.wordpress.org/plugin/some-plugin.zip</a>” instead of “<a href="https://downloads.wordpress.org/plugin/some-plugin-1.0.0.zip">https://downloads.wordpress.org/plugin/some-plugin-1.0.0.zip</a>.”</p>
<h1>Continuous Integration</h1>
<p>The build server needs the following, which doesn’t necessarily need to be in version control:</p>
<ul>
<li>Apache server with mod_rewrite</li>
<li>MySQL with a database for the project</li>
<li>PHP with the appropriate Apache modules</li>
<li>.htaccess file for the web root directory containing:<ul>
<li><IfModule mod_rewrite.c></li>
<li>RewriteEngine On</li>
<li>RewriteBase /{root}</li>
<li>RewriteRule ^index\.php$ - [L]</li>
<li>RewriteCond %{REQUEST_FILENAME} !-f</li>
<li>RewriteCond %{REQUEST_FILENAME} !-d</li>
<li>RewriteRule . /{root}/index.php [L]</li>
<li></IfModule></li>
</ul>
</li>
<li>A zip file containing the uploaded content</li>
<li>wp-config.php containing the necessary database credentials</li>
</ul>
<p>However, we maintain the following in version control:</p>
<ul>
<li>data.sql (the MySQL database dump from above)</li>
<li>wordpress (single line of WP URL to download and install)</li>
<li>plugins (multiple lines of plugin URLs to download and install)</li>
<li>wp-content/ (your work)</li>
</ul>
<p>And so, the following is a suggested build configuration:</p>
<ol>
<li>Clear out the target test web directory (for websites with large content, you may want to move the contents directory: wp-content/uploads to restore later to speed up the process)</li>
<li>Download the latest WordPress core at: <a href="https://wordpress.org/latest.tar.gz">https://wordpress.org/latest.tar.gz</a></li>
<li>If the project requires a specific WordPress core version, find what you need here: <a href="https://wordpress.org/download/release-archive/">https://wordpress.org/download/release-archive/</a></li>
<li>Extract the WordPress core to the target test web directory</li>
<li>Copy the held wp-config.php to the root of the target test web directory</li>
<li>Copy the work to the target test web directory</li>
<li>For each entry in the plugins list, download and extract the plugin to the wp-contents/plugins directory</li>
<li>Extract the uploaded content and copy it to the wp-content/uploads directory</li>
<li>Populate the test database with the database dump in version control</li>
<li>Output the URL to access the test WordPress website.</li>
</ol>
<p><br/> After a successful build, the build server should have a working WordPress website in some web directory. The build configuration should provide the URL for a user to access for testing.<br/> <br/> To ease the development and deployment process, consider making use of development and release branches.</p>
<h1>Development Branch</h1>
<p>The development branch shall attempt to provide the opportunity for developers to sync with production content.<br/> <br/> The build configuration is modified to also include the step of downloading the uploads directory and obtain a database dump from the production site. These artifacts are then stored on the build server for retrieval and possible integration with the codebase.<br/> <br/> Specifically, regarding the database:</p>
<ol>
<li>The build configuration uses the data dump in version control first to apply any non-WordPress data.</li>
<li>Then the build configuration will use the data dump from production to populate the WordPress data.</li>
<li>Finally, the build configuration dumps the resulting database from the above and stores it as a build artifact.</li>
<li>Developers then use this artifact to synchronize the data dump in version control so that developers working off from the development branch can have access to the latest production data (note that this data does not necessarily include content)</li>
</ol>
<h1>Staging Branch</h1>
<p>The staging branch shall include database configuration changes to be deployed to production.<br/> <br/> The build configuration is similar to the development branch’s build configuration except that it doesn’t sync with the production database since the staging environment is intended to replace what’s currently in production. Thus, the staging environment is meant to stage the next production iteration.<br/> <br/> In lieu of an explicit staging branch, the development branch can be used. In this case, there would be two build configurations: one for development that syncs its database with what’s in production and the other for staging that does not sync with the production database.</p>
<h1>Master Branch</h1>
<p>Note that the build configuration in the development branch does not affect the volatile data in production. That is, the uploads directory or the database.<br/> <br/> However, the release branch is an opportunity for developers to push their changes to production as a deployment even in the database!<br/> <br/> The build configuration for the release branch blows away the current instance and builds the site from scratch.<br/> <br/> Thus, the flow for a deployment is to synchronize the development branch with production and then trigger the release.<br/> <br/> The build configuration shall keep a running backup of current data dumps before running the deployment so that the instance can be rolled back as needed.</p>JavaScript Game Enginestag:www.techhui.com,2015-06-17:1702911:BlogPost:1343212015-06-17T21:52:54.000ZDouglas Chinghttp://www.techhui.com/profile/DouglasChing
<p dir="ltr"><span>Recently I’ve been interested in games created using JavaScript. JavaScript is everywhere and works with a lot of devices and platforms including mobile devices that run on iOS, Android, Windows and FirefoxOS. On the web seems that games using HTML and JavaScript have started to replace those using older technologies like Flash. Here is a list of JavaScript libraries that I have seen recommended for creating games. To compile this list I looked at libraries that are free,…</span></p>
<p dir="ltr"><span>Recently I’ve been interested in games created using JavaScript. JavaScript is everywhere and works with a lot of devices and platforms including mobile devices that run on iOS, Android, Windows and FirefoxOS. On the web seems that games using HTML and JavaScript have started to replace those using older technologies like Flash. Here is a list of JavaScript libraries that I have seen recommended for creating games. To compile this list I looked at libraries that are free, preferably open source, actively updated and focuses mainly on 2D.</span></p>
<p><span><span><br/><br/></span></span></p>
<p dir="ltr"><strong>CreateJS</strong></p>
<p dir="ltr"><a href="http://createjs.com/"><span>http://createjs.com/</span></a></p>
<p><span><span> </span></span></p>
<p dir="ltr"><span>CreateJS is a suite of libraries that can be used to create interactive content using HTML5 and JavaScript. CreateJS is composed of several separate libraries: EaselJS, TweenJS, SoundJS and PreloadJS to handle functionality commonly needed in games and animation. Unlike the other libraries in this list CreateJS isn’t targeted at creating games. Instead it seem like it’s goal is closer to being a Flash replacement. It also has many integrations with tools. Adobe Flash CC is able to export directly to CreateJS.</span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><strong>CraftyJS</strong></p>
<p dir="ltr"><a href="http://craftyjs.com/"><span>http://craftyjs.com/</span></a></p>
<p><span><span> </span></span></p>
<p dir="ltr"><span>CraftyJS is a Javascript game engine that describes itself as a “flexible framework for Javascript games”. It features:</span></p>
<ol>
<li dir="ltr"><p dir="ltr"><span>OpenSource</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Works with all modern browsers including IE9</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Uses Cavas or DOM to render entities</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Small file size</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Sprit map support</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Collision detection</span></p>
</li>
</ol>
<p><span><span> </span></span></p>
<p dir="ltr"><span><strong>Pixi.js</strong></span></p>
<p dir="ltr"><a href="https://github.com/GoodBoyDigital/pixi.js"><span>https://github.com/GoodBoyDigital/pixi.js</span></a></p>
<p><span><span> </span></span></p>
<p dir="ltr"><span>Pixi.js is a lightweight 2D library that uses WebGL, falls back on Canvas and boasts fast performance for both. Some game engines make use of Pixi.js’ strong 2D support. Some of the features include:</span></p>
<p><span><span> </span></span></p>
<ol>
<li dir="ltr"><p dir="ltr"><span>Asset loader / sprite sheet loader</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Masking</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Filters</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Easy to use API</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Full mouse and multi-touch interaction</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>WebGL and Canvas rendering</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Texture atlases</span></p>
</li>
</ol>
<p><span><span> </span></span></p>
<p dir="ltr"><strong>Kiwi.js</strong></p>
<p dir="ltr"><a href="http://www.kiwijs.org/"><span>http://www.kiwijs.org/</span></a></p>
<p dir="ltr"></p>
<p dir="ltr"><span>Kiwi.js is a fun and friendly open source HTML5 game engine. Some of Kiwi.js’ features include:</span></p>
<p><span><span> </span></span></p>
<ol>
<li dir="ltr"><p dir="ltr"><span>Canvas and WebGL rendering</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Support for spritesheets, texture atlases and individual images</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Entity/Component system</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Multitouch support</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>State management</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>File management and loading</span></p>
</li>
</ol>
<p><span><span> </span></span></p>
<p dir="ltr"><strong>Melon.js</strong></p>
<p dir="ltr"><span><a href="http://melonjs.org/">http://melonjs.org/</a></span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><span>Melon.js is a free, open source light weigh JavaScript game engine. Some of its features include:</span></p>
<p><span><span> </span></span></p>
<ol>
<li dir="ltr"><p dir="ltr"><span>Lightweight physic implementation</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Collision detection</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Tween effects</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Transition effects</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Basic particle system</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Spritesheet and packed texture support</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>State manager</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Tile map integration</span></p>
</li>
</ol>
<p><span><span> </span></span></p>
<p dir="ltr"><strong>Panda</strong></p>
<p dir="ltr"><a href="http://www.pandajs.net/"><span>http://www.pandajs.net/</span></a></p>
<p><span><span> </span></span></p>
<p dir="ltr"><span>Panda is a free HTML5 game engine. It features:</span></p>
<p><span><span> </span></span></p>
<ol>
<li dir="ltr"><p dir="ltr"><span>Canvas/WebGL rendering</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Particle engine</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Tweening</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Physics engine</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Timers</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Sound manager</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Ability to organize code in modules</span></p>
</li>
</ol>
<p><span><span> </span></span></p>
<p dir="ltr"><strong>Phaser</strong></p>
<p dir="ltr"><a href="https://phaser.io/"><span>https://phaser.io/</span></a></p>
<p><span><span> </span></span></p>
<p dir="ltr"><span>Phaser is a fast, free and fun open source framework for games. Phaser is popular on GitHub. One thing that interests me about Phaser is it is one of the few game engines that has a set up guide using TypeScript. Some of Phaser’s features include:</span></p>
<p><span><span> </span></span></p>
<ol>
<li dir="ltr"><p dir="ltr"><span>WebGL & Canvas</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Preloader</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Physics</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Sprites</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Animation</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Particles</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Tilemaps</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Camera</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Plugin system</span></p>
</li>
</ol>
<p><span><span> </span></span></p>
<p dir="ltr"><strong>Quintus</strong></p>
<p dir="ltr"><a href="http://www.html5quintus.com/"><span>http://www.html5quintus.com/</span></a></p>
<p><span><span> </span></span></p>
<p dir="ltr"><span>Quintus is an “easy-to-learn, fun-to-use” JavaScript HTML5 game engine. Quintus seems to be a younger library, but I’ve seen it mentioned on several sites. Quintus also seems to cover the basics of a game engine, but is not as full-featured or refined as other game engines on this list.</span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><strong>Stage.js</strong></p>
<p dir="ltr"><a href="http://piqnt.com/stage.js/"><span>http://piqnt.com/stage.js/</span></a></p>
<p><span><span> </span></span></p>
<p dir="ltr"><span>Stage.js is a 2D HTML5 JavaScript game engine that is lightweight, fast and open source. Stage.js seems to include many of the basics for a game engine including the game loop, events, support for mouse and touch, texture atlas, images, animation and tweening. </span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><span>In the future I hope to pick a few of these and hopefully one day create a simple game. If anyone knows of any good JavaScript game engines that are not on this list please let me know.</span></p>
<p><span> </span></p>Spaceballstag:www.techhui.com,2015-06-08:1702911:BlogPost:1340392015-06-08T10:00:00.000ZDavid Chunghttp://www.techhui.com/profile/DavidChung
<p>I like to hone my problem-solving skills by going over some programming contest questions and I also like to use programming contest problems in interviews because it allows me to gauge whether the candidate is a just a coder or a problem solver. That's not to say that if you can't come up with a correct solution, you aren't a problem solver -- if I'm the interviewer, I'm more interested in how you approach the problem and whether you can break up and present the problem in an abstract…</p>
<p>I like to hone my problem-solving skills by going over some programming contest questions and I also like to use programming contest problems in interviews because it allows me to gauge whether the candidate is a just a coder or a problem solver. That's not to say that if you can't come up with a correct solution, you aren't a problem solver -- if I'm the interviewer, I'm more interested in how you approach the problem and whether you can break up and present the problem in an abstract manner.</p>
<p>So here is a programming contest problem I used recently in an interview: <a href="http://acm.student.cs.uwaterloo.ca/~acm00/150131/A-ack.pdf" target="_blank">Spaceballs</a>! My <a href="https://cs.uwaterloo.ca/" target="_blank">Alma Mater</a> hosts <a href="http://acm.student.cs.uwaterloo.ca/" target="_blank">programming contests</a> and this was one of the recent problems.</p>
<p>In case the link breaks, here is the problem:</p>
<blockquote><p>Juliet reads an interesting sci-fi book. In one chapter, the main character needs to solve a problem of maximizing the utilization of cargo spaceships. The ships transport valuable items that have the form of D-dimensional mesh with the size of 3 nodes in each dimension. The nodes are formed by balls of the same weight. The connections between balls are so light that their weight is negligible compared to the weight of balls. This means that the weight of any item is determined solely by the number of its nodes. On the other hand, the value of such an item is equal to the number of nodes plus the number of connections.</p>
<p>Zero Dimension (Weight = 1, Price = 1)<br/> First Dimension (Weight = 3, Price = 5)<br/> Second Dimension (Weight = 9, Price = 21)</p>
<p>Each spaceships has a limited tonnage and we want to maximize the total value of items that maybe stored in the ship without exceeding the tonnage. Your task is to decide what items of what dimension should be loaded to maximize their total value, providing that we have an unlimited supply of items of all dimensions</p>
<p><strong>Input Specification:</strong></p>
<p>The first line of the input contains the number of test cases N. Each test case then consists of a single line containing one positive integer number K < 10,000,000 giving the ship cargo capacity.</p>
<p><strong>Output Specification:</strong></p>
<p>For each test case, print one line containing space-separated non-negative numbers Xm Xm−1 . . . X1 X0, where Xm > 0 and Xi (0 ≤ i ≤ m ) is the number of items of the i-th dimension that we need to store to maximize their total value.</p>
<p><strong>Sample Input:</strong><br/> 4<br/> 1<br/> 100<br/> 175<br/> 9841</p>
<p><strong>Output of Sample Input:</strong><br/> 1<br/> 1 0 2 0 1<br/> 2 0 1 1 1<br/> 1 1 1 1 1 1 1 1 1</p>
</blockquote>
<p>In this blog post, I shall go over what my proposed solution would look like in at most pseudo-code.</p>
<p>The first step is the understand what the problem is asking for. Given a number of nodes, K, we want to assign them into dimension containers, Xm, such that the maximum value is achieved.</p>
<p>For example, looking at the second sample test case, K = 100: X0 = 1, with a total weight of 1; X2 = 2, with a total weight of 18; X4 = 1, with a total weight of 81. So 1 + 18 + 81 = 100 = K. Notice that I didn't even look at the value. It's obvious that higher dimensions have greater value and so we want to fit the balls from high to low dimension to achieve the greatest value.</p>
<p>Each dimension adds a mesh of 3 nodes. So each dimension holds 3^i balls. So, X0 holds 3^0 = 1, X1 holds 3^1 = 3, X2, holds 3^2 = 9, X3 holds 3^3 = 27.</p>
<p>The problem also has a cap for K. 3^15 = 14,348,907, which exceeds the cap. Therefore, the highest dimension that a cargo ship can hold is 3^14 = 4,782,969.</p>
<p>So we really have 15 buckets that can be filled with i-th dimension cargo. If we see the problem as receiving K balls, then every time an i-th dimension bucket is used, 3^i balls are consumed from K as stored balls.</p>
<p>Starting from the highest 14th dimensional bucket, we will attempt to consume the remaining balls without going negative. If we can't, then we will go down a dimension and see if that dimension is able to consume. We will continue to consume balls until we reach zero balls. The 0-th dimension consumes single balls so we will eventually achieve this.</p>
<p>So here is my pseudo-code of my solution:</p>
<p><span style="font-family: terminal,monaco;">SolveSpaceballs(K)</span></p>
<p><span style="font-family: terminal,monaco;"># The dimensional buckets</span></p>
<p><span style="font-family: terminal,monaco;">X = X[14]</span></p>
<p></p>
<p><span style="font-family: terminal,monaco;"># Start at the 14th dimension</span></p>
<p><span style="font-family: terminal,monaco;">i = 14</span></p>
<p></p>
<p><span style="font-family: terminal,monaco;"># Track how many balls were consumed</span></p>
<p><span style="font-family: terminal,monaco;">L = K</span></p>
<p></p>
<p><span style="font-family: terminal,monaco;"># Loop until all balls are consumed</span></p>
<p><span style="font-family: terminal,monaco;">while L > 0</span></p>
<p></p>
<p><span style="font-family: terminal,monaco;"> <span style="font-family: terminal,monaco;"># If we can consume 3^i balls...</span><br/> if L <= 3^i<br/></span></p>
<p></p>
<p><span style="font-family: terminal,monaco;"> # Then we will use this bucket</span></p>
<p><span style="font-family: terminal,monaco;"> X[i] += 1 <br/></span></p>
<p></p>
<p><span style="font-family: terminal,monaco;"> # We consumed 3^i balls</span></p>
<p><span style="font-family: terminal,monaco;"> L -= 3^i</span></p>
<p></p>
<p><span style="font-family: terminal,monaco;"> else</span></p>
<p></p>
<p><span style="font-family: terminal,monaco;"> # Otherwise, we will move to the next bucket down</span></p>
<p><span style="font-family: terminal,monaco;"> i -= 1</span></p>
<p><span style="font-family: terminal,monaco;">END</span></p>
<p>The solution fills the buckets with the number of times it is used. We can iterate through the buckets and print out its value as per specification so that we start from the 14th dimension and skip the element until we reach a non-zero bucket to begin printing values.</p>
<p>So let's run the test cases:</p>
<p><strong>K = 1</strong></p>
<p>Loop and decrement i until i = 0 where 3^0 = 1 and increment X[0] = 1 for a final result of:</p>
<p>[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]</p>
<p>Output: 1</p>
<p></p>
<p><strong>K = 100</strong></p>
<p>Loop and decrement i until i = 4 where 3^4 = 81 and increment X[4] = 1 leaving L = 19.</p>
<p>Loop and decrement i until i = 2 where 3^2 = 9 and increment X[2] = 1 leaving L = 10.</p>
<p>Loop but L can still be consumed by 3^2 so increment X[2] = 2 leaving L = 1.</p>
<p>Loop and decrement i until i = 0 where 3^0 = 1 and increment X[0] = 1 for a final result of:</p>
<p>[1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]</p>
<p>Output: 1, 0, 2, 0, 1</p>
<p></p>
<p><strong>K = 175</strong></p>
<p>Loop and decrement i until i = 4 where 3^4 = 81 and increment X[4] = 1 leaving L = 94.</p>
<p>Loop but L can still be consumed by 3^4 so increment X[4] = 2 leaving L = 13.</p>
<p>Loop and decrement i until i = 2 where 3^2 = 9 and increment X[2] = 1 leaving L = 4.</p>
<p>Loop and decrement i until i = 1 where 3^1 = 3 and increment X[1] = 1 leaving L = 1.</p>
<p>Loop and decrement i until i = 0 where 3^0 = 1 and increment X[0] = 1 for a final result of:</p>
<p>[1, 1, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0]</p>
<p>Output: 2, 0, 1, 1, 1</p>
<p></p>
<p><strong>K = 9841</strong></p>
<p>Loop and decrement i until i = 8 where 3^8 = 6561 and increment X[8] = 1 leaving L = 3280.</p>
<p>Loop and decrement i until i = 7 where 3^7 = 2187 and increment X[7] = 1 leaving L = 1093.</p>
<p>Loop and decrement i until i = 6 where 3^6 = 729 and increment X[6] = 1 leaving L = 364.</p>
<p>Loop and decrement i until i = 5 where 3^5 = 243 and increment X[5] = 1 leaving L = 121.</p>
<p>Loop and decrement i until i = 4 where 3^4 = 81 and increment X[4] = 1 leaving L = 40.</p>
<p>Loop and decrement i until i = 3 where 3^3 = 27 and increment X[3] = 1 leaving L = 13.</p>
<p>Loop and decrement i until i = 2 where 3^2 = 9 and increment X[2] = 1 leaving L = 4.</p>
<p>Loop and decrement i until i = 1 where 3^1 = 3 and increment X[1] = 1 leaving L = 1.</p>
<p>Loop and decrement i until i = 0 where 3^0 = 1 and increment X[0] = 1 for a final result of:</p>
<p>[1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0]</p>
<p>Output: 1, 1, 1, 1, 1, 1, 1, 1, 1</p>
<p></p>
<p>I am curious what others think of this problem and other approaches to this problem. I thought this problem was pretty straight-forward but a common pitfall is reading too much into the i-th dimension value and the i-th dimension itself.</p>A Look at Windows 10 Technical Preview Build 10061tag:www.techhui.com,2015-04-23:1702911:BlogPost:1343512015-04-23T22:50:38.000ZDouglas Chinghttp://www.techhui.com/profile/DouglasChing
<p dir="ltr">In my <a href="http://www.techhui.com/profiles/blogs/windows-phone-10-tech-preview-and-experience-using-windows-phone" target="_blank">last blog post</a> I wrote about Windows 10 preview for phones. Yesterday Microsoft released the latest technical preview for Windows 10 on desktops, build 10061. With the rumored end of July release date of Windows 10 here is a look at where Windows 10 is today. The current build is the most refined one yet, but is still very buggy and…</p>
<p dir="ltr">In my <a href="http://www.techhui.com/profiles/blogs/windows-phone-10-tech-preview-and-experience-using-windows-phone" target="_blank">last blog post</a> I wrote about Windows 10 preview for phones. Yesterday Microsoft released the latest technical preview for Windows 10 on desktops, build 10061. With the rumored end of July release date of Windows 10 here is a look at where Windows 10 is today. The current build is the most refined one yet, but is still very buggy and hopefully many things will be fixed and updated before final release. One thing that is pretty neat about Windows 10 development is Microsoft released the builds early over the last year and has actually made updates based on user feedback.</p>
<p><span><span> </span></span></p>
<p dir="ltr"><strong>Start Menu vs Start Page</strong></p>
<p dir="ltr"><span>The most noticeable change from Windows 8 to Windows 10 that people will look for is probably going to be the Start Menu. Windows 8 removed the Start Menu and replaced it with a Start Page and that did not go over very well.</span></p>
<p><span><span> </span></span></p>
<p><span><span><a href="http://storage.ning.com/topology/rest/1.0/file/get/396586803?profile=original" target="_self"><img src="http://storage.ning.com/topology/rest/1.0/file/get/396586803?profile=original" width="600" class="align-center"></a></span></span></p>
<p></p>
<p dir="ltr"><span>In Windows 10 the Start Menu is back. It no longer takes up the entire screen. Users can resize the menu by dragging the edges. The left side of the menu acts more like the traditional Start Menu of Windows 7 with a list of recent applications and the ability to go to a list of all applications and the shutdown button. The right side of the menu functions like the Windows 8 Start Page, but within a smaller area.</span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><strong>Charms Are Gone, Replaced by Notifications Panel</strong></p>
<p dir="ltr"><span>The Charms Bar completely gone. It’s been replaced by the notifications panel. The notifications panel is similar to what you would see in Android, iOS or Windows Phone when you pull down from the top. It contains a list of recent notifications and an area with frequently used settings and toggles. This is almost completely different from what the Charms Bar did. The functionality of the Charms Bar got moved into the individual app windows instead.</span></p>
<p><span><span><br> <a href="http://storage.ning.com/topology/rest/1.0/file/get/396587440?profile=original" target="_self"><img src="http://storage.ning.com/topology/rest/1.0/file/get/396587440?profile=original" width="283" class="align-center"></a><br></span></span></p>
<p></p>
<p dir="ltr"><strong>Multiple Destkops</strong></p>
<p dir="ltr"><span>Windows 10 finally introduces a native multiple desktop feature. Clicking on the multiple desktop icon in the taskbar opens up the multiple desktop window. The user can create as many desktops as they want and can also drag apps from one desktop to another.</span></p>
<p><span><span><br> <a href="http://storage.ning.com/topology/rest/1.0/file/get/396588506?profile=original" target="_self"><img src="http://storage.ning.com/topology/rest/1.0/file/get/396588506?profile=original" width="600" class="align-center"></a><br></span></span></p>
<p></p>
<p dir="ltr"><strong>Desktop vs Tablet Mode</strong></p>
<p dir="ltr"><span>One of the big problems with Windows 8 is how it attempted to combine desktops and tablets into a single UI. Based on what people say about Windows 8 I don’t think they got it right. Users ended up with a UI that either functioned like the Windows 7 UI or jumped into a full screen tablet mode for Windows Store Apps, completely separate from the desktop. You could work on both if you used the split view, but it was as if the desktop was contained in an app itself and felt a lot like using 2 separate OSes at the same time. This is Windows 8's view of using an app and the destkop:</span></p>
<p dir="ltr"><a href="http://storage.ning.com/topology/rest/1.0/file/get/396588606?profile=original" target="_self"><img src="http://storage.ning.com/topology/rest/1.0/file/get/396588606?profile=RESIZE_1024x1024" width="600" class="align-center"></a></p>
<p><span><span> </span></span></p>
<p dir="ltr"><span>Windows 10 tries to fix this by bringing Windows Store apps into the desktop instead of having the entire desktop environment function like another store app. Windows 10 apps can now run in windows on the desktop alongside Windows desktop apps.</span></p>
<p dir="ltr"><span><a href="http://storage.ning.com/topology/rest/1.0/file/get/396589010?profile=original" target="_self"><img src="http://storage.ning.com/topology/rest/1.0/file/get/396589010?profile=original" width="600" class="align-center"></a></span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><span>Windows 10 also has a “Tablet mode” that detects if the device no longer as a keyboard and mouse attached and asks the user if they want to go into “Tablet mode”. The user can also go into this mode by toggling “Tablet mode” in the notifications area.</span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><span>In Tablet mode app, both desktop and store apps open in full screen. The desktop and task bar get cleared of icons and some UI elements become larger.</span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><span>In Tablet mode the user can use a split view similar to Windows 8.</span></p>
<p dir="ltr"></p>
<p dir="ltr"><span>The user can split two Windows Store apps.</span></p>
<p><img src="http://storage.ning.com/topology/rest/1.0/file/get/396590743?profile=original" width="600" class="align-center"></p>
<p dir="ltr"></p>
<p dir="ltr"><span>The user can split two desktop apps.</span></p>
<p dir="ltr"><span><a href="http://storage.ning.com/topology/rest/1.0/file/get/396591603?profile=original" target="_self"><img src="http://storage.ning.com/topology/rest/1.0/file/get/396591603?profile=original" width="600" class="align-center"></a></span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><span>The user can split a store app and a desktop app.</span></p>
<p dir="ltr"><a href="http://imgur.com/Z80Hq2B"><img src="http://i.imgur.com/Z80Hq2B.png" title="source: imgur.com" class="align-center"></a></p>
<p><span><span> </span></span></p>
<p dir="ltr"><span>Unlike in Windows 8 store apps and desktop apps are treated in a similar way. The user isn’t put into a situation where they are using the desktop within an app view.</span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><span>If the user exits Tablet mode all their apps are displayed accordingly back on the desktop.</span></p>
<p><span><span><a href="http://storage.ning.com/topology/rest/1.0/file/get/396589010?profile=original" target="_self"><img src="http://storage.ning.com/topology/rest/1.0/file/get/396589010?profile=RESIZE_1024x1024" width="600" class="align-center"></a><br> <br></span></span></p>
<p dir="ltr"><strong>Cortana, Spartan, Apps</strong></p>
<p dir="ltr"><span>Cortana, the counterpart to Google’s Google Now and Apple’s Siri is going to be integrated into Windows 10’s Search. In theory Cortana will be able to keep you updated on things you are interested in across devices.</span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><span>Windows 10 will include a new browser. Codenamed Spartan it is being developed as a more modern browser than IE that doesn’t maintain the backwards compatibility that has hindered IE’s development over the years. One of the highlights of the Spartan browser is the ability to use a pen to mark up pages and share them with others. It will also have a feature that formats articles into a more readable view (similar to Readability).</span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><span>Apps in Windows 10 will become more “universal”. In Windows 8 Windows Store apps could be developed to work on Windows Phone and Windows, but they were still largely separated. They could share code but had completely separated UI. In Windows 10 the lines between apps on desktops, laptops, tablets and phones will be further blurred. We will have to wait until Microsoft’s Build conference to find out more. Microsoft’s own Office, Email/Calendar and Maps apps are already built using the newer universal app model.</span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><span>I don’t know if what Microsoft does with Windows 10 will work well or be well received, but I’m interested in what they are attempting to do. As a consumer I like many of the features that are being added and I like that the 2 completely different UIs of Windows 8 is getting combined into a single more consistent UI. As a developer the ability to write a single app and have it run on phones, tablets and laptops/desktops is more compelling than what Microsoft pitched with Windows 8. Windows 10 is still just a tech preview and there are many bugs and issues. It looks like Microsoft has a lot of work ahead, but I’m looking forward to seeing the final Windows 10 build and I think it will be an improvement over Windows 8 from what I have seen so far.</span></p>
<p><span id="docs-internal-guid-5d1b6c19-e86a-8432-6638-6661da9fcd90"><br> <br> <br> <br> <br> <br></span></p>Google API Authorization Using Oauth2 in Ruby on Railstag:www.techhui.com,2015-04-23:1702911:BlogPost:1340562015-04-23T04:30:00.000ZLeo Dhttp://www.techhui.com/profile/LeoD
<p>Say you are writing a web app that will help its users optimize their companies' online marketing. In that case your web app would need to be able to access its users google analytics web site data. The way you allow your site users to authorize your web app to to access their google analytics data, is with Oauth2. Oauth2 is a security protocol for third party application authorization. When a user visits your web app, you present them with a link that will take them to a google page…</p>
<p>Say you are writing a web app that will help its users optimize their companies' online marketing. In that case your web app would need to be able to access its users google analytics web site data. The way you allow your site users to authorize your web app to to access their google analytics data, is with Oauth2. Oauth2 is a security protocol for third party application authorization. When a user visits your web app, you present them with a link that will take them to a google page where they will be able to authorize your app to access their data. Google knows who your user is because your user is logged into Google and if not, Google will ask them to log in. The way Google knows what the web app the user is giving permission to access their google analytics data, is via parameters in the url the user clicked on your site. Those parameters tell Google to what Google project, your site user is giving authorization to access their data. So, for your web app, you will need one Google project associated with it, and each of your users will need to have a Google app that they are authorized to access, and whose data they will authorize your Google Project to access. Your site users will in effect be giving the Google Project you set up for your site, access to their Google Analytics data. An example of a Google app might be: read-only access to Google Analytics. So, if user A has been authorized to access the Google Analytics data for site X, then user A can log into your site, and then authorize your site to access Google Analytics data for site X on behalf of user A. Your site will then be able to access Google Analytics data for site X on behalf of user A until user A revokes access to your site. Once a site user who has been directed to Google via an authorize link on your site, clicks a button on the Google site indicating that they want your site to be able to access their data, they will be redirected to your site, and the redirect url will have a code. Your site will use that code to send a server to server message to google, which will retrurn an access token and a refresh tokens. Google access tokens last one hour, but you can get new ones via the refresh token. A lot of this is taken care of for you by the Oauth2 Ruby library (gem).</p>
<p>For this blog post, I am assuming you are using devise, and therefore can invoke current_user in your controllers to get the currently logged in user. I am also assuming that you add a field to your users table called ggl_access_token to store a serialized version of a hash containing the access and refresh tokens, and a field, and another field called google_profile_id to store the application id of the site for which users want your web app to access Google Analytics API data.</p>
<p>For your Rails app, you will need the Oauth2 and Legato gems. You can add these lines to your Gemfile:</p>
<blockquote><p>gem 'oauth2',<br/> gem 'legato'</p>
</blockquote>
<p></p>
<p>The Oauth2 gem is for authorization, and the legato gem is for querying Google data in a Ruby idiomatic way, without the json commands that Google expects, and you'll use it to allow a site user to choose what app he wants your site to access data for. </p>
<p>For your site, you will need a Google Project. To create a google project, which is technically what your site users are giving permission to, to access their data. You can view your current google projects and add new ones here:</p>
<blockquote><p><a href="https://console.developers.google.com/">https://console.developers.google.com/</a></p>
</blockquote>
<p>Create a project. Then click on "Credentials" under the "APIs & Auth" menu header to your left. You will then see the Client ID and Client Secret for each of your projects. Refer to the ones for the project that you are using to access the Google APIs for this web app. You can click on "Edit Settings" within a project, to add the url you will be using for the authorization callback. For example:</p>
<blockquote><p>http://localhost:3000/authorize_google_api</p>
</blockquote>
<p>This will need to match up with what you assign to the <span>GOOGLE_REDIRECT_HOST environment variable.</span></p>
<p>the following should be in a Rails environment variables file:</p>
<blockquote><p>ENV['GOOGLE_OAUTH_CLIENT_ID'] = ''"<br/> ENV['GOOGLE_OAUTH_SECRET_KEY'] = ''"<br/> ENV['GOOGLE_REDIRECT_HOST'] = 'http://localhost:3000'</p>
<p><span>ENV['GOOGLE_REDIRECT_PATH'] = '/<span>authorize_google_api</span>'</span></p>
</blockquote>
<p>I load mine at application startup via code in config/environment.rb</p>
<blockquote><p>env_vars = File.join(Rails.root, 'config', 'env_vars.rb')<br/> load(env_vars) if File.exists?(env_vars)</p>
</blockquote>
<p>of course, the first two environment variables should not be empty strings but the values you got from the Google developer's console page under the Credentials section, and the last two will change depending on whether you are in development or production, what your application's web address is, and the value you choose for the redirect path for your app. Just make sure to add the resulting url to the authorized callbacks in the Google developer's console page, or the callback and authorization will fail.</p>
<p>Add a link on your site that asks your users to authorize your site to access their Google data like so:</p>
<blockquote><p>Click <%= link_to 'here', @google_oauth_service.<span>get_authorize_url</span> %> to authorize us to access your app.</p>
</blockquote>
<p>This takes advantage of a GoogleOauthService object (in <span>@google_oauth_service</span>), that is set up in a before_action filter, that we will set up below.</p>
<p>Put the following onto a controller of your choice, possibly a new one, and add a route to it:</p>
<blockquote><p>i.e. in a controller called <span>oauth_authorize</span>:</p>
<p>def authorize_google_api<br/> google_oauth_service = GoogleOauthService.new(current_user)<br/> google_oauth_service.set_access_token(params[:code])<br/> google_oauth_service.refresh_access_token<br/> redirect_to root_path, :notice => "you have been successfully authorized!"<br/> end</p>
<p>in routes.rb:</p>
<p>get 'authorize_google_api' => 'oauth_authorize#authorize_google_api'</p>
</blockquote>
<p>This will handle the Google callback, once the user clicks on the authorize button at the Google site, and is redirected back to your app.</p>
<p></p>
<p>put the following into your application controller or, better yet if you are using Rails 4, into a controller concern and include that concern into the site's application controller:</p>
<blockquote><p>def refresh_token</p>
<p> @google_oauth_service.refresh_access_token<br/> end</p>
<p>def google_oauth_service<br/> @google_oauth_service = GoogleOauthService.new(current_user, current_user.google_profile_id)<br/> if current_user.ggl_acc_token<br/> @google_oauth_service.restore_access_token<br/> if @google_oauth_service.expired?<br/> refresh_token<br/> end<br/> end<br/> end</p>
</blockquote>
<p>Then use a before_action in any controller or for any controller where you need to access the Google API on behalf of a site user:</p>
<blockquote><p>before_action :google_oauth_service</p>
</blockquote>
<p></p>
<p>put the following into a file inside app/services folder:</p>
<blockquote><p>require 'oauth2'</p>
<p>class GoogleOauthService</p>
<p> GOOGLE_OAUTH_CLIENT_ID = ENV['GOOGLE_OAUTH_CLIENT_ID']<br/> GOOGLE_OAUTH_SECRET_KEY = ENV['GOOGLE_OAUTH_SECRET_KEY']<br/> GOOGLE_REDIRECT_HOST = ENV['GOOGLE_REDIRECT_HOST']</p>
<p><span> GOOGLE_REDIRECT_PATH = ENV['GOOGLE_REDIRECT_PATH']</span><br/> GOOGLE_REDIRECT_URI = "#{GOOGLE_REDIRECT_HOST}#{<span>ENV['GOOGLE_REDIRECT_PATH']}</span>"<br/> QUERY_ROOT = "https://www.googleapis.com/analytics/v3/data/ga?"</p>
<p> attr_reader :ga_id, :oauth_auth_code, :client, :user</p>
<p> def initialize(user, ga_id=nil)<br/> @user = user<br/> @ga_id = ga_id if ga_id<br/> @client = OAuth2::Client.new(GOOGLE_OAUTH_CLIENT_ID, GOOGLE_OAUTH_SECRET_KEY, {<br/> :authorize_url => 'https://accounts.google.com/o/oauth2/auth',<br/> :token_url => 'https://accounts.google.com/o/oauth2/token'<br/> })<br/> end</p>
<p> def get_authorize_url<br/> url = @client.auth_code.authorize_url({<br/> :scope => 'https://www.googleapis.com/auth/analytics.readonly',<br/> :redirect_uri => GOOGLE_REDIRECT_URI,<br/> :access_type => 'offline'<br/> })<br/> url #copy this url into browser<br/> end</p>
<p> def set_access_token(code=nil)<br/> @access_token = @client.auth_code.get_token(code || @oauth_auth_code,<br/> {:redirect_uri => GOOGLE_REDIRECT_URI})<br/> @serialized_access_token = @access_token.to_hash.to_json<br/> user.update_attribute(:ggl_acc_token, @serialized_access_token)<br/> nil<br/> end</p>
<p> def get_sessions_and_pageviews_by_country<br/> query = "start-date=2015-01-01&end-date=2015-02-01&metrics=ga:sessions,ga:pageviews&dimensions=ga:country"<br/> response_json = @access_token.get("#{QUERY_ROOT}ids=ga:#{@ga_id}&#{query}").body<br/> JSON.parse(response_json)<br/> end</p>
<p> def execute_query(query)<br/> response_json = @access_token.get("#{QUERY_ROOT}ids=ga:#{@ga_id}&#{query}").body<br/> JSON.parse(response_json)<br/> end</p>
<p> def restore_access_token<br/> @serialized_access_token = user.ggl_acc_token<br/> @access_token = OAuth2::AccessToken.from_hash @client,<br/> {:refresh_token => JSON.parse(@serialized_access_token)['refresh_token'],<br/> :access_token => JSON.parse(@serialized_access_token)['access_token'],<br/> :expires_at => JSON.parse(@serialized_access_token)['expires_at']}<br/> nil<br/> end</p>
<p> def expired?<br/> restore_access_token unless @access_token<br/> @access_token.expired?<br/> end</p>
<p><span> def access_token_object</span><br/><span> restore_access_token unless @access_token</span><br/><span> @access_token</span><br/><span> end</span></p>
<p> def access_token<br/> restore_access_token unless @access_token<br/> @access_token.token<br/> end</p>
<p> def refresh_token<br/> restore_access_token unless @access_token<br/> @access_token.refresh_token<br/> end</p>
<p> def refresh_access_token<br/> restore_access_token unless @access_token<br/> @access_token = @access_token.refresh!<br/> @serialized_access_token = @access_token.to_hash.to_json<br/> user.update_attribute(:ggl_acc_token, @serialized_access_token)<br/> nil<br/> end</p>
<p>end</p>
</blockquote>
<p></p>
<p>This service class is a wrapper around the OAuth2 Ruby library. It serves mainly to encapsulate the needed OAuth2 functionality and isolate the controller or concern from OAuth2 library details. The thing to keep in mind is that the OAuth2::AccessToken object (<a href="http://www.rubydoc.info/github/intridea/oauth2/OAuth2/AccessToken">http://www.rubydoc.info/github/intridea/oauth2/OAuth2/AccessToken</a>), has both a refresh and access tokens inside it, so it's deceptively named. When the access token inside the OAuth2::AccessToken object has expired, which you can tell by calling expired? on it, you just call the refresh! method, and the oauth library will refresh the access token and possibly even refresh the refresh token, depending on how old the refresh token is. Also, notice that OAuth2::AccessToken has a to_hash method for serializing it so you can store it in a database field, and a from_hash method for restoring it from its serialized form. Also, as long as the client id client secret, callback domain, and callback path do not change for the Google Project you are using for your app, you use for your cache the authorization link returned by <span>get_authorize_url, since it depends only on your site and the Google Project associated with your site, and not on the details of a specific site user or their Google apps.</span></p>
<p>You will need to allow site users to pick which of their Google Apps they want your site to access data for. You can do this with a select box. Here is some controller code to get the list for a given user:</p>
<blockquote><p>def get_google_profiles<br/> google_user = Legato::User.new(@google_oauth_service.access_token_object)<br/> @profiles = google_user.profiles.map{|profile| GoogleProfile.new(profile.id, profile.name)}<br/> end</p>
</blockquote>
<p>Store whatever app id a site user chooses in the google_profile_id in that user's row in the users table.</p>
<p>For testing, you can play the part of a user, and revoke authorization at the following url:</p>
<blockquote><p><a href="https://security.google.com/settings/security/permissions?pli=1">https://security.google.com/settings/security/permissions?pli=1</a></p>
</blockquote>
<p>Of course, to do that, you will need to be authorized as a user on some Google application, possibly Google Analytics for some web site.</p>
<p>Of course, a site user might revoke access to their Google app at some point, and in that case, your site would have no way of knowing until they actually try to refresh an expired access token or make a query using an existing non-expired access token. So you want to be able to catch such errors. To do that, you can add a rescue_from call to your application controller, or a concern that you include into the controller:</p>
<p></p>
<blockquote><p>rescue_from OAuth2::Error do |oauth2_error|<br/> if current_user.ggl_acc_token<br/> begin<br/> refresh_token<br/> redirect_to root_path, :notice => "Your google token has been refreshed."<br/> rescue Exception => exception<br/> oauth_error<br/> end<br/> else<br/> oauth_error<br/> end<br/> end</p>
<p>def oauth_error<br/> if current_user.ggl_acc_token<br/> current_user.update_attribute(:ggl_acc_token, nil)<br/> end<br/> redirect_to root_path, :notice => "You need to reauthorize our site to use access your data."<br/> end</p>
</blockquote>
<p></p>
<p>I borrowed heavily from the following page in writing this code and this blog post:</p>
<blockquote><p><a href="https://github.com/tpitale/legato/wiki/OAuth2-and-Google">https://github.com/tpitale/legato/wiki/OAuth2-and-Google</a></p>
</blockquote>
<p></p>
<p></p>
<p></p>Bootcamp'd: A Retrospectivetag:www.techhui.com,2015-04-13:1702911:BlogPost:1343352015-04-13T21:00:00.000ZGeorge Leehttp://www.techhui.com/profile/GeorgeLee
<blockquote><p class="graf--p">“I never want to become a teacher.” — 20 year old me.</p>
</blockquote>
<p class="graf--p"></p>
<p class="graf--p">I stood at a crossroads as a junior in college. Organic Chemistry had destroyed any hope I had of going to medical school. I had declared Biology as my major, but I began to have second thoughts. I fell back on the thing I was good at, which was Mathematics. Still, I wasn’t sure what I would do with that degree.…</p>
<p class="graf--p"></p>
<blockquote><p class="graf--p">“I never want to become a teacher.” — 20 year old me.</p>
</blockquote>
<p class="graf--p"></p>
<p class="graf--p">I stood at a crossroads as a junior in college. Organic Chemistry had destroyed any hope I had of going to medical school. I had declared Biology as my major, but I began to have second thoughts. I fell back on the thing I was good at, which was Mathematics. Still, I wasn’t sure what I would do with that degree.</p>
<p class="graf--p"></p>
<p class="graf--p">I thought about becoming a teacher, but the more I thought about it the more I didn’t want to do it. I thought I would be good at teaching. I might have grown to enjoy it. But, I was pretty sure it would drive me insane. I didn’t want to deal with misbehaving students. I didn’t want to deal with school politics. I wanted something more hands on.</p>
<p class="graf--p"></p>
<p class="graf--p">Fast forward to today. I received my Master’s in Computer Science and am employed as a software engineer. I taught a one day class on Javascript at the local outreach college. I’ve done some volunteer work teaching Ruby on Rails to women at <a href="http://www.railsbridge.org/" class="markup--anchor markup--p-anchor">RailsBridge</a> Honolulu. I started the local <a href="https://www.facebook.com/groups/ohanajs" class="markup--anchor markup--p-anchor">Javascript users group</a> and continue to organize talks and meetups. My efforts have not gone unnoticed and I got an opportunity to teach at <a href="http://www.devleague.com/" class="markup--anchor markup--p-anchor">Dev League</a>. The offer was to take over the part time class for 3 months.</p>
<p class="graf--p"></p>
<p class="graf--p">I immediately said yes. As I tell my students, I have a problem saying no. There were reasons for me to turn it down. I have many side projects that need to get done. But, I wanted to help out a friend and it was a good opportunity to give back to the tech community. Yeah, it’d be 20 more hours per week, but it’s only for 3 months, right?</p>
<p class="graf--p"></p>
<p class="graf--p">I started by putting a daily schedule together. I taught twice during the week at night, so I went to the gym in the mornings. I set aside some time on nights I didn’t teach to work on side projects or rest. When class was over, I left to make sure I got enough rest for the next day. I started thinking about the topics we’d cover and what my approach would be.</p>
<p class="graf--p"></p>
<p class="graf--p">It wasn’t easy adjusting to the schedule, but I pulled it off. I treated it as another job and made sure to keep my day job and teaching separate. I started losing weight because of my time at the gym. I made sure to get enough rest so I could make it through another day. It all worked out pretty well. During the first 8 weeks, I skipped one day at the gym.</p>
<p class="graf--p"></p>
<p class="graf--p">But then something happened. I’m not sure I can pinpoint the exact cause. I think it was one night after teaching algorithms. I told some students that I found discrete math interesting. I recalled a graph algorithm my boss used to schedule our hours. I ended up staying about 2 hours after class talking.</p>
<p class="graf--p"></p>
<p class="graf--p">It started to become more than a job. I began to care about my students. I always wanted to help them with their projects and understand the material. But, as I got to know them better, I became invested in their success. I tried to give advice and shared my observations of the tech industry in Hawaii. I told tales of how I succeeded and failed. I empathized with each of the students. It was a lot of fun.</p>
<p class="graf--p"></p>
<p class="graf--p">Sure, there were times where things got tough. Coming up with curriculum was difficult. Trying to help 8 students with 8 different projects is a challenge. I didn’t get to all the topics I wanted to cover. The students got to see me mess up on more than one occasion. I hope it demonstrated that even after all that education and experience, it’s okay to make mistakes. I’m still human after all.</p>
<p class="graf--p"></p>
<p class="graf--p">Looking back, there were some things we did that worked well for the students.</p>
<ol class="postList">
<li class="graf--li">Standup: Every class day, we started off with standup meeting. Each student said what they did since the last meeting and what their next step was going to be. Since they were doing this part time, they needed to work on things outside of class. This held them accountable and also got everyone to speak for a little bit.</li>
<li class="graf--li">Writing tests for the students: For some of our lessons, we wrote unit tests. These tests gave the students immediate feedback on whether their implementation was correct. We stumbled on tests a few times (I’m used to RSpec), but they kept the students on track.</li>
<li class="graf--li">Personal projects: For the last month, the students worked on their own personal project. We helped the students manage the scope of their projects and kept them on track. We also provided help, but the students had to come up with their project idea.</li>
</ol>
<p></p>
<p class="graf--p">At the same time, there were things that we could do better.</p>
<ol class="postList">
<li class="graf--li">Keeping people on task outside of class: This was the biggest challenge for the part-time cohort. We expected students to work on projects or assignments outside of class. For the most part, students were motivated enough to find work when they needed to. Still, we needed to do a better job of giving the students work to do.</li>
<li class="graf--li">Managing the group project: The students worked on a group project during the month of February. We split the project up into 4 parts and had pairs of students work on each one. We simulated an open-source environment where the project owners (the instructors) reviewed pull requests. Yet, we did a poor job of time management and could not get the entire system up in a working state. Some of the teams were blocked on others, which made it difficult to keep them engaged. The students did learn a lot from the experience, so I can’t say it was a complete failure.</li>
</ol>
<p></p>
<p class="graf--p">This was an amazing experience and I’m thankful to Jason, Russel, and Jon for giving me the opportunity. I developed a bond with each student and have become invested in their success. Turning the lights off on the last day was difficult, but we did our best to prepare them for the road ahead.</p>
<p class="graf--p">I can’t wait to see what they do next.</p>
<p class="graf--p"></p>
<p class="graf--p"><em>This blog is also cross-posted on <a href="https://medium.com/@keokilee/bootcamp-d-a-retrospective-1f96f318152d" target="_blank">Medium</a>.</em></p>Rails on Windows With Bitnamitag:www.techhui.com,2015-03-25:1702911:BlogPost:1335132015-03-25T21:23:11.000ZGeorge Leehttp://www.techhui.com/profile/GeorgeLee
<p><span style="font-size: 13px;">When I first started learning Ruby on Rails back in 2007, one thing was made clear: don’t even try setting it up on a Windows machine. Since then, we had some open source projects like</span> <a class="markup--anchor markup--p-anchor" href="http://railsinstaller.org/en" style="font-size: 13px;">RailsInstaller</a> <span style="font-size: 13px;">that make it really easy to set up a development environment on your machine. Also, with the advent of virtual machines…</span></p>
<p><span style="font-size: 13px;">When I first started learning Ruby on Rails back in 2007, one thing was made clear: don’t even try setting it up on a Windows machine. Since then, we had some open source projects like</span> <a href="http://railsinstaller.org/en" class="markup--anchor markup--p-anchor" style="font-size: 13px;">RailsInstaller</a> <span style="font-size: 13px;">that make it really easy to set up a development environment on your machine. Also, with the advent of virtual machines and</span> <a href="https://www.vagrantup.com/" class="markup--anchor markup--p-anchor" style="font-size: 13px;">Vagrant</a><span style="font-size: 13px;">, it is really easy to get a Linux environment set up regardless of what operating system you’re on.</span></p>
<p class="graf--p">These things are all great if you are setting up a development box, but what about production? RailsInstaller is used for development and the virtual machine approach doesn’t work if your system administrator is not familiar with Linux at all. However, a lot has changed in the past 8 years and it is possible to get a production setup on Windows. Doing so is not straightforward and the resources are limited, but it is in fact possible.</p>
<p class="graf--p">We’ll set up our production environment using <a href="https://bitnami.com/stack/ruby" class="markup--anchor markup--p-anchor">Bitnami’s Ruby stack</a>, which bundles Ruby, Apache, Postgres, and some gems that will get our production setup to work. Most of this is based off of <a href="http://stackoverflow.com/a/11619989" class="markup--anchor markup--p-anchor">this Stack Overflow answer</a> with some minor changes.</p>
<h3 class="graf--h3">Install Bitnami and Set Up Your Project</h3>
<p class="graf--p">First of all, go to the Bitnami Ruby stack page and download and run the local installer. Once that is done, you should have a new directory that contains all of the components that Bitnami installed. You should also have a new command line shortcut in your start menu that is called “Use Bitnami Ruby Stack”. Whenever you are executing commands, make sure to use the terminal window created by that shortcut. It runs as administrator, sets up your path, and takes you directly to the Bitnami directory.</p>
<p class="graf--p">Next, you will need a way to download your project. I chose to use <a href="http://windows.github.com" class="markup--anchor markup--p-anchor">Github for Windows</a> to make it easier to talk to a Github repository. It is a little annoying to go back and forth between the command line and Github for Windows, but it was easier than attempting to install OpenSSL. Once that is installed, clone your project into Bitnami’s projects directory so that it can be easily accessed from the command line.</p>
<p class="graf--p">After that, normal Ruby commands should work within the Bitnami cmd terminal, so you can use your usual commands to set up your project (bundle install, rake db:create, rake db:migrate, etc). I set up a PostgreSQL database on another server, so I won’t get into configuring the database. Once the database is set up, you only need to update the database.yml to point to that database.</p>
<h3 class="graf--h3">Setting up Apache as a Reverse Proxy</h3>
<p class="graf--p">Bitnami comes with both Apache and Nginx. Since Bitnami’s service manager already has Apache set up (at the time of this writing), we will use that as our server. Nginx could work with a little bit of effort.</p>
<p class="graf--p">Open the httpd.conf for Bitnami (something like C:\<path to Bitnami>\apache2\conf\httpd.conf) and make sure the following modules are not commented out.</p>
<p><a href="https://gist.github.com/keokilee/5def7622c3a52df36a3e">https://gist.github.com/keokilee/5def7622c3a52df36a3e</a></p>
<p class="graf--p">After that, edit bitnami.conf (something like C:\<path to Bitnami>\apache2\conf\bitnami\bitnami.conf). Replace the virtual host block with the following (replacing <ruby stack> with the path to your installation and <project dir> with the directory for your project). It should look similar to <a href="https://gist.github.com/keokilee/429f39d20d08a8f37f69">https://gist.github.com/keokilee/429f39d20d08a8f37f69</a></p>
<p class="graf--p">This also sets up far-future expiration headers for assets so your server isn’t hammered with constant requests.</p>
<h3 class="graf--h3">Installing the App as a Windows Service</h3>
<p class="graf--p">Create a batch script (*.bat) file to start up your Rails application. Mine looks something like <a href="https://gist.github.com/keokilee/7266195a3463302dc71f">https://gist.github.com/keokilee/7266195a3463302dc71f</a></p>
<p class="graf--p">I used Thin to start up our server because it is installed by default with Bitnami. I could use Puma or another server, but again I did not want to deal with more installation issues. We will pass in the port number as an argument to the script.</p>
<p class="graf--p">Next, download <a href="http://nssm.cc/" class="markup--anchor markup--p-anchor">NSSM (Non-Sucking Service Manager)</a> and put it on your path. Run “nssm install <service name>” and the GUI should appear.</p>
<br />
<div class="aspectRatioPlaceholder is-locked"><img class="graf-image align-full" src="https://d262ilb51hltx0.cloudfront.net/max/800/1*phnKSbAQiepgafSbVtTFYA.png"/>Installing a service named “startApp” in the NSSM GUI.</div>
<br />
<p></p>
<p class="graf--p">Set the path to be the path to your batch script. The startup directory should be your Github project directory. Arguments should just include the port number. In the Apache config, we have two servers in our load balancer, so you’ll need to create one service with port 3000 as the argument and another with port 3001.</p>
<p class="graf--p">Once that is done, start the services you created using Windows’ Services menu (Start menu -> Administrative Tools -> Services). Then, open Bitnami’s GUI and restart the Apache server. Once that is done, you should be able to go to localhost and see your app.</p>
<h3 class="graf--h3">Setting Up SSL</h3>
<p class="graf--p">Most of the above was culled from that Stack Overflow answer, but we also needed to set up SSL on our application. This requires a few changes to our setup. First, let’s update our Apache config. My new bitnami.conf virtual hosts looks something like <a href="https://gist.github.com/keokilee/9980702b6b687fd32403">https://gist.github.com/keokilee/9980702b6b687fd32403</a></p>
<p class="graf--p">The main changes are 1) we set up a redirect from port 80 to go to our SSL URL) and 2) we added in a bunch of SSL configuration options. Make sure to input the correct paths to your SSL certificate (SSLCertificateFile), private key (SSLCertificateKeyFile), and a combined certificate plus private key for the proxy members (SSLProxyMachineCertificateFile).</p>
<p class="graf--p">Next, we need to update our thin servers to use SSL. The batch script should now look something like <a href="https://gist.github.com/keokilee/b650b1f80d658d84ff14">https://gist.github.com/keokilee/b650b1f80d658d84ff14</a></p>
<p class="graf--p">Restart your services and Apache and the site should now work with SSL.</p>
<p class="graf--p">That’s the gist of how we set up our Rails 4.1.8 app on Windows server. I’m sure there are things we could change like using Puma instead of Thin or Nginx instead of Apache, but this got us a working system with a minimal amount of headache. Still, if you have suggestions or comments, let me know.</p>
<p class="graf--p"></p>
<p class="graf--p"><em>This blog post originally appeared on <a href="https://medium.com/@keokilee/rails-on-windows-with-bitnami-8c04d886eddc" target="_blank">Medium</a>.</em></p>Remembering 3/11 and Yurekurutag:www.techhui.com,2015-03-11:1702911:BlogPost:1334982015-03-11T21:30:00.000ZChristopher Kobayashihttp://www.techhui.com/profile/ChristopherKobayashi
<p><iframe frameborder="0" height="315" src="https://www.youtube.com/embed/QXqjxOqPTLg?wmode=opaque" width="560"></iframe>
</p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/396595417?profile=original" target="_self"><img class="align-left" src="http://storage.ning.com/topology/rest/1.0/file/get/396595417?profile=original" width="199"></img></a> About 15 seconds into this video you'll hear an alarm from an iOS app called <a href="https://itunes.apple.com/us/app/yurekuru-call/id398954883?mt=8" target="_blank">Yurekuru</a>, which is a Japanese word that translates to a shake or sway is…</p>
<p><iframe width="560" height="315" src="https://www.youtube.com/embed/QXqjxOqPTLg?wmode=opaque" frameborder="0"></iframe> </p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/396595417?profile=original" target="_self"><img src="http://storage.ning.com/topology/rest/1.0/file/get/396595417?profile=original" width="199" class="align-left"></a>About 15 seconds into this video you'll hear an alarm from an iOS app called <a href="https://itunes.apple.com/us/app/yurekuru-call/id398954883?mt=8" target="_blank">Yurekuru</a>, which is a Japanese word that translates to a shake or sway is coming.</p>
<p>The alarm and a push notification would warn you of an earthquake. And depending on your location, how long until you'll feel it and estimated intensity.</p>
<p>The app receives warnings called <a href="http://en.wikipedia.org/wiki/Earthquake_Early_Warning_%28Japan%29" target="_blank">Earthquake Early Warning (EEW)</a> issued by the Japan Meteorological Agency. According to Wikipedia, there were <a href="http://en.wikipedia.org/wiki/2011_T%C5%8Dhoku_earthquake_and_tsunami#Earthquake" target="_blank">over 1,000 seismometers in Japan</a> at that time.</p>
<p>Actually most phones made in Japan at that time had this capability due to regulations that made it mandatory for 3G phones since 2007. Apple iPhone's didn't have this capability and thus an iOS app was made available.</p>
<p>We had over 1,000 earthquakes in March. It was unnerving when you were on a train and somebody's phone started to make this noise. After a few seconds almost everyone's phone was going making it. A 'ring, ring' here and then behind you. Next to you. And then your phone.</p>
<p>I would quickly look to figure out when and how big it was going to be. And then you would brace yourself. The car would become silent and you could feel the anticipation from around you. I would wonder is this going to be the big one that everyone talks about and we were over due for.</p>
<p>Since there were so many earthquakes, many got fatigued from so many alerts. I set my alarm threshold higher so that I wouldn't receive alerts for smaller earthquakes. I think it was set to 3 or 4.</p>
<p>Here's a visualization of the earthquakes that occurred in 2011. It gets intense in March...</p>
<p><iframe width="560" height="315" src="https://www.youtube.com/embed/NSBjEvPH2j4?wmode=opaque" frameborder="0"></iframe> </p>
<p>I haven't heard the Yurekuru alarm sound in a while. Even though it's only a YouTube video, hearing it again gives me goose bumps.</p>Today I Learned — The Apptag:www.techhui.com,2015-03-11:1702911:BlogPost:1335002015-03-11T21:43:02.000ZGeorge Leehttp://www.techhui.com/profile/GeorgeLee
<p><span style="font-size: 13px;">People who know me know that I’ve been pretty busy lately. People who really know me know that I’m actually slammed. Yet, I’m taking a personal challenge to complete a small application in the month of March. As it turns out, I have an idea for a small bite-sized application that I can build in a month. It’s also a great chance to challenge myself to learn new frameworks and libraries.</span></p>
<h3 class="graf--h3">The Problem</h3>
<p class="graf--p">I’ve…</p>
<p><span style="font-size: 13px;">People who know me know that I’ve been pretty busy lately. People who really know me know that I’m actually slammed. Yet, I’m taking a personal challenge to complete a small application in the month of March. As it turns out, I have an idea for a small bite-sized application that I can build in a month. It’s also a great chance to challenge myself to learn new frameworks and libraries.</span></p>
<h3 class="graf--h3">The Problem</h3>
<p class="graf--p">I’ve been tracking the things I learn in a given day in a small <a href="https://github.com/keokilee/til" class="markup--anchor markup--p-anchor">Github repository</a>. Other than the challenges of keeping up with it on a daily basis (as you can tell by the dates in the repo), it works fairly well. It’s great to have a centralized place that I can come back to and review my notes.</p>
<p class="graf--p">However, there are a few shortcomings of this approach. I did organize it by dates on purpose because I wanted it to be a daily thing (yeah, not so much). The <a href="https://github.com/thoughtbot/til" class="markup--anchor markup--p-anchor">original Thoughtbot repo</a> organized it by categories, which might be a better approach. However, I really like having items indexed by the date as well, but doing both is not really something you can do in a file structure like this. Also, as I learn things in multiple categories, I would prefer not to have to fumble around and make sure I open the right file in the right directory. I also tend to write short one-liners, so multiple files in a directory might not be the best approach.</p>
<p class="graf--p">What would be really great is a website where I can go and input the things I learned. I can also tag items and view the things I learned that belong to those tags. If I’m really ambitious, you’ll be able to see what your friends have learned, too.</p>
<h3 class="graf--h3">The Technology</h3>
<p class="graf--p">I don’t like doing the same thing twice. Even at work, there’s always lessons learned in a previous project that can be applied. It can be something small like a library or it can be higher-level like code organization.</p>
<p class="graf--p">For personal projects, I like to change things up a lot. In previous projects, I’ve used <a href="http://nodejs.org/" class="markup--anchor markup--p-anchor">Node</a>, <a href="http://mongodb.org" class="markup--anchor markup--p-anchor">MongoDB</a>, <a href="http://backbonejs.org" class="markup--anchor markup--p-anchor">BackboneJS</a>, and <a href="http://coffeescript.org" class="markup--anchor markup--p-anchor">Coffeescript</a>. For this project, I’m incorporating <a href="http://foundation.zurb.com/apps/" class="markup--anchor markup--p-anchor">Foundation for Apps</a>, <a href="https://babeljs.io/" class="markup--anchor markup--p-anchor">Babel</a> (an ES6 to ES5 transpiler), and <a href="https://firebase.com" class="markup--anchor markup--p-anchor">Firebase</a>. My goal is to write as little backend code as possible and to use Firebase as my backend. I’m also hoping to do most of the design myself, which will either be awesome or horrific. Maybe somewhere in the middle.</p>
<p class="graf--p">I’m still just getting started with building the application, but some initial thoughts:</p>
<ul class="postList">
<li class="graf--li">Foundation for Apps adds an entire workflow based on <a href="https://angularjs.org/" class="markup--anchor markup--li-anchor">Angular</a> and <a href="http://gulpjs.com/" class="markup--anchor markup--li-anchor">Gulp</a>. I ended up refactoring the gulp tasks because I added in <a href="http://browserify.org/" class="markup--anchor markup--li-anchor">Browserify</a>. They also changed the grid classes and their integration with <a href="https://github.com/angular-ui/ui-router" class="markup--anchor markup--li-anchor">UI Router</a> is kind of magic. Overall, I wish I had read the docs more rather than just jumping in head first as I tend to do.</li>
<li class="graf--li">Babel and ES6 is pretty cool. Admittedly, I haven’t done much beyond some shorthand (arrow functions and object properties) and using let instead of var. For example: <a href="https://gist.github.com/keokilee/9e5642ca2338f7dd44cb">https://gist.github.com/keokilee/9e5642ca2338f7dd44cb</a></li>
</ul>
<ul class="postList">
<li class="graf--li">Firebase is what I was really excited about. I had used it over a year ago for a tutorial, but back then it was a real-time data store and hosting. Firebase can now handle <a href="https://www.firebase.com/docs/web/guide/user-auth.html" class="markup--anchor markup--li-anchor">user authentication</a>, which makes this concept of a “no custom backend” app actually feasible. I have Github logins working and I’ll probably add in other services over the coming days.</li>
</ul>
<p class="graf--p">I’m excited to be working on this application over the course of the next month. I already have so many feature ideas, but the first step is to scratch my own itch and build something that I would use.</p>
<p class="graf--p"><em>This blog post is also cross posted on <a href="https://medium.com/@keokilee/today-i-learned-the-app-420313a150a3" target="_blank">Medium</a>.</em></p>Remembering 3/11 and Twittertag:www.techhui.com,2015-03-11:1702911:BlogPost:1336102015-03-11T06:30:00.000ZChristopher Kobayashihttp://www.techhui.com/profile/ChristopherKobayashi
<p>I was sitting at my desk on the 6th floor with a fresh cup of coffee that I bought from Tully's downstairs. They're a bit pricey, but they smelled and tasted so good I could never resist. I usually got a hot cup of the daily special and did so that day.</p>
<p>Took a few sips and started a discussion with a colleague about the project that we were on.</p>
<p>The desk I was assigned to was in the corner with a window overlooking a major street and I could see down it all the way to…</p>
<p>I was sitting at my desk on the 6th floor with a fresh cup of coffee that I bought from Tully's downstairs. They're a bit pricey, but they smelled and tasted so good I could never resist. I usually got a hot cup of the daily special and did so that day.</p>
<p>Took a few sips and started a discussion with a colleague about the project that we were on.</p>
<p>The desk I was assigned to was in the corner with a window overlooking a major street and I could see down it all the way to Shimbashi station. The salaray-man district of Tokyo. It was Friday, March 11, 2011 at around 2:45pm and a beautiful day.</p>
<p>I always took off the cover to drink, especially for really hot coffee. The plastic seemed in the way.</p>
<p>A large earthquake started. It felt like one of those rolling types. The liquid was swishing back and forth. Everyone looked up, because it seemed larger than usual. The liquid started to splash, so I had to cover it.</p>
<p>One by one, we all realized it wasn't going to stop. The building was swaying, our copy machine started rolling into the aisle, and then people either ducked under their desks or ran toward the exit.</p>
<p>I grabbed the person next to me and headed for the door. Scenes of 9/11 and the building collapsing flashed in my head.</p>
<p>And then it eased and stopped.</p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/396595345?profile=original" target="_self"><img src="http://storage.ning.com/topology/rest/1.0/file/get/396595345?profile=original" width="380"></a></p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/396595617?profile=original" target="_self"><img src="http://storage.ning.com/topology/rest/1.0/file/get/396595617?profile=original" width="451"></a></p>
<p>Earthquakes are common in Japan. When I first got there I would run under doorways and freak out, but after a few months in the country you got used to them. Nobody would panic. I don't think anybody really cared. Until that day.</p>
<p>At 2:46pm Japan Standard Time a <a href="http://en.wikipedia.org/wiki/2011_T%C5%8Dhoku_earthquake_and_tsunami" target="_blank">magnitude 9.0 undersea megathrust earthquake</a> shook Japan, moved the island about 8 feet, and tilted the Earth's axis by 4 inches.</p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/396602024?profile=original" target="_self"><img src="http://storage.ning.com/topology/rest/1.0/file/get/396602024?profile=RESIZE_320x320" width="250" class="align-left"></a>It was only a 5.0 in Tokyo, but the largest we've ever experienced. It bent the top of the Tokyo tower... </p>
<p>For whatever reason we didn't leave the office. We got up, stared at each other, and then some even got back to work.</p>
<p>I wanted to leave the building.</p>
<p>And then an aftershock hit. The book cases that we stacked in the meeting area came crashing down, almost hitting the managers and president of the company, and breaking the meeting table. </p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/396603790?profile=original" target="_self"><img src="http://storage.ning.com/topology/rest/1.0/file/get/396603790?profile=original" width="520"></a></p>
<p>Finally, we decided to leave and head to an evacuation zone, which was Hibiya park down the street from us.</p>
<p>After we get there one of the managers asks me, "did you shut down the servers?". I answered no. "We should go back and then shut them down, and gather our belongings". Scenes of 9/11 flash in my mind again. </p>
<p>I tried calling my wife, no signal.</p>
<p>We all head back up using the stairs. Everyone's phones were dead, but the office's Internet was still working. Twitter was going off especially about a tsunami. Someone posted a link to a live stream of the tsunami on Al-Jazeera's website. We watched in horror...</p>
<p><iframe width="560" height="315" src="https://www.youtube.com/embed/Hw1zrleDcBw?wmode=opaque" frameborder="0"></iframe> </p>
<p>Phone system was down, but the Internet was working. Facebook and Twitter became our main means of communication. A lot of good advice from Twitter users that were based in Tokyo, like use Google Maps to figure out your walk home and make sure to print it out. And tips on how to save your iPhone's battery life.</p>
<p>I tweeted out a message about going home.</p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/396604656?profile=original" target="_self"><img src="http://storage.ning.com/topology/rest/1.0/file/get/396604656?profile=original" width="591"></a></p>
<p>The train system stopped. Traffic was at a standstill. Bicycles were sold out. Convenience stores emptied. Millions of Tokyoites started to walk home. It felt like the biggest concert ever just ended.</p>
<p>And then a reply. My wife! I was so relieved... </p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/396606073?profile=original" target="_self"><img src="http://storage.ning.com/topology/rest/1.0/file/get/396606073?profile=original" width="437"></a></p>
<p>Luckily I downloaded the app and setup an account for her a couple of weeks prior. And showed her how to get the news.</p>
<p>She didn't want to tweet. She wasn't even on Facebook and refused to get on. I'm glad that she replied.</p>
<p>Every time I passed a major train station I would tweet it out. It was comforting knowing that she got my pings. And it was nice getting encouragement from friends telling me Gambare!</p>
<p>5 hours later...</p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/396606276?profile=original" target="_self"><img src="http://storage.ning.com/topology/rest/1.0/file/get/396606276?profile=original" width="577"></a></p>
<p>Twitter proved it's usefulness to Japan that day.</p>Ruby on SOAPtag:www.techhui.com,2015-03-10:1702911:BlogPost:1336082015-03-10T05:00:00.000ZLeo Dhttp://www.techhui.com/profile/LeoD
<p>The slightly misnamed SOAP (Simple Object Access Protocol) protocol is in a sense a type-strong version of the much better know JSON interchange format. The Ruby community clearly doesn't have as much affection for SOAP as the Java and .Net communities, but that makes sense as Ruby is a dynamic language with duck typing, which meshes better in philosophy with the lightweight JSON format, rather than the much more expressive and heavyweight SOAP format.</p>
<p>If given the choice between…</p>
<p>The slightly misnamed SOAP (Simple Object Access Protocol) protocol is in a sense a type-strong version of the much better know JSON interchange format. The Ruby community clearly doesn't have as much affection for SOAP as the Java and .Net communities, but that makes sense as Ruby is a dynamic language with duck typing, which meshes better in philosophy with the lightweight JSON format, rather than the much more expressive and heavyweight SOAP format.</p>
<p>If given the choice between SOAP and JSON, I would always choose JSON. But I don't always get to choose. Sometimes a third party vendor has already made that decision, or the service I need is already implemented in SOAP.</p>
<p></p>
<p>The soap2r gem seems to be one of the the best maintained ruby gems for implementing SOAP clients/interfaces, and the only Ruby gem that does what SOAP libraries are supposed to do: keep you away from the XML and let you communicate above the XML layer in the language the library is written in. XML is for computer programs, not for people. High level languages are better suited for direct program modification.</p>
<p></p>
<p>What the soap2r gem does is look at the web service's WSDL (web service description language) file, and write code for you to communicate with a client that consumes that service or a server that offers that service, or both. A WSDL file tells soap2r everything it needs to know about the methods in the service and the objects that can be passed as parameters to those methods or returned as responses from those methods, including objects that can be nested within those objects.</p>
<p></p>
<p>To illustrate using the soap2r gem, I'm going to build wrapper for and query the calculator service at <a href="http://www.service-repository.com/service/overview/877027757">http://www.service-repository.com/service/overview/877027757</a> . Service Repository is a web site that contains links to free SOAP services, and diagnostic pages to make requests against those services, using the site's backend SOAP client implementation. The service I chose to use for this blog post is the Calculator service, which you can find at <a href="http://www.service-repository.com/%C2%A0">http://www.service-repository.com/</a> .</p>
<p></p>
<p>First thing I do for any Ruby project, is create a Gemfile. Here is the Gemfile I used for this blog post:</p>
<p>Gemfile</p>
<blockquote><p>source 'https://rubygems.org'</p>
<p>ruby '2.0.0'<br/>gem 'soap2r', '1.5.8'</p>
</blockquote>
<p></p>
<p>I lock down my Ruby version for repeatabillity and gem compatibility, and I also use bundler to actually retrieve my gem from the Ruby gem repository. Bundler comes included with RVM(Ruby version manager), which I also highly recommend to avoid altering or polluting your machine's default gemset with miscellaneous gems.</p>
<p>So, create a .ruby-version and .ruby-gemset files to lock down your ruby version and gemset.</p>
<p>.ruby-version</p>
<blockquote><p>ruby-2.0.0-p576</p>
</blockquote>
<p>.ruby-gemset</p>
<blockquote><p>soap-blog</p>
</blockquote>
<p>now, install Ruby 2.0.0 if you don't already have it:</p>
<p>$rvm install ruby-2.0.0-p576</p>
<p>Put the Gemfile, the .ruby-version, and the .ruby-gemset files into a directory you will use to house your project, and cd into that directory. RVM, if it was properly installed, will auto-magically switch to the right Ruby, and also create a gemset associated with that Ruby version, and having the name specified in the .ruby-gemset file (if it doesn't already exist).</p>
<p>Now, to get the soap2r gem and its dependencies installed, run:</p>
<p>$ bundler install</p>
<p>You are now ready to start using soap2r. Since you installed the soap2r gem as a gem in your current gemset, while you are in your project directory(which has a .ruby-gemset file referencing that gemset), you can use the executables that are included with the soap2r gem. The one we will be using in this post is ruby2wsdl, which can generate client and server wrapper libraries that allow us to program in pure Ruby while using SOAP as the communication mechanism. For this blog post, we are using an already existing service, so we just need to implement the client. We can generate the client stub and support files by running ruby2wsdl with the following options:</p>
<p>$ wsdl2ruby.rb --wsdl <a href="http://soaptest.parasoft.com/calculator.wsdl">http://soaptest.parasoft.com/calculator.wsdl</a> --type client --force</p>
<p>As you can see at <a href="http://www.service-repository.com/service/overview/877027757">http://www.service-repository.com/service/overview/877027757</a>, for this service, the WSDL is at url </p>
<p><a href="http://soaptest.parasoft.com/calculator.wsdl">http://soaptest.parasoft.com/calculator.wsdl</a><span> , and that is what was passed to ruby2wsdl.</span></p>
<p><span>However, the actual endpoint for sending requests (i.e add, multiply, divide, subtract), is at:</span></p>
<p><span><a href="http://ws1.parasoft.com/glue/calculator">http://ws1.parasoft.com/glue/calculator</a> , which you can see by clicking on the "Endpoints" tab.</span></p>
<p>These are two separate URL's and trying to use either in place of the other, will not work.</p>
<p></p>
<p>Running the ruby2wsdl command with the specified options, will have generated a few files:</p>
<p>CalculatorClient.rb #a file with sample client code</p>
<p>CalculatorMappingRegistry.rb #Ruby code that maps SOAP namespaces and objects to Ruby classes</p>
<p>CalculatorDriver.rb #code that implements wrappers for the wsdl's methods in Ruby</p>
<p>Calculator.rb #Ruby code that contains constructors for the service's request and response objects</p>
<p></p>
<p>You don't really need CalculatorClient.rb to run your code. It's only there as a sample, and a pretty poor one at that, since it shows how to invoke all the service's methods in Ruby, but with null arguments, which will lead to errors for methods that require non-null request objects as parameters.</p>
<p>Ok, now to the fun stuff. Here's all the code you have to write, in order to use the Calculator service. Copy it into a file named my_calculator.rb in your project directory.</p>
<p></p>
<blockquote><p>$:.unshift File.dirname(__FILE__) #tells Ruby to include current directory in classpath, so files can require each other<br/>load 'CalculatorDriver.rb' #the only file you need to load explicitly; the others will be loaded indirectly</p>
<p>class MyCalculator #a convenience class to encapsulate the service's functionality</p>
<p> #note that the service's request endpoint is not the same as the wsdl endpoint</p>
<p> CLIENT = ICalculator.new('http://ws1.parasoft.com/glue/calculator')<br/> CLIENT.wiredump_dev = STDERR #set this to see XML sent and received</p>
<p> def self.add(a,b) #method to encapsulate service's add request<br/> response = CLIENT.add(Add.new(a,b))<br/> response.result<br/> end</p>
<p> def self.divide(a,b) #method to encapsulate service's divide request<br/> response = CLIENT.divide(Divide.new(a,b))<br/> response.result<br/> end<br/>end</p>
<p>#ok let's test the services</p>
<p>sum = MyCalculator.add(3,7)<br/>puts "3 + 7: #{sum}"</p>
<p>quotient = MyCalculator.divide(3,7)<br/>puts "3 / 7: #{quotient}"</p>
</blockquote>
<p></p>
<p>Now you can run this file via</p>
<p>$ruby my_calculator.rb</p>
<p>Below is the output you will see. It includes the desired calculated quantities and the incoming/outgoing XML that you never have to look at (once you remove the line: CLIENT.wiredump_dev = STDERR), because soap2r does all the marshalling/unmarshalling and Ruby/SOAP object and method conversions for you. Take a look at the XML that went over the wire in both directions. soap2r is what allows us to not worry about the XML or the HTTP protocol, and just write in pure Ruby as if we were calling a method on any old class.</p>
<p></p>
<blockquote><p>Wire dump:</p>
<p>= Request</p>
<p>! CONNECT TO ws1.parasoft.com:80<br/> ! CONNECTION ESTABLISHED<br/> POST /glue/calculator HTTP/1.1<br/> Content-Type: text/xml; charset=utf-8<br/> SOAPAction: "add"<br/> User-Agent: SOAP4R/1.6.1-SNAPSHOT (2.6.0.1, ruby 2.0.0 (2014-09-19))<br/> Accept: */*<br/> Date: Tue, 10 Mar 2015 03:52:22 GMT<br/> Content-Length: 379<br/> Host: ws1.parasoft.com</p>
<p><?xml version="1.0" encoding="utf-8" ?><br/> <env:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br/> xmlns:xsd="http://www.w3.org/2001/XMLSchema"<br/> xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"><br/> <env:Body><br/> <n1:add xmlns:n1="http://www.parasoft.com/wsdl/calculator/"><br/> <n1:x>3</n1:x><br/> <n1:y>7</n1:y><br/> </n1:add><br/> </env:Body><br/> </env:Envelope></p>
<p>= Response</p>
<p>HTTP/1.1 200 OK<br/> Date: Tue, 10 Mar 2015 03:51:40 GMT<br/> Content-Type: text/xml; charset=UTF-8<br/> Server: TME-GLUE/4.1.2<br/> Content-Length: 376</p>
<p>3 + 7: 10.0<br/> <?xml version='1.0' encoding='UTF-8'?><br/> <soap:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'><soap:Body><n:addResponse xmlns:n='http://www.parasoft.com/wsdl/calculator/'><n:Result xsi:type='xsd:float'>10.0</n:Result></n:addResponse></soap:Body></soap:Envelope></p>
<p>Wire dump:</p>
<p>= Request</p>
<p>POST /glue/calculator HTTP/1.1<br/> Content-Type: text/xml; charset=utf-8<br/> SOAPAction: "divide"<br/> User-Agent: SOAP4R/1.6.1-SNAPSHOT (2.6.0.1, ruby 2.0.0 (2014-09-19))<br/> Accept: */*<br/> Date: Tue, 10 Mar 2015 03:52:22 GMT<br/> Content-Length: 421<br/> Host: ws1.parasoft.com</p>
<p><?xml version="1.0" encoding="utf-8" ?><br/> <env:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br/> xmlns:xsd="http://www.w3.org/2001/XMLSchema"<br/> xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"><br/> <env:Body><br/> <n1:divide xmlns:n1="http://www.parasoft.com/wsdl/calculator/"><br/> <n1:numerator>3</n1:numerator><br/> <n1:denominator>7</n1:denominator><br/> </n1:divide><br/> </env:Body><br/> </env:Envelope></p>
<p>= Response</p>
<p>HTTP/1.1 200 OK<br/> Date: Tue, 10 Mar 2015 03:51:40 GMT<br/> Content-Type: text/xml; charset=UTF-8<br/> Server: TME-GLUE/4.1.2<br/> Content-Length: 388</p>
<p><?xml version='1.0' encoding='UTF-8'?><br/> <soap:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'><soap:Body><n:divideResponse xmlns:n='http://www.parasoft.com/wsdl/calculator/'><n:Result xsi:type='xsd:float'>0.42857143</n:Result></n:divideResponse></soap:Body></soap:Envelope></p>
<p>3 / 7: 0.42857143</p>
<p></p>
</blockquote>
<p> </p>Windows Phone 10 Tech Preview and Experience Using Windows Phone for 2 Yearstag:www.techhui.com,2015-03-02:1702911:BlogPost:1334692015-03-02T15:30:00.000ZDouglas Chinghttp://www.techhui.com/profile/DouglasChing
<p dir="ltr"><span>Nearly 2 years ago I blogged about my</span> <a href="http://www.techhui.com/profiles/blogs/my-experiences-with-windows-phone-8"><span>experiences using Windows Phone for 6 months</span></a><span>. I’m back to update my impression of Windows Phone as a whole and also blog about Windows 10 for phones. Windows Phone has gone through several updates and in early February 2015 Microsoft released the first Tech Preview for Windows 10 on phones.…</span></p>
<p dir="ltr"><span>Nearly 2 years ago I blogged about my</span> <a href="http://www.techhui.com/profiles/blogs/my-experiences-with-windows-phone-8"><span>experiences using Windows Phone for 6 months</span></a><span>. I’m back to update my impression of Windows Phone as a whole and also blog about Windows 10 for phones. Windows Phone has gone through several updates and in early February 2015 Microsoft released the first Tech Preview for Windows 10 on phones.</span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><strong>User Interface and Performance</strong></p>
<p>Two years ago Windows Phone’s UI was made up of a flat tile design. It still has that same design, but added more tile sizes, the ability to add a background and in a recent update, folders. The UI is still fluid and fast although on older devices it starts to stutter sometimes.</p>
<p><span><span> </span></span></p>
<p dir="ltr"><strong>Live Tiles</strong></p>
<p>Live Tiles are still around and work about the same as before. Instead of the 3 sizes from 2 years ago tiles can be made very small, small, medium and large. Tiles can also be placed in a Live Folder and you can see tiny live tiles in that folder. </p>
<p><span><span> </span></span></p>
<p dir="ltr"><strong>Kid’s Corner</strong></p>
<p>Kid’s Corner was a differentiating feature for Windows Phone 8 2 years ago and it’s still around, but hasn’t been updated. It still allows the user to set specific apps to a separate home screen so that people using your phone don’t have full access to all of your phone’s features and apps. I still find it useful, however Microsoft later added a similar feature called App Corner which does nearly the same thing. Although it works okay I don’t know why there is a Kid’s Corner and an App Corner now.</p>
<p><span><span> </span></span></p>
<p dir="ltr"><strong>Lenses</strong></p>
<p>Windows Phone has a concept of a lens. When using the camera app you can open up a selection of lenses which are other apps that the camera can hook into. Over two years companies have created additional lenses that add functionality to the basic camera app.</p>
<p><span><span> </span></span></p>
<p dir="ltr"><strong>People Hub</strong></p>
<p>When Windows Phone 8 first came out People Hub was one of the talking points. It was supposed to make Windows Phone personal and make it easier for users to get to their contact fast. From People Hub a user could get to a contact and then interact with them directly via phone, email, Facebook, Twitter without opening separate apps. Unfortunately People Hub has gone away. Hubs in general have been deprecated and Windows Phone seems to be moving away from the integration it first started with.</p>
<p><span><span> </span></span></p>
<p dir="ltr"><strong>Notification Center</strong></p>
<p>Windows Phone 8 started off without any notification center. Users were expected to rely on the Live Tiles that show updates about emails, posts and other app happenings. Over the last 2 years Microsoft introduced a notification center that follows how most other mobile OSes manage notifications.</p>
<p dir="ltr"></p>
<p dir="ltr"><strong>Cortana</strong></p>
<p dir="ltr">Cortana is a virtual assistant for Windows Phone. Like other virtual assistants you can speak to Cortana and it will speak back with answers. Cortana will also suggest news and events, show you the weather, alert you to traffic conditions and do many of the types of things you would expect from a virtual assistant. I think it has been a nice addition to Windows Phone and look forward to further integration. It seems like Microsoft is interested in making Cortana sort of a hub between users and their data. It is even coming to Windows 10 on desktops.</p>
<p><span><span> </span></span></p>
<p dir="ltr"><strong>Apps</strong></p>
<p>Two years ago Windows Phone had 145,000 apps in the store. Today they have 300,000. The number of apps continues to be a sticking point for users considering Windows Phone. From my personal use I have seen the app situation improve quite a lot. From having very little choice in the beginning to being a solid 3rd app ecosystem after iOS and Android it has been interesting to see how the Windows App store grows. One thing that I enjoyed is the introduction of universal apps in the Windows Store. These apps are available for both Windows Phone and Windows 8. I always look for apps that are usable on both Windows 8 and Windows Phone. Windows 10 promises to bring more app unification for both consumers and developers.</p>
<p><span><span> </span></span></p>
<p dir="ltr"><strong>Windows 10 For Phone Technical Preview</strong></p>
<p><strong> </strong></p>
<p dir="ltr"><span>That brings us to the Windows 10 for phone technical preview. With Windows 10 Microsoft is trying to unify all their operating systems. They recently released the first technical preview for Windows 10 for phones. I was planning to only focus on this for this post, but realized there isn’t much to show for now. Here are some things that are different:</span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><strong>Home Screen</strong></p>
<p>The Windows 10 home screen looks and acts similar to the Windows 8 home screen. It adds the ability to put a background behind tiles versus Windows Phone 8’s background within tiles. It also adds additional tile sizes with a larger vertical tile and an extra large tile size. Below from left to right: Windows Phone 8, Windows Phone 8.1 and Windows 10 for phones home screens.</p>
<p dir="ltr"><a href="http://storage.ning.com/topology/rest/1.0/file/get/396594351?profile=original" target="_self"><img src="http://storage.ning.com/topology/rest/1.0/file/get/396594351?profile=original" width="644" class="align-full"></a></p>
<p></p>
<p dir="ltr">Windows 10 adds additional options in the notification center. Windows Phone 8 allowed for 4-5 quick options in the notification. Windows 10 allows for multiple rows of options. Below the notification center for Windows Phone 8 and Windows 10 for phones.</p>
<p dir="ltr"><a href="http://storage.ning.com/topology/rest/1.0/file/get/396594645?profile=original" target="_self"><img src="http://storage.ning.com/topology/rest/1.0/file/get/396594645?profile=original" width="417" class="align-full"></a></p>
<p dir="ltr"></p>
<p>In addition the toasts in Windows 10 are planned to be actionable and individual notifications can be dismissed. In Windows Phone 8 all notifications under a group had to be cleared at the same time and toasts could only be dismissed or linked to open the notifying app.</p>
<p><span><span> </span></span></p>
<p dir="ltr"><span>In Windows 10 the system options are organized into separate categories instead of displayed in a large list. </span></p>
<p><span><span><br> <a href="http://storage.ning.com/topology/rest/1.0/file/get/396595456?profile=original" target="_self"><img src="http://storage.ning.com/topology/rest/1.0/file/get/396595456?profile=original" width="379" class="align-full"></a><br></span></span></p>
<p>That is about it for the first technical preview. I'm sure there have been many changes under the hood. There are many other small UI updates and inconsistancies, but since this is a tech preview the UI is most likely going to change before final release.</p>
<p><span><span> </span></span></p>
<p dir="ltr"><span>One trend that people have been noticing about Windows 10 for phones is that Microsoft is moving away from the their typography heavy UI and moving more toward how UI in Android and iOS is done. Perhaps this is to make Windows UI more mainstream so that users coming from other platforms feel more comfortable with the UI and developers don’t feel that they need to redo their entire UI in order to bring their apps to Windows.</span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><span>It will be interesting to see how Windows 10 for phones changes over the next few months. As a user I’m looking forward to Windows 10 and I plan to stick with a Windows Phone for now. As a developer we are going to see a lot come out at BUILD this year. I’m hopeful that Microsoft will be able to improve the APIs and tools so developers can build more powerful apps that work across all Windows 10 devices from phones to tablets, laptops, desktops and XBox.</span></p>ArchISO with Broadcom Driverstag:www.techhui.com,2015-02-16:1702911:BlogPost:1318402015-02-16T10:15:26.000ZDavid Chunghttp://www.techhui.com/profile/DavidChung
<p><span style="font-size: 13px;">As a reference for myself in the future and for others who may find this information useful, this blog post describes my experience with installing </span><a href="http://www.archlinux.org" style="font-size: 13px;" target="_blank">ArchLinux</a> <span style="font-size: 13px;">on a machine that requires Broadcom wireless drivers for Wi-Fi and Ethernet isn't available.</span></p>
<p>I recently decided to install ArchLinux on my…</p>
<p><span style="font-size: 13px;">As a reference for myself in the future and for others who may find this information useful, this blog post describes my experience with installing </span><a href="http://www.archlinux.org" target="_blank" style="font-size: 13px;">ArchLinux</a> <span style="font-size: 13px;">on a machine that requires Broadcom wireless drivers for Wi-Fi and Ethernet isn't available.</span></p>
<p>I recently decided to install ArchLinux on my <a href="https://en.wikipedia.org/wiki/Dell_Inspiron_1525" target="_blank">Dell Inspiron 1525</a>, which in the past I had to connect the computer to the Internet via an Ethernet cable since ArchLinux didn't come with the necessary Broadcom wireless drivers for my computer. Furthermore, the ArchLinux installer requires an Internet connection to download the packages for installation.</p>
<p>After some research, I discovered <a href="https://wiki.archlinux.org/index.php/Archiso" target="_blank">archiso</a>, which allows one to create a custom-built live CD image for ArchLinux.</p>
<p>So my goal was to create a live CD that had the necessary wireless drivers so that I can proceed with the installation without needing an Ethernet cable.</p>
<h1>Prerequisites</h1>
<p>For a successful ArchLinux install with a machine that has Broadcom wireless, you will need:</p>
<ul>
<li>Of course, your current environment needs to be ArchLinux</li>
<li>Your current environment needs to be x86_64. Otherwise, archiso won't run</li>
<li>Your current environment needs Internet access</li>
</ul>
<h1>ArchISO Journal</h1>
<p>Run in a root terminal and create a directory to work in</p>
<p><span style="font-family: terminal,monaco; color: #808080;">sudo su -<br/> cd ~<br/> mkdir archiso<br/></span></p>
<p></p>
<p>Install <a href="https://www.archlinux.org/packages/?name=archiso" target="_blank">archiso</a></p>
<p><span style="font-family: terminal,monaco; color: #808080;">pacman -S archiso</span></p>
<p></p>
<p>Copy the base releng directory tree into your work directory<br/> <span style="font-family: terminal,monaco; color: #808080;">cp -r /usr/share/archiso/configs/releng/ archiso</span></p>
<p></p>
<p>Do whatever you need to do to get <a href="https://wiki.archlinux.org/index.php/Broadcom_wireless" target="_blank">Broadcom wireless</a>. For me, I need <a href="https://aur.archlinux.org/packages/broadcom-wl/" target="_blank">broadcom-wl</a> since I have the LP hardware and I don't want to go download firmware and broadcom-wl works so well for me.</p>
<p>So, the next step for me is to build the broadcom-wl package from <a href="https://wiki.archlinux.org/index.php/Arch_User_Repository" target="_blank">AUR</a>.</p>
<p></p>
<p>When that's done, then I need to create a custom repository containing the built broadcom-wl package.</p>
<p><span style="font-family: terminal,monaco; color: #808080;">mkdir /root/custompkg/i686<br/> <span style="font-family: terminal,monaco; color: #808080;">mkdir /root/custompkg/</span>x86_64</span></p>
<p></p>
<p>After copying the built packages to the above directories, I create the repo database.</p>
<p><span style="font-family: terminal,monaco; color: #808080;">repo-add /root/custompkgs/i686/custompkgs.db.tar.gz /root/custompkgs/i686/broadcom-wl*<br/> <span style="font-family: terminal,monaco; color: #808080;">repo-add /root/custompkgs/x86_64/custompkgs.db.tar.gz /root/custompkgs/x86_64/broadcom-wl*</span><br/></span></p>
<p></p>
<p>Now add the custom repo to the pacman configuration in the work directory (/root/archiso/pacman.conf):</p>
<p><span style="font-family: terminal,monaco; color: #808080;">[custompkgs]</span><br/> <span style="font-family: terminal,monaco; color: #808080;">SigLevel = Optional TrustAll</span><br/> <span style="font-family: terminal,monaco; color: #808080;">Server = file:///root/custompkgs/$arch</span></p>
<p></p>
<p>Modify /root/archiso/releng/airootfs/root/customize_airootfs.sh to make configuration changes for the system as needed. In my case, I needed to blacklist b43 and ssb:</p>
<p><span style="font-family: terminal,monaco; color: #808080;">echo "blacklist b43" >> /etc/modprobe.d/blacklist.conf</span><br/> <span style="font-family: terminal,monaco; color: #808080;">echo "blacklist ssb" >> /etc/modprobe.d/blacklist.conf</span></p>
<p></p>
<p>After all that, run /root/archiso/releng/build.sh.</p>
<p>The script will create /root/archiso/releng/out/archlinux-*.dual.iso, which can be used to create your live CD and perform the install with the Broadcom wireless drivers enabled!</p>SB 627: Continuation of the Manoa Innovation Centertag:www.techhui.com,2015-02-16:1702911:BlogPost:1334392015-02-16T22:00:00.000ZDaniel Leuckhttp://www.techhui.com/profile/dleuck
<p><a href="http://www.htdc.org/sites/default/files/micpics.jpg?width=200" target="_blank"><img class="align-left" src="http://www.htdc.org/sites/default/files/micpics.jpg?width=200"></img></a> On behalf of Ikayzo, inc., formerly a Manoa Innovation Center tenant, I respectfully submit testimony in STRONG SUPPORT of SB 627, the ten year extension of HTDC's land lease agreement with the University of Hawaii that facilitates uninterrupted operation of the Manoa Innovation Center.</p>
<p><br></br> The center played a critical role in the formation and scaling of both Ikayzo and Contix. In…</p>
<p><a target="_blank" href="http://www.htdc.org/sites/default/files/micpics.jpg?width=200"><img class="align-left" src="http://www.htdc.org/sites/default/files/micpics.jpg?width=200"/></a>On behalf of Ikayzo, inc., formerly a Manoa Innovation Center tenant, I respectfully submit testimony in STRONG SUPPORT of SB 627, the ten year extension of HTDC's land lease agreement with the University of Hawaii that facilitates uninterrupted operation of the Manoa Innovation Center.</p>
<p><br/> The center played a critical role in the formation and scaling of both Ikayzo and Contix. In addition to the facility, which is well tuned to a technology startup’s needs, we utilized their workshops, professional service provider program, CEO forum and frequently benefited from the expertise of our neighbor companies as well as HTDC’s superb staff.</p>
<p><br/> The center’s proximity to UH Manoa allowed us to easily collaborate with the university in numerous ways including working with professors, finding interns who were matches for our needs (many of whom are now employees) and working together on tech conferences that benefited the community. Together, the University of Hawaii and the Manoa Innovation Center comprise a unique innovation ecosystem that benefits both the school and the center’s technology startups in innumerable ways.</p>
<p><br/> It is my sincere hope that many other Hawaiʻi startups will be afforded the opportunity to benefit from the Manoa Innovation Center’s services and facilities as we did.</p>
<p><br/> Thank you for the opportunity to offer testimony on <a href="http://www.capitol.hawaii.gov/measure_indiv.aspx?billtype=SB&billnumber=627" target="_blank">this bill</a>.</p>Programming for Kidstag:www.techhui.com,2015-01-04:1702911:BlogPost:1323312015-01-04T23:05:58.000ZDouglas Chinghttp://www.techhui.com/profile/DouglasChing
<p dir="ltr">One thing I noticed in 2014 was an overall push to “learn to code”. Today computers are everywhere and we are only getting more reliant on them every day. It makes sense that more people and kids in particular are being exposed to programming. Here are some resources that I have found very easy to set up if you want to teach your kids about programming. Since I mainly use Windows this will be mainly a Windows centric post. Also because this is a list of resources for kids I…</p>
<p dir="ltr">One thing I noticed in 2014 was an overall push to “learn to code”. Today computers are everywhere and we are only getting more reliant on them every day. It makes sense that more people and kids in particular are being exposed to programming. Here are some resources that I have found very easy to set up if you want to teach your kids about programming. Since I mainly use Windows this will be mainly a Windows centric post. Also because this is a list of resources for kids I am focusing on things that focus on at least programming concepts and don’t put emphasis on the actual typing of code or syntax.</p>
<p><span><span> </span></span></p>
<p dir="ltr"><strong>code.org</strong></p>
<p dir="ltr"><span>First of all code.org is one of the best places to go to learn the basics of coding. It contains simple and fun videos, games and online workshops as well as links to other apps and resources. Their “Code with Anna and Elsa” (from Frozen) is a really cool tool for kids to learn about coding. You’ll see many of the below resources have been featured on code.org.</span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><strong>Scratch</strong></p>
<p dir="ltr"><a href="http://scratch.mit.edu/"><span>http://scratch.mit.edu/</span></a></p>
<p dir="ltr"><span>Scratch is probably one of the more well-known and popular tools for teaching kids to code. Multimedia (images, sounds) are imported into the “stage”. The coding is done using blocks that can be dragged to the “Scripts” area. One of the more compelling elements of Scratch is that it is easy to copy someone else’s work and build on it. Work can also be easily displayed online for all to see.</span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><a href="http://storage.ning.com/topology/rest/1.0/file/get/396594337?profile=original" target="_self"><img src="http://storage.ning.com/topology/rest/1.0/file/get/396594337?profile=RESIZE_1024x1024" width="750" class="align-full"></a></p>
<p><span><span> </span></span></p>
<p dir="ltr"><span>Parent friendliness: Scratch is free and everything is done in the browser so there is no application you need to install, although it does require the Flash plugin for your browser.</span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><strong>Lightbot</strong></p>
<p dir="ltr"><span><a href="http://lightbot.com/">http://lightbot.com/</a></span></p>
<p dir="ltr"><span>Lightbot is a programming puzzle game that is available on various platforms. It teaches programming concepts rather than actual coding. If your kid likes games more than he/she like creating then this app could be a good place to start.</span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><span><a href="http://storage.ning.com/topology/rest/1.0/file/get/396595648?profile=original" target="_self"><img src="http://storage.ning.com/topology/rest/1.0/file/get/396595648?profile=original" width="708" class="align-full"></a></span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><span>Parent friendliness: Lightbot ranges from around $2.99 - $4.99 on the various app stores. There is a Lightbot Jr. app for younger kids (under 9). There is also a free limited Flash version that can be tried out in a browser. Aside from the small purchase price there is nothing parents need to do to set things up for their kids.</span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><span>Kodu Game Lab</span></p>
<p dir="ltr"><a href="http://www.kodugamelab.com/"><span>http://www.kodugamelab.com/</span></a></p>
<p dir="ltr"><span>Kodu is a Windows app made specifically to create games. It focuses on game design and programming using visual commands.</span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><span><a href="http://storage.ning.com/topology/rest/1.0/file/get/396602044?profile=original" target="_self"><img src="http://storage.ning.com/topology/rest/1.0/file/get/396602044?profile=RESIZE_1024x1024" width="750" class="align-full"></a></span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><span>Parent friendliness: Kodu is free, but only for Windows. There is an XBox version for $5. The XBox and Windows Store versions are simply install and play. Anyone can set it up. The main Kodu app that runs on Windows desktop requires some prerequisite installs which most Windows computers should already have.</span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><strong>Project Spark</strong></p>
<p dir="ltr"><a href="http://welcome.projectspark.com/"><span>http://welcome.projectspark.com/</span></a></p>
<p dir="ltr"><span>Project Spark is another Windows app where kids can create worlds and games. It’s like a more refined and advanced Kodu specifically targeted toward the XBox crowd. Like Kodu it emphasises game design, but also includes ample programming concepts. Users can create games and then share them online with others. The big draw I think is the potential to create games that look and play like modern PC games and then share them with others or play others creations.</span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><span><a href="http://storage.ning.com/topology/rest/1.0/file/get/396603917?profile=original" target="_self"><img src="http://storage.ning.com/topology/rest/1.0/file/get/396603917?profile=RESIZE_1024x1024" width="750" class="align-full"></a></span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><span>Parent friendliness: It’s free on XBox and Windows. The catch is there are packs up for purchase that offer additional content and premade games. It also has fairly high requirements on Windows as the graphics it uses are similar to a modern PC game.</span></p>
<p><span id="docs-internal-guid-3312bf35-b71d-7d29-e7ac-9e6c9c3b84b7"><br></span></p>
<p dir="ltr"><strong>TouchDevelop</strong></p>
<p dir="ltr"><span><a href="https://www.touchdevelop.com/">https://www.touchdevelop.com/</a></span></p>
<p dir="ltr"><span>TouchDevelop is a bit more complicated than the resources above. Instead of using blocks of code or visual programming TouchDevelop shows users commands that are closer to actual code. What is pretty neat about TouchDevelop is that there are 3 difficulty levels. Beginners work with code that is similar to how Scratch works with limited options and commands. Intermediate users can work with more coding options and and Expert users get the ability to use “Javascripty” code. There are several tutorials that show how to create simply mobile and browser based games. Projects can be published to the web or published to mobile app stores using Windows App Studio or Apache Cordova.<br> <br></span></p>
<p><span><span><span><a href="http://storage.ning.com/topology/rest/1.0/file/get/396604166?profile=original" target="_self"><img src="http://storage.ning.com/topology/rest/1.0/file/get/396604166?profile=RESIZE_1024x1024" width="750" class="align-full"></a></span></span></span></p>
<p></p>
<p dir="ltr"></p>
<p dir="ltr"><span>Parent friendliness: It is all browser based, free and nothing needs to be installed. Creating apps using TouchDevelop is far more complicated than the options above, but it’s also much closer to the type of coding your kids will start to see if they move on from visual tools into more advanced programming tools.</span></p>
<p></p>
<p></p>10 of My Debugging Trickstag:www.techhui.com,2014-11-09:1702911:BlogPost:1319332014-11-09T10:06:07.000ZDouglas Chinghttp://www.techhui.com/profile/DouglasChing
<p dir="ltr">Being able to solve problems and fix bugs is probably high on the list of things that make a programmer a good programmer. These days programming is assisted with many tools and techniques. Stepping through code using advanced IDEs and debuggers find many issues before they become issues. Intellisense, code completion and syntax highlighting also reduce bugs before they can become bugs. Exception handling and error logging help a lot when issues occur in programs. Testing…</p>
<p dir="ltr">Being able to solve problems and fix bugs is probably high on the list of things that make a programmer a good programmer. These days programming is assisted with many tools and techniques. Stepping through code using advanced IDEs and debuggers find many issues before they become issues. Intellisense, code completion and syntax highlighting also reduce bugs before they can become bugs. Exception handling and error logging help a lot when issues occur in programs. Testing frameworks and methodologies help us to validate code and functionality in addition to lessening the introduction of additional bugs.</p>
<p><span><span> </span></span></p>
<p dir="ltr"><span>What happens when all of that fails or when we are given an application we are not familiar with or is not debug or test friendly? What types of non technical techniques do you use when attacking a difficult issue? Here are 10 things I find myself doing when confronted with a hard to find bug.</span></p>
<p><span><span> </span></span></p>
<ol>
<li dir="ltr"><p dir="ltr"><span>Compare files and environment. Make sure your code is exactly the same as the code where the issue takes place. If possible make sure your environment is also the same. Pay attention to configuration and versioning. Sometimes it’s not the code, but mismatched versions.</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Try to keep things simple. Some of the worse bugs are the ones with simple solutions. If you find yourself coming up with complicated solutions to fix a bug step back and consider whether things really need to be complicated.</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Don’t rush. Not many people work better when they rush. Take enough time so that you don’t skip over obvious issues.</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Keep your users in mind. As a programmer we tend to know how a program works and will often avoid doing things that will break things. Trying to remember that users will always do things in a way that was not expected can help to open up possible issues. Make sure to get detailed reproduction steps and details about the user’s environment. I always try to remember the Who, What, When, Where, Why and Hows of an issue.</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Remember that if something is going wrong the majority of the time it’s not the computer’s fault. We may sometimes come across an error where we think it’s an issue with the framework or something out of our control. Unfortunately it’s more likely there is an error in our code. Remembering this can prevent going down paths not related to the issue.</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Do things an alternate way. If the functionality is simple enough explore doing it an alternate way. This will help to uncover what the program needs to do. If your alternate way exhibits the same issues you can narrow down the causes. Even better if your alternate way ends up working. Even if you don’t write any alternative code, just thinking about it can help to solve the issue.</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Break things down. If you have unfamiliar or complicated code it may help to break it down into its simplest parts. Take out everything except for the basic functionality and build back up to see where an error is coming from. Sometimes it helps to isolate code. Take it out of the application and put it into an empty application to see what happens.</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Have someone else look at the issue. Sometimes focusing on an issue results in focusing on an entirely wrong area or becoming blind to an obvious bug. Having someone else look at the issue can bring new things to light.</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Break things. Breaking code can sometimes help you to understand code far better than only reading or stepping through code. Like reading a book we tend to overlook things that we have seen countless times before. Breaking something on purpose can help to break out of the mentality that you think you know how something is working and open up new ways to attack the problem.</span></p>
</li>
<li dir="ltr"><p dir="ltr"><span>Take some time away or sleep on it. This may not be an ideal method when you have a deadline, but many times taking a break from trying to fix a bug results in fresh perspective needed to find the solution. Resting your brain and destressing also helps.</span></p>
</li>
</ol>
<p><span><span> </span></span></p>
<p dir="ltr"><span>Do you have any techniques that you use to make those invisible bugs visible?</span></p>
<p><span id="docs-internal-guid-1f411ed0-9401-0133-845d-d03682035d7e"><br/><br/></span></p>Nodeschool in Honolulutag:www.techhui.com,2014-11-08:1702911:BlogPost:1321112014-11-08T00:30:00.000ZGeorge Leehttp://www.techhui.com/profile/GeorgeLee
<p>At the time of this writing, we have had two <a href="http://nodeschool.io" target="_blank">Nodeschool</a> events here in sunny Honolulu, so tl;dr it’s been pretty successful. Admittedly, I had concerns going in to the first event. Sure, Nodeschool has been successful worldwide with new chapters opening every day, but that doesn’t mean it’d be a guaranteed success. Being the organizer for <a href="http://www.facebook.com/groups/ohanajs" target="_blank">Ohana.js</a> (our local Javascript…</p>
<p>At the time of this writing, we have had two <a href="http://nodeschool.io" target="_blank">Nodeschool</a> events here in sunny Honolulu, so tl;dr it’s been pretty successful. Admittedly, I had concerns going in to the first event. Sure, Nodeschool has been successful worldwide with new chapters opening every day, but that doesn’t mean it’d be a guaranteed success. Being the organizer for <a href="http://www.facebook.com/groups/ohanajs" target="_blank">Ohana.js</a> (our local Javascript user’s group), I was unsure of how well it’d be received given that you can do the workshops in the comfort of your own home. I think learning with others is great, but I also think it’s a hard sell on others.</p>
<p>Our first meetup was on October 7th, 2014 and we had about 25 people attend. Most of the attendees were either regulars to Ohana.js meetups or students at <a href="http://www.devleague.com/" target="_blank">Dev League</a> (our local hacker school). The Dev League students only had about 2 weeks of Javascript under their belt (and at the time of this event, the <a href="https://www.github.com/sethvincent/javascripting" target="_blank">Javascripting</a> workshop was not available), but their instructors and TAs were available for help. In the future, we’ll definitely check out the Javascripting workshop for people who might be new to programming.</p>
<p>At the first meetup, we had a lot of trouble with the wifi connection, but we eventually got it to work. Once that was up, we did some introductions to break the ice. <a href="https://twitter.com/wangbus" target="_blank">@wangbus</a> and <a href="https://twitter.com/taesup" target="_blank">@taesup</a> of <a href="http://slickage.com/" target="_blank">Slickage</a> then did a great job of explaining what Node is and how they use it at their company. Many thanks to them for doing that introduction, as I was ready to jump in to code right away.</p>
<p>For the first event, we just stuck with <a href="https://www.github.com/rvagg/learnyounode" target="_blank">Learn You Node</a>. We went through the exercises one at a time, first introducing the problem before giving students time to implement a solution. We had a good ratio of students to mentors, although I got the sense that some mentors wanted to be working on workshops themselves. @wangbus, @taesup, and I took turns implementing solutions to the first 6 exercises in Learn You Node. Overall, everyone was able to follow along and the response was very positive. We proposed that we do these events monthly and the group was unanimous in agreement.</p>
<p>Before the second event, I set up a poll on Facebook asking attendees what workshops they were interested in. The clear winner was <a href="https://www.github.com/substack/stream-adventure" target="_blank">Stream Adventure</a>, so we had two groups at the second Nodeschool event on November 4th, 2014: one that continued Learn You Node and one that started on Stream Adventure. Our turnout at the second event was a bit smaller (partly my fault, as I didn’t advertise this one as much), but there were still some new faces. @taesup and I lead the Learn You Node group, where we quickly went over the first 6 before getting started on 7. By the end of the night, we only got to exercise 9, which was a bit challenging for those who are newer to programming. I believe the Stream Adventure group got to exercise 6 or 7 before calling it quits.</p>
<p>Overall, I’d say the event was a success. There are some things I need to get better at (namely sponsorships or at least getting some snacks in the room), but the feedback has been overwhelmingly positive. Some attendees continued to work on workshops after the event was over. Clearly, my fears of Nodeschool events not working were unfounded. The events weren’t flawless, but we’re going to get better every time we do it.</p>
<p>Finally, mahalo to @wangbus, @taesup, <a href="https://twitter.com/theremix" target="_blank">@theremix</a>, <a href="https://github.com/thgaskell" target="_blank">@thgaskell</a>, <a href="https://github.com/mrbarbasa" target="_blank">@mrbarbasa</a>, and others who provided suggestions, helped set up, and mentored students. I’m way too disorganized to put this all together myself. You guys are awesome!</p>The Neglected Requirements Processtag:www.techhui.com,2014-10-20:1702911:BlogPost:1299822014-10-20T15:30:00.000ZDavid Chunghttp://www.techhui.com/profile/DavidChung
<p>In my experience with software development thus far, I find that requirements analysis is often overlooked or completely ignored. I believe that by not spending some time understanding the need for the software that's about to built, the developers may really be building an inferior product, which in the end is costly for the stakeholders of the project.</p>
<p>From my experience, there is often the misconception that the requirements process, in which requirements are discovered, is a slow…</p>
<p>In my experience with software development thus far, I find that requirements analysis is often overlooked or completely ignored. I believe that by not spending some time understanding the need for the software that's about to built, the developers may really be building an inferior product, which in the end is costly for the stakeholders of the project.</p>
<p>From my experience, there is often the misconception that the requirements process, in which requirements are discovered, is a slow process and is seen as the waterfall approach of software development. The perception is that the team needs to completely understand the requirements first before development. However, the requirements specifications can be built iteratively in parallel with software projects that are built iteratively when requirements are discovered as the project evolves and additional details are discovered.</p>
<h1>Fundamental Truths</h1>
<p><a href="http://www.informit.com/store/mastering-the-requirements-process-getting-requirements-9780321815743?aid=3B419801-6640-4A1F-A653-6CD00295FCDD" target="_blank">Mastering the Requirements Process: Getting Requirements Right by Suzanne and James Robertson</a> is a great book outlining their industry-proven experiences with the requirements process.</p>
<p>In the 3rd edition, they outline some fundamental truths and I shall share my experiences with them:</p>
<h2>Requirements are not really about requirements.</h2>
<p>Too often have I seen teams come up with a requirements document that focused primarily on what they believe the software needs to do. In essence, they are describing a solution to a problem that is not yet discovered and it is often the case that the software that is ultimately built is actually not needed.</p>
<p>Robertson explains that the requirements process is to understand the problem that the owner wants to solve and to describe a solution to address that problem directly.</p>
<h2>If we must build software, then it must be optimally valuable for its owner.</h2>
<p>This truth is often encountered after the team builds the software specified in the requirements document above. When the needs are not yet discovered but software development continues without this discovery, then the software built may not ultimately be needed by its owner and it will be seen as a failure.</p>
<p>Finding the optimal value for the owner is a matter of "understanding the owner's problem well enough to deliver a solution that provides the best payback at the best price."</p>
<h2>If your software does not have to satisfy a need, then you can build anything. However, if it is meant to satisfy a need, then you have to know what that need is to build the right software.</h2>
<p>This truth also follows from the above truth. From my experience, software developers enjoy building software and they can definitely do it well. However, it is often the case that what they build is ultimately not needed by the owner so the team ends up exceeding their budget.</p>
<p>Robertson mentions the danger of "[eliminating] the requirements discovery and [rushing] headlong into constructing the (inevitably) wrong product." Unfortunately, that observation is very true as the software development team are eager to build software while management often overlook the importance of requirements discovery.</p>
<p>I think the takeaway from this truth is that software developers can build anything but as a team, we need to know what need we are attempting to address by building the software and constrain our solution accordingly so that we don't end up exceeding our budget.</p>
<h2>There is an important difference between building a piece of software and solving a business problem. The former does not necessarily accomplish the latter.</h2>
<p>Software owners need to understand the cost of developing and deploying software. If they want their software to solve a problem, then "any development effort must start with the problem, and not with a perceived solution."</p>
<p>We need to be careful not to jump straight to the solution without understanding what the problem is. As mentioned above, I typically see software development teams eager to start building and they can come up with many solutions but if they are not constrained to the problem that the owner wants to solve, then they may end up wasting resources.</p>
<h2>The requirements do not have to be written, but they have to become known to the builders.</h2>
<p>Robertson claims that "the developers are almost always underwhelmed by [the requirements specifications] and either ignore it or willfully comply with it" but I find that developers often appreciate requirements specifications at least as a reference.</p>
<p>I believe the following statement from Robertson can't be stressed enough:</p>
<blockquote><p>In many cases the act of writing a requirement helps both the business analyst and the stakeholder to completely understand it. As well as improving the understanding, a correctly written requirement provides trace documentation. The rationale of a requirement, or the justification on a story card, documents the team’s decisions. It also provides the testers and the developers with a clear indication of the importance of the requirement, which in turn suggests how much effort to expend on it. Additionally, the cost of future maintenance is reduced when the maintainers know why a requirement exists.</p>
</blockquote>
<p>In general, complete requirements reduces pain points and errors in the development process. Maintenance is especially a pain when requirements are not complete because then you are forced to revisit the requirements with the likelihood of introducing additional errors.</p>
<p>Overall, by skipping requirements analysis in the beginning, you will definitely pay for it during maintenance.</p>
<h2>Your customer won’t always give you the right answer. Sometimes it is impossible for the customer to know what is right, and sometimes he just doesn’t know what he needs.</h2>
<p>This truth is tough because you want to make the customer happy but at the same time, you have to realize that you need to take the customers' stories as a factor in coming up with a solution to the problem they are trying to address rather than being a definitive answer to their problem.</p>
<p>It is often frustrating when the solution needs to change because not all aspects of the problem were explored. So when a customer states a solution, one has to prod some more to ensure that the customer's needs are going to be met.</p>
<h2>Requirements do not come about by chance. There needs to be some kind of orderly process for developing them.</h2>
<p>I think this truth is a given. There needs to be some process in place to extract requirements.</p>
<p>Of course, the process needs to be in-tune with the culture of the team. Otherwise, team members will likely resist or not put effort into the process.</p>
<h2>You can be as iterative as you want, but you still need to understand what the business needs.</h2>
<p>I have often seen software developers ignore requirements simply because they are working in an agile environment. However, the way I see it,iterative development requires you to make advances to the project and if you're working on something that's not needed, then you're essentially blocking forward progress!</p>
<p>What I've seen that I think works well in an agile environment is to allocate time to do some requirements discovery work that blocks the implementation tasks. For example, in a SCRUM-like environment, you could have a discovery story that blocks an implementation story and schedule accordingly.</p>
<h2>There is no silver bullet. All our methods and tools will not compensate for poor thought and poor workmanship.</h2>
<p>Requirements analysis is hard work and I believe it is mastered through regular practice.</p>
<p>Therefore, I think it's beneficial if teams started working on their requirements analysis skills because as Robertson states, there is no one-size-fits-all method on getting requirements right -- it's whatever works best with the culture of the company.</p>
<h2>Requirements, if they are to be implemented successfully, must be measurable and testable.</h2>
<p>When requirements are done correctly, you can easily draw up a test plan that accompanies your requirements specifications because the requirements already state their success criterion.</p>
<p>It is often much more painful to come up with a test plan later in the project.</p>
<p>All requirements need to be testable so that you can verify that the requirement is indeed met so "if you cannot find a measurement for a requirement, then it is not a requirement, but merely an idle thought."</p>
<h2>You, the business analyst, will change the way the user thinks about his problem, either now or later.</h2>
<p>Requirements analysis is a group effort. A single analyst can't possibly think of all aspects of a problem and so requires help from other stakeholders of project to write up complete requirements.</p>
<p>After several interactions and guidance with stakeholders, they will eventually understand what you're looking for in terms of requirements and begin to start thinking their problem in that manner.</p>
<h1>Next Posts</h1>
<p>Consider this blog post as an introduction to the requirements process and my experience with it in software development teams. I think I will share specific areas mentioned in the truths above from past experiences in greater details in future posts.</p>Testing in iOS7 and Kiwitag:www.techhui.com,2014-09-23:1702911:BlogPost:1315892014-09-23T02:14:09.000ZGeorge Leehttp://www.techhui.com/profile/GeorgeLee
<p>For whatever reason, testing did not seem to be a focal part of Apple's development tools until Xcode 5. Prior to then, tests were typically implemented using OCUnit, but it was difficult to integrate with the Cocoa framework. That changed in Xcode 5, where <a href="https://developer.apple.com/Library/ios/documentation/DeveloperTools/Conceptual/testing_with_xcode/A3-transitioning_ocunit_to_xctest/A3-transitioning_ocunit_to_xctest.html" target="_blank">OCUnit was swapped out for XCTest…</a></p>
<p>For whatever reason, testing did not seem to be a focal part of Apple's development tools until Xcode 5. Prior to then, tests were typically implemented using OCUnit, but it was difficult to integrate with the Cocoa framework. That changed in Xcode 5, where <a href="https://developer.apple.com/Library/ios/documentation/DeveloperTools/Conceptual/testing_with_xcode/A3-transitioning_ocunit_to_xctest/A3-transitioning_ocunit_to_xctest.html" target="_blank">OCUnit was swapped out for XCTest</a> and better testing support was added to Xcode. In addition to that change, the advent of <a href="http://cocoapods.org/" target="_blank">CocoaPods</a> let other developers create their own testing frameworks that can be installed into other user's Xcode workspace. This allows developers to create pods for different approaches to testing like <a href="http://en.wikipedia.org/wiki/Behavior-driven_development" target="_blank">Behavior Driven Development (BDD</a>).</p>
<p>Those of us who work with <a href="http://rubyonrails.org/" target="_blank">Ruby on Rails</a> regularly are aware of BDD thanks to <a href="http://rspec.info/" target="_blank">RSpec</a>. <a href="https://github.com/kiwi-bdd/Kiwi" target="_blank">Kiwi</a> is an iOS testing framework which acts very much like Rspec but for Objective C. Of course, the new hotness is now Swift and iOS8, so some of this may not apply. Kiwi is not compatible with Swift at the moment, although there are likely newer iOS frameworks out there that do support it. XCTest might also be worth checking out too, now that Apple has provided better integration for tests in Xcode 6.</p>
<p>There's a demo project up on <a href="http://github.com/keokilee/hicrime" target="_blank">Github</a>. It was built on Xcode 6 and iOS 8 and there appear to be some bugs in it (as members of our local iOS group can attest to). Nonetheless, let me walk through some of the features in Kiwi and iOS testing.</p>
<p><strong>Basic specs</strong></p>
<p>Here's a simple Kiwi Spec</p>
<div style="font-family: monospace;"><br/> #import <Kiwi/Kiwi.h><p>#import "ViewController.h"</p>
<p>SPEC_BEGIN(ViewControllerSpec)</p>
<p>describe(@"ViewController", ^{</p>
<p> let(controller, ^{return [[ViewController alloc] init];});</p>
<p> beforeEach(^{</p>
<p> [controller viewDidLoad];</p>
<p> );</p>
<p> it(@"initializes an empty list of incidents", ^{</p>
<p> [[[controller incidents] should] beEmpty];</p>
<p> });</p>
<p>});</p>
<p>SPEC_END</p>
<p></p>
</div>
<p>We start with a describe block, which tells us what we are testing. In it is a let block, which lets me declare a variable (controller in this case) that is created before each test. This makes sure we're always working with a fresh instance of a controller. We also have a beforeEach block where we do some pre-test setup. In this case, we're running the viewDidLoad function to trigger any view setup. Finally, we have an "it" block for our test. We are checking that the incidents array is empty (has 0 elements).</p>
<p>For those are unfamiliar with Rspec and specifications, this might look a little weird. One of the major differences between standard unit tests and specifications (specs) is that test names are more descriptive. When the test actually runs, the output would read as "ViewController initializes an empty list of incidents".</p>
<p><strong>Mocks and Spies</strong></p>
<p>The Hicrime app makes network requests, which makes testing difficult. Kiwi has built-in support for mocking and stubbing.</p>
<div style="font-family: monospace;"><br/> #import <Kiwi/Kiwi.h><p>#import "ViewController.h"</p>
<p>#import "AFHTTPRequestOperationManager.h"</p>
<p>SPEC_BEGIN(MocksControllerSpec)</p>
<p>describe(@"ViewController", ^{</p>
<p> let(controller, ^{return [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"ViewController"];</p>
<p> let(mockManager, ^{return [AFHTTPRequestOperationManager mock];});</p>
<p> beforeEach(^{</p>
<p> [AFHTTPRequestOperationManager stub:@selector(manager) andReturn:mockManager];</p>
<p> });</p>
<p> it(@"fetches using the data.honolulu.gov endpoint", ^{</p>
<p> KWCaptureSpy *spy = [mockManager captureArgument:@selector(GET:parameters:success:failure:) atIndex:0];</p>
<p> [controller loadView];</p>
<p> [controller viewDidLoad];</p>
<p> [[[spy argument] should] equal:@"http://data.honolulu.gov/resource/a96q-gyhq.json"];</p>
<p> });</p>
<p>});</p>
<p>SPEC_END</p>
<p></p>
</div>
<p>In this spec, we're using <a href="https://github.com/AFNetworking/AFNetworking" target="_blank">AFNetworking</a>'s HTTPRequestOperationManager and mocking it out so that it doesn't actually run. We then create a spy to capture the URL parameter to AFNetworking's GET method. After calling viewDidLoad, we check that we received the correct URL endpoint for the crime data on the <a href="http://data.honolulu.gov" target="_blank">Honolulu open data site</a>.</p>
<p><strong>Continuous Integration</strong></p>
<p>Facebook actually open sourced a build tool for Cocoa projects called <a href="https://github.com/facebook/xctool" target="_blank">xctool</a> that's based off of Apple's <a href="https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/xcodebuild.1.html" target="_blank">xcodebuild</a>. The main benefit is that xctool can be used for continuous integration. <a href="https://travis-ci.org/" target="_blank">TravisCI</a>, a hosted CI server that's free for open source projects, uses xctool by default to run your tests. All you need to do is provide the workspace file and the scheme for your project. A travis.yml for our system might look like:</p>
<div style="font-family: monospace;"><br/> language: objective-c<br/> xcode_workspace: HICrime.xcworkspace<br/> xcode_scheme: HICrime</div>
<p></p>
<p>For more info, check out their <a href="http://docs.travis-ci.com/user/languages/objective-c/" target="_blank">documentation on setting up an Objective C project</a>. Also note that as of this writing, TravisCI does not have support for iOS 8. They should have support in the near future.</p>
<p>Testing with Kiwi worked pretty well in our last iOS 7 project. However, now that Swift is offically released, I'm on the lookout for a BDD framework that supports Apple's new language. If anyone out there has recommendations on a testing framework (or if you just stick to XCTest), let me know!</p>Neurological Tech Shift: How Technology Affects Our Brain’s Behaviortag:www.techhui.com,2014-09-22:1702911:BlogPost:1317882014-09-22T17:38:48.000ZKyle H. Alberthttp://www.techhui.com/profile/KyleHAlbert
<p>The evolution of the Internet and various esteemed digital technologies during the 21st century wholly revolutionized the way we do business, socialize with people, and consume entertainment. Whether you are a college student or professional, digital devices serve as a valuable tool in fulfilling your personal and work-related endeavors. But, have you ever wonder about the impacts of your daily exposure to technology? Without even realizing it, there’s a scientific and a neurological shift…</p>
<p>The evolution of the Internet and various esteemed digital technologies during the 21st century wholly revolutionized the way we do business, socialize with people, and consume entertainment. Whether you are a college student or professional, digital devices serve as a valuable tool in fulfilling your personal and work-related endeavors. But, have you ever wonder about the impacts of your daily exposure to technology? Without even realizing it, there’s a scientific and a neurological shift happening in the way we process information, communicate, read, and interact with each other. Some of them are good, while others are alarming. Below, we’ve listed down the different ways on how technology vehemently affects your brain system.</p>
<p><strong><a href="http://storage.ning.com/topology/rest/1.0/file/get/396592598?profile=original" target="_self"><img src="http://storage.ning.com/topology/rest/1.0/file/get/396592598?profile=original" width="200" class="align-left"></a>The Internet is Rewiring Our Brains</strong></p>
<p>Research confirmed that constant exposure to technology does not only change our lives, but also our brains. <a href="http://newsroom.ucla.edu/stories/081015_gary-small-ibrain">Dr. Gary Small</a>, director of the University of California’s Memory and Aging Research Center, believes that “the human brain is malleable, always changing in response to the environment.” Digital Natives (the ones who were born in the world of cell phones, laptops, text messaging, and social networking) suffer from neutral circuitry. Thus, they are most likely to experience complex reasoning, heightened multitasking skills, and enhanced decision-making. On the other hand, they’ll also suffer from the “rewired brain syndrome,” which is characterized by diminished skills and lessened emotional aptitude such as empathy; where people can act robotic.</p>
<p><strong>Technology Tells Our Brain to Stay Awake</strong></p>
<p>According to a 2013 data presented by Belfast Telegraph, nine of 10 people are sacrificing their good night’s sleep just to be able to access the internet and stay in touch with the virtual world. It’s because of the “blue light” emitted by our mobile phones and tablets that mimic the daylight effect which suppresses the production of melatonin, a brain chemical which helps us sleep. In order to fight this, Dr Chris Idzikowski of Edinburgh Sleep Center suggests that “sufferers should try and avoid using phones, laptops, and other screen-based devices for at least an hour before bed.” Another method given by Bob Kelley, a correspondent for many different news portals, is to engage in a digital therapy, wherein, you will need to use your mobile device to improve your sleeping patterns and stay well-rested. For example, <a href="http://news.o2.co.uk/2014/09/01/dont-hit-snooze-the-5-best-apps-to-get-you-out-of-bed-in-the-morning/">there are apps that monitors your sleep cycle</a>, and wakes you during the lightest phase of your sleep, ensuring you have a better overall sleeping experience. (source: <a href="http://www.o2.co.uk">www.o2.co.uk</a>)</p>
<p> </p>
<p><strong>Affecting Our Ability To Read</strong></p>
<p>As you get exposed to digital resources, your ability to read books with lengthy articles are also affected. Too much exposure to virtual media will inhibit our brain’s capacity to appreciate longer sentences, fully constructed arguments, and complex plot/narrative. It also affects our brain’s neutral pathways, which could shorten our attention span. This is due to the fact that as internet users, we’re used to skim on web articles impatiently and switch from different tabs, just to find an interesting online content.</p>
<p></p>
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/396592645?profile=original" target="_self"><img src="http://storage.ning.com/topology/rest/1.0/file/get/396592645?profile=original" width="500" class="align-center"></a></p>
<p><strong>Addictive To Our Brains</strong></p>
<p>In an article from WebMD entitled <a href="http://www.webmd.com/mental-health/features/when-technology-addiction-takes-over-your-life">“The Paradox of Modern Life,”</a> Edward Hallowell, MD reiterated that “the great thing about modern life is you can do so much, [thus], the curse of modern life is you can do so much." Being constantly exposed to electronic devices as well as the internet may lead to technological addiction or what is being coined as “technology overload.” This type of neurological shift can directly interfere with our day-to-day activities which include normal conversations, social events, work, and business. Moreover, this type of obsession with the digital world may lead to severe cases of insomnia, added by Dr. Hallowell.</p>
<p><strong>Losing Our Ability To Contextualize</strong></p>
<p>GPS and other navigational services such as Google Maps may lead to lost sense of place. It’s because they are capable of showing and giving directions, leading to unchallenged brain. If we rely on these types of tools, we are losing our brain’s ability to contextualize or to think and provide information about an underlying situation as it happens.</p>
<p>So, these are the five major effects of excessive technological consumption to our brains. Take note that results may vary from one person to another, as our brain has its own distinct way of processing information. Did you find our post helpful? Can you relate to one of the scenarios we’ve written above? Share with us your interesting experiences and arguments by posting a comment below.</p>
<p></p>
<p>Images courtesy of : Merrill College of Journalism Press Releases and Pacific Northwest National Laboratory - PNNL via flickr licensed under creative commons.</p>
<p> </p>Importing large data sets in Rails and Postgrestag:www.techhui.com,2014-09-17:1702911:BlogPost:1315592014-09-17T01:00:00.000ZLeo Dhttp://www.techhui.com/profile/LeoD
<p>In one of my recent projects, I needed to import a lot of data from csv files into a database as persisted domain objects in a web application. This file import functionality wasn't just for application bootstrapping or a one-time legacy data migration, but for a recurring task that allowed the web app to receive updates from a third party vendor.</p>
<p>The number of records in each file could reach into the millions, so I knew from the outset that the plain-vanilla method of creating…</p>
<p>In one of my recent projects, I needed to import a lot of data from csv files into a database as persisted domain objects in a web application. This file import functionality wasn't just for application bootstrapping or a one-time legacy data migration, but for a recurring task that allowed the web app to receive updates from a third party vendor.</p>
<p>The number of records in each file could reach into the millions, so I knew from the outset that the plain-vanilla method of creating Rails ActiveRecord instances one at a time, was probably not going to cut it.</p>
<p>I implemented the data import functionality according to two approaches. The first was to use the smarter_csv and activrecord_import gems, to read records in batches from a csv file and import those batches into the database in chunks. The advantage of this method is that the code is pure Ruby, and total portability is assured. The activerecord_import and smarter_csv gems, are optimized for speed, so performance is also very good within the context of running within a framework like Rails. However, ActiveRecord has so much meta-programming magic and so many included modules,not to mention validations and callbacks, that it adds a lot of extra cpu time to any large import task. We can do even better if we avoid it completely.</p>
<p>The second approach does just that. It uses the native Potgres COPY command, and avoids ActiveRecord entirely. This approach sacrifices portability for speed. If I needed to swap out Potgres in favor of another RDBMS system, I would have to adapt the code to whatever native COPY command that RDBMS system has, or fall back to the first approach. I don't consider portability to be a binary trait, so I tend to favor mostly portable solutions, and make exceptions for areas where breaking portability is warranted. In case I need to transition to a new database vendor, having maintained a high degree of portability, means very few code changes. So, partial credit applies here, and partial portability provides most of the code re-use benefit of total portability, and allows for better performance when needed.</p>
<p>I benchmarked these two approaches using a scenario in which I need to import 1 million records from a single csv file. For reference, I also implemented a basic approach of reading one entry a time and saving it to the database, as a third benchmark comparison. I imported 1 million records using the two non-basic approaches. I only imported 1000 records using the basic approach due to its slow speed, but extrapolated the time results to infer the time for 1 million records.</p>
<p>The running time results were as follows:</p>
<ul>
<li>one at a time, 1000 records; time to import: 13.288410138; total inferred time for 1 million recods: 13,288 seconds, or 3.69 hours</li>
<li>in batches with activerecord_import and smart_csv: 1 million records, total time : 391.37 seconds</li>
<li>via copy command, 1 million records; total time: 118.55 seconds</li>
</ul>
<p></p>
<p>The results are pretty conclusive. The basic approach is about 40 times slower than the batch approach, and the batch approach is about 3 times slower than the native copy command approach. And, while these last two running times, may seem similar enough in comparison to that for the first approach, a factor of 3, can make a difference between an application being able to run real time, and not.</p>
<p>In this case, breaking convention, and using a high-performance custom approach, is well worth the risk of limited future portability issues.</p>
<p></p>
<p>Code snippets follow:</p>
<p><span>Import via Postgres copy command:</span></p>
<p><span style="font-family: 'andale mono', times;"> 1|conn = ActiveRecord::Base.connection</span><br/> <span style="font-family: 'andale mono', times;"> 2|rc = conn.raw_connection</span><br/> <span style="font-family: 'andale mono', times;"> 3|columns = <span>[:name,:description, :cost, :price, :quantity, :sale, :size]</span></span><br/> <span style="font-family: 'andale mono', times;"> 4|#rc.exec("COPY large_table (col1, col2, etc) FROM STDIN WITH CSV") #sample COPY usage</span><br/> <span style="font-family: 'andale mono', times;"> 5|started_time = Time.now</span><br/> <span style="font-family: 'andale mono', times;"> 6|rc.transaction do</span><br/> <span style="font-family: 'andale mono', times;"> 7| rc.exec("COPY fake_data_points (#{columns.map(&:to_s).join(', ')}) FROM STDIN")</span></p>
<p><span style="font-family: 'andale mono', times;"> 8| file = File.open('/tmp/fake_reporting_data.csv', 'r')</span><br/> <span style="font-family: 'andale mono', times;"> 9| index = 0</span><br/> <span style="font-family: 'andale mono', times;">10| while !file.eof?</span><br/> <span style="font-family: 'andale mono', times;">11| rc.put_copy_data(file.readline)</span><br/> <span style="font-family: 'andale mono', times;">12| end</span><br/> <span style="font-family: 'andale mono', times;">13| rc.put_copy_end<span><br/></span></span></p>
<p><span style="font-family: 'andale mono', times;">14| #show error messages</span><br/> <span style="font-family: 'andale mono', times;">15| while res = rc.get_result</span><span style="font-family: 'andale mono', times;"> </span><br/> <span style="font-family: 'andale mono', times;">16| print e_message <span>if e_message = res.error_message </span></span><br/> <span style="font-family: 'andale mono', times;">17| end</span></p>
<p><span style="font-family: 'andale mono', times;">18|end</span><br/> <span style="font-family: 'andale mono', times;">19|finished_time = Time.now</span><br/> <span style="font-family: 'andale mono', times;">20|puts "time to import: #{finished_time-started_time}"</span></p>
<p></p>
<p>Line 7 sets the template for all actual data copy executions, which occur on line 11, one per line in the csv file. Lines 14-17 run boilerplate Potgres specific code for retrieving errors.</p>
<p></p>
<p>Import via single instance at a time creation:</p>
<p><span style="font-family: 'andale mono', times;"> 1|index = 0</span><br/> <span style="font-family: 'andale mono', times;"> 2|time_to_import = Benchmark.realtime do</span><br/> <span style="font-family: 'andale mono', times;"> 3| CSV.foreach('/tmp/fake_reporting_data.csv', {:col_sep => "\t", headers: true}) do |row|</span><br/> <span style="font-family: 'andale mono', times;"> 4| break if index > 1000 #get results for 1000 records, and extraplote to a million records</span><br/> <span style="font-family: 'andale mono', times;"> 5| begin</span><br/> <span style="font-family: 'andale mono', times;"> 6| hash = Hash[row.to_hash.map{|k,v|[k.underscore.to_sym,v]}]</span><br/> <span style="font-family: 'andale mono', times;"> 7| FakeDataPoint.create!()</span><br/> <span style="font-family: 'andale mono', times;"> 8| index += 1</span><br/> <span style="font-family: 'andale mono', times;"> 9| rescue Exception</span><br/> <span style="font-family: 'andale mono', times;">10| end</span><br/> <span style="font-family: 'andale mono', times;">11| end</span><br/> <span style="font-family: 'andale mono', times;">12|end</span><br/> <span style="font-family: 'andale mono', times;">13|puts "time to import: #{time_to_import}"</span></p>
<p>The only thing worth pointing out here is that line 6 turns camel-cased csv headers like StockQuantity, to symbols for active record fields in the FakeDataPoint model, like :stock_quantity.</p>
<p>Import via activerecord_import and smart_csv gems:</p>
<p> <span style="font-family: 'andale mono', times;">1|require "csv"</span><br/> <span style="font-family: 'andale mono', times;"> 2|require "benchmark"</span><br/> <span style="font-family: 'andale mono', times;"> 3|columns = [:name,:description, :cost, :price, :quantity, :sale, :size]</span><br/> <span style="font-family: 'andale mono', times;"> 4|total_time = 0</span><br/> <span style="font-family: 'andale mono', times;"> 5|index = 0</span></p>
<p><span style="font-family: 'andale mono', times;"> 6|time_to_transform = Benchmark.realtime do</span></p>
<p><span style="font-family: 'andale mono', times;"> 7| SmarterCSV.process('/tmp/fake_reporting_data.csv', {:chunk_size => 10000, :col_sep => "\t"}) do |chunk|</span><br/> <span style="font-family: 'andale mono', times;"> 8| transformed_chunk = chunk.map{|row|columns.map{|attr|row[attr]}}</span><br/> <span style="font-family: 'andale mono', times;"> 9| FakeDataPoint.import(columns, transformed_chunk, validate: false)</span><span style="font-family: 'andale mono', times;">|</span><br/> <span style="font-family: 'andale mono', times;">10| end</span></p>
<p><span style="font-family: 'andale mono', times;">11|end</span><br/> <span style="font-family: 'andale mono', times;">12|puts "total time to import: #{total_time}"</span></p>
<p>Here, I import in chunks of 10,000 lines. On line 8, I create an array with the values in a line of the csv file, in the order in which their corresponding keys are in the columns array. The activerecord_api import function that I call on line 9, expects an array of arrays, where the inner arrays contain record attributes according to the first argument given to the function.</p>
<p>I've used the standard ruby benchmark library in these snippets. I can cut down on cruft, by avoiding the recording of start and end times, and the subtraction between the two, at the cost of including the code to benchmark in a Ruby code block.</p>
<p></p>writing a json api service in Railstag:www.techhui.com,2014-09-06:1702911:BlogPost:1316532014-09-06T03:00:00.000ZLeo Dhttp://www.techhui.com/profile/LeoD
<p>In the past few years, I've written a few json API's in rails. There are a few trends driving the popularity of API's, one being Service Oriented Architecture, and another being client side rendering. </p>
<p>Service Oriented Architecture can apply to all services, not just browser accessible ones. It consists of making services available via a standard like SOAP or JSON, to increase re-usability and modularity, SOAP and JSON being the two most popular SOA protocols. SOAP is XML-based,…</p>
<p>In the past few years, I've written a few json API's in rails. There are a few trends driving the popularity of API's, one being Service Oriented Architecture, and another being client side rendering. </p>
<p>Service Oriented Architecture can apply to all services, not just browser accessible ones. It consists of making services available via a standard like SOAP or JSON, to increase re-usability and modularity, SOAP and JSON being the two most popular SOA protocols. SOAP is XML-based, while JSON is Javascript object based, and therefore consists simply of arrays, hashes, and primitive types. JSON is by far the more popular approach in the web and Ruby communities, and is a more lightweight approach than SOAP. JSON is also the most popular choice for browser facing API's. Browser facing API's are gaining a lot of momentum as rich clients gain popularity and more of the rendering responsibility is being offloaded to the client for reasons of speed, interactivity, and integration with client-side MVC frameworks.</p>
<p>A simple JSON API in Rails might look like this:</p>
<p><span style="font-family: 'andale mono', times;"> 1|class Api::V1::SelfCare::ReceiptsController < ApplicationController</span></p>
<p><span style="font-family: 'andale mono', times;"> 2 | respond_to :json</span></p>
<p><span style="font-family: 'andale mono', times;"> 3| def payment_posted</span><br/> <span style="font-family: 'andale mono', times;"> 4| [:contract_id, :amount, :payment_type].each do |field|</span><br/> <span style="font-family: 'andale mono', times;"> 5| unless params[field]</span><br/> <span style="font-family: 'andale mono', times;"> 6| return respond_with({:success => false, :reason => "missing field: #{field}"}, :location => nil, :status => 400)</span><br/> <span style="font-family: 'andale mono', times;"> 7| end</span><br/> <span style="font-family: 'andale mono', times;"> 8| end</span><br/> <span style="font-family: 'andale mono', times;"> 9| contract_id = params[:contract_id</span><br/> <span style="font-family: 'andale mono', times;">10| amount = params[:amount]</span><br/> <span style="font-family: 'andale mono', times;">11| payment_type = params[:payment_type]</span><br/> <span style="font-family: 'andale mono', times;">12| begin</span><br/> <span style="font-family: 'andale mono', times;">13| Float(amount)</span><br/> <span style="font-family: 'andale mono', times;">14| rescue ArgumentError => e</span><br/> <span style="font-family: 'andale mono', times;">15| return respond_with({:success => false, :reason => "invalid amount: #{amount}"}, :location => nil, :status => 400)</span><br/> <span style="font-family: 'andale mono', times;">16| end</span><br/> <span style="font-family: 'andale mono', times;">17| unless ['CREDIT', 'DEBIT'].include?(payment_type)</span><br/> <span style="font-family: 'andale mono', times;">18| return respond_with({:success => false,</span> <br/> <span style="font-family: 'andale mono', times;">19| :reason => "invalid payment_type: #{payment_type}"},</span> <br/> <span style="font-family: 'andale mono', times;">20| :location => nil, :status => 400)</span><br/> <span style="font-family: 'andale mono', times;">21| end</span><br/> <span style="font-family: 'andale mono', times;">22| user = User.find_by_contract_id(contract_id)</span><br/> <span style="font-family: 'andale mono', times;">23| if user</span><br/> <span style="font-family: 'andale mono', times;">24| PaymentMailer.payment_posted(user, amount, payment_type).deliver</span><br/> <span style="font-family: 'andale mono', times;">25| respond_with({:success => true}, :location => nil)</span><br/> <span style="font-family: 'andale mono', times;">26| else</span><br/> <span style="font-family: 'andale mono', times;">27| respond_with({:success => false, :reason => 'invalid contract_id'}, :location => nil, :status => 404)</span><br/> <span style="font-family: 'andale mono', times;">28| end</span><br/> <span style="font-family: 'andale mono', times;">29| end</span><br/> <span style="font-family: 'andale mono', times;">30|end</span></p>
<p>Line 2 is a Rails directive to set this controller to respond to JSON type requests. This service only has one endpoint, which corresponds to the payment_posted method on line 3. In lines 4-8, I check that all required parameters are specified. In case of one or more missing values, I return a JSON response indicating the first missing value. I also return an HTTP status of 400. The community seems to be divided on whether JSON API's should return status as status codes or JSON messages, so I return both. The status code is useful for client side frameworks that make use of such status codes, like jQuery. The JSON message can be useful for debugging or manual testing, and can be used to return status information of arbitrary structure that an HTTP status code can't communicate.</p>
<p></p>
<p>Lines 12-16 make sure the amount parameter is parseable as a Float type, and return a message otherwise. Notice that in Rails controllers, rendering does not return from the controller method. It's actually necessary to specify the return keyword to avoid double rendering errors to return from a method before the control flow does.</p>
<p></p>
<p>Lines 17-21 check that the payment_type parameter has one of the allowable values.</p>
<p></p>
<p>Line 22 tries to find a user with the given contract id. If one is found, a thank-you email is sent to the user. If one isn't found, an error is returned to the client. I don't use an explicit return here because the control flow will result in exiting from the method regardless, so there is no risk of a double-rendering error.</p>
<p></p>
<p>The RSpec tests might look like:</p>
<p><span style="font-family: 'andale mono', times;"> 1|require "spec_helper"</span></p>
<p><span style="font-family: 'andale mono', times;"> 2|describe Api::V1::SelfCare::ReceiptsController do</span></p>
<p><span style="font-family: 'andale mono', times;"> 3| before do</span><br/> <span style="font-family: 'andale mono', times;"> 4| User.create!(:contract_id => '112233', :email => 'john@smith.org')</span><br/> <span style="font-family: 'andale mono', times;"> 5| #request.env["HTTP_ACCEPT"] = 'application/json'</span><br/> <span style="font-family: 'andale mono', times;"> 6| #request.env["HTTP_CONTENT_TYPE"] = 'application/json'</span><br/> <span style="font-family: 'andale mono', times;"> 7| end</span></p>
<p><span style="font-family: 'andale mono', times;"> 8| describe "POST #payment_posted" do</span><br/> <span style="font-family: 'andale mono', times;"> 9| params_base = {</span><br/> <span style="font-family: 'andale mono', times;">10| contract_id: '112233',</span><br/> <span style="font-family: 'andale mono', times;">11| amount: 30.10,</span><br/> <span style="font-family: 'andale mono', times;">12| payment_type: 'CREDIT'</span><br/> <span style="font-family: 'andale mono', times;">13| }</span><br/> <span style="font-family: 'andale mono', times;">14| let(:params) { params_base.dup }</span></p>
<p><span style="font-family: 'andale mono', times;">15| context "with valid attributes" do</span><br/> <span style="font-family: 'andale mono', times;">16| before :each do</span><br/> <span style="font-family: 'andale mono', times;">17| post :payment_posted, params, :format => :json</span><br/> <span style="font-family: 'andale mono', times;">18| end</span></p>
<p><span style="font-family: 'andale mono', times;">19| it "should successfully return content type as application/json" do</span><br/> <span style="font-family: 'andale mono', times;">20| response.content_type.should eq('application/json')</span><br/> <span style="font-family: 'andale mono', times;">21| end</span></p>
<p><span style="font-family: 'andale mono', times;">22| it "should return success within the body" do</span><br/> <span style="font-family: 'andale mono', times;">23| response.body.should include('"success":true')</span><br/> <span style="font-family: 'andale mono', times;">24| end</span></p>
<p><span style="font-family: 'andale mono', times;">25| it "should return status 201" do</span><br/> <span style="font-family: 'andale mono', times;">26| response.status.should eq(201)</span><br/> <span style="font-family: 'andale mono', times;">27| end</span></p>
<p><span style="font-family: 'andale mono', times;">28| end</span></p>
<p><span style="font-family: 'andale mono', times;">29|end</span></p>
<p></p>
<p>Notice the commented out JSON request header settings on line 5-6. They aren't necessary, since the JSON request format is specified on line 17, which has the equivalent effect.</p>
<p>The tests are testing anything that complicated, just that the result has the expected JSON body, the right HTTP status, and the right content type. Of course, these tests aren't comprehensive, but they illustrate the types of things to test for and the syntax/commands to do it.</p>
<p>I also like to use CURL, which is a command line network utility that can make may types of network requests, including HTTP requests, with and without SSL. With CURL, you can set HTTP headers, set cookie values, and many other things.</p>
<p>CURL is client platform and server platform agnostic. It's a great tool to use to see if an API works as advertised or to demonstrate to others that your API is working as advertised.</p>
<p>Here is a CURL invocation to test the API:</p>
<p>curl -v -H "Accept: application/json" -H "Content-type: application/json" -X POST -d ' {"contract_id":"123456", "amount": 30.95, "payment_type": "CREDIT"}' http://localhost:3000/api/v1/self_care/payment_posted</p>
<p>In this case, I've set two HTTP headers to specify the JSON type of this request. I's also specified POST parameters using the -d option. Finally, I've specified the API endpoint URL, which in this case has domain localhost:3000 because I am testing an app running locally on my machine.</p>
<p>If you want to get this running, you'll also need this snippet for your routes.rb file:</p>
<p>namespace :api do<br/> namespace :v1 do<br/> namespace :self_care do<br/> post '/payment_posted', :to => 'receipts#payment_posted'<br/> end<br/> end<br/> end</p>
<p>That's about it for this quick tour of JSON API's in Rails. For more info, I recommend "Rails 3 In Action" by Yehuda Katz and Ryan Bigg. Most of the book uses the Cucumber testing framework, but the chapter on API's uses Rspec as I've done above.</p>ASP.NET vNext - Some of the Things I Look Forward Totag:www.techhui.com,2014-09-05:1702911:BlogPost:1315532014-09-05T03:00:00.000ZDouglas Chinghttp://www.techhui.com/profile/DouglasChing
<p dir="ltr">I like to try to keep up with new technologies. Being a developer who has used Microsoft development tools all my career I’m always interested in seeing what is coming next. Recently Microsoft unveiled ASP.NET vNext and it seems to be their most ambitious version of ASP.NET yet.</p>
<p><span><span> </span></span></p>
<p dir="ltr"><span>Here are some of the things I’m looking forward to in ASP.NET vNext</span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><strong>Build Not…</strong></p>
<p dir="ltr">I like to try to keep up with new technologies. Being a developer who has used Microsoft development tools all my career I’m always interested in seeing what is coming next. Recently Microsoft unveiled ASP.NET vNext and it seems to be their most ambitious version of ASP.NET yet.</p>
<p><span><span> </span></span></p>
<p dir="ltr"><span>Here are some of the things I’m looking forward to in ASP.NET vNext</span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><strong>Build Not Needed</strong></p>
<p dir="ltr"><span>Developers will no longer need to manually build and compile ASP.NET applications. The new .NET compiler will build projects in memory. A developer will be able to change a file, hit refresh in the browser and see the changes. ASP.NET could always do something like this for certain project types, but not with MVC. Now all ASP.NET projects will have this ability to not require a build to disk as a prerequisite for deployment. This also opens up the possibility of developing entirely in the cloud in a more streamlined manner than what is possible now.</span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><strong>New Project System</strong></p>
<p dir="ltr"><span>The new project system is not Visual Studio specific. No longer are all your project files listed in a .proj file. For anyone who has experienced version and merge conflicts in Visual Studio’s project files this should be a welcome change. I believe every Microsoft developer has been caught adding files to a project, but not pushing the project changes to source control, causing compile errors when your Continuous Delivery system (or another developer) tries to compile the project. Now the project file is used more for keeping track of dependencies and more general project settings.</span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><strong>Ability to Deploy Side-by-Side Versions</strong></p>
<p dir="ltr"><span>Currently if you want to use .net 4.5.x you need to install it on the server for the entire server. With ASP.NET vNext you can run your web sites with different versions of the framework. This also means web sites will be more insulated from changes on the server and should not break as many things if an errant patch is deployed to the server.</span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><strong>Cloud Optimized Runtime</strong></p>
<p dir="ltr"><span>vNext will allow web applications to only require the libraries it needs in order to run. Previously you needed to install the entire .NET framework for ASP.NET applications (about 200MB). Now you can isolate a web site so it only contains the assemblies needed (about 11MB).</span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><strong>Develop Anywhere, Cross Platform</strong></p>
<p dir="ltr"><span>Developers will be able to develop ASP.NET application on Windows, Mac and Linux. Visual Studio will no longer be required to run an ASP.NET application. There is already a Sublime Text 3 extension for ASP.NET vNext and example on Mac OSX</span> <a href="https://github.com/ligershark/Kulture"><span>https://github.com/ligershark/Kulture</span></a> <span>and an example video: <a href="https://www.youtube.com/watch?v=1g2I9SJZ5XI">https://www.youtube.com/watch?v=1g2I9SJZ5XI</a>. Warning, do not install the CTP bits on a machine you rely on. Everything is all still early in development.</span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><strong>MVC, WebAPI and WebPages = MVC6</strong></p>
<p dir="ltr"><span>These 3 frameworks are very similar, but different enough that it’s not a seamless experience if you want to use them all together. In ASP.NET vNext they will all be part of MVC6. In vNext with these 3 combined we will hopefully have a smoother development experience with more uniform code and less confusion as to what goes where.</span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><strong>What Happened to WebForms?</strong></p>
<p dir="ltr"><span>I don’t dislike WebForms, but there is no denying that while it is still useful as an intranet LOB web application framework, it's not the best choice for building public facing web sites. While WebForms will probably still be around in vNext it’s interesting to note that everything about vNext so far has focused on ASP.NET MVC. It’s not clear how WebForms will be handled, but it is clear that ASP.NET MVC is the primary focus at the moment.</span></p>
<p><span><span> </span></span></p>
<p dir="ltr"><span>Along with previous announcements of a new open source .NET compiler</span> <a href="http://roslyn.codeplex.com/"><span>http://roslyn.codeplex.com/</span></a><span>, a new JIT compiler RyuJIT and updates to Visual Studio to support things like NPM, Grunt, solid Git integration and the increasingly numerous packages that can be had from NuGet there are a lot of things for an ASP.NET developer to look forward to. </span></p>
<p dir="ltr">ASP.NET vNext is in the "Community Technology Preview" (CTP) stage with a RTM sometime in 2015.</p>
<p><span> </span></p>Real Time Bidding in Online Advertisingtag:www.techhui.com,2014-08-12:1702911:BlogPost:1314092014-08-12T01:00:00.000ZJoseph Luihttp://www.techhui.com/profile/JosephLui448
<p><a href="http://storage.ning.com/topology/rest/1.0/file/get/396595615?profile=original" target="_self"><img class="align-center" src="http://storage.ning.com/topology/rest/1.0/file/get/396595615?profile=original" width="286"></img></a></p>
<p></p>
<p><em><span class="font-size-2">The motivation behind this blog was a question on how different online advertising partners identify you and coordinate their ad efforts in real time bidding ("RTB") for a slice of your attention when they show you an ad. This is meant to explain a technique called "UUID synching". However, that got me thinking I should frame the…</span></em></p>
<p><a target="_self" href="http://storage.ning.com/topology/rest/1.0/file/get/396595615?profile=original"><img class="align-center" src="http://storage.ning.com/topology/rest/1.0/file/get/396595615?profile=original" width="286"></a></p>
<p></p>
<p><em><span class="font-size-2">The motivation behind this blog was a question on how different online advertising partners identify you and coordinate their ad efforts in real time bidding ("RTB") for a slice of your attention when they show you an ad. This is meant to explain a technique called "UUID synching". However, that got me thinking I should frame the discussion by first explaining the world of RTB. In this blog, I use household brand name companies merely for illustrative purposes. Please note I do not know if mentioned companies or sites actually use RTB specifically.</span></em></p>
<p></p>
<p>When you visit a major site on the Internet, have you ever wondered who or what decides what ads to show you at the top or side banners? Once upon a time, this was a very simple process. The site operator had business arrangements with some advertisers and they'd show their ads on site for a set amount of time. Everybody visiting the site would see the same ads. Over time, advertisers and site operators grew more sophisticated and began to either directly observe or infer things about you and your behavior. They might know things like your gender, ethnicity, zip code, age, or household income. Using this profile, they target ads at you that are more relevant to you and maximizes the chance of you clicking or buying something from their advertising partner. But how do advertisers determine how much money they should pay the site operator for your impression or your click?</p>
<p></p>
<p>As you can imagine, the process for determining impression pricing also started simple and grew quite sophisticated with time. Today, many of your online eyeballs are actually bid on by several interested advertisers and negotiated almost instantly with your impression going to the highest bidder. For example, let's say you visit yahoo.com and it knows you are a female in her mid-20s with disposable income living in Hawaii in the summer. Yahoo turns around and asks its advertisers who is interested in this potential consumer and how much do you want to pay for this impression right here right now? Coca Cola Bottling Company fires back saying "$0.20"; Amazon says "$1.00!"; Capital One says "$1.25!" You then see a Capital One credit card commercial at the top of Yahoo. This happens over a span of milliseconds and is imperceptible to you. The process is known as "real time bidding", or "RTB" for short. RTB makes up about a quarter of digital ad spending these days. This translates to about a $4.5 billion industry in the United States alone for 2014.<a href="http://www.emarketer.com/Article/Programmatic-Ad-Spend-Set-Soar/1010343" target="_blank">*</a> By 2017, some estimate U.S. RTB spending to grow to about $20.8 billion worldwide.<a href="http://www.pubmatic.com/press/2013/new-idc-study-shows-real-time-bidding-rtb-display-ad-spend-to-grow-worldwide-to-208-billion-by-2017.php" target="_blank">*</a> It is projected to continue to grow and eventually comprise as much of 80% of online advertising dollars by 2022 around the world.<a href="http://www.pubmatic.com/press/2013/new-idc-study-shows-real-time-bidding-rtb-display-ad-spend-to-grow-worldwide-to-208-billion-by-2017.php" target="_blank">*</a></p>
<p></p>
<p>Of course, for something like this to be done in milliseconds means there is a lot of machinery going on in the background which is usually outsourced to another entity, even amongst large multinationals. Furthermore, as an advertiser you want to maximize your reach but don't want the onerous task of forming relationships with countless site operators around the world. As a site operator, you also want to maximize the number of potential advertisers with you but not carry the onerous burden of forming relationships with countless advertisers around the world. So of course, there are companies that specialize in each. A Demand Side Platform (DSP) specializes in aggregating advertisers. They have the technical and business expertise to attract advertisers and allow them to setup their automated RTB online marketing campaigns. A basic campaign may look like, "I want to spend $.20 per click over the summer for young females with disposable income. I want to spend $.10 for mid-aged people in the winter on the west coast." DSPs process advertisers' campaign rules and bid in real-time on their behalf and will usually offer monitoring and reports on how well their campaigns are doing. The same is true for the other side. A Supply Side Platform (SSP) specializes in aggregating site operators allowing them to register their site, specify what type of impressions they supply, and amongst other parameters, possible bounds on how little they are willing to sell impressions for. SSPs then relay impressions from their sites to multiple DSPs for real-time ad bidding.</p>
<p></p>
<p>This is where this blog post gets technical. Clearly, a DSP would like to be able to uniquely identify your browser, so that the next time an ad is being requested, they will know that it's you and make better ad selection decisions, such as by analyzing ads they served to you in the past and how you responded. This unique identifier is cookie-based and known as a "universally unique identifier", or "UUID". In RTB however, SSPs are ultimately what interact with your browser so they manage the cookies on your browser containing their own UUID representing you. Because of security measures built into all browsers however, a site can't access the cookies of another domain. Therefore a DSP can't readily know the UUID of the SSP and vice versa, but yet during bid negotiation both sides need to have synched their UUIDs representing you to do their jobs most effectively. That way when an SSP sends an ad request to DSPs for bidding, it can tell the DSP that it is coming from you.</p>
<p></p>
<p>So, what to do? DSPs and SSPs need to uniquely identify you through cookies with their own UUIDs but can't readily synchronize them due to cross-domain cookie restrictions. One way is to display an invisible image (ex. one transparent pixel) served from the other party's domain with your UUID appended to it. For example, let's say your brother is visiting Yahoo.</p>
<p></p>
<ol>
<li>Yahoo's SSP (SSP1) sends your impression out for bid with their UUID of you: "Young male with moderate income (uuid: ssp-abcde) is visiting Yahoo. How much do you want to pay for this impression?"</li>
<li>DSPs connected to this SSP receive the bid and respond on behalf of their clients with bid amount.</li>
<li>DSP1 wins the impression, looks up in their own database of SSP UUIDs but does not find "ssp-abcde".</li>
<li>They serve a Nike ad on Yahoo to your brother and set a cookie on your brother's browser tagging it with uuid "dsp-xyzhe".</li>
<li>Here's the trick. DSP1 also writes a one pixel invisible image along with the ad but served off SSP1.com and their "dsp-xyzhe" UUID appended to the url. SSP1 receives this image call and now knows that their "ssp-abcde" is the same person (or at least browser) as DSP1's "dsp-xyzhe". They update their internal mappings accordingly.</li>
<li>Next time your brother visits Yahoo again, SSP1 sends that impression out to bid but tagged as "uuid: dsp-xyzhe" to DSP1 who now knows that they served a Nike ad to him in the past. He clicked on it, so maybe they should send more shoe ads on behalf of their clients.</li>
</ol>
<p></p>
<p>This process is widely used in industry and known as "UUID synching". The steps above are a simplified case but hopefully serves to illustrate the inner workings of UUID synching well. So the next time you peek under the hood of your browser and see calls made out to seemingly random addresses, you can attribute some of that to the whirling cogs of a global machine pushing many millions of dollars of ad inventory around everyday.</p>