2012/05/08

Udacity timings

So, the three Udacity courses that I'm doing at the moment:

1) CS101 - the introductory course, aka "How to Build a Search Engine"
2) CS212 - "Design of Computer Programs"
3) CS262 - "Programming Languages"

Are all currently on week 4 of 7. Which means Week 5 will start on the 14th; Week 6 will start on the 21st, and Week 7 will start on the 28th.
And whaddaya know, I'm getting married during Week 5, on honeymoon throughout Week 6, and getting back just in time to catch up on a week and a half of material and then do the assessments.

On the bright side, CS101 is fairly simple - as an introductory course - and because the course matter hasn't changed since it was last run I can access all of the lessons now. So I'm finished with CS101, and I'll just need to refresh my memory a bit before doing the assessment/exam/whatever.
CS212 is okay - the concepts aren't generally that complex, but some of the application does get pretty tricky, because it's trying to teach habits of thought and rules of thumb, more than specific methods. A sort of "do I really want a hammer for this job, or a spanner?" At least, that's my impression; equally, it assumes a fair bit of knowledge that you can get from other students on the forum, or from other websites etc in order to focus on what he really wants to get across. As such it's quite rewarding, but more of a time commitment than it might have been.
CS262, is cool. Like CS101 it takes a big, ambitious-sounding aim - in this case "Write your own web browser" - and yes, this means that by the time I am finished I will have written my own Google and my own Firefox XD - and gets you there through the course of seven weeks. There is some commonality of material with CS212, which is all to the good. For example, CS212 introduced Regular Expressions, then sort of assumed that you knew how they worked; which I did, because I'd been slightly more comprehensively introduced to them by CS262!

Well, at the end of the day I work best under pressure - so I guess it's all to the good that it's fallen out this way, because I'll have a crunch around when I finish the courses, and then get back to the original point of this - my app!

2012/04/28

7 card hands

Further to what I discussed here, interestingly enough one of the pieces of work in the Udacity course CS212 is to write a function to find the best hand of five cards in a group of 7.

So I've still got the problem of dealing out the flop (cards on the table) as well as the hands for each of the players, but I can come back to that, this is a 'killing two birds with one stone' moment.

Now, out of seven cards, let's call them C1-C7 (or C0-C6 if you prefer), how many different hands could I have?
Hmmm. Well, out of my set of 7, I can discard any two; and working through the sets 1-2, 1-3, etc up to 6-7, I can get 21 different sets; leaving me with, conversely, 21 sets of 5.

Remembering good coding practices, however, we want to generalise. So rather than doing something like:

for i in 21:
    hand = [1, 2, 3, 4, 5, 6, 7] - discard[i]

where discard = [(1,2), (1,3)...]

Actually, hang on - maybe that isn't so bad. As long as discard is generated by a function which is more general, discard itself can be fixed values.
To explain what I'm talking about here, discard takes the form of a list, with each item on the list being the two cards to discard, leaving a five-card hand.
It is possible to have a program where discard is 'hard-coded', meaning that my code literally says:
discard = [(1,2), (1,3), (1,4), (1,5), (1,6), (1,7), (2,3), (2,4), (2,5), (2,6), (2,7), (3,4), (3,5), (3,6), (3,7), (4,5), (4,6), (4,7), (5,6), (5,7), (6,7)]
Now that has three problems with it:
1) it's ugly. Yes, this matters!
2) it's error prone - what if I mis-typed one of those options? A hand will appear twice, or not appear at all. What is more, this means that this scales poorly - or in other words, if I had to do this for sets of 100, it's massively more difficult.
3) it's hard to adjust.
Having all that data hidden away in discard is fine.
In fact, I think it will be clearer if I generate discard elsewhere and then just refer to it here.

Right, enough messing about. I decided that Python must have a way of handling what I want to do; so I did some research and found: this Python documentation of something called itertools - or methods for achieving things which require a lot of iteration.
Specifically something called combinations. Combinations("ABC", 2) would give AB AC BC - perfect!
No need to mess about with what I was talking about with discard as a first step, I've jumped to having all the possible 5-card hands output from a 7-card input.
Now what I need to do is rank the 5-card hands against each other - well, all I need is to run hand_rank (a function already written as part of the Udacity material) - and it's job done.
So after all that, the result looks like this:
def best_hand(hand):
    "From a 7-card hand, return the best 5 card hand."
    hands = itertools.combinations(hand,5)
    return max(hands, key=hand_rank)
Back to the problem of dealing.

2012/04/26

Poker? Poke 'er!

Having mostly completed CS 101 (Introduction to Computer Science, aka Build a Search Engine), which was awesome, I just need to wait for a final exam to come out.

So I have moved on to looking at CS 212 (Design of Computer Programs), which has so far focussed on a program to judge winning poker hands, with an added bonus of a procedure to deal the hands. And here I hit a problem, because that procedure is:

