<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Uncategorized on shocksolution.com</title><link>https://shocksolution.com/tags/uncategorized/</link><description>Recent content in Uncategorized on shocksolution.com</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Fri, 23 May 2025 20:40:15 +0000</lastBuildDate><atom:link href="https://shocksolution.com/tags/uncategorized/index.xml" rel="self" type="application/rss+xml"/><item><title>Accessing a Mulesoft API mock with curl</title><link>https://shocksolution.com/posts/accessing-a-mulesoft-api-mock-with-curl/</link><pubDate>Fri, 23 May 2025 20:40:15 +0000</pubDate><guid>https://shocksolution.com/posts/accessing-a-mulesoft-api-mock-with-curl/</guid><description>&lt;p&gt;Using curl to access a Mulesoft API mock requires a little trick. Mulesoft gives you the ability to test out a mock of your API design. The easiest way to try the API is to click on the Documentation button on the right side of the API Designer, select an endpoint, and click &amp;ldquo;Try it.&amp;rdquo; If you have made the mock public, you can also use curl to test, but there is a little trick to using curl.&lt;/p&gt;</description></item><item><title>Google Apps Script: Spreadsheet to Document</title><link>https://shocksolution.com/posts/google-apps-script-spreadsheet-to-document/</link><pubDate>Thu, 19 May 2022 02:38:02 +0000</pubDate><guid>https://shocksolution.com/posts/google-apps-script-spreadsheet-to-document/</guid><description>&lt;p&gt;For an explanation of this script, see &lt;a href="https://jeffreyeverhart.com/2020/09/29/auto-fill-a-google-doc-template-from-google-sheet-data/"&gt;Jeffrey Everhart&amp;rsquo;s excellent introduction to Apps Script&lt;/a&gt;.&lt;/p&gt;&#10;&lt;div class="code-block"&gt;&#10; &lt;button class="code-copy" type="button" hidden aria-label="Copy code to clipboard"&gt;&#10; &lt;span class="code-copy-label" aria-hidden="true"&gt;Copy&lt;/span&gt;&#10; &lt;/button&gt;&#10; &lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;function onOpen() {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; const ui = SpreadsheetApp.getUi();&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; const menu = ui.createMenu(&amp;#39;AutoFill Docs&amp;#39;);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; menu.addItem(&amp;#39;Create New Docs&amp;#39;, &amp;#39;createNewGoogleDocs&amp;#39;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; menu.addToUi();&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;function createNewGoogleDocs() {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; //This value should be the id of your document template that we created in the last step&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; const googleDocTemplate = DriveApp.getFileById(&amp;#39;1It9mTOqk0dVyPVaxmjRXa5tXdWMzgsaDxvb4Nm11nsM&amp;#39;);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; //This value should be the id of the folder where you want your completed documents stored&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; const destinationFolder = DriveApp.getFolderById(&amp;#39;1jeg1V6q1ZJ6OWz-A4LNS5f8GtE9x4SQ4&amp;#39;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; //Here we store the sheet as a variable&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; const sheet = SpreadsheetApp&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .getActiveSpreadsheet()&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .getSheetByName(&amp;#39;Data&amp;#39;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; //Now we get all of the values as a 2D array&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; const rows = sheet.getDataRange().getValues();&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; //Start processing each spreadsheet row&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; rows.forEach(function(row, index){&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; //Here we check if this row is the headers, if so we skip it&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; if (index === 0) return;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; //Here we check if a document has already been generated by looking at &amp;#39;Document Link&amp;#39;, if so we skip it&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; if (row[5]) return;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; //Using the row data in a template literal, we make a copy of our template document in our destinationFolder&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; const copy = googleDocTemplate.makeCopy(`${row[1]}, ${row[0]} Employee Details` , destinationFolder)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; //Once we have the copy, we then open it using the DocumentApp&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; const doc = DocumentApp.openById(copy.getId())&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; //All of the content lives in the body, so we get that for editing&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; const body = doc.getBody();&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; //In this line we do some friendly date formatting, that may or may not work for you locale&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; const friendlyDate = new Date(row[3]).toLocaleDateString();&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; //In these lines, we replace our replacement tokens with values from our spreadsheet row&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; body.replaceText(&amp;#39;{{First Name}}&amp;#39;, row[0]);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; body.replaceText(&amp;#39;{{Last Name}}&amp;#39;, row[1]);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; body.replaceText(&amp;#39;{{Hours}}&amp;#39;, row[2]);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; body.replaceText(&amp;#39;{{Date Completed}}&amp;#39;, friendlyDate);&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; //We make our changes permanent by saving and closing the document&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; doc.saveAndClose();&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; //Store the url of our new document in a variable&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; const url = doc.getUrl();&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; //Write that value back to the &amp;#39;Document Link&amp;#39; column in the spreadsheet. &#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sheet.getRange(index + 1, 6).setValue(url)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; })&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#10; &lt;/div&gt;</description></item><item><title>How to Enable Multi Factor Authentication (MFA) on your IEEE Email Account</title><link>https://shocksolution.com/posts/how-to-enable-multi-factor-authentication-mfa-on-your-ieee-email-account/</link><pubDate>Wed, 08 Sep 2021 04:03:20 +0000</pubDate><guid>https://shocksolution.com/posts/how-to-enable-multi-factor-authentication-mfa-on-your-ieee-email-account/</guid><description>&lt;p&gt;If you&amp;rsquo;ve been around IEEE for a long time, you remember when your email address ____@ieee.org was just an alias that forwarded all email to your actual email provider. However, in 2013 the IEEE partnered with Google to create an actual Gmail account for your IEEE email address. While the intent behind this benefit is certainly appreciated, it was actually an inconvenience for many of us who were already established with an email provider. We didn&amp;rsquo;t want to migrate our entire digital live to IEEE&amp;rsquo;s new Gmail account. I wrote a popular blog post back in 2013 about &lt;a href="https://shocksolution.com/2013/10/16/how-to-fix-your-ieee-email-alias-so-that-it-delivers-all-messages/"&gt;how to configure your IEEE Gmail account to forward 100% of all email to your actual email provider&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Running Unity games via Steam in Linux</title><link>https://shocksolution.com/posts/running-unity-games-via-steam-in-linux/</link><pubDate>Mon, 28 May 2018 19:15:33 +0000</pubDate><guid>https://shocksolution.com/posts/running-unity-games-via-steam-in-linux/</guid><description>&lt;p&gt;There seems to be a lot of confusion about how to run games built on the &lt;a href="https://unity3d.com/"&gt;Unity engine&lt;/a&gt; distributed by Steam on a Linux system. I recently solved this problem after backing the promising &lt;a href="https://%3Cwww.planet-nomads.com/%3E"&gt;survival sandbox game Planet Nomads&lt;/a&gt; on Kickstarter. Here is how to configure an Ubuntu Linux system and launch Planet Nomads successfully.&lt;/p&gt;&#10;&lt;h2 id="prerequisites"&gt;Prerequisites&lt;/h2&gt;&#10;&lt;p&gt;If you have an Nvidia card, you must download and install the &lt;a href="http://%3Cwww.nvidia.com/Download/driverResults.aspx/114708/en-us%3E"&gt;official proprietary drivers provided by Nvidia.&lt;/a&gt; I could not get Unity to launch with the open-source drivers. Once I installed the proprietary (closed source) drivers, I was able to launch Planet Nomads from the Steam application.&lt;/p&gt;</description></item><item><title>Configure CentOS/RedHat VMs with Kickstart files on Virtualbox</title><link>https://shocksolution.com/posts/configure-centos-redhat-vms-with-kickstart-files-on-virtualbox/</link><pubDate>Sat, 05 May 2018 18:54:50 +0000</pubDate><guid>https://shocksolution.com/posts/configure-centos-redhat-vms-with-kickstart-files-on-virtualbox/</guid><description>&lt;p&gt;&lt;a href="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/installation_guide/chap-kickstart-installations"&gt;Kickstart&lt;/a&gt; is a type of file that&amp;rsquo;s used to automatically install RedHat or CentOS Linux on a physical or virtual server. If you are managing more than a few servers, it&amp;rsquo;s a good idea to configure the servers via kickstart files instead of logging in and configuring each one manually. However, some unfortunate choices were made when defining the &lt;a href="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/installation_guide/sect-kickstart-syntax"&gt;Kickstart file format&lt;/a&gt;, and it&amp;rsquo;s not the easiest thing to use. When creating a new Kickstart or making major changes, it&amp;rsquo;s good to have way to quickly iterate and test your changes. Iterating on a Kickstart file is slow and inconvenient in an enterprise environment in which a freshly booted server obtains an image and Kickstarter file via PXEboot. To speed up Kickstart testing and debugging, I&amp;rsquo;ve developed a simple way to use Kickstart files with CentOS/RedHat guest virtual machines that run in VirtualBox on my Mac. This process should also work with Windows or Linux hosts. When the RedHat installer is booting, it looks for a file called ks.cfg on a volume with label OEMDRV. First, we will create this volume as a small virtual disk image. On a Mac, you can create this image with Disk Utility as shown below. Note that the Name needs to be OEMDRV (though you can make the filename anything you want). &lt;figure class="ma0 w-75"&gt;&lt;img src="https://shocksolution.com/images/create-oemdrv-disk-image-osx-disk-utility.png"&#10;&#9;&#9;&#9;alt="Create OEMDRV disk image OSX Disk Utility"&gt;&lt;figcaption&gt;&#10;&#9;&#9;&#9;&lt;p&gt;Create OEMDRV disk image OSX Disk Utility&lt;/p&gt;</description></item><item><title>General error: 2006 MySQL server has gone away</title><link>https://shocksolution.com/posts/general-error-2006-mysql-server-has-gone-away/</link><pubDate>Tue, 10 Apr 2018 03:19:57 +0000</pubDate><guid>https://shocksolution.com/posts/general-error-2006-mysql-server-has-gone-away/</guid><description>&lt;p&gt;&amp;ldquo;MySQL Server has gone away&amp;rdquo; is a cryptic error that can be hard to troubleshoot (look at all the various responses on Stack Overflow!) Many problems can cause this error; I would like to document one specific case. In this example, the client is a PHP app using the Phalcon framework:&lt;/p&gt;&#10;&lt;div class="code-block"&gt;&#10; &lt;button class="code-copy" type="button" hidden aria-label="Copy code to clipboard"&gt;&#10; &lt;span class="code-copy-label" aria-hidden="true"&gt;Copy&lt;/span&gt;&#10; &lt;/button&gt;&#10; &lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[Mon, 09 Apr 18 03:34:08 -0400][ERROR] SQLSTATE[HY000]: General error: 2006 MySQL server has gone away&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;exception &amp;#39;PDOException&amp;#39; with message &amp;#39;SQLSTATE[HY000]: General error: 2006 MySQL server has gone away&amp;#39; in /path/to/ModelBase.php:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Stack trace:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;#0 [internal function]: PDOStatement-&amp;gt;execute()&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;#17 {main}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#10; &lt;/div&gt;&lt;p&gt;This error can be tricky to troubleshoot. I looked in three logs:&lt;/p&gt;</description></item><item><title>Viewing logs for a cluster of instances on Google Stackdriver Logging</title><link>https://shocksolution.com/posts/viewing-logs-for-a-cluster-of-instances-on-google-stackdriver-logging/</link><pubDate>Tue, 27 Mar 2018 14:01:51 +0000</pubDate><guid>https://shocksolution.com/posts/viewing-logs-for-a-cluster-of-instances-on-google-stackdriver-logging/</guid><description>&lt;p&gt;StackDriver Logging is a great feature of Google Compute Engine (GCE). You pretty much need a centralized logging solution if you are taking maximum advantage of the features offered by GCE. For example, most production applications will run on a cluster of web servers. If you set up the cluster as a managed instance group on GCE, Google can auto-scale the size of the cluster based on traffic. The challenge is that it&amp;rsquo;s much  harder to troubleshoot errors across a cluster. The requests that caused the error could be spread across any number of servers, with randomly assigned names. If load drops and the server pool contracts, you will entirely lose any log data on a server that&amp;rsquo;s auto-deleted. StackDriver Logging is the answer to this problem. Configure all servers to send all logs to StackDriver, and you can view all of your web server logs in one interface, with the entries in chronological order. &lt;a href="https://gist.github.com/craigafinch/a2025a867eae1dfc236c6162072024a5"&gt;View StackDriver Advanced Filter as a Gist on GitHub&lt;/a&gt; The problem is that the Stackdriver docs only explain how to select an instance by the instance ID, which is a random-looking string that is not visible in the Console. Further, if you have a large cluster of disposable servers, you would have to look up the ID for every instance. If an instance was deleted when the cluster was auto-scaled, you won&amp;rsquo;t even know what to look up. Therefore, it&amp;rsquo;s much better to search for the logs based on a human-readable server name. For example, assume that your servers are Google Compute Engine instances that are named [region]-[zone]-web-[id]. Here&amp;rsquo;s a filter to match on that naming convention: [sourcecode language=&amp;ldquo;plain&amp;rdquo;] resource.type=&amp;ldquo;gce_instance&amp;rdquo; logName=&amp;ldquo;projects/my-project-name/logs/apache-error&amp;rdquo; labels.&amp;ldquo;compute.googleapis.com/resource_name&amp;rdquo;:&amp;quot;-web-&amp;quot; textPayload:&amp;ldquo;execution time&amp;rdquo; [/sourcecode]&lt;/p&gt;</description></item><item><title>Run DSSP with GROMACS 4.5.5 on Red Hat Linux</title><link>https://shocksolution.com/posts/getting-dssp-to-run-with-gromacs-4-5-5-on-red-hat-linux/</link><pubDate>Mon, 15 Oct 2012 10:00:50 +0000</pubDate><guid>https://shocksolution.com/posts/getting-dssp-to-run-with-gromacs-4-5-5-on-red-hat-linux/</guid><description>&lt;h2 id="update"&gt;UPDATE&lt;/h2&gt;&#10;&lt;p&gt;&lt;strong&gt;A new version of GROMACS (4.6 series) has been released since this post was written. Please try installing the latest version of GROMACS before attempting the steps in this post.&lt;/strong&gt;&lt;/p&gt;&#10;&lt;h3 id="fixing-gromacs"&gt;Fixing GROMACS&lt;/h3&gt;&#10;&lt;p&gt;There is a bug in the &lt;strong&gt;do_dssp&lt;/strong&gt;command in GROMACS 4.5.5 that prevents the analysis of secondary structure using &lt;a href="https://swift.cmbi.umcn.nl/gv/dssp/" title="DSSP"&gt;DSSP&lt;/a&gt; . Attempting to run&lt;strong&gt;do_dssp&lt;/strong&gt; will result in a segmentation fault. The bug has been patched since 4.5.5, but this version has not been released (see &lt;a href="http://lists.gromacs.org/pipermail/gmx-users/2011-November/066357.html" title="GROMACS%20Mailing%20List"&gt;this post on the GROMACS mailing list&lt;/a&gt;). To get the patched version, &lt;a href="http://lists.gromacs.org/pipermail/gmx-users/2011-November/066375.html" title="GROMACS%20Mailing%20List"&gt;follow the instructions from this post&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Mini Maker Faire Orlando Report: Electronics</title><link>https://shocksolution.com/posts/mini-maker-faire-orlando-report-electronics/</link><pubDate>Sun, 03 Jun 2012 19:28:31 +0000</pubDate><guid>https://shocksolution.com/posts/mini-maker-faire-orlando-report-electronics/</guid><description>&lt;p&gt;In my &lt;a href="https://shocksolution.com/2012/05/mini-maker-faire-orlando-report-hardware/" title="Mini%20Maker%20Faire%20Orlando%20Report:%20Hardware"&gt;previous post about the Mini Maker Faire Orlando&lt;/a&gt;, I described some of the cool hardware that was on display.  In this post, I&amp;rsquo;m going to describe some of the electronics available from local vendors.&lt;/p&gt;&#10;&lt;h2 id="electrimod"&gt;&lt;a href="http://%3Cwww.electrimod.com/z/%3E" title="Electrimod:%20Pluggable%20PIC%20microcontroller%20modules"&gt;Electrimod&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;&lt;figure class="ma0 w-75"&gt;&lt;img src="https://shocksolution.com/images/MiniStack_1-150x150.jpg"&#10;&#9;&#9;&#9;alt="Electrimod MiniStack"&gt;&lt;figcaption&gt;&#10;&#9;&#9;&#9;&lt;p&gt;Electrimod MiniStack&lt;/p&gt;&#10;&#9;&#9;&lt;/figcaption&gt;&#10;&lt;/figure&gt;&#10; Local vendor Electrimod (Clermont, FL) was on hand to showcase their pluggable modules for PIC microcontroller development.  Basically, Electrimod is developing products that are equivalent to Arduino shields.  You start with the PIC module, and then plug in whatever other modules you need to build your prototype in the form of a stack. These brand-new products aren&amp;rsquo;t available yet, but they should be shipping by June or July 2012.&lt;/p&gt;</description></item><item><title>TeXLive and Asymptote on CentOS 5</title><link>https://shocksolution.com/posts/texlive-and-asymptote-on-centos-5/</link><pubDate>Mon, 03 Oct 2011 18:18:50 +0000</pubDate><guid>https://shocksolution.com/posts/texlive-and-asymptote-on-centos-5/</guid><description>&lt;h2 id="tex-live"&gt;Tex Live&lt;/h2&gt;&#10;&lt;p&gt;For reasons unknown, a &lt;a href="http://%3Cwww.tug.org/texlive/%3E" title="TeX%20Live"&gt;TeX Live&lt;/a&gt; package is not available for Red Hat Enterprise Linux/Centos 5 from the major repositories (EPEL or DAG).  I consider this to be a glaring omission, since TeXLive is a great improvement upon teTeX.  Since I don&amp;rsquo;t have time right now to package it myself, I installed TeX Live manually in my user directory and it&amp;rsquo;s working fine.  I used the network install process, which starts with &lt;a href="http://%3Cwww.tug.org/texlive/acquire-netinstall.html%3E" title="Tex%20Live%20installation%20script"&gt;downloading a command-line installer&lt;/a&gt; and then following the &lt;a href="http://%3Cwww.tug.org/texlive/doc/texlive-en/texlive-en.html#x1-150003%3E" title="Detailed%20TeX%20Live%20installation%20instructions"&gt;detailed installation instructions&lt;/a&gt; with the base path set to $HOME/texlive/2011.&lt;/p&gt;</description></item><item><title>How to install Octave video tools on CentOS 5</title><link>https://shocksolution.com/posts/how-to-install-octave-video-tools-on-centos-5/</link><pubDate>Wed, 14 Sep 2011 15:57:44 +0000</pubDate><guid>https://shocksolution.com/posts/how-to-install-octave-video-tools-on-centos-5/</guid><description>&lt;p&gt;This post describes how to get &lt;a href="http://%3C%3Cwww.gnu.org/software/octave/&amp;amp;gt%3E;" title="GNU%20Octave:%20free%20software%20that%20works%20like%20MATLAB"&gt;GNU Octave&lt;/a&gt; up and running on a CentOS 5 Linux system for use in reading, processing, and writing video files.  You will need to use the &lt;a href="http://fedoraproject.org/wiki/EPEL" title="How%20to%20set%20up%20EPEL%20repository"&gt;EPEL&lt;/a&gt; and &lt;a href="http://wiki.centos.org/AdditionalResources/Repositories/RPMForge" title="How%20to%20set%20up%20DAG/RPMForge%20repository"&gt;DAG/rpmforge&lt;/a&gt; repositories, but I won&amp;rsquo;t explain how to do that here. NOTE: I had to go through some trial and error to get this working.  I tried to summarize only the necessary steps, but I can&amp;rsquo;t guarantee I got it completely right until I try a fresh install on another system which does not have any of the dependencies already installed.  Please leave a comment if you encounter any problems. As a superuser, use &lt;strong&gt;yum&lt;/strong&gt;to install octave.  You need octave-devel and ncurses-devel in order to install any Octave packages.  You will need to have the EPEL repository enabled: yum install octave octave-devel ncurses-devel As a superuser, use&lt;strong&gt;yum&lt;/strong&gt; to install ffmpeg and ffmpeg-devel from the rpmforge repo.  The video package for octave uses the ffmpeg libraries (avilib) to perform the actual video processing.  You will need the ffmpeg-devel package, because Octave builds the video package from source.&lt;/p&gt;</description></item><item><title>Moving example code to GitHub</title><link>https://shocksolution.com/posts/moving-example-code-to-github/</link><pubDate>Fri, 04 Mar 2011 18:09:32 +0000</pubDate><guid>https://shocksolution.com/posts/moving-example-code-to-github/</guid><description>&lt;p&gt;As this site has grown, the example code has gradually become unmanageable. I&amp;rsquo;ve posted snippets and fragments here and there over the years, and the original code is scattered in various locations across several computers. Further, as people have pointed out bugs or ways to improve the examples, I&amp;rsquo;ve had a hard time making changes. This is problem is crying out for version control with a central repository. Since I&amp;rsquo;ve been using &lt;a href="http://git-scm.com/" title="Git"&gt;Git&lt;/a&gt; for the past year or so, I decided to try &lt;a href="https://github.com/"&gt;GitHub&lt;/a&gt;. So, I am gradually moving all the examples from the site to: &lt;a href="https://github.com/cfinch/Shocksolution_Examples" title="GitHub"&gt;&lt;a href="https://github.com/cfinch/Shocksolution_Examples"&gt;https://github.com/cfinch/Shocksolution_Examples&lt;/a&gt;&lt;/a&gt; When I put code in a post, I will provide a link to GitHub where you can browse or download the code.  You won&amp;rsquo; t need to use Git, or even learn anything about it.&lt;/p&gt;</description></item><item><title>Reading an array from a text file with Fortran 90/95</title><link>https://shocksolution.com/posts/reading-an-array-from-a-text-file-with-fortran-9095/</link><pubDate>Fri, 21 May 2010 20:59:26 +0000</pubDate><guid>https://shocksolution.com/posts/reading-an-array-from-a-text-file-with-fortran-9095/</guid><description>&lt;p&gt;If you&amp;rsquo;re used to coding in more modern languages, Fortran I/O can seem a little bizarre.  Strings in Fortran are much more difficult to work with, since they are fixed-length rather than null-terminated. The following example illustrates a simple way to read an array of numbers from a text file when the array length is unknown at compile time.&lt;/p&gt;&#10;&lt;div class="code-block"&gt;&#10; &lt;button class="code-copy" type="button" hidden aria-label="Copy code to clipboard"&gt;&#10; &lt;span class="code-copy-label" aria-hidden="true"&gt;Copy&lt;/span&gt;&#10; &lt;/button&gt;&#10; &lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;program io_test&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; real, dimension(:), allocatable :: x&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; integer :: n&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; open (unit=99, file=&amp;#39;array.txt&amp;#39;, status=&amp;#39;old&amp;#39;, action=&amp;#39;read&amp;#39;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; read(99, *), n&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; allocate(x(n))&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; read(99,*) x&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; write(*,*) x&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#10; &lt;/div&gt;&lt;p&gt;Here is the text file that the array is read from. The integer on the first line is the number of elements to read from the next line.&lt;/p&gt;</description></item><item><title>Managing a pool of MPI processes with Python and Pypar</title><link>https://shocksolution.com/posts/managing-a-pool-of-mpi-processes-with-python-and-pypar/</link><pubDate>Sat, 17 Apr 2010 18:52:13 +0000</pubDate><guid>https://shocksolution.com/posts/managing-a-pool-of-mpi-processes-with-python-and-pypar/</guid><description>&lt;p&gt;MPI is a standard for communication between multiple processes in parallel computing. These processes can be running on different cores, CPUs, or entirely different computers in a grid. MPI is a standard, and there are many implementations available (many are open source). The features of MPI can be accessed from Python with the packages &lt;a href="http://code.google.com/p/pypar/" title="pypar"&gt;pypar&lt;/a&gt; and &lt;a href="http://mpi4py.scipy.org/" title="mpi4py"&gt;mpi4py&lt;/a&gt;.  Here I present a Python script that implements a &amp;ldquo;process pool&amp;rdquo; &lt;a href="http://en.wikipedia.org/wiki/Design_pattern_(computer_science)" title="Design patterns on Wikipedia"&gt;design pattern&lt;/a&gt; using pypar.  I have observed a pattern often enough in my own work that I wrote this framework to avoid reinventing the wheel every time I come across it. This pattern is useful for any &lt;a href="http://en.wikipedia.org/wiki/Embarrassingly_parallel" title="Embarassingly%20Parallel"&gt;embarrassingly parallel&lt;/a&gt; problem.  This describes a computing task that can be easily accelerated by running multiple parallel processes that do not not need to interact with one another.  For example, I have large scientific data sets from several runs of an experiment that need to be analyzed.  Since the data from each run can be analyzed independently from the other runs, I can analyze all the data sets at once on a parallel machine.   The code below implements a &amp;ldquo;master-worker&amp;rdquo; paradigm that requires at least three processes to accelerate the calculation.  The first process be comes the master, which does no calculation but hands out tasks to the workers.  The rest of the processes are workers, which receive a chunk of work, finish it, return the result to the master process, and then wait for more work.&lt;/p&gt;</description></item><item><title>Redirecting text output from Python functions</title><link>https://shocksolution.com/posts/redirecting-text-output-from-python-functions/</link><pubDate>Sat, 16 Aug 2008 20:47:05 +0000</pubDate><guid>https://shocksolution.com/posts/redirecting-text-output-from-python-functions/</guid><description>&lt;p&gt;Two posts ago, I described how I wrote a function in Python that reads in a binary file from Labview. In my last post, I described using wxPython to write a GUI to process the data from those binary files. Naturally, I called the binary-file-reader function from the GUI. The problem is that the file reader prints a lot of information to the terminal, using Python &lt;strong&gt;print&lt;/strong&gt;statements. None of this goes to the GUI, requiring the user to run the GUI from a terminal and keep an eye on the text output, which is inconvenient. However, I don&amp;rsquo;t want to modify the file reader to include GUI-specific code, because that would be less modular and less re-usable. Instead, I learned that Python has a very easy facility to redirect&lt;strong&gt;stdout&lt;/strong&gt;, the default destination of the &lt;strong&gt;print&lt;/strong&gt; statement. I modified the file reader as follows:&lt;/p&gt;</description></item><item><title>Blog infrastructure update</title><link>https://shocksolution.com/posts/blog-infrastructure-update/</link><pubDate>Mon, 08 Oct 2007 01:48:30 +0000</pubDate><guid>https://shocksolution.com/posts/blog-infrastructure-update/</guid><description>&lt;p&gt;During the past week, the blog engine was updated and a few things were tweaked &amp;ldquo;under the hood.&amp;rdquo;  You may have already noticed that the theme has been totally changed.  It&amp;rsquo;s a modified version of the &lt;a href="http://%3Cwww.blogohblog.com/wordpress-theme-blue-box/%3E" title="Blue%20Box%20theme"&gt;Blue Box theme&lt;/a&gt; by Bob&amp;ndash;the header photo is mine.&lt;/p&gt;</description></item><item><title>How do you say "bye bye Ubuntu" in Zulu?</title><link>https://shocksolution.com/posts/how-do-you-say-bye-bye-ubuntu-in-zulu/</link><pubDate>Wed, 11 Apr 2007 18:48:46 +0000</pubDate><guid>https://shocksolution.com/posts/how-do-you-say-bye-bye-ubuntu-in-zulu/</guid><description>&lt;p&gt;I finally had enough and wiped Ubuntu off of my computer at work, and now Gentoo is happily running.  Maybe I could have gotten Ubuntu to do what I wanted if I had spent more time with it, but I was sick of playing with it instead of getting work done.  To be fair to Ubuntu, maybe I&amp;rsquo;m just more familiar with how to do strange things with Gentoo.  Things like installing and using my open-source toolchain:&lt;/p&gt;</description></item><item><title>Who got fired for this?</title><link>https://shocksolution.com/posts/who-got-fired-for-this/</link><pubDate>Mon, 19 Mar 2007 02:34:32 +0000</pubDate><guid>https://shocksolution.com/posts/who-got-fired-for-this/</guid><description>&lt;p&gt;What an unusual pine tree! Who would have guessed that this is actually a &lt;em&gt;giant&lt;/em&gt; &lt;em&gt;antenna&lt;/em&gt;, cleverly disguised as a tree? &lt;a href="http://%3Cwww.flickr.com/photos/a_mirror_dimly/426125676/%3E"&gt;&lt;img src="http://farm1.static.flickr.com/179/426125676_14a3e297aa_m.jpg" alt="New Pine Species"&gt;&lt;/a&gt; I just hope that my taxpayer dollars weren&amp;rsquo;t used on this monstrosity.&lt;/p&gt;</description></item><item><title>How the E815 dies</title><link>https://shocksolution.com/posts/how-the-e815-dies/</link><pubDate>Mon, 19 Mar 2007 00:21:30 +0000</pubDate><guid>https://shocksolution.com/posts/how-the-e815-dies/</guid><description>&lt;p&gt;I have a Motorola E815 cell phone.  This morning, I was reminded why it hasn&amp;rsquo;t been an entirely satisfying experience.  The E815 has excellent reception (on Verizon&amp;rsquo;s network) and lots of software features that work really well. Unfortunately the mechanical quality leaves a lot to be desired.  The E815&amp;rsquo;s weakness is the socket where the wall charger attaches.  My first E815 crashed as I was unplugging the charger.  I unplugged it and the phone rebooted.  This had happened several times before, but this time the phone got to a certain point in its boot cycle and rebooted again.  I couldn&amp;rsquo;t even turn it off using the end/power key&amp;ndash;I had to remove the battery.  Fortunately there were about three weeks left on the warranty, and Verizon eventually got me a new one that worked (on the third try).  Last night, I plugged in my phone before bed and set the alarm.  Early this morning the alarm went off, so I opened the phone and hit the &amp;ldquo;end&amp;rdquo; key to shut it up.  The phone rebooted and came back to the alarm screen.  I unplugged it and hit &amp;ldquo;end&amp;rdquo; again, and it worked.  Moral of the story&amp;ndash;be VERY careful when plugging/unplugging your E815 charger, and try not to do anything with the phone when it&amp;rsquo;s plugged in.  Also, sign up for Verizon&amp;rsquo;s free backup service to save your contacts in case the phone dies, and transfer your photos and ringtones to a micro-SD card.&lt;/p&gt;</description></item></channel></rss>