Archive for the ‘Programming’ Category

Learning Haskell for a Greater Good!

Thursday, April 12th, 2012

tl;dr – Learning Haskell and functional programming, yay!

So I have finally decided after years of using imperative style languages that I am going to Learn me some Haskell for a greater good, as I have been curious about the functional side of programming. Now it has taken me quite some time to get here, I have been toying with the idea of functional programming for quite a while, just haven’t gotten around to it as the imperative languages seem to be just fine for what I do for a living, Systems Administration/Engineering. I have been toying with either learning Haskell or Erlang, and have decided on Haskell. Why?, well I don’t really know just kind of happened that I chose Haskell.

About a day after I started reading Learn you a Haskell for a Great Good! I noticed this article – (The Downfall of Imperative Programming) fly across my twitter stream from @LordCope. Now, it is a well written article and surprisingly the comments are for the most part well thought out (I really abhor reading commentary on the internets), and I have to agree with what Bartosz says here in response to a comment about functional programming being the downfall of the imperative languages, “Of course it’s an exaggeration :-) . Just like object oriented programming didn’t eliminate C, Haskell will not eliminate Java. It will just dislodge it into its well deserved niche.” I personally, and honestly think that to be the best that one can be it is sometimes necessary to open one’s mind and try new things, and for me right now that is Haskell and functional programming, and so far I am really enjoying myself.

After I finish with Learn you a Haskell for Great Good! I am going to move on to Real World Haskell which is also freely available online, and while I am not associated with any of the authors in any way, shape or form, if you like the books I strongly encourage you to purchase them as they require a lot of effort to write.

Learning Python Resources

Sunday, September 4th, 2011

I originally posted this on my blog http://www.barrymorrison.com/2011/09/04/learning-python-resources/ but thought it’d be a good fit over hear as well. These are simply links to Python resources I’ve collected recently in an effort to tech myself Python. Hopefully others can find it equally valuable.

http://code.google.com/edu/languages/google-python-class/index.html

http://i.imgur.com/YQafj.png

http://code.google.com/appengine/docs/python/gettingstarted/

http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-00-introduction-to-computer-science-and-programming-fall-2008/

http://diveintopython.org/toc/index.html

http://codingbat.com/

http://www.lightbird.net/py-by-example/

http://rgruet.free.fr/PQR26/PQR2.6.html

http://www.udemy.com/learn-python-the-hard-way/

http://learnpythonthehardway.org/

http://www.swaroopch.com/notes/Python

http://www.pythonchallenge.com/

http://www.youtube.com/user/thenewboston#p/search/0/4Mf0h3HphEA

Get Yesterday’s Date

Tuesday, August 16th, 2011

I was working on a script that parsed log files. The file names were log.mmddyy (log.080811). This was a little bit of a learning experience for me (new to shell scripting). I was working on a Solaris 10 box, but I thought I’d do all my dev/testing on Ubuntu. Big mistake. Linux was running bash/gnu tools. Solaris was not. After I figured out how to do it on Ubuntu, I had to figure out how to do it on Solaris (thanks Scott!), then I did it in Powershell (had done something similar already for another script) and since I’m teaching myself Python, I wanted to do it in Python.

Are they the “right” way to do them? They work! Probably not a “right” way to do them, as there is always more than one way to do something

Shell

#!/bin/bash
 
os=`uname`
 
if [ $os == 'Linux' ];
    then
    yesterday="$(date -d 'yesterday' +%m%d%y)"
    echo $yesterday
elif [ $os == 'SunOS' ];
    then
    yesterday=`TZ=GMT+24 date +%m%d%y`
    echo $yesterday
fi

Gnu Date

#!/usr/bin/bash
 
## Get Yesterday
yesterday="$(date -d 'yesterday' +%m%d%y)"

Powershell

$yesterday = (get-date -format mmddyy).adddays(-1)
$yesterday.tostring('MMddyy')

Python

 
import datetime
today = datetime.datetime.today()
one_day = datetime.timedelta(days=1)
yesterday = today - one_day
yesterday.strftime('%m%d%y')

Normalize MAC address with Python

Tuesday, August 16th, 2011

In an earlier post, Scott did this in a simple shell script. I was curious if I could do it in Python since I am learning Python.

Below is my first attempt. Watch for upcoming updated version.

import sys
 
if not sys.argv[1:]:
   mac = raw_input ("Enter MAC address\n")
   print "Mac is %s\n"; % (mac)
   #sys.exit(0)
else:
   mac = sys.argv[1]
   print "Mac is %s\n" % (mac)
 
##I'm checking to see if someone is giving me in the right format
maclen=len(mac)
if maclen == 12:
    ## converting to list, since strings are immuatable
    maclist=list(mac)
    ## defining positions on list
    positions=2,5,8,11,14
 
    for i in positions:
        maclist.insert(i,':')
    ##joining list at the ','
    newmac=",".join(maclist)
    ## stripping ',' out and converting to lowercase.  
    final12mac=newmac.replace(',','').lower()
 
    print final12mac
 