def deal(numhands, n = 5, deck = [r+s for r in '23456789TJQKA' for s in 'SHDC']):
"Shuffle the deck and deal out numhands n-card hands"
random.shuffle(deck)
return [deck[n*i:n*(i+1)] for i in range(numhands)]
Just to explain what's going on here:
First it defines (def) a function called 'deal'. Deal can take as inputs the number of hands to deal (numhands), the number of cards per hand (n), and the definition of the pack of cards (where r is the card values, and s is the suits).
Then there's a bit of a description of the function, before shuffling the pack randomly.
Finally the idea is to return an output where:
we get a number of hands (numhands), each containing n cards, by counting out the first n cards, then the next n cards, until the hands are complete.

This is okay for a whole bunch of card games; in fact, considering poker it would work for Five-card Stud, which may be what was intended. But what I've always played is Texas Hold'Em, which has a different structure.
For anyone who hasn't had the pleasure of playing Hold'Em, the basic structure is that each player receives two cards in their own hand, and there are then five cards dealt face up on the table. Each player makes their best hand of five.

So I've tried to put together a function to do that job:
def deal(numhands, n=2, face=5, deck=[r+s for r in '23456789TJQKA' for s in 'SHDC']):
    random.shuffle(deck)
    hands_out = deck[0:face] + deck[(n*i+face):(n*(i+1)+face)] for i in range(numhands)]
    return hands_out

which unfortunately...doesn't work.
I believe the logic is sound; I'm just getting some part of the syntax wrong. I'll come back to it; once this works, I will also have to make an additional function to work out the best hand of five cards from the seven available to each player, and the rest of the code should then follow.

2012/04/20

The reason for my absence

I have been having far, far too much fun diving right into the courses at Udacity. I will raise one caveat - the instruction is very Youtube-heavy, so if your Internet is slow the experience could be somewhat frustrating.

That said, the instruction is engaging; the pace is good, and the diversions entertaining. I have also greatly appreciated the fact that you generally only sit watching/listening for a couple of minutes before you are asked to once more engage brain and do something.

Having initially focussed on the introductory course, because all the material for it is accessible now, I already feel that I have a reasonable grasp of Python.
Incidentally, as well as teaching me a wholly new programming language (shiny!), I've had a refresher on some of the principles of Object Oriented Programming, which is handy
Give it another couple of days working at it, and I expect that I will have achieved the initial promise, of writing a search engine.
Yes, that's right, using Udacity, Python and a few days of my time, I too can create a Google! Cue maniacal laughter.


Oh - and one last thing - it isn't too late to sign up!

2012/04/13

Sire, there is no royal road to learning*

I talk a lot about the frustrations of learning to program; there are a number of reasons why there may be more than the bare minimum going on here, but there is always some frustration in programming.

So today I thought I'd share some alternative routes to getting into programming, other than this somewhat foolhardy "Dive right in and use the Internet!" approach which I've taken.
First off, there are real live courses at actual Universities, or FE Colleges near you. However, costs can be prohibitive, and a lot of the time you need to be in a classroom, so working it around a job isn't exactly practical.
So we move on to distance learning. Well, there's always the Open University; but their costs can still be substantial.
There are also books like Dummies Guide to... or a similar idea for Android specifically. I learned a bit about Visual Basic for Microsoft Excel from a tome that seemed big enough to be the Liber Paginarum Fulvarum**, though I got more from diving into already-written software and then referring to the book when in trouble than from working through it in any systematic way.
Moving right along, there are also respected academic institutions who have some or all of their courses available online. That could be very handy, but there's no interaction, so it might not be much more rewarding than a book or similar.

There's also a Wiki-based solution and other similar efforts out there; and for anyone who has a grasp of the basics but wants to get into more real problems, there is the excellent OpenHatch, set up to prepare people for getting involved in Open Source projects.

Finally, there is the one that I am trying at the moment, which I discovered through an excellent blog I read called Unequally Yoked; Leah who blogs there has recently been taking courses including How to Build A Search Engine over at Udacity and recommended it highly. The next round of classes is starting on Monday (the 16th April) so if you want to have a crack at it, come join the party!
Because I have previous programming experience but no knowledge of Python, I've gone for How To Build a Search Engine (which is an introductory class), Programming Languages and also Designing Computer Programs.
For the inexperienced I'd advise starting with How to Build a Search Engine and leaving it at that. I may find that three at once is a tad ambitious, but I had to resist the temptation to sign up for all six, so I think I'm doing well!

*Slight misquote of Euclid, speaking to Ptolemy "Sire, there is no royal road to geometry"; the meaning remains - if you want to learn something useful, expect it to take a while. Viz the 10,000 hour rule.
**by Achmed The I-Just-Get-These-Headaches

2012/04/11

Testing Test...

Spent much of the day going around and around and around in circles. The word is argh.

