Showing posts with label software. Show all posts
Showing posts with label software. Show all posts

Thursday, 30 December 2010

Hello, Android!

Well so far Android is hard to program to. Considering I've only ever done to a screen of whatever size I decide, this is very new. Also being an app leaves me with alot of other things to consider. Layout is a huge issue.

Eclipse handles the vast majority of the initial set-up so managed to do this with 2 lines of code changed.


Good start I believe.

miTanks, Part 1

So now that I have an Android phone my next plan is to create an app. I could port some of my CLI games across very easily, but that's no fun. I'm going to remake Tanks, with the help of a friend, herein refered to as Foo.

Tanks is a simple turn-based game. Each player has a tank. On your turn you select the angle to shoot and the power, and then fire. Some minor physics determine travel of the shot. Then there is collision and damage calculations. Rince and repeat until there is only one tank left standing.


I'll get Foo to post an about Foo thing here aswell. Foo has an LG p500 (Optimus One), that runs Android 2.2. Slightly better specs than the Galaxy 580 for a similar price. Galaxy 580 runs Android 2.1, so will use that as the minimum version.

Wednesday, 22 December 2010

miNote

Problem:
University requires we keep some form of log book. Physical or virtual. As I am doing software a virtual one sounded good. Now, I'm not rich so I use Open Office. Compatibility and laziness meant I didn't want to use any word editting software like Microsoft Word or Open Writer. Using notepad is also pretty lame. Now I don't need to know all the crap I had written in earlier; don't need to correct spelling mistakes; CLI is fine; all I need is a time stamp with each post. Didn't want an online thing, like this blog, incase I couldn't get online when I needed it. So I decided to create my own note taking program.

tl;dr Need a program to take notes and timestamp.

Solution:
Decided to go with Java for this one. Just because I was using it at the time. This would probably be much better had it been written in C or something equiv. Since there is no need for high performance the language speed is irrelevent. I went with a basic CLI interface that logs each 'post' with a timestamp on an enter key press. Having seen a friend make a similar GUI version and struggle with clicking a button for each post, he was trying to include multiline posts, it seemed the CLI was a good plan. The posts are only timestamped if the times differ by more than a minute. This will probably be increased later on as up to the minute is a bit over the top for recording information in this case.

Code:

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Scanner;
/**
 * @author Michael Standen
 * Saves my notes, with appropriate time stamp.
 */
public class MiNote {

 /**
  * @param args
  * @throws IOException
  */
 public static void main(String[] args) throws IOException {
  // Initialise things.
  Scanner scanner = new Scanner(System.in);
  System.out.println("Please enter the path of the notes file:");
  File notes = new File(scanner.nextLine());
  // Checks file exists.
  while (!notes.exists()){
   System.out.println("File does not exist. Create new? Y/N");
   if (scanner.nextLine().equalsIgnoreCase("y")){
    // Creates a new file with the name provided.
    if (!notes.createNewFile()){
     // Error in creation, get new file name.
     System.out.println("Error in file creation. Please enter new file path:");
     notes = new File(scanner.nextLine());
    } else {
     new BufferedWriter(new FileWriter(notes, true)).append("Created " +
       new SimpleDateFormat("(d MMM yyyy 'at' HH:mm z)").format(new Date())
       + '\n').close();
    }
   } else {
    System.out.print("Please enter the path of the notes file:");
    notes = new File(scanner.nextLine());
   }
  }
  // Success. Outputs the current date.
  System.out.println("Success. The current time is: " +
    new SimpleDateFormat("(d MMM yyyy 'at' HH:mm z)" + '\n').format(new Date()));
  // Write the opening date and time.
  new BufferedWriter(new FileWriter(notes, true)).append("" + '\n' + "Opened " +
    new SimpleDateFormat("(d MMM yyyy 'at' HH:mm z)" +
      '\n').format(new Date())).close();

  while(true){
   String line = scanner.nextLine();
   if (line.equalsIgnoreCase("q")){
    // Quits the program.
    break;
   } else if (line.equalsIgnoreCase("r")){
    // Outputs the entire file.
    readNotes(notes);
   } else {
    writeNotes(notes, line);
   }
  }
 }
 /**
  * Appends the note to the file and adds appropriate time and date stamp.
  * @param notes the file to be writen to.
  * @param line the String to be added.
  * @throws IOException
  */
 private static void writeNotes(File notes, String line) throws IOException{
  // Make the file writable.
  notes.setWritable(true);
  // Create the file writer.
  BufferedWriter writer = new BufferedWriter(new FileWriter(notes, true));
  // Create date variables to see if time stamp is applicable.
  Calendar now = Calendar.getInstance();
  now.setTime(new Date());
  Calendar edit = Calendar.getInstance();
  edit.setTime(new Date(notes.lastModified()));
  // Create formatter for the time stamp
  SimpleDateFormat formatter;
  // Appends the date if it is different then the last edited date.
  if (now.get(Calendar.DAY_OF_MONTH) != edit.get(Calendar.DAY_OF_MONTH)){
   formatter = new SimpleDateFormat("(d MMM yyyy 'at' HH:mm z)");
   writer.append("" + '\n' + formatter.format(new Date()) + ": " + '\n');
  } else if (now.get(Calendar.HOUR_OF_DAY) != edit.get(Calendar.HOUR_OF_DAY) ||
    now.get(Calendar.MINUTE) != edit.get(Calendar.MINUTE)){
   formatter = new SimpleDateFormat("(HH:mm z)");
   writer.append("" + '\n' + formatter.format(new Date()) + ": " + '\n');
  }
  writer.append(line + '\n');
  writer.close();
 }
 /**
  * Reads the file and prints the standard output.
  * @param notes the file to be read.
  * @return false if unable to read, true otherwise.
  * @throws FileNotFoundException
  */
 private static void readNotes(File notes) throws FileNotFoundException {
  // Outputs the file.
  notes.setReadable(true);
  Scanner scanner = new Scanner(notes);
  while(scanner.hasNext()){
   System.out.println(scanner.nextLine());
  }
 }
}


