<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Programming on Neil Grogan</title><link>/tags/programming/</link><description>Recent content in Programming on Neil Grogan</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Fri, 25 Nov 2022 00:00:00 +0000</lastBuildDate><atom:link href="/tags/programming/index.xml" rel="self" type="application/rss+xml"/><item><title>Convert Bank Transactions XLS to CSV in Python</title><link>/bank-xls-csv/</link><pubDate>Fri, 25 Nov 2022 00:00:00 +0000</pubDate><guid>/bank-xls-csv/</guid><description>&lt;p&gt;I&amp;rsquo;ve written previously on importing transactions to hledger/&lt;a href="../../ledger"&gt;ledger&lt;/a&gt; from
&lt;a href="../../kbc-tx-js"&gt;KBC&lt;/a&gt; bank in JavaScript and &lt;a href="../../bank-tx-py"&gt;PTSB&lt;/a&gt; bank in Python. I took different
approaches to each:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For KBC, you needed to log in and run Javascript which scrape the transaction
table and download it formatted as CSV&lt;/li&gt;
&lt;li&gt;For PTSB, the script automatted logging in, get the transaction table and save
locally as CSV&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Both approaches are valid - but suffer from the same issues: any change the bank
makes to it website needs to be updated in the code. The KBC/JavaScript approach
was a bit more robust in that it would just search for rows on a website and
download as CSV.&lt;/p&gt;</description></item><item><title>Scraping Transaction Data from KBC Bank</title><link>/kbc-tx-js/</link><pubDate>Mon, 13 May 2019 00:00:00 +0000</pubDate><guid>/kbc-tx-js/</guid><description>&lt;p&gt;In a previous post, I mentioned &lt;a href="../../bank-tx-py"&gt;importing transactions&lt;/a&gt; using
&lt;a href="../../ledger"&gt;ledger&lt;/a&gt;/&lt;a href="https://hledger.org/"&gt;hledger&lt;/a&gt; and plain text accounting. As my former bank &lt;a href="https://www.permanenttsb.ie/"&gt;PTSB&lt;/a&gt;
recently raised their fees, I decided to move to &lt;a href="https://www.kbc.ie/"&gt;KBC&lt;/a&gt;. I was excited to see,
as part of the open payments directive, they have a nice &lt;a href="https://www.kbc.ie/psd2-developer-portal/home"&gt;developer
portal&lt;/a&gt;. I reached out to KBC&amp;rsquo;s dev team, but alas they are only accepting
registered companies, who meet stringent criteria. They told me they hope to
open it up soon to end users, I live in hope!&lt;/p&gt;</description></item><item><title>Python 3 In-Memory Zip File</title><link>/py-bin-zip/</link><pubDate>Sun, 14 Jan 2018 00:00:00 +0000</pubDate><guid>/py-bin-zip/</guid><description>&lt;p&gt;
In Python, &lt;a href="https://docs.python.org/3/library/io.html#io.BytesIO"&gt;BytesIO&lt;/a&gt; is the way to store binary data in memory. Most examples you’ll see using zip files in memory is to store string data and indeed the most common example you’ll find online from the &lt;a href="https://docs.python.org/3/library/zipfile.html"&gt;zipfile&lt;/a&gt; module is &lt;code&gt;zipfile.writestr(file_name, &amp;#34;Text Data&amp;#34;)&lt;/code&gt;. But what if you want to store binary data of a PDF or Excel Spreadsheet that’s also in memory? You could use &lt;code&gt;zipfile.write()&lt;/code&gt; (designed to take binary data) but then you can’t specify a filename (since our in-memory file was never written to a location on disk). The reason for this is simple: for a web request or for a test case, you shouldn’t need to store any files on disk.&lt;/p&gt;</description></item><item><title>Scraping Data from your Bank in Python</title><link>/bank-tx-py/</link><pubDate>Wed, 12 Jul 2017 00:00:00 +0000</pubDate><guid>/bank-tx-py/</guid><description>&lt;p&gt;As part of my previous posts, I talked about &lt;a href="../../ledger"&gt;ledger&lt;/a&gt; and plain text
accounting. The only part missing is that you need a method to import
transactions from your bank. For this I have been doing this by hand, bi-weekly.
I would have to do the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Log in to online banking&lt;/li&gt;
&lt;li&gt;Go to the transactions page&lt;/li&gt;
&lt;li&gt;Select the date range for transactions I needed (double check last date of
transaction in ledger at this point)&lt;/li&gt;
&lt;li&gt;Download the &lt;a href="https://en.wikipedia.org/wiki/Microsoft_Excel"&gt;Microsoft Excel&lt;/a&gt; format file that wasn&amp;rsquo;t in the proper format&lt;/li&gt;
&lt;li&gt;Convert this Excel file into a CSV file that matched my import format (watch
the dates, is it YYYY-MM-DD or DD/MM/YYYY?)&lt;/li&gt;
&lt;li&gt;Finally import the CSV file into ledger&lt;/li&gt;
&lt;li&gt;Check the balance matches between my online banking and ledger&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;em&gt;Sounds like a lot of work right?&lt;/em&gt;&lt;/p&gt;</description></item><item><title>Slack Bots for Work</title><link>/slack-bot/</link><pubDate>Thu, 16 Feb 2017 00:00:00 +0000</pubDate><guid>/slack-bot/</guid><description>&lt;p&gt;In a previous post, I mentioned how I get notified of the &lt;a href="../../rest-menu"&gt;restaurant
menu&lt;/a&gt; via a Ruby script. Recently I&amp;rsquo;ve moved to a totally different
product area and the main communication channel we use is &lt;a href="https://www.slack.com"&gt;Slack&lt;/a&gt;. Naturally
enough, I ported the Ruby code I wrote, and it now posts the menu every day to
our Slack channel.&lt;/p&gt;
&lt;p&gt;This also got me thinking of what other information would be handy to have. I
scouted around for ideas and came up with an obvious one: reminder of the bus
times to and from the office. So here&amp;rsquo;s my bus times notification slack bot:&lt;/p&gt;</description></item><item><title>Automatic Newsletter Cleanup in Gmail</title><link>/gmail-newsletter-filter/</link><pubDate>Fri, 19 Aug 2016 00:00:00 +0000</pubDate><guid>/gmail-newsletter-filter/</guid><description>&lt;p&gt;If you haven&amp;rsquo;t tried &lt;a href="https://developers.google.com/apps-script/"&gt;Google Apps Script&lt;/a&gt;, I found a really nifty use for it:
&lt;em&gt;smart filtering&lt;/em&gt; for email. Wait, shouldn&amp;rsquo;t I just use Gmails&amp;rsquo; built-in
filters? As it turns out you can&amp;rsquo;t - my filter needs to act on email that
matched that filter &lt;em&gt;in the past&lt;/em&gt;. So in other words: a filter can only act on
email it actually &amp;ldquo;filters&amp;rdquo;, which kinda makes sense! I&amp;rsquo;m a big fan of
automation (and email is ripe for automation), as you can see from &lt;a href="../../outlook"&gt;my post on
meetings in Outlook&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Fill hours worked in SAP Netweaver Automatically</title><link>/autohours/</link><pubDate>Mon, 01 Feb 2016 00:00:00 +0000</pubDate><guid>/autohours/</guid><description>&lt;p&gt;Continuing the theme of automation, one of the most repetitive tasks if you work
for a big company is timesheets. So I set out to rectify this by scripting it!&lt;/p&gt;
&lt;p&gt;Start with you configuration, I named mine &lt;code&gt;hours.ini&lt;/code&gt;:&lt;/p&gt;
&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-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[DEFAULT]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;url &lt;span style="color:#f92672"&gt;=&lt;/span&gt; FILL_ME_IN
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;username &lt;span style="color:#f92672"&gt;=&lt;/span&gt; FILL_ME_IN
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;password &lt;span style="color:#f92672"&gt;=&lt;/span&gt; FILL_ME_IN
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;then we need the magic of &lt;a href="http://www.seleniumhq.org/"&gt;Selenium&lt;/a&gt; to do the heavy
lifting, so we install it:&lt;/p&gt;
&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-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ pip3 install selenium
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I called this script, unsurprisingly &lt;code&gt;hours.py&lt;/code&gt;:&lt;/p&gt;</description></item><item><title>Automated 'Push' Restaurant menu</title><link>/rest-menu/</link><pubDate>Sun, 10 Jan 2016 00:00:00 +0000</pubDate><guid>/rest-menu/</guid><description>&lt;p&gt;I love trying to automate the world, it just feels like magic some of the time!
I also really enjoy information coming to me, instead of having to seek it. As
we are still only in 2016, we have no world killing Artificial Intelligence
(yet). So we have to start small, ease the first world problems! So I decided to
make my workplaces&amp;rsquo; restaurant menu come to me!&lt;/p&gt;
&lt;p&gt;I decided to write it in Ruby and use push notifications, rather than email or
SMS. It uses a web automation framework called
&lt;a href="http://www.seleniumhq.org/"&gt;Selenium&lt;/a&gt;, which is available in many languages,
including Javascript, Python, Java and obviously Ruby!&lt;/p&gt;</description></item><item><title>Adventures with React</title><link>/react/</link><pubDate>Thu, 22 Oct 2015 00:00:00 +0000</pubDate><guid>/react/</guid><description>&lt;p&gt;Recently I&amp;rsquo;d seen a post on &lt;a href="https://news.ycombinator.com/item?id=10499683"&gt;Hacker News&lt;/a&gt; about a &lt;a href="https://reactforbeginners.com/"&gt;course for the React
JavaScript Framework&lt;/a&gt;. I haven&amp;rsquo;t done much with JavaScript, apart from a
course in work, which was focused on the language itself and &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt;.
&lt;a href="https://facebook.github.io/react/"&gt;React&lt;/a&gt; is a front end framework, which allows you to build reusable
components (and generate them with data.)&lt;/p&gt;
&lt;p&gt;The only real experience I have is writing an application (using
&lt;a href="http://nodejs.org/"&gt;Node.js&lt;/a&gt;) for &lt;a href="../../ucd"&gt;my MSc course&lt;/a&gt; which was an &lt;a href="http://www.w3schools.com/ajax/default.asp"&gt;AJAX&lt;/a&gt; application for
interacting with &lt;a href="https://en.wikipedia.org/wiki/Amazon_SimpleDB"&gt;Amazon SimpleDB&lt;/a&gt;. It was fun to write and weird that I
could use the same language from the front-end to the back-end.&lt;/p&gt;</description></item><item><title>Automatically Decline and Delete or Accept and Delete Outlook 2010 Meetings</title><link>/outlook/</link><pubDate>Tue, 06 Oct 2015 00:00:00 +0000</pubDate><guid>/outlook/</guid><description>&lt;p&gt;You can follow the
&lt;a href="https://web.archive.org/web/20151016112956/http://blogs.technet.com/b/sharepoint_republic/archive/2011/12/09/outlook-rule-to-auto-accept-or-auto-decline-meeting-invites.aspx"&gt;Microsoft TechNet guide to add VisualBasic code in Outlook rules&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You can just replace the code they give with this:&lt;/p&gt;
&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-vb" data-lang="vb"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;Sub&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;AutoDeclineMeetings&lt;/span&gt;(oRequest &lt;span style="color:#f92672"&gt;As&lt;/span&gt; MeetingItem)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;#39; If its not a meeting, we don&amp;#39;t process
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;If&lt;/span&gt; oRequest.MessageClass &lt;span style="color:#f92672"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;IPM.Schedule.Meeting.Request&amp;#34;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;Then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;Exit&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;Sub&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;End&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;If&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;#39; Get the appointment in the meeting
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;Dim&lt;/span&gt; oAppt &lt;span style="color:#f92672"&gt;As&lt;/span&gt; AppointmentItem
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;Set&lt;/span&gt; oAppt &lt;span style="color:#f92672"&gt;=&lt;/span&gt; oRequest.GetAssociatedAppointment(&lt;span style="color:#66d9ef"&gt;True&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;#39; Send a decline response
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;Dim&lt;/span&gt; oResponse
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;Set&lt;/span&gt; oResponse &lt;span style="color:#f92672"&gt;=&lt;/span&gt; oAppt.Respond(olMeetingDeclined, &lt;span style="color:#66d9ef"&gt;True&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; oResponse.Send
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;#39; Lastly, delete the message
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;oRequest.Delete
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;End&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;Sub&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;Sub&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;AutoAcceptMeetings&lt;/span&gt;(oRequest &lt;span style="color:#f92672"&gt;As&lt;/span&gt; MeetingItem)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;#39; If its not a meeting, we don&amp;#39;t process
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;If&lt;/span&gt; oRequest.MessageClass &lt;span style="color:#f92672"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;IPM.Schedule.Meeting.Request&amp;#34;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;Then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;Exit&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;Sub&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;End&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;If&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;#39; Get the appointment in the meeting
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;Dim&lt;/span&gt; oAppt &lt;span style="color:#f92672"&gt;As&lt;/span&gt; AppointmentItem
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;Set&lt;/span&gt; oAppt &lt;span style="color:#f92672"&gt;=&lt;/span&gt; oRequest.GetAssociatedAppointment(&lt;span style="color:#66d9ef"&gt;True&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;#39; Send an accept response
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;Dim&lt;/span&gt; oResponse
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;Set&lt;/span&gt; oResponse &lt;span style="color:#f92672"&gt;=&lt;/span&gt; oAppt.Respond(olMeetingAccepted, &lt;span style="color:#66d9ef"&gt;True&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; oResponse.Send
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;#39; Lastly, (optionally) delete the message
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&amp;#39;oRequest.Delete
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;End&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;Sub&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For anything else you may want to do with the meeting, check the
&lt;a href="https://docs.microsoft.com/en-us/previous-versions/office/dn320338(v=office.15)"&gt;Outlook Visual Basic Developer Docs&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Full Stack Web Application with Node.js Tutorial</title><link>/web-app-nodejs-tutorial/</link><pubDate>Mon, 31 Mar 2014 00:00:00 +0000</pubDate><guid>/web-app-nodejs-tutorial/</guid><description>&lt;p&gt;I&amp;rsquo;ve followed this tutorial personally, not using Mongo as the database at
first. It&amp;rsquo;s clear and to the point and provides just what you need to know to
get started. Highly recommended.&lt;/p&gt;</description></item><item><title>Programming is hard</title><link>/programming-is-hard/</link><pubDate>Mon, 07 May 2012 00:00:00 +0000</pubDate><guid>/programming-is-hard/</guid><description>&lt;p&gt;A great
&lt;a href="http://writing.bryanwoods4e.com/1-poor-poor-child"&gt;essay on why programming is hard&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It&amp;rsquo;s harder than you think. Right now you&amp;rsquo;re probably underestimating the
amount of frustration and discomfort you&amp;rsquo;re about to experience, without
realizing that by doing so you&amp;rsquo;re creating all sorts of subtle barriers to
obtaining a deep understanding of programming.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id="language-does-matter"&gt;Language does matter&lt;/h4&gt;
&lt;p&gt;I find this part extremely true: my first language is Java. Every programming
language I&amp;rsquo;ve tried since has been through comparing it to Java. I&amp;rsquo;ve had
criticism of each different language based on my assumptions. Scripting
languages being prone to bad coding because they are not strictly typed, having
to do tedious work with languages that require memory management (my time is too
valuable!).&lt;/p&gt;</description></item><item><title>Very Simple Java Twitter Bot (Twitter4J)</title><link>/very-simple-java-twitter-bot-twitter4j/</link><pubDate>Wed, 01 Feb 2012 00:00:00 +0000</pubDate><guid>/very-simple-java-twitter-bot-twitter4j/</guid><description>&lt;p&gt;Below is code for the start of a Twitter bot I am going to build in Java. It&amp;rsquo;s
the most basic way of getting Oauth working (with any account, not just your
developer account) and it shows your timeline and can update your status -
that&amp;rsquo;s it for now. The neat thing is it uses Java&amp;rsquo;s awesome serialisation, so
you only should have to authorise your twitter account once!&lt;/p&gt;
&lt;h3 id="what-you-will-need"&gt;What you will need:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Twitter4j Libraries&lt;/li&gt;
&lt;li&gt;Oauth Consumer and Secret Key off twitter&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;That is it!&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;script src="https://gist.github.com/2469810.js"&gt; &lt;/script&gt;
&lt;h3 id="what-the-code-does"&gt;What the code does:&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Once only:&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Output Percentage of File (Bash code)</title><link>/output-percentage-of-file-bash-code/</link><pubDate>Sat, 05 Feb 2011 00:00:00 +0000</pubDate><guid>/output-percentage-of-file-bash-code/</guid><description>&lt;p&gt;I wrote this script recently for a friend in a job who needed to output a
certain percentage of a log file, but no more and no less. This was in Linux
using bash, so I had a go at writing a solution, which you see below. Posting
this up in case it&amp;rsquo;s useful to anyone else!&lt;/p&gt;
&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-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# !/bin/sh # Public Domain, by Neil Grogan 2010 # Script&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;to output last 30% of file by lines
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; OLDFILE&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&amp;amp;quot;oldlog.txt&amp;amp;quot;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; NEWFILE&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;newlog.txt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; PERCENT&lt;span style="color:#f92672"&gt;=&lt;/span&gt;0.7
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;#Use wc to count lines&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; LINES&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;$(&lt;/span&gt;wc -l $OLDFILE | awk &lt;span style="color:#e6db74"&gt;&amp;#39;{ print $1}&amp;#39;&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;#Linespercent = 2 decimal places, lines by percent, round to whole&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; LINESPERCENT&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;$(&lt;/span&gt;echo &lt;span style="color:#e6db74"&gt;&amp;#34;scale=2; &lt;/span&gt;$LINES&lt;span style="color:#e6db74"&gt;*&lt;/span&gt;$PERCENT&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; | bc | xargs printf &lt;span style="color:#e6db74"&gt;&amp;#34;%1.0f&amp;#34;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Use tail to get last 30% and output, can use tail -s with sleep time to have it run on sched.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; tail -n $LINESPERCENT $OLDFILE &amp;gt;&amp;gt; $NEWFILE&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Technology New Years Resolutions</title><link>/technology-new-years-resolutions/</link><pubDate>Mon, 04 Jan 2010 00:00:00 +0000</pubDate><guid>/technology-new-years-resolutions/</guid><description>&lt;p&gt;Some people make new years resolutions about eating healthier, exercising more
etc. I find that boring, who doesn&amp;rsquo;t want to be healthier? So I am making a list
of technology resolutions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Learn &lt;a href="http://en.wikipedia.org/wiki/C_(programming_language)"&gt;C&lt;/a&gt; in
&lt;a href="http://developer.apple.com/tools/xcode/"&gt;XCode&lt;/a&gt; on a
&lt;a href="http://www.apple.com/getamac/"&gt;Mac&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Make an awesome
&lt;a href="http://en.wikipedia.org/wiki/Customer_relationship_management"&gt;CRM&lt;/a&gt; program
for &lt;a href="http://www.itb.ie/StudyatITB/bn104.html"&gt;College degree&lt;/a&gt;
(&lt;a href="http://www.python.org/"&gt;Python&lt;/a&gt;,
&lt;a href="http://code.google.com/appengine/"&gt;Google App Engine&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Learn &lt;a href="http://www.vim.org/"&gt;Vim&lt;/a&gt; and
&lt;a href="http://www.gnu.org/software/emacs/"&gt;Emacs&lt;/a&gt; bindings, using them for code&lt;/li&gt;
&lt;li&gt;Learn to use &lt;a href="http://git-scm.com/"&gt;Git&lt;/a&gt;, possibly
&lt;a href="http://mercurial.selenic.com/"&gt;mercurial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Learn some &lt;a href="http://en.wikipedia.org/wiki/Objective-C"&gt;Obj-C&lt;/a&gt; with
&lt;a href="http://developer.apple.com/cocoa/"&gt;Cocoa&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Learn some &lt;a href="http://en.wikipedia.org/wiki/C++"&gt;C++&lt;/a&gt; with
&lt;a href="http://qt.nokia.com/products"&gt;Qt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Learn
&lt;a href="http://www.blogger.com/goog_1262610794764"&gt;Python +&lt;/a&gt;&lt;a href="http://www.blogger.com/goog_1262610794764"&gt;Tcl&lt;/a&gt;&lt;a href="http://www.blogger.com/goog_1262610794764"&gt;/&lt;/a&gt;&lt;a href="http://wiki.python.org/moin/TkInter"&gt;tk&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Learn more about the &lt;a href="http://kerneltrap.org/node/5214"&gt;design of Linux kernel&lt;/a&gt;
and study some of it&amp;rsquo;s code&lt;/li&gt;
&lt;li&gt;Do Sysadmin stuff on my server on &lt;a href="http://www.linode.com/"&gt;Linode&lt;/a&gt;; like
&lt;a href="http://www.blogger.com/goog_1262610794776"&gt;setting up&lt;/a&gt;&lt;a href="http://www.blogger.com/goog_1262610794776"&gt;Sendmail&lt;/a&gt;&lt;a href="http://www.blogger.com/goog_1262610794776"&gt;,&lt;/a&gt;&lt;a href="http://www.blogger.com/goog_1262610794776"&gt;IRC&lt;/a&gt;&lt;a href="http://library.linode.com/"&gt;Servers and other stuff&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;If I have time, investigate &lt;a href="http://cakephp.org/"&gt;CakePHP&lt;/a&gt;,
&lt;a href="http://www.djangoproject.com/"&gt;Django&lt;/a&gt;, maybe
&lt;a href="http://www.ruby-lang.org/"&gt;Ruby&lt;/a&gt; (&lt;a href="http://rubyonrails.org/"&gt;on Rails&lt;/a&gt;?) and
it&amp;rsquo;s ilk&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That should keep me busy besides college and working! I didn&amp;rsquo;t include any
security stuff, as we&amp;rsquo;re doing best practice for my honours degree next year. If
anyone has any of their own, I&amp;rsquo;d love to see, or any resources to help me
complete my list ^-^ Happy 2010!&lt;/p&gt;</description></item><item><title>Why Should I Care What Color the Bikeshed Is?</title><link>/why-should-i-care-what-color-bikeshed/</link><pubDate>Mon, 07 Dec 2009 00:00:00 +0000</pubDate><guid>/why-should-i-care-what-color-bikeshed/</guid><description>&lt;p&gt;&amp;ldquo;The really, really short answer is that you should not. The somewhat longer
answer is that just because you are capable of building a bikeshed does not mean
you should stop others from building one just because you do not like the color
they plan to paint it. This is a metaphor indicating that you need not argue
about every little feature just because you know enough to do so. Some people
have commented that the amount of noise generated by a change is inversely
proportional to the complexity of the change.&amp;rdquo;&lt;/p&gt;</description></item><item><title>Comp Sci - An Interview with Stanford's Undegraduate Professor</title><link>/comp-sci-interview-with-stanfords/</link><pubDate>Fri, 07 Sep 2007 00:00:00 +0000</pubDate><guid>/comp-sci-interview-with-stanfords/</guid><description>&lt;p&gt;This is the guy who runs Stanford University Undergraduate programme. He talks
about the future of computer science:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Computer Science will evolve more than most other subjects as it expands into
other areas, especially Biology and other areas people don&amp;rsquo;t normally
associate with it&lt;/li&gt;
&lt;li&gt;Industry ties with Colleges are going to be very important&lt;/li&gt;
&lt;li&gt;Computer Science with Law is the next big area&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thanks to
&lt;a href="http://scobleizer.com/2007/08/31/google-sun-yahoo-hp-cisco-and/"&gt;Robert Scoble for doing the interview&lt;/a&gt;.&lt;/p&gt;</description></item></channel></rss>