I begin to wonder whether I should try condensing the app into one view for now, then trying to figure out how to add a second view separately...might be a way to separate out the issues enough to attack them productively.

2012/04/10

Source Not Found

I haven't yet found any useful suggestions on dealing with Source Not Found; so, I'm going to take some stabs in the dark and see if any of them result in a scream.

First off, I know that I have said that the warnings aren't that important, as long as there aren't any actual errors. How about I just test that; I comment out the unnecessary import statements [a simple /* on one side and */ on the other does the trick. Alternatively for single lines // works.]

Commenting in this way is a great method to quickly change code around - because if I decide that removing something was a mistake, I just have to uncomment it, not remember how it went and re-type it.

Then the remaining warning is around
private DatePickerDialog.OnDateSetListener mDatePicked;
and how I use it in
mDatePicked = new DatePickerDialog.OnDateSetListener() {
In that Eclipse is telling me that mDatePicked is not used! Um, oops...what's gone wrong here then? I declare mDatePicked, as you see above, then I do some stuff onDateSet.
Now, I have a sneaking suspicion that there's some duplication between these two lines, so let's see what happens if I take one out, leaving
mDatePicked {
 Nope, that errors. Badly. Howabout taking out the first one? Also makes things worse, in that the warning has upgraded to an error.
Aha! Stack Overflow to the rescue! Looks like the whole thing is redundant now I've got
public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
So I'll just try cutting out the lot, see what I get. No...that causes even more problems. I'm going around in circles here. I believe the technical term is GAH!

2012/04/09

Testing, Testing, 1-2-1-2

To test an app, first thing you need is for Eclipse to not report any errors.

Then you need to feel that there is enough of your app complete to be worth testing. For instance, I don't really-truly care about whether the home screen looks right, if all I can do is look at it. I want to know whether it works when I press buttons.

Then you Save All (Ctrl+Shift+S), and finally you go to the green and white Button for "Run Wedding Logistics".

Having already specified a test machine (in my case using the specs for my own Android phone), it should just load up. Be aware though, this step can be veeeery slow.
And...ah. Oh dear:
Well, at least you can see what Toast looks like! As well, of course, as the appearance of the testing software [which is included in Eclipse].

It does occur to me that most programming I've done will talk about de-bugging, and this seemed to be more of a 'run program' option. Hmmm. *Looks around* Aha!
I clicked on this:
I should have gone for this:
The Debug button. Debugging is one of those terms that is more literal than you think - while the origins are obscure, it was popularised in the days of the first computers, vast buildings full of valves such as Colossus or ENIAC. - when it was possible for a bug like a moth to get into the works and cause the machine to behave in unexpected ways. The archetypal bug is pictured here.

I believe my error is linked to the fact that the tutorials from hackaday were with already completed and tested code - so the bit of seeing it work at the end was just the reward. Anyway, now I hit Debug, so I'll see what pops out:
Source not found.
Ah. I have no idea. Will have to come back to this once I've done some more reading.

2012/04/07

Index Post up to Saturday 5th April

For convenience:

I began by introducing myself; the software that I am using; and my first decisions in the design process.

I then made a start on this project, working on a design in DroidDraw; before moving my work into Eclipse, then getting bogged down for several posts as I worked out how to solve a niggling little problem.

That got me up to last weekend, when I disappeared on my stag do, and came back a little hungover; bringing me into this week.

This week I began with switching between the two activities which currently make up the app; fun with onClickListeners, then made some slow progress which culminates in a couple of finishing touches.

Next week we go on to testing.

Finishing touches

As I said last time, I reckon there are two things left to do before I have a module that is worth testing.

First - I want to notify the user when a date is entered successfully. Now, this is not essential in the grand scheme of things, because when the whole app is complete, closing SSA will lead the user to a screen which shows the date (among other things). Whether or not I decide to retain it then, I want to have it now, just so that I know it's working when I test it!

The easiest way to do that is with what is called Toast - I imagine because when it is ready, it pops up! Toast is a kind of message that appears in a little box floating on the screen for a set duration.
Toast has three key components (or 'arguments', in this instance). The Context, being the current state of the application; the Text, being what you want your Toast to display; and the Duration, being how long to display it for.

As usual with Android's imaginative variable names, we get something like this:

Context context = getApplicationContext();
        CharSequence text = "You are getting married on " + WedDate "!";
        int duration = Toast.LENGTH_LONG;
        Toast toast = Toast.makeText(context, text, duration);
        toast.show();
As you can see, here we will tell people "You are getting married on []!", for a duration of Toast.LENGTH_LONG. I don't know exactly how long that is, but it's a few seconds; certainly long enough to read this message.

Alright, so on to the second thing I wanted to add - and this is probably entirely temporary: a message on WLA to confirm that the app knows the user's wedding date.
I've put exactly the same Toast, just replacing "You are getting married on " with "Your wedding date is ", so that if I close SSA and get back to WLA at the same time as a Toast appears, I will know which Activity is responsible for it.

In both these cases, I already had the import statement - import android.widget.Toast - otherwise I would have to add it before Eclipse would be happy.

Now, bearing in mind that 1) This is one small corner of the planned app, and 2) That it may not even begin to work when tested - it's time to start testing this thing, and see what breaks!

2012/04/05

Slow Improvement

Aha! It gets better - I have not only discovered that it is possible to make the calendar appear, not just the day/month/year spinners; I have also discovered a method called onDateSetListener. I've even found out how to make a value (like "Yes, a date has been picked") persist from one session to the next.

The calendar thing I'm going to just make note of for now - remembering as I said back here that as long as it works, prettiness comes later.

The method onDateSetListener might explain some of the problems I've had with onClickSetListener - it wasn't quite the right method for what I was doing. I'll try replacing it based on what I've found at the Android Developers' forum and Stack Overflow.

So from
WeddingDate = (DatePicker)findViewById(R.id.datepicker
WeddingDate.setOnClickListener(this);
I now have:
WeddingDate = (DatePicker)findViewById(R.id.datepicker);
        mDatePicked = new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int monthOfYear,
int dayOfMonth) {
// TODO Auto-generated method stub
I think that's progress, of a sort? At least, Eclipse isn't flagging any major errors, and I can put something into the method stub to cover the last point I mentioned up top - making sure that once a date is picked, the user doesn't have to do it again.

That's where this comes in. Now, the example given isn't quite right - it's for a setting that the user might change at any time, so the setting is re-saved every time the application closes. I want mine to save the setting solely when the user finishes with SSA - if they ever say they want to change the date, I'll get the app to just bring them back to SSA.

So, in WLA I have put
        SharedPreferences settings = getSharedPreferences(WedPrefs,0);
        String WedDate = settings.getString("WedDate", "");
which is aimed at getting together an object called "settings", which in addition to knowing the Wedding Date can also hold other information in future. I've picked my variable names and properties such that they match up with the if block I created here.
Coming back to SSA, where it said //TODO above, I've now got
SharedPreferences settings = getSharedPreferences(WedPrefs,0);
SharedPreferences.Editor editor = settings.edit();
WedDate = String.valueOf(year) + String.valueOf(monthOfYear) + String.valueOf(dayOfMonth);
editor.putString(WedDate);
This still isn't quite right - the string WedDate operates, and becomes year + monthOfYear + dayOfMonth [for example the 19th May 2012 would appear as 2012419* which I think is the easiest way to grab it back out afterwards] but then Eclipse isn't keen on editor.putString(WedDate); and I'm not sure why.

Well, I wasn't. I tried typing it again, and when the tips popped up:
I saw that the putString method requires two separate arguments.
By analogy with the method in WLA, the first argument has to be "WedDate".
Because of the name I've given in SSA, the second argument has to be WedDate. Fortunately one is in "" and the other is not, so that isn't confusing at all!
May want to change one of those names, I'll think about it.


In any case, this has taken a while, but I've nearly finished the initial stage. There are two immediate steps remaining - one, a message to inform the user whether the date is entered successfully, and two, something on the WLA to state whether a date already exists.
Then to build this into the full app, I'll need something to direct the app back from SSA to WLA - if I understand Android convention correctly, that will be automatic as long as I close down SSA correctly.
Then I can start testing it.

*2012419, you say? Yes. 2012 for the year; then Java counts months from 0 to 11, so in spite of being the fifth month May comes out as 4; then 19 for the 19th. I think that the month will show as 4, not 04...
Some systems counting from 0 and others from 1 is the reason for fence-post errors!

2012/04/04

Struggling with SSA (no, not what you might think!*)

AAAAAAAARRRRRRRRRRRRRRGGGGHHHHHHHHHHHHHH!
'scuse shouting, this is frustrating.

The latest thing I've tried is:
        DatePicker WeddingDate = (DatePicker)findViewById(R.id.datepicker);
        WeddingDate.setOnClickListener(this);
 based on an example I found for implementing an OnClickListener.

[OnClickListener being a method which can look out for an action by the user and take action when it is detected.]

However, Eclipse doesn't like this - the specific error it's giving me is

The method setOnClickListener(View.OnClickListener) in the type View is not applicable for the arguments (SplashScreenActivity)
 The above is shown in red to give some inkling of how angry Eclipse is with me. Now, I actually just realised an error in the above - I already defined WeddingDate as a DatePicker above, so re-defining it like this is just going to confuse Eclipse. So I take that out to get:
WeddingDate = (DatePicker)findViewById(R.id.datepicker
WeddingDate.setOnClickListener(this);
Main difference? WeddingDate is now highlighted in blue - Eclipse has recognised it as a defined object. The error is still marked, however.
My best guess is that I shouldn't be using an OnClickListener on a DatePicker. Hmmm. There is a way to use auto-completion to check that.

Aha. By typing
WeddingDate.set
I get a list of methods whose names begin "set" that might apply to the object WeddingDate. It's a long'un, but the beginning looks something like this:

and as I go down the list, setOnClickListener is a valid option.

Better yet, when I take the suggested variable of setOnClickListener(l) I get a different error.
l cannot be resolved to a variable
Which is fine, because it shows me that the previous error related not to the method setOnClickListener, but only to the argument, which the first time is "this" and the second time is "l". They've given me different errors because in Java "this" has a default meaning (thus the purple colouring) and "l" does not.

I do not know how to resolve this at present, but I'm sure I can come back to it.





*I realized after dubbing my SplashScreen as SSA** for the purposes of this blog that in the parlance of American Evangelicals SSA stands for same-sex attraction; as such "struggling with SSA" is the process that homophobic Evangelicals have to go through if they realise they are homosexual.
I don't feel attracted to men, and even if I did it wouldn't change the fact that I am attracted to women; so not only is the wedding still on, but the post title might be misleading to people from that world.

** I learn from the fiancée that SSA is also a term in Chemistry for the Steady-State Approximation.

† SSA also stands for the Secular Student Alliance who are all kinds of awesome if you're USian and not so keen on the Religious Right.


Nested footnotes FTW!

Do we have a date, dear?

I have this ongoing problem of how to persuade my app to listen out for word from the calendar on the front page [for a quick reminder, that looks something like the below:]
I need this page to notice when a date has been entered; save the date somewhere accessible for all other parts of the app; then call up the next page of the app.

As my last few posts have alluded to, this is where not having worked with Android or Java before is really kicking my arse - because this is basic stuff, and I'm having to do a lot of reading and looking at example code to figure it out.
As a result, some of my code may be more apt for an entry on The Daily WTF than Google Play [as the name suggests, the Daily WTF is a blog exposing code that makes programmers go WTF!?]. That in itself doesn't trouble me, as long as it works.

So, with no further ado, here's the next bit I've been working with.



        if(WedDate.matches("")) {
        Intent intent = new Intent(this, SplashScreenActivity.class);
        startActivity(intent); } 
To give a little background, this is in WLA, the main view for the app - and before loading, it is checking whether there is a value for WedDate. If one exists, then great - the app can continue in this page. If however the app doesn't know the date of the wedding, it loads SSA to ask the user for it.
As best I understand it, this is the best way to do things - I don't want to load WLA and then force new users to navigate away from it, and I don't want to make regular users faff about with the date before going on to do useful things.

So far so good - no errors being marked by Eclipse here! Doesn't mean there won't be a problem at run-time, of course, but...baby-steps.
On to SSA, and what we do when the user inputs a date.

2012/04/02

Discipline!

Well, after a rip-roaring stag do (yesh, it was awesome, thank you very much), I need to get back in the groove. I spent most of today reading [yes, on topic reading! Android theory from here mostly], but not a lot of writing.
See if we can't reverse that balance tomorrow.

2012/03/30

Further Posting Cancelled

Until Monday, due to the intervention of my stag party.

I'll get back to work (assuming I come home safely!) on Monday, see y'all then.

2012/03/29

Android Theory

I've been delving around in Android and Java help materials - tutorials, guides and forums - to help me put together this part of the app.

So, here's the first thing that I've found out, from the official guide to developing for Android here:

An activity represents a single screen with a user interface.
That means I don't want WeddingLogisticsActivity to be a big thing - I want to deal with something called, I don't know, SplashScreenActivity (now referred to as SSA) which is aimed purely at this initial screen of the app.
[Note for future reference - I will probably want a test so that SSA only runs the first time you open the app. Easiest thing that occurs to me is to check whether the variable WeddingDate is empty; if it is, run SSA, otherwise don't. That should avoid problems.]

Looking in more detail at this page, I think the way to proceed is to tell WLA to start an activity called SSA, in the terms
Intent intent = new Intent(this, SignInActivity.class);
startActivity(intent);
Or in my case:
        Intent intent = new Intent(this, SplashScreenActivity.class); 
        startActivity(intent);
Then I set up the beginnings of the new Activity for SSA in the same way; only to realise that I need to put SSA in its own file, called (logically enough) SplashScreenActivity.java as otherwise the app would get confused.
Now, I'm still seeing an error in WLA on the line Intent intent etc, as the app doesn't seem to recognise it; so I tried adding an import statement as below:
import android.content.Intent;
which solved the problem.
Import statements are my friend.

Right, in the classic way of things, it is past time to post this, and I still haven't solved the original problem. Tomorrow, I promise!

2012/03/28

Java Adventures

So, this is where I've hit the problem that Java is not a language I'm familiar with.

So that's why this post is a bit late - I've had to delve into some Java resources to figure out how to distinguish my arse from my elbow.

Anyway, I already had:

public class WeddingLogisticsActivity extends Activity {


/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}


I'm fairly sure I need to declare a DatePicker (tell the app to expect a DatePicker, and what to call it), so I added
DatePicker WeddingDate;
This means when I refer to WeddingDate, the app knows what I'm talking about.
Then, from looking at example code, (mostly from hackaday which I mentioned before), I need to tell the app what to do with WeddingDate. And...I can't quite figure that bit out yet. More reading required!

2012/03/27

Code: Import, Activity, Extend

This next bit is focussed in the source-code folder (src), in a section named WeddingLogisticActivity.java

Eclipse has automatically added in what you see on the left here.
First of all we have the name of the package, which will eventually uniquely identify Wedding Logistics on Google Play.
Then we have the import statements. One analogy for these is academic references - if you write an essay which doesn't show the sources for your statements of fact then your readers will think you're making it up. Well, think of your app as a very sceptical reader - unless every statement is ultimately backed up in a reference [unless every method is in an imported library], it won't believe you [won't be able to execute that method].

The import statements I have already just cover me for the basic operation of the Android Operating System, and for the initial Activity that I'll get to in a moment, so I'll be adding a few, to deal with the Context (the situation on your Android), the View (what's on screen), an OnClickListener (to notice when, say, the user clicks on a button), deal with Buttons, Toast (messages that appear temporarily on screen. So called because they pop-up, I think), and a DatePicker, &c.
I've got the outline of my list from the excellent hackaday.com Android Tutorial and then added one for the DatePicker. Eclipse helpfully highlights all of the import statements I'm not using at the moment
(see the little row of symbols on the left?) so I can remove any unnecessary imports once the code is finished. Equally, as I expand the app, I'm likely to need to add more imports to cover new features.

Then we declare a public class called WeddingLogisticsActivity (henceforth abbreviated to WLA), and that it extends the core Activity.
Just to unpack that a bit - public means that other processes can refer to WLA; class - well, for a full definition of that I'll give you the wikipedia article, but the short version is that it means I could have several examples of WLA, based on the definition of it given here.
As to the bit about extending Activity, well, the Activity is a core Android class which handles some basic stuff for me - saying WLA extends Activity is a way of telling the system I want WLA to start with all the attributes of Activity, and then I want to give it some more.

At present, all WLA does which is apparent to the user is load the screen from last time; however, if the user attempts to enter the date, nothing will happen. If they click Done, nothing will happen. Unfortunately, I'm out of time, so I'll get to rectifying that next time!

2012/03/26

Projecting in Eclipse

Starting with Eclipse, we have to start a new project, which is pretty simple:
File > New > Android Project.
I am calling this project Wedding Logistics, though in places where I feel the need to abbreviate that will be WedLog.

Then I have a decision to make; there are various versions of the Android Operating System out there in the wild. The earlier the version I opt for, the more phones will be able to successfully run my app - but the fewer features I'll be able to use.
This calls for a little research; a quick google gets me this graph from Wikipedia.
The figures are a year out of date, and show 90% of users on Android 2.2 and above. Given that new Android phones are on Ice Cream Sandwich (4.0 and up), working in Android 2.2 is ample.
Now, for Eclipse purposes, we need to translate that version number into an Application Programming Interface (API) number. Android 2.2, aka Froyo, is API 8. This means anyone trying to operate my app on APIs 1-7 is out of luck, but I should be okay for 8 and up.

Next thing I have to do is name the package; this is something for when [eventually] I get this thing onto the App store. Every app needs a unique package name, and to guarantee that, the convention is to use your website url followed by the app name. So for me, that is uk.co.blogger.becomingandroid.weddinglogistics for this app. Ungainly, but it'll do.

Now Eclipse will do its magic - it has created a raft of files that I will need as part of the app, and populated them with bits of generic code. This is part of where an IDE saves hassle. Now, as I mentioned last time, the output from Droid Draw can come straight into Eclipse - specifically, under the folder res (for Resources), layout, main.xml
Now here, I'm following the advice from a tutorial I used; I may need to alter it later, but it will do for now.
I go and have a look at the results in Eclipse, and...ah. Oh dear.
There are two errors; and it doesn't look like it did in Droid Draw. I think the problem is that I used an Absolute Layout - it looked neater. I'll try it with a Relative Layout, remembering that this is meant to be fast-and-dirty!

 Now, calendar appearance aside, that's a bit more like it. Also, there not being any major errors, I can go ahead.
There are however some warnings, highlighting possible problems. On this occasion, they're reminding me that I don't need to hard-code the text (like "Welcome to Wedding Logistics 0.1") - it can go in strings instead. I'm going to ignore that this time, because this text is only appearing on this screen, so I don't see any real advantage to putting it in strings for easy re-use.

You'll also notice that I got rid of the second option for entering the date - firstly, this date-selector looks more like what I had in mind for that, and secondly I have changed the note at the end. This will make the code simpler, though I may return to giving users an approximate option on the front screen later.

So, with the extra faff I had to go through with this, I'll be coming back to the actual code in the src folder next time. There will be import statements!

2012/03/23

Making a start

First, a quick reminder of what I decided last time were the core features to aim for:
So some form of calendar function - allowing you to set your date, then keeping track of a countdown; then an ability to enter notes with target completion dates; ability to check back previously created notes; and probably a display with the next few tasks.
Now, there are a variety of ways to approach the next stage. One would be to fire up Droid Draw and plot out the user interface first, then once I'd plotted out how I wanted the thing to look I could work on pulling the back-end together to make it work. Another thing I could do would be to plot out the logical flow of data - where the user enters it, how the app needs to manipulate it, and how it needs to be output.
The third focus which occurs to me is to think in modules of code - a module for note-entering, a module for checking previous notes, a module for displaying priority tasks, a module for the count-down.

Thinking further, however, I realised that working in Droid Draw and with modules of code may be compatible with each other; after all, when you press a button, you want it to do something; so it has to be associated with a bit of code to tell the app "When 'Go!' is pressed, this is what you do," or whatever. Based on the fact that I can combine these two approaches, I think that's the way to go - the disadvantage of working with dataflow is it's less concrete, and so for a (relatively) simple initial app it's probably unnecessary.
My only wariness around starting in Droid Draw is concern I might get too bogged down in making it look pretty before it actually works; then again, I should be able to replace an ugly button in a stupid place with a shiny one placed ergonomically or whatever without actually changing the underlying code. So, as long as you can see all the features on the screen, no complaining if it's ugly!

So we fire up Droid Draw, and it looks something like this:

As you can see, we've got an Android screen on the left, options of things to add top right, and bottom right is currently a blank space.
[The blank space is where the output xml will appear when I hit 'Generate'. The xml will basically be code telling Eclipse how to make the screen look like what I draw on the left. I'll go into that process in more detail later.]

 To me, the obvious place to start is where the user will commence, first time they open the app - the calendar to pick a date.

What you see here is a first stab at that. The explanatory text is done using TextView boxes; a DatePicker gives us our calendar, and at this stage I'm unsure whether the 'Done!' button for that is necessary

I have then put an alternative, for anyone using the software before they have a date booked. This is just using text boxes at the moment; ideally I'd prefer a drop-down list with months, and then the same with years; or I could settle for radio-buttons with Spring/Summer/Autumn/Winter and then a box for years. Something like that, I'm flexible at this stage.

Items are named, so for example the calendar is called @+id/date_picker, the Done button next to it is called @+id/exact to distinguish it from the other Done button being @+id/approx, and so on. You get the idea - everything has a name which is short and to the point, so that when I'm writing code about it I can see what I'm doing more easily.
Once I'm done with this (for now), I hit 'Generate' on Droid Draw, which spits out a load of lovely xml [for anyone interested, that can be found here]. I can paste that directly into res.layout/main.xml [all will be explained!] and have the above appear in my app. Next step is the code.

Oh, one last point - see my little p.s. note to the User at the bottom? Yeah, it isn't just good to remind yourself what's going on by commenting your code - let the User know too!

Next time: Into Eclipse

2012/03/22

Beginnings 3: Early Design Decisions

So, I'm set up with all the tools to write an Android app, give it a pretty interface, and test it. So this seems to open the question - what do I want it to do?

There are thousands of apps already available, to do almost anything imaginable. You can get an app to play The Sims. You can replace your touchscreen keyboard. You can add an archery scoring tool.
According to the might wiki, there are 450,000 apps for Android! How can I do something that's never been done before?
Well, bluntly, I can't. I may not even be able to do something better than it's been done before. That's okay though - it means rather than searching Google Play with ever odder search terms to find something that hasn't been done before, I can just come up with something that seems achievable and get cracking.

I've been spending a lot of time lately helping my fiancée in planning our wedding (for anyone interested in that side of things, her blog as linked there is a good place to start) and the number of lists and pieces of paper to keep track of everything is insane!
Everything has a different timescale; different participants; costs to budget for; and so on.
Basically it is one of the largest events that people are likely to find themselves organising in a non-professional context. Maybe I can do something to help?

Thinking about this, I can think of a lot of things that an 'ideal' version of wedding planning software would do for you. The key thing is to start with a core functionality that's actually useful and then add capabilities once the core is up and running - otherwise it becomes a huge project for one person, I have to learn a lot more before I can get started, and I'm more likely to give up with it incomplete!

Ideal Version:
Keep track of budget - how much things cost and what proportion is paid for.
Keep track of RSVPs - to the main event/reception (if separate), hen and stag.
Replace all the little bitty notes - to-do lists, records, contact details, ideas.
Count-down - knowing what day is W-Day, and being able to categorise tasks by 12 months before, 6 months before, the day before, day of the wedding, whatever.
Tracking primary responsibility for tasks - is the groom handling the music? Is the bride mostly dealing with the caterers?
Be able to synchronise between multiple devices - the bride and groom, and possibly also the best man, maid of honour, ushers, even parents.
With the above, ideally be able to output something (be it a spreadsheet, Google Doc, whatever) to a computer for handling on a larger screen.
BACK UP AUTOMATICALLY - this is a big deal. The more of the critical pieces of paper that are moving onto an Android, the more careful we need to be that one inopportune crash, or getting your phone nicked, won't mess everything up; and relying on busy people to manually backup is going to lead to some failures. I have no idea how easy this is - have to look into it later.

That's quite a lot of features, and different pages within the app, all of which would have to interact smoothly with one another. What's the core of it? I reckon the combination of a to-do list and count-down will do the trick - key reasons being I think it's enough to be useful, but it doesn't require interacting with other phones or linking to PC; it will have easy room for expansion in noting responsibility for tasks; and phones are obviously *already* good for noting contact details, so integrating those into the app aren't the highest priority.

So some form of calendar function - allowing you to set your date, then keeping track of a countdown; then an ability to enter notes with target completion dates; ability to check back previously created notes; and probably a display with the next few tasks. That sounds like a pretty good initial feature list to me.

I can start breaking that down into what I'll actually need code-module-wise next time. Then I can give myself a specification - to write code able to perform these functions - and then I can maybe start writing some actual code!

2012/03/21

Beginnings 2: Software and Tools

So now we know why I'm doing this, let's have a look at what I'm using to do it!

First off for any programming, it's good to have a solid Integrated Development Environment, or IDE. It is possible to write code using Notepad and then compile it with a standalone compiler, but that's like saying it's possible to write a novel without having proofreaders - you're making your life more difficult, and at the end of the day the results will be worse.

To compare code in an IDE with the same code hand-typed:

So here we have a Java "Hello World!" program.
You can see that there is colour-coding for common elements - the declarations are purple, comments are in green, and the string "Hello world!" is blue.

What you can't see is that Eclipse has automatically indented lines as they are typed; nor that when you open a brace { or parenthesis ( it closes them.

It will even, when you type System. show a list of possible continuations.

Then if you, say, forget the semi-colon to end a line, it will highlight that line as problematic and suggest you add it.
And here is the equivalent hand-typed.

There's no indentation, so it's harder to see what is going on; and with all the text the same colour doesn't help.

If I forget a piece of syntax, or misspell a command here, the first I know of it will be when the compiler throws an error. Not fun.

So, an IDE is essential - but which one to use?

I have chosen Eclipse. Primarily, this is because Eclipse is a very popular IDE for the Java family of languages - and Androids run on a form of Java. It is also because Eclipse is free (yay! says my wallet) and open source (yay! say my principles).
Eclipse can be found here.
Once you've installed Eclipse, you need to add the right attachments to make it work with Androids. It's like buying an electric drill - you need the right drill bit to do the job.
Specifically, you need the Android Development Tools (ADT), and the Android Software Development Kit (SDK). Fortunately, there's a very good tutorial on the whole process here to walk you through that.

Once you've done this, Eclipse doesn't just have the usual advantages of an IDE - you can also run virtual Android devices with a variety of specifications, to test your program on more phones than just the one in your pocket! (More testing is always good...)

So far so good. I've added two more bits'n'bobs which look as though they may be useful, and offer functionality which is lacking in Eclipse:
DroidDraw, which is a visual environment for laying out interfaces and screens. Hopefully when it comes to prettying up an app, this will make the process reasonably simple. DroidDraw is found at this site, which not only has the downloads, but also tutorials on how to get started with it.
SQLiteBrowser, which is a database manager, found (among other places) here. I've added this because it may help with handling storage and retrieval of data.

Last thing to mention:
Scrap paper and a pencil/whiteboard and a pen can also come in handy; especially for planning out the outline of a program before you jump in and start coding.

Next Steps: So what do we want an app for?

2012/03/20

Beginnings 1: Whys and Wherefores

Who am I, and why am I doing this?

I'm young, highly qualified and unemployed. There's a lot of it about, oddly enough. I want to get a job developing software, and part of the problem is that my formal programming education is slim; so I need pieces of work to point to, an "I did that!" I am learning to write Android apps partly just to improve my skills, and partly to build up a portfolio of work which I can show to prospective employers.

Why blog about it? Self-discipline, primarily. If I know that the results are public, I have more motivation to push on through the debug phases, the design crises, etc. With the added possibility of showing the blog itself to people.

Why Android, not iOS?
1) I have an Android phone, and it's much more appealing to write an app I can use myself.
2) I have an Android phone, so I have a test-bed in my pocket.
3) Getting an app out on the Android Market (or Google Play, as it seems to be now) is a lot easier than getting one onto the Apple Store.
4) I just prefer the Android philosophy of an open platform.

Coming soon: Software and Tools.