<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tim Hoolihan</title>
	<atom:link href="http://hoolihan.net/blog-tim/feed/" rel="self" type="application/rss+xml" />
	<link>http://hoolihan.net/blog-tim</link>
	<description>Technical Blog</description>
	<lastBuildDate>Fri, 16 Jan 2026 12:07:32 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.11</generator>
	<item>
		<title>8-bit CPUs</title>
		<link>http://hoolihan.net/blog-tim/2026/01/16/8-bit-cpus/</link>
		
		<dc:creator><![CDATA[Tim]]></dc:creator>
		<pubDate>Fri, 16 Jan 2026 12:07:32 +0000</pubDate>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Retro]]></category>
		<guid isPermaLink="false">http://hoolihan.net/blog-tim/?p=4181</guid>

					<description><![CDATA[I&#8217;ve been doing some retro programming on the 2600 and learning 6502 assembly. Between that and some podcast listening, I was surprised to hear how much overlap and inspiration there was between the 8-bit processor families. I always thought they were very different. So I used claude and mermaidjs to come up with the following [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>I&#8217;ve been doing some retro programming on the 2600 and learning 6502 assembly. Between that and some podcast listening, I was surprised to hear how much overlap and inspiration there was between the 8-bit processor families. I always thought they were very different. So I used claude and mermaidjs to come up with the following illustration:</p>


<figure class="wp-block-image"><a href="http://hoolihan.net/blog-tim/wp-content/uploads/2026/01/6502-Family-Systems-Flow-2026-01-15-235320-2048x553.png"><img fetchpriority="high" decoding="async" width="2560" height="691" src="http://hoolihan.net/blog-tim/wp-content/uploads/2026/01/6502-Family-Systems-Flow-2026-01-15-235320-scaled.png" alt="" class="wp-image-4182" srcset="http://hoolihan.net/blog-tim/wp-content/uploads/2026/01/6502-Family-Systems-Flow-2026-01-15-235320-scaled.png 2560w, http://hoolihan.net/blog-tim/wp-content/uploads/2026/01/6502-Family-Systems-Flow-2026-01-15-235320-300x81.png 300w, http://hoolihan.net/blog-tim/wp-content/uploads/2026/01/6502-Family-Systems-Flow-2026-01-15-235320-1024x276.png 1024w, http://hoolihan.net/blog-tim/wp-content/uploads/2026/01/6502-Family-Systems-Flow-2026-01-15-235320-768x207.png 768w, http://hoolihan.net/blog-tim/wp-content/uploads/2026/01/6502-Family-Systems-Flow-2026-01-15-235320-1536x415.png 1536w, http://hoolihan.net/blog-tim/wp-content/uploads/2026/01/6502-Family-Systems-Flow-2026-01-15-235320-2048x553.png 2048w" sizes="(max-width: 2560px) 100vw, 2560px" />Click here or on the image to enlarge</a></figure>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Using AI to Rapidly Generate a Playlist</title>
		<link>http://hoolihan.net/blog-tim/2025/05/26/using-ai-to-rapidly-generate-a-playlist/</link>
		
		<dc:creator><![CDATA[Tim]]></dc:creator>
		<pubDate>Mon, 26 May 2025 13:09:32 +0000</pubDate>
				<category><![CDATA[AI]]></category>
		<guid isPermaLink="false">http://hoolihan.net/blog-tim/?p=4176</guid>

					<description><![CDATA[This weekend I was at my daughter&#8217;s dance recital and noticed some music I would like for the work day. While doing technical or involved work, I like music without words that is not too distracting. I love jazz, but find it taking my mind off my work often, so I listen to lofi, chillhop, [&#8230;]]]></description>
										<content:encoded><![CDATA[This weekend I was at my daughter&#8217;s dance recital and noticed some music I would like for the work day. While doing technical or involved work, I like music without words that is not too distracting. I love jazz, but find it taking my mind off my work often, so I listen to lofi, chillhop, or classical. Some of the music was very classical based, but new. Strong strings or piano, but with modern beats. I used shazaam on a song I was curious about. <br /><br />Fast forward to today, I&#8217;m doing some coding work on an idea I have on my day off. No, I won&#8217;t work all memorial day, but my family is sleeping in and I have some time. So I thought I&#8217;d see if AI could help me. Here was my prompt:<br /><br /><i>I like a genre of music that I struggle to name. Modern music that has a classical feel. Sometimes a bit of a modern or hip hot beat. Piano or string based. An example of this would be Jody Gwin&#8217;s &#8220;They don&#8217;t care about us&#8221;. <br /><br />Please: <br />1. come up with a suitable name for this genre<br />2. search for similar music, 30-100 songs<br />3. Create a playlist named after step 1 that I can download for import into amazon music</i><br /><br />The AI did this in markdown. I pointed out that I needed something that could be imported. It did point me to a service I could use for Amazon music, called Soundiiz. The AI didn&#8217;t know that it could import m3u, so it suggested csv. <br /><br />The csv it created ended up successful for 29 of almost 100 songs. I&#8217;m not sure how much of that is on the AI, and how much is amazon music being picky about song and artist names. Many of the names include accents, etc. Things that may be finicky. <br /><br />Still, in the end, I created a playlist with a lot of examples of the songs I wanted with a decent name &#8220;Neo Classical Fusion&#8221;. I can always explore the artists included to add more songs manually. <br /><br />As is often cited, AI isn&#8217;t perfect, but it made this a faster task and got me off to a good start.]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Playing Pitfall the Mayan Adventure on a Modern Windows 11 PC</title>
		<link>http://hoolihan.net/blog-tim/2024/01/01/playing-pitfall-the-mayan-adventure-on-a-modern-windows-11-pc/</link>
		
		<dc:creator><![CDATA[Tim]]></dc:creator>
		<pubDate>Mon, 01 Jan 2024 22:46:38 +0000</pubDate>
				<category><![CDATA[Games]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">http://hoolihan.net/blog-tim/?p=4165</guid>

					<description><![CDATA[Pitfall the Mayan Adventure was on Genesis (MegaDrive), Super Nintendo, and PC for Windows 95. It requires the CD to be in the drive in order to read audio. I tried a variety of methods including virtualbox that worked to varying degrees. But I find a solution that provided a better gameplay experience and better [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Pitfall the Mayan Adventure was on Genesis (MegaDrive), Super Nintendo, and PC for Windows 95. It requires the CD to be in the drive in order to read audio. I tried a variety of methods including virtualbox that worked to varying degrees. But I find a solution that provided a better gameplay experience and better audio. Not all of these steps may be necessary, but I found it&#8217;s what worked for me.</p>
<p>Copy the contents of the CD to a folder on your PC. Go into the Assets folder and change the compatibility settings of PITFALL.EXE, and set it to run in Windows XP (Service Pack 3) mode. I also set it to 8-bit color, disable fullscreen optimizations, and Run as Administrator. That said, I&#8217;m not sure the last 3 are necessary.</p>
<p><img decoding="async" src="/blog-tim/wp-content/uploads/2024/01/PitFallSettings.png"></p>
<p>Add the dlls from <a href="https://www.google.com/search?q=dgvoodoo2">dgvoodoo2</a> to the ASSETS folder. These override the newer graphic APIs with earlier versions.</p>
<p>Run PITFALL.EXE directly from the ASSETS folder. The CD will still need to be in the drive, for the audio to work.</p>
<p>Lastly, rather than trying to figure out the joystick interface in the settings, I used <a href="https://xpadder.com/">xpadder</a> to configure my controller to use the keys from the keyboard settings.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Equivalent of Numpy&#8217;s Clip function in R</title>
		<link>http://hoolihan.net/blog-tim/2020/10/10/equivalent-of-numpys-clip-function-in-r/</link>
		
		<dc:creator><![CDATA[Tim]]></dc:creator>
		<pubDate>Sat, 10 Oct 2020 14:51:37 +0000</pubDate>
				<category><![CDATA[Data Science]]></category>
		<category><![CDATA[Math]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[R]]></category>
		<category><![CDATA[clip]]></category>
		<category><![CDATA[numpy]]></category>
		<guid isPermaLink="false">http://hoolihan.net/blog-tim/?p=4142</guid>

					<description><![CDATA[Numpy&#8217;s clip function is a handy function that brings all data in a series into a range. For example, in machine learning, it is common to have activation functions that take a continuous range of values and bring them to a range like 0 to 1, or -1 to 1. In my case, I was [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><a href="https://numpy.org/doc/stable/reference/generated/numpy.clip.html">Numpy&#8217;s clip function</a> is a handy function that brings all data in a series into a range. For example, in machine learning, it is common to have activation functions that take a continuous range of values and bring them to a range like 0 to 1, or -1 to 1.</p>
<p>In my case, I was working on some quality control charts that have control limits. In this case, control limits could be calculated to be below 0, but should never be. I was working in R. R has a function max() that can take two values and return the max. So by applying that function over a series, you make make sure each value was at least 0. But it felt a bit cumbersome compared to clip. min() and max() are not vectorized in R. That makes sense, because you may want the max or min of the entire series, so it makes sense that you can pass a series or many values, and get a single answer.</p>
<p>Note that in my use case, the second value is a scalar. But it could be a vector of the same size.</p>
<p>I discovered the pmin and pmax functions which can clip a single bound, or be combined to approximate the clip function. Here&#8217;s a gist showing plots of how this works:</p>
<p><script src="https://gist.github.com/f656ccb37c551807e063ab2538fb4aeb.js"></script></p>
<p>To see the plotted output, <a href="/blog-tim/wp-content/uploads/2020/10/clip_plot.png">click here.</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Using Tensorboard with Multiple Model Runs</title>
		<link>http://hoolihan.net/blog-tim/2018/07/13/using-tensorboard-with-multiple-model-runs/</link>
		
		<dc:creator><![CDATA[Tim]]></dc:creator>
		<pubDate>Fri, 13 Jul 2018 15:47:53 +0000</pubDate>
				<category><![CDATA[Data Science]]></category>
		<category><![CDATA[Machine Learning]]></category>
		<category><![CDATA[deep learning]]></category>
		<category><![CDATA[keras]]></category>
		<category><![CDATA[tensorboard]]></category>
		<category><![CDATA[tensorflow]]></category>
		<guid isPermaLink="false">http://hoolihan.net/blog-tim/?p=4112</guid>

					<description><![CDATA[I tend to use Keras when doing deep learning, with tensorflow as the back-end. This allows use of tensorboard, a web interface that will chart loss and other metrics by training iteration, as well as visualize the computation graph. I noticed tensorboard has an area of the interface for showing different runs, but wasn&#8217;t able [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>I tend to use Keras when doing deep learning, with tensorflow as the back-end. This allows use of tensorboard, a web interface that will chart loss and other metrics by training iteration, as well as visualize the computation graph. I noticed tensorboard has an area of the interface for showing different runs, but wasn&#8217;t able to see the different runs. Turns out I was using it incorrectly. I used the same directory for all runs, but to use it correctly you should use a subdirectory per run. Here&#8217;s how I set it up to work for me:</p>
<p>First, I needed a unique name for each run. I already had a function that I used for naming logs that captures the start time of the run when initialized. Here&#8217;s that code:</p>
<p><script src="https://gist.github.com/e5aaaedc68163c8e776dd3b5894a2e5e.js"></script></p>
<p>Then, I used that to create a constant for the tensorboard log directory:</p>
<p><script src="https://gist.github.com/6f0ec761402b94fa63fd0df151f9740d.js"></script></p>
<p>Finally, I run <strong>tensorboard on the parent directory</strong>, without the unique run name:</p>
<p><script src="https://gist.github.com/41d1e2f42c6a100953f8dcc0442b1f88.js"></script></p>
<p>If you&#8217;re wondering why I pass the host parameter to explicitly be all hosts, this is so that it works when running on a cloud GPU server. </p>
<p>You&#8217;ll now see each subdirectory as a unique run in the interface:</p>
<p><figure id="attachment_4114" aria-describedby="caption-attachment-4114" style="width: 985px" class="wp-caption alignnone"><a href="http://hoolihan.net/blog-tim/wp-content/uploads/2018/07/Screenshot-2018-07-13-11.35.13.png"><img decoding="async" src="http://hoolihan.net/blog-tim/wp-content/uploads/2018/07/Screenshot-2018-07-13-11.35.13.png" alt="Multiple runs in tensorboard" width="985" height="724" class="size-full wp-image-4114" srcset="http://hoolihan.net/blog-tim/wp-content/uploads/2018/07/Screenshot-2018-07-13-11.35.13.png 985w, http://hoolihan.net/blog-tim/wp-content/uploads/2018/07/Screenshot-2018-07-13-11.35.13-300x221.png 300w, http://hoolihan.net/blog-tim/wp-content/uploads/2018/07/Screenshot-2018-07-13-11.35.13-768x564.png 768w" sizes="(max-width: 985px) 100vw, 985px" /></a><figcaption id="caption-attachment-4114" class="wp-caption-text">Multiple runs in tensorboard</figcaption></figure></p>
<p>That should do it. Comment if you have questions or feedback.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>StirTrek 2018 Talk: Machine Learning in R</title>
		<link>http://hoolihan.net/blog-tim/2018/05/05/stirtrek-2018-talk-machine-learning-in-r/</link>
		
		<dc:creator><![CDATA[Tim]]></dc:creator>
		<pubDate>Sat, 05 May 2018 13:57:23 +0000</pubDate>
				<category><![CDATA[Data Science]]></category>
		<category><![CDATA[Machine Learning]]></category>
		<category><![CDATA[R]]></category>
		<guid isPermaLink="false">http://hoolihan.net/blog-tim/?p=4102</guid>

					<description><![CDATA[I had the chance to speak at StirTrek 2018 about Machine Learning in R. I have been to StirTrek before, but it’s been a few years. The conference has really grown, as there are over 2000 attendees now. I was in the 3:30 timeslot. I talked in a full theater and they broadcast the talk [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>I had the chance to speak at StirTrek 2018 about Machine Learning in R. I have been to StirTrek before, but it’s been a few years. The conference has really grown, as there are over 2000 attendees now. </p>
<p>I was in the 3:30 timeslot. I talked in a full theater and they broadcast the talk to two other theaters. I don’t know what attendance was like in the overflow rooms. Most of the follow up questions were from developers looking for resources to get started, tutorials, etc. It seemed like a sign that attendees were interested in going further, which was the point of the talk. </p>
<p><figure id="attachment_4104" aria-describedby="caption-attachment-4104" style="width: 660px" class="wp-caption alignnone"><a href="http://hoolihan.net/blog-tim/wp-content/uploads/2018/05/F96088BE-ADD9-44AC-AE69-9E21E16AC56C.jpeg"><img decoding="async" src="http://hoolihan.net/blog-tim/wp-content/uploads/2018/05/F96088BE-ADD9-44AC-AE69-9E21E16AC56C-1024x768.jpeg" alt="" width="660" height="495" class="size-large wp-image-4104" srcset="http://hoolihan.net/blog-tim/wp-content/uploads/2018/05/F96088BE-ADD9-44AC-AE69-9E21E16AC56C-1024x768.jpeg 1024w, http://hoolihan.net/blog-tim/wp-content/uploads/2018/05/F96088BE-ADD9-44AC-AE69-9E21E16AC56C-300x225.jpeg 300w, http://hoolihan.net/blog-tim/wp-content/uploads/2018/05/F96088BE-ADD9-44AC-AE69-9E21E16AC56C-768x576.jpeg 768w, http://hoolihan.net/blog-tim/wp-content/uploads/2018/05/F96088BE-ADD9-44AC-AE69-9E21E16AC56C.jpeg 2048w" sizes="(max-width: 660px) 100vw, 660px" /></a><figcaption id="caption-attachment-4104" class="wp-caption-text">Start of the Talk Agenda</figcaption></figure></p>
<p>The organizers did a great job. I had a helpful proctor who notified about time, and made sure I was setup and informed. </p>
<p><figure id="attachment_4105" aria-describedby="caption-attachment-4105" style="width: 660px" class="wp-caption alignnone"><a href="http://hoolihan.net/blog-tim/wp-content/uploads/2018/05/37F42494-81DA-4350-A5D9-34BD0F316404.jpeg"><img loading="lazy" decoding="async" src="http://hoolihan.net/blog-tim/wp-content/uploads/2018/05/37F42494-81DA-4350-A5D9-34BD0F316404-1024x576.jpeg" alt="" width="660" height="371" class="size-large wp-image-4105" srcset="http://hoolihan.net/blog-tim/wp-content/uploads/2018/05/37F42494-81DA-4350-A5D9-34BD0F316404-1024x576.jpeg 1024w, http://hoolihan.net/blog-tim/wp-content/uploads/2018/05/37F42494-81DA-4350-A5D9-34BD0F316404-300x169.jpeg 300w, http://hoolihan.net/blog-tim/wp-content/uploads/2018/05/37F42494-81DA-4350-A5D9-34BD0F316404-768x432.jpeg 768w" sizes="auto, (max-width: 660px) 100vw, 660px" /></a><figcaption id="caption-attachment-4105" class="wp-caption-text">Regression as an intro to modeling</figcaption></figure></p>
<p>The talk will go up later this month on YouTube, and I’ll add it to the blog. Thanks to all who attended, and a big thanks to all who helped organize, sponsor, and volunteered for the conference. </p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Hadoop: Accessing Google Cloud Storage</title>
		<link>http://hoolihan.net/blog-tim/2017/12/23/hadoop-accessing-google-cloud-storage/</link>
		
		<dc:creator><![CDATA[Tim]]></dc:creator>
		<pubDate>Sat, 23 Dec 2017 16:33:05 +0000</pubDate>
				<category><![CDATA[Data]]></category>
		<category><![CDATA[Data Science]]></category>
		<category><![CDATA[Hadoop]]></category>
		<category><![CDATA[OS X]]></category>
		<category><![CDATA[google cloud]]></category>
		<category><![CDATA[hadoop]]></category>
		<category><![CDATA[macos]]></category>
		<guid isPermaLink="false">http://hoolihan.net/blog-tim/?p=4098</guid>

					<description><![CDATA[First, go here to choose the hadoop google cloud storage connector for your version of hadoop, likely hadoop 2. Copy that file to $HADOOP_HOME/share/hadoop/tools/lib/. If you followed the instruction in the prior post, that directory is already in your class path. If not, add the following to your hadoop-env.sh file (found in $HADOOP_CONF directory): #GS [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>First, go <a href="https://cloud.google.com/dataproc/docs/concepts/connectors/cloud-storage" rel="noopener" target="_blank">here</a> to choose the hadoop google cloud storage connector for your version of hadoop, likely hadoop 2.</p>
<p>Copy that file to $HADOOP_HOME/share/hadoop/tools/lib/. If you followed the instruction in the <a href="http://hoolihan.net/blog-tim/2017/12/23/hadoop-accessing-s3/" rel="noopener" target="_blank">prior post</a>, that directory is already in your class path. If not, add the following to your hadoop-env.sh file (found in $HADOOP_CONF directory):</p>
<p><code>#GS / AWS S3 Support<br />
export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:$HADOOP_HOME/share/hadoop/tools/lib/*</code></p>
<p>Create a service account in google cloud that has the necessary Storage permissions. Download the credentials and save somewhere, in my case I renamed the file and saved it in .config/gcloud/hadoop.json.</p>
<p>Add the following properties in your core-site.xml:<br />
<code>&lt;configuration&gt;<br />
  &lt;property&gt;<br />
    &lt;name&gt;fs.gs.project.id&lt;/name&gt;<br />
    &lt;value&gt;someproject-123&lt;/value&gt;<br />
    &lt;description&gt;<br />
      Required. Google Cloud Project ID with access to configured GCS buckets.<br />
    &lt;/description&gt;<br />
  &lt;/property&gt;</p>
<p>  &lt;property&gt;<br />
    &lt;name&gt;google.cloud.auth.service.account.enable&lt;/name&gt;<br />
    &lt;value&gt;true&lt;/value&gt;<br />
    &lt;description&gt;<br />
      Whether to use a service account for GCS authorizaiton.<br />
    &lt;/description&gt;<br />
  &lt;/property&gt;</p>
<p>  &lt;property&gt;<br />
    &lt;name&gt;google.cloud.auth.service.account.json.keyfile&lt;/name&gt;<br />
    &lt;value&gt;/Users/tim/.config/gcloud/hadoop.json&lt;/value&gt;<br />
  &lt;/property&gt;</p>
<p>  &lt;property&gt;<br />
    &lt;name&gt;fs.gs.impl&lt;/name&gt;<br />
    &lt;value&gt;com.google.cloud.hadoop.fs.gcs.GoogleHadoopFileSystem&lt;/value&gt;<br />
    &lt;description&gt;The implementation class of the GS Filesystem&lt;/description&gt;<br />
  &lt;/property&gt;</p>
<p>  &lt;property&gt;<br />
    &lt;name&gt;fs.AbstractFileSystem.gs.impl&lt;/name&gt;<br />
    &lt;value&gt;com.google.cloud.hadoop.fs.gcs.GoogleHadoopFS&lt;/value&gt;<br />
    &lt;description&gt;The implementation class of the GS AbstractFileSystem.&lt;/description&gt;<br />
  &lt;/property&gt;</p>
<p>&lt;/configuration&gt;</code></p>
<p>Note to change someproject-123 to your actual project-id, which can be found in the google cloud dashboard. </p>
<p>Now test this setup with:</p>
<p><code>hdfs dfs -ls gs://somebucket</code></p>
<p>Of course you&#8217;ll need to replace somebucket with an actual bucket/directory in your google storage account. </p>
<p>Now you should be setup to use S3 and Google storage with your local hadoop setup.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Hadoop: Accessing S3</title>
		<link>http://hoolihan.net/blog-tim/2017/12/23/hadoop-accessing-s3/</link>
					<comments>http://hoolihan.net/blog-tim/2017/12/23/hadoop-accessing-s3/#comments</comments>
		
		<dc:creator><![CDATA[Tim]]></dc:creator>
		<pubDate>Sat, 23 Dec 2017 15:50:01 +0000</pubDate>
				<category><![CDATA[Data]]></category>
		<category><![CDATA[Data Science]]></category>
		<category><![CDATA[Hadoop]]></category>
		<category><![CDATA[OS X]]></category>
		<category><![CDATA[aws]]></category>
		<category><![CDATA[hadoop]]></category>
		<category><![CDATA[mapreduce]]></category>
		<category><![CDATA[s3]]></category>
		<guid isPermaLink="false">http://hoolihan.net/blog-tim/?p=4095</guid>

					<description><![CDATA[This post follows in a series of doing local hadoop setup on macOS for development / learning purposes. In the first post, we installed hadoop. If you get stuck or need more detail, feel free to check out the apache docs on S3 support. First, we have to add the directory with the necessary jar [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>This post follows in a <a href="//hoolihan.net/blog-tim/?s=hadoop" rel="noopener" target="_blank">series</a> of doing local hadoop setup on macOS for development / learning purposes. In the <a href="http://hoolihan.net/blog-tim/2017/12/23/hadoop-installing-macos/" rel="noopener" target="_blank">first post</a>, we installed hadoop.</p>
<p>If you get stuck or need more detail, feel free to <a href="https://hadoop.apache.org/docs/stable/hadoop-aws/tools/hadoop-aws/index.html" rel="noopener" target="_blank">check out the apache docs on S3 support</a>.</p>
<p>First, we have to add the directory with the necessary jar files to the Hadoop classpath. In hadoop-env.sh (which is in the $HADOOP_CONF directory), add the following lines to the end of the file:</p>
<p><code>#AWS S3 Support<br />
export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:$HADOOP_HOME/share/hadoop/tools/lib/*</code></p>
<p>Make sure you have the following properties set in your core-site.xml file (which is in the $HADOOP_CONF directory).</p>
<p><code>&lt;configuration&gt;</p>
<p>  &lt;property&gt;<br />
    &lt;name&gt;fs.s3a.access.key&lt;/name&gt;<br />
    &lt;value&gt;KEY_HERE&lt;/value&gt;<br />
    &lt;description&gt;AWS access key ID.<br />
    Omit for IAM role-based or provider-based authentication.&lt;/description&gt;<br />
  &lt;/property&gt;</p>
<p>  &lt;property&gt;<br />
    &lt;name&gt;fs.s3a.secret.key&lt;/name&gt;<br />
    &lt;value&gt;SECRET_KEY_HERE&lt;/value&gt;<br />
    &lt;description&gt;AWS secret key.<br />
    Omit for IAM role-based or provider-based authentication.&lt;/description&gt;<br />
  &lt;/property&gt;</p>
<p>  &lt;property&gt;<br />
    &lt;name&gt;fs.s3a.impl&lt;/name&gt;<br />
    &lt;value&gt;org.apache.hadoop.fs.s3a.S3AFileSystem&lt;/value&gt;<br />
    &lt;description&gt;The implementation class of the S3A Filesystem&lt;/description&gt;<br />
  &lt;/property&gt;</p>
<p>  &lt;property&gt;<br />
    &lt;name&gt;fs.AbstractFileSystem.s3a.impl&lt;/name&gt;<br />
    &lt;value&gt;org.apache.hadoop.fs.s3a.S3A&lt;/value&gt;<br />
    &lt;description&gt;The implementation class of the S3A AbstractFileSystem.&lt;/description&gt;<br />
  &lt;/property&gt;</p>
<p>&lt;/configuration&gt; </code></p>
<p>Note that you will need to replace KEY_HERE and SECRET_KEY_HERE with your actual S3 access keys. You can also set the appropriate environment variables with your keys. I put them in this file because I use multiple AWS profile using the configuration files, which is not picked up on by hadoop.</p>
<p>You can test access by using a public data set. For example, I tested with:</p>
<p><code>hdfs dfs -ls s3a://nasanex/NEX-DCP30</code></p>
<p>You should see the contents of that bucket, which includes 5 files.</p>
<p>Note the use of s3a in the protocol, this is the preferred provider over s3n and the deprecated s3. </p>
<p>In the next post, we&#8217;ll look at setting up google cloud storage in a similar manner.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://hoolihan.net/blog-tim/2017/12/23/hadoop-accessing-s3/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Hadoop: Installing on macOS</title>
		<link>http://hoolihan.net/blog-tim/2017/12/23/hadoop-installing-macos/</link>
					<comments>http://hoolihan.net/blog-tim/2017/12/23/hadoop-installing-macos/#comments</comments>
		
		<dc:creator><![CDATA[Tim]]></dc:creator>
		<pubDate>Sat, 23 Dec 2017 15:25:37 +0000</pubDate>
				<category><![CDATA[Data]]></category>
		<category><![CDATA[Data Science]]></category>
		<category><![CDATA[Hadoop]]></category>
		<category><![CDATA[hadop]]></category>
		<category><![CDATA[homebrew]]></category>
		<category><![CDATA[macos]]></category>
		<category><![CDATA[mapreduce]]></category>
		<guid isPermaLink="false">http://hoolihan.net/blog-tim/?p=4091</guid>

					<description><![CDATA[Hadoop is traditionally run on a linux-based system. For learning and development purposes, you may want to install hadoop on macOS. This is the first in a series of posts that will walkthrough working with Hadoop and cloud-based storage. First, you&#8217;ll want to use homebrew to install hadoop and any related tools you would like. [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Hadoop is traditionally run on a linux-based system. For learning and development purposes, you may want to install hadoop on macOS. </p>
<p>This is the first in a <a href="//hoolihan.net/blog-tim/?s=hadoop">series</a> of posts that will walkthrough working with Hadoop and cloud-based storage. </p>
<p>First, you&#8217;ll want to use homebrew to install hadoop and any related tools you would like.<br />
<code>brew install hadoop apache-spark pig hbase</code></p>
<p>Next, you&#8217;ll want to setup some environment variables. This can be in your shell rc file (.bashrc, .zshrc), or other places if you use a shell config tool like oh-my-zsh. </p>
<p>Make sure you have set JAVA_HOME, which may differ from my setup below.</p>
<p><code>export HADOOP_INSTALL=/usr/local/opt<br />
export HADOOP_HOME=$HADOOP_INSTALL/hadoop/libexec<br />
export HADOOP_CONF=$HADOOP_HOME/etc/hadoop<br />
PATH="$HADOOP_HOME/sbin:$HADOOP_HOME/bin:$PATH"</code></p>
<p>Then test your install with the following:</p>
<p><code>hdfs dfs -ls ~</code></p>
<p>You should see the contents of your home directory.</p>
<p>You can also run a hadoop example with:<br />
<code>yarn jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-*.jar pi 10 100</code></p>
<p>You should see a (poor) estimate of pi.</p>
<p>You should now be set to use hadoop. In future posts we will look at using the S3 filesystem from AWS and the Google Cloud Storage as well.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://hoolihan.net/blog-tim/2017/12/23/hadoop-installing-macos/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Files and Pipes in R Video Demo</title>
		<link>http://hoolihan.net/blog-tim/2017/07/06/files-pipes-r-video-demo/</link>
		
		<dc:creator><![CDATA[Tim]]></dc:creator>
		<pubDate>Thu, 06 Jul 2017 15:39:18 +0000</pubDate>
				<category><![CDATA[Data]]></category>
		<category><![CDATA[Data Science]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[R]]></category>
		<category><![CDATA[files]]></category>
		<category><![CDATA[gpg]]></category>
		<category><![CDATA[gzfile]]></category>
		<category><![CDATA[gzip]]></category>
		<category><![CDATA[pipes]]></category>
		<category><![CDATA[video]]></category>
		<guid isPermaLink="false">http://hoolihan.net/blog-tim/?p=4084</guid>

					<description><![CDATA[I&#8217;ve worked with various alternate file handlers in python before and wanted to explore the options in R. I was pleasantly surprised to find handlers prebuilt for tasks like compressing data. In addition, a pipe function is available to allow you to use less common commands on your file, like gpg for encryption. I put [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>I&#8217;ve worked with various alternate file handlers in python before and wanted to explore the options in R. I was pleasantly surprised to find handlers prebuilt for tasks like compressing data. In addition, a pipe function is available to allow you to use less common commands on your file, like gpg for encryption.</p>
<p>I put together a quick video demo of how to use these functions, and it&#8217;s available on youtube:</p>
<p><iframe loading="lazy" title="Files and Pipes in R" width="500" height="281" src="https://www.youtube.com/embed/ROJRPBWxdw4?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></p>
<p>If you are having a hard time reading the text, <a href="https://www.youtube.com/watch?v=ROJRPBWxdw4">click here to view the video directly on youtube</a>.</p>
<p>Comment here or on the video with any feedback or questions.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