##assuming that 17 characters will either have - or : in MAC address    
elif maclen == 17:
    ##replacing - with : and converting to lowercase
    mac17final=mac.replace('-',':').lower()
    print mac17final
else:
    ## I'm telling them that if it isn't 12 or 17 characters, it has X chars
    print "There are only %s characters" % (maclen)

FizzBuzz

Monday, August 1st, 2011

Because someone I follow on twitter mentioned it (I had read this article before), I did the fizzbuzz in python (quite a while ago), though as someone pointed out not very pythonically, here’s my entry (non-pythonic python):

I’ll maybe work on making it more pythonic later.

#!/usr/bin/env python
 
i = 100
count = 0
while (count < i):
    if (count % 3 == 0 and count % 5 == 0):
        print "FizzBuzz: %d" % (count)
    elif (count % 5 == 0 and count &gt; 0):
        print "Buzz: %d" % (count)
    elif (count % 3 == 0):
        print "Fizz: %d" % (count)
    else:
        print "Count is %d" % (count)
    count += 1

Set Default Printer with Powershell

Wednesday, July 13th, 2011

Quick, Dirty, Simple. Set the default printer with Powershell. Needed this as a part of a logon script to set default printer for certain users on a terminal server.

## Get the Printer with WMI
$printer = Get-WmiObject -Query "Select * from Win32_Printer Where Name = 'PDFCreator'"
 
## Set printer as default printer
$printer.SetDefaultPrinter()

Dirtoday – Extended

Tuesday, July 12th, 2011

Extended version of Hal’s original “dirtoday” script via twitter https://twitter.com/#!/halr9000/status/88211937720156160

## NAME: Dirtoday.ps1
## AUTHOR: Barry Morrison
## LASTEDIT: 07/05/2011 16:18:33
<#
 .Synopsis
 Get's files from today's date. Will also return narrowed results based on keyword
 .Description
 Get's files from today's date. Will also return narrowed results based on keyword
 .Parameter Path
 Will run in current directory. Path argument will allow you to define a path not in current working directory
 .Parameter Keyword
 Keyword argument will allow you to define a keyword to search on to narrow results.
 .Example
 PS C:\scripts > .\dirtoday.ps1
 
 Directory: C:\scripts
 
 Mode LastWriteTime Length Name
 ---- ------------- ------ ----
 -a--- 7/5/2011 3:25 PM 114 cat
 -a--- 7/5/2011 4:11 PM 2252 dirtoday.ps1
 -a--- 7/5/2011 3:46 PM 848 dirtoday2.ps1
 -a--- 7/5/2011 2:55 PM 110 info.txt
 -a--- 7/5/2011 1:52 PM 37 test.foo
 
 .Example
 PS C:\scripts > .\dirtoday.ps1 -path "c:\Users\John Doe\Pictures"
 
 Directory: C:\Users\John Doe\Pictures
 
 Mode LastWriteTime Length Name
 ---- ------------- ------ ----
 -a--- 7/5/2011 11:05 AM 49888 weinerdog.jpg
 
 .Example
 PS C:\scripts > .\dirtoday.ps1 -keyword foo
 
 cat:2:test.foo:1:blah, blah, foo, ice cream,
 test.foo:1:blah, blah, foo, ice cream,
 
#>
 
param(
 [string]$Path = "",
 [string]$keyword = "";
 )
 
## Checking to see if the Keyword argument is passed -- If it is, search for $keyword
if ($keyword) {
   $files = dir -Path $path | Where-Object { $_.lastwritetime -ge (get-date).date } | Select-String $keyword
   ## If there are not results returned, tell me!
   if (!$files) {
     Write-Output "Nothing Here"
   }else{
     ## If Results exist, give them to me!
     $files
   }
 } else {
 ## If not keyword argument is passed, do a simple search
   $files = dir -Path $path | Where-Object { $_.lastwritetime -ge (get-date).date }
   ## Like above, checking to see if no results are found for the query
   if (!$files) {
     ## Tell me if nothing exists
     Write-Output "Nothing Here"
   }else{
     ## Write results if something exists
     $files
  }
}

Quick python to parse a file and get IP’s

Thursday, May 12th, 2011

Being busy with sysadminy type stuff, I haven’t been able to practice my Python as much as I would like, though I am eating my own words and practicing. I was reading somewhere about adding IP’s to a iptables block list, and thought about creating a quick and dirty parser to go through a log file (or any other file for that matter) and grep out any ip addy’s. The caveat here is that it was quick and dirty and only works on ipv4, and only outputs to STDOUT, but that can all be fix0red real quickstyle (which I think I’ll do as I carry on and make it better). I am still learning how to do things the pythonic way, as opposed to just getting things working, so please be gentle, the style comes with time. *Should have mentioned this before, but I am on CentOS 5.6, and the python version is 2.4.3 (system) so that is why there is no with statement.

#!/usr/bin/env python
 