Notes:
CLI programming is cool. If someone has no idea what's going on, they will be impressed. Also comments are important. Remember that.

miCrawler

Problem: At my work it was decided that we were to do mail drops. Rather than leaving the office and walking around the local area, we hit up local real estates offices etc and found all the addresses of houses for sale, our target audience. As it happened the real estate people were not helpful, there websites were. More helpful then these was the TradeMe website. As it turned out most of the real estate agents also listed the houses for sale on there anyway.
For a while it was my job to go through every listing and put them into a spreadsheet for some processing. After a day of this I thought it would be easier to write a web crawler to do it all for me.

tl;dr We need to get all the addresses off TradeMe, that are local and recent.

Solution:
Having recently done Python at university, I decided to use that. As all I wanted was a CLI program that I could implement quickly, it seemed to be a good fit. The program searches the list of listings for the listing number and then searches each listing for the address. If it has one, it is appended to a txt file. This file can then be added to a spreadsheet using imports.
Credit must go to a couple of places for this:
http://forums.devshed.com/python-programming-11/webcrawler-in-python-73318.html
http://www.daniweb.com/code/snippet216420.html
daniweb is a great source for help, although I can't stand the website. Found it tricky to navigate. Google helped with that.

Code:

#!C:/Program Files/Python/Python 2.7
import urllib, time
print "miCrawler version 0.1"
f = open('addressFile.txt', 'a')
# The below URL is the houses for sale in the manukau area, in list view, sorted by most recent, page 1
# May need to be updated occassionally.
tmManukau1 = 'http://www.trademe.co.nz/browse/property/regionlistings.aspx?mcat=0350-5748-3399-&v=List&key=100055&page='
tmManukau2 = '&sort_order=expiry_desc'
for i in range(0, 60):
    tmManukau = tmManukau1 + str(i) + tmManukau2
   
    page = urllib.urlopen(tmManukau).read()
    # Note that line 637 is the first occurance of a url for a particular listing.
    # The 9 digits following this string will represent a listing.
   
    auctionString = '/Trade-me-property/Residential-property/Houses-for-sale/auction-'
   
    pos = 1
    pos = page.find(auctionString)
    # Loops through this process until there are no more valid links on the page.
    while (pos != -1):
        # This will build a string for the URL of the listing found.
        listingURL = 'http://www.trademe.co.nz' + page[pos : pos + 77]
        listing = urllib.urlopen(listingURL).read()
        # Gets the address from the listing, the 26 skips the <td> and spaces.
        addSPos = listing.find('<td>', listing.find('Location:')) + 26
        addEPos = listing.find('</td>', addSPos)
        address = listing[addSPos : addEPos]
        try:
            int(address[0])
            address = address.replace('<br />', '\t')
            print (address + '\n')
            f.write(address + '\n')
        except ValueError:
            print (address + 'HAS NO NUMBER \n')
        finally:
            # Each address occurs twice, skip the second.
            pos = page.find(auctionString, page.find(auctionString, pos + 78) + 78)


Note:
This is very specific. It only searches Manukau and surrounding areas. Small changes on the urls will need to be made for that to change. The range in the loop determines which pages are to be read. Also I have no idea what that mcat number is and may need to be updated.
I suppose the main key here is this line:

 listing = urllib.urlopen(listingURL).read()


'listing' now contains the entire html code for the page. Performing some search functions on here for the auction numbers allows the program to find the relevent listing and from that page find the address. Simple enough.
The random hard coded numbers are there due to formatting. Easiest way I could think of to get around it. So that's that one. Never used all the 1,180 addresses. Kept the boss off my back for a while though.

miWork

So I've made a couple random programs. They work. Not well, and they don't look great, but they do what they are supposed to. I have a theme going where every program is prefixed with mi. Yes like Apple.

I will be releasing the code from most of my small projects, for two reasons:
Firstly, it may help someone else out there with something. I know from experience that having some example code to deconstruct helps me understand things.
Secondly, if I lose it, it will be here. Storing everything on a tiny usb is never a good idea.

Any comments, questions or suggestions are always welcome.

Cheers,

Tuesday, 21 December 2010

About Me

So this should probably be in here some where.

My names Michael, or Milk. I'm 19. Studying at the University of Auckland, for an Engineering Degree specialising in software. My spelling isn't great. I have a beautiful daughter, and lovely girlfriend.

Don't really do to much. Like playing Halo alot. That's always good fun. /b/ is also another of my weaknesses. So is not finishing my own projects. Once I have a semi-working prototype I'm usually happy to stop. Most of the time there is no point to my project except to prove to myself that I can do it.

Have a part time job working for Guardian Storage Ltd. It's a job. And yeah.

That's all I can think of at the moment.

Cheers,