#import the necessary modules
import re #for regular expressions - to match ip's
import sys #for parsing command line opts
 
# I need to probably make this more pythonic but am working on that...
# if file is specified on command line, parse, else ask for file
if sys.argv[1:]:
    print "File: %s" % (sys.argv[1])
    logfile = sys.argv[1]
else:
    logfile = raw_input("Please enter a file to parse, e.g /var/log/secure: ")
 
try:
    # open the file
    file = open(logfile, "r")
    # create an empty list
    ips = []
    # read through the file
    for text in file.readlines():
       #strip off the \n
        text = text.rstrip()
       #this is probably not the best way, but it works for now
        regex = re.findall(r'(?:[\d]{1,3})\.(?:[\d]{1,3})\.(?:[\d]{1,3})\.(?:[\d]{1,3})$', text)
        # if the regex is not empty and is not already in ips list append
        if regex is not None and regex not in ips:
            ips.append(regex)
 
 
    #loop through the list
    for ip in ips:
        #I know there is argument as to whether the string join method is pythonic
        addy = "".join(ip)
        if addy is not '':
            print "IP: %s" % (addy)
    #cleanup and close file
    file.close()
#catch any standard error (we can add more later)
except IOError, (errno, strerror):
    print "I/O Error(%s) : %s" % (errno, strerror)

Output looks like:

File: /var/log/secure
IP: 68.169.40.177
IP: 14.63.253.14
IP: 113.105.159.162
IP: 125.208.5.78
IP: 89.187.142.141
IP: 212.116.152.36

Actually, I’ll fix the output so it writes it to a file for keeping, mind you this is just a quick addition so it won’t double check to see if the ip address is already there, so it will write dupes…also learned that one should not update vim tab options in mid-coding, as python doesn’t like mixing tabs and spaces…if you need to check “python -m tabnanny file.py” will tell you where you went wrong :), then in vi you can type :retab and it should fix it…

original:
#loop through the list
    for ip in ips:
        #I know there is argument as to whether the string join method is pythonic
        addy = "".join(ip)
        if addy is not '':
            print "IP: %s" % (addy)
    #cleanup and close file
    file.close()
 
new (for output to file):
    for ip in ips:
        outfile = open("/tmp/blocked_ips", "a")
        addy = "".join(ip)
        if addy is not '':
           print "IP: %s" % (addy)
           outfile.write(addy)
           outfile.write("\n")
    file.close()
    outfile.close()

It seems to work, though it’s probably not the best way to do it, and is most definitely not pythonic, though again I’ll plead that I am still learning the style portion. So now that we have the ip’s to block here is a small shell script to add them to your iptables configs, if you so choose, you might need to update for your configuration.

BLOCKDB="/tmp/blocked_ips"
IPS=$(grep -Ev "^#" $BLOCKDB) #so you can use # to add comments to and it will grep them out
for i in $IPS
do
    iptables -A INPUT -s $i -j DROP
    iptables -A OUTPUT -d $i -j DROP
done

As noted many times, these are both quick and dirty, neither do any real error checking or sanity checking, but it took me 20 mins, so use at your own risk, I make no claims as to the usability or completeness of said code. As a sidenote if you want to loop through all the log files or a bunch of files, you can do the following “for i in `ls -1 /var/log/`; do ./get_ips.py /var/log/$i; done” – Two things, 1. I named the file get_ips.py, 2. This is extremely hackish.

As mentioned by someone, I fixed the outer try statement:

#!/usr/bin/env python
#fixed the import, just red PEP 8
import sys
import re
 
try:
    if sys.argv[1:]:
        print "File: %s" % (sys.argv[1])
        logfile = sys.argv[1]
    else:
        logfile = raw_input("Please enter a log file to parse, e.g /var/log/secure: ")
    try:
        file = open(logfile, "r")
        ips = []
        for text in file.readlines():
           text = text.rstrip()
           regex = re.findall(r'(?:[\d]{1,3})\.(?:[\d]{1,3})\.(?:[\d]{1,3})\.(?:[\d]{1,3})$',text)
           if regex is not None and regex not in ips:
               ips.append(regex)
 
        for ip in ips:
           outfile = open("/tmp/blocked_ips_test", "a")
           addy = "".join(ip)
           if addy is not '':
              print "IP: %s" % (addy)
              outfile.write(addy)
              outfile.write("\n")
    finally:
        file.close()
        outfile.close()
except IOError, (errno, strerror):
        print "I/O Error(%s) : %s" % (errno, strerror)

Ok, fixed for the last time (hopefully) imabonehead refactored, moved the finally clause inside, and moved the except outside.

Meta:
Contact:
Scott:
Systems Engineer, Geek, Horror fan.

Ways to reach Scott:
Twitter
FriendFeed
Facebook
LinkedIn
Tumblr
Zerply
About.me

Barry:
Systems Administrator / Geek.

Ways to reach Barry:
Twitter
Friendfeed
Associations:
Twitter:

View more tweets | Powered by HL Twitter