FizzBuzz
FizzBuzz is an old coding test used to make sure that interviewees are capable of solving basic coding problems.
The test is thus:
Write a program to count from 1 to 100, when it is on a multiple of 3 have it print Fizz, when it is on a multiple of 5 have it print Buzz. If it is on a multiple of both 3 and 5 have it print FizzBuzz.
The code for this in a simple C++ application is:
int main ()
{
int i = 1;
while (i<101)
{
cout<<"\n"<<i<<": "<<endl;
if (i%3==0)
cout<<"Fizz";
if (i%5==0)
cout<<"Buzz";
i++;
}
}
When I came across FizzBuzz and it’s solution I thought the same thing that I think when I see any application: How can I port this to Android?
So I decided to make a version of FizzBuzz on Android which would really Fizz and Buzz!
So here it is: FizzBuzz for Android.
Coding FizzBuzz for Android turned out to me be much more challenging than I expected:
The UI in android cannot be written to directly from an Activity’s onCreate or onResume methods, however a background function should never execute UI code.
Also when sound files are played they are played by a background service and the system for checking their completion is complicated and better suited to longer audio files. Fizz and Buzz have static lengths and I never want to play Buzz before Fizz, so a logical solution is to wait for 250ms after launching Fizz before launching Buzz.
Also in order to have the lines arrive in a steady order and not have any audio play over other audio I determined that it would be best for every line to take 1 second.
Both the wait for Buzz and the 1 second line wait require a sleep or wait, neither of these functions should be run in the UI thread.
The solution I found was to launch a Runnable as a thread.
The runnable contains the logic and launches the Fizz sound, it also uses another thread to launch the Buzz sound. When the runnable needs to output a new line to the table it uses runonuithread().
public class FizzBuzzActivity extends Activity {
private MediaPlayer fizzMP, buzzMP;
private TableLayout displayTable;
private String srowText, srowNumb;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
displayTable = (TableLayout) findViewById(R.id.table);
fizzMP = MediaPlayer.create(FizzBuzzActivity.this, R.raw.fizz);
buzzMP = MediaPlayer.create(FizzBuzzActivity.this, R.raw.buzz);
new Thread(mUpdate).start();
}
private Runnable mUpdate = new Runnable() {
public void run() {
for (int i = 1; i < 101; i++) {
srowText = "";
srowNumb = i + "|";
srowText = "";
if (i % 3 == 0) {
fizzMP.start();
srowText += "Fizz";
}
if (i % 5 == 0) {
srowText += "Buzz";
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(250);
} catch (InterruptedException e) {
e.printStackTrace();
}
buzzMP.start();
}
}).start();
}
runOnUiThread(new Runnable() {
@Override
public void run() {
TableRow newRow = new TableRow(FizzBuzzActivity.this);
TextView rowNumb = new TextView(FizzBuzzActivity.this);
TextView rowText = new TextView(FizzBuzzActivity.this);
rowNumb.setText(srowNumb);
rowText.setText(srowText);
newRow.addView(rowNumb, 0);
newRow.addView(rowText, 1);
displayTable.addView(newRow,
new TableLayout.LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
}
});
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
complete(buzzMP, fizzMP);
}
void complete(MediaPlayer MP1, MediaPlayer MP2) {
MP1.release();
MP2.release();
}
};
The Audio samples I used in FizzBuzz were clipped from files on SoundBible.com and the Source Code for FizzBuzz is available on GitHub.
It’s amazing how much you can learn doing a simple little project like this one.
-Rory
Discussion: How to add Target Selection for Capture Route Activity
Lots of college stuff was going on, so I wasn’t able to work on Shortest Walking Route for a while.
Now thankfully things have died down.
My first concern is tackling Target Selection for Capture Route Activity:
When the user chooses “Capture Route” on the Home Screen, they should be asked where they are going. When they get to that location Location Service should automatically turn off and play a sound to let the user know.
I’ve thought up a few ways to do the transition and drawn them out, please have a look and comment or message me to let me know what you think of them:
Idea 1: When the user clicks on “Capture Route” it opens Target Selection Activity (an activity with a big map, like Display Routes), which shows the user a Selection List (like the one currently in Display Routes Activity). If the user chooses to create a new target, then the Selection List dissapears and they choose a location in the view underneath.
Upside: as the use taps on different potential selections I can have the map behind the Selection List zoom to the location they are choosing, this should make it easier to be sure that the right location is being chosen.
Idea 2: When the user clicks on “Capture Route” it opens a Selection List dialog over the Home screen, in this dialog the user can choose one of the saved targets ore choose to create a new target.
If the user chooses an existing target they go on to Capture Route, if they choose to create a new target they are brought instead to map where they can choose a location to be a target.
Upside: If the user is frequently choosing the same targets then this will skip the Target Selection screen which will make the process of starting a Route Capture quicker.
Idea 3: keep the relationship between Home and Capture Route Activity the same, show the Selection List in Capture Route Activity and pass the user out to Target creation if they they opt to add a new Target.
Please let me know what you think of these ideas, and if you have any other ideas I should be considering.
-Rory
Sample Result
Today I stopped my car in a driveway and turned Capture Route on, I captured myself driving from there to work. I drove up the hill to foggy Killiney and back down through Ballybrack Village. (Blue Line, Route 10)
Yesterday I stopped in that same driveway and started a capture which took me down to the Graduate Roundabout and down Church Road. (Green Line, Route 9)
Doing this gave me two clean routes, with their starting and ending points roughly the same, with their last points being just before I drove into the underground carpark in Cherrywood.
By tapping on these final points I can view the information stored for the routes.
From these results we can see that the route over the hill is around 560m shorter, but the higher speeds on the other route even it out.
I’ll have to capture the route through Killiney again without the fog and see how if it makes a difference.
Please give SWR v0.0.11 a go and let me know what results you get!
-Rory
Version 0.0.10 Raphael ‘Satellite’ Savina Edition
A few days ago I was talking to my good friend Raphael Savina and he made a feature request:
Raphael wanted to be able to view his Routes against a satellite image instead of a map.
I had already discovered that you could easily turn satellite images on and off with this code:
MapView.setSatellite(true/false);
So I made a deal with Raphael: if he would draw me a satellite I would write the code and get the version up ASAP.
Raphael promptly supplied me with a lovely drawing of a satellite and I made the necessary changes to DisplayRouteActivity and displayroutes.xml to turn the icon in the titlebar of Display Routes into a functional button.
And the result is Version 0.0.10 of Shortest Walking Route.
Note:
I’ve edited all of my icons to better fit into the Menu Icon Guidelines, which has resulted in the application icon going from being slightly bigger than it should be to slightly smaller.
What’s Next:
- Adding a Target function so you can tell Shortest Walking Route where you are going and have it terminate the gps capture when you get there.
- Tuning down the number of GPS fixes captured to more efficiently represent a route.
- Finding more useful information about routes to display
Version 0.0.8 Burritos And Blues Edition
I am very excited to announce that with Version 0.0.8 Shortest Walking Route is now officially supported by Dublin’s Fastest Growing Burrito Chain: Burritos And Bues!
As part of this exciting new partnership you can now see the locations and opening hours of Ireland’s best burrito shops whenever you look at the Display Routes screen of Shortest Walking Route!
Install Version 0.0.8 on your Android device right now to see for yourself!
- If you have used previous versions of this application you may notice that your routes look more messy in Display Routes. This is because I have disabled filtering of GPS data when it is going to be displayed and started filtering it while it is being captured instead. This should save space in the database (as useless data is no-longer kept there) and help resolve some stability issues.
- In order to let new users get the most up-to-the-minute information about Burritos And Blues opening hours, I have changed the application to allow users to go directly in Display Routes without capturing a route first.
- Fun!
- Excitement!
- Really Wild Things!
- ListView!
Update: The maps weren’t working properly in the version I originally posted. Should be fine now.
Version 0.0.6
Just a little update this time.
I noticed a problem with the Capture Route ending routes and starting a new one when the next GPS fix arrived.
This was caused by a bit of code I put in to the onStop() to clean up when the application was killed from the outside. I’ve moved this to the onDestroy() which should still retain the function without disrupting how the application is working. This change brought to you by the Android Activity Lifecycle.
I’ve also added a persistent notification to be displayed while Capture Route is running. This should help prevent people accidentally leaving the GPS capture running and wasting battery life.
Unfortunately because I implemented the notification using a future compatible tool called NotificationCompat.Builder, it has tripled the size of Shortest Walking Route to 161.22kb.
So please, download and install Version 0.0.6 and let me know what problems you find or features you want.
What’s Next:
Back to work on filtering out inaccurate results and getting the paths to display information about themselves when they are tapped.
Version 0.0.5
Quite a few updates in this version:
Capture Route now has a Start/Stop Button at the top which will allow you to record routes as long as you like.
I’ve now implemented Display Routes, which can be accessed from SWR’s home screen once you have captured at least one route with Capture Route.
Display Routes will allow you to select the routes you want to see and it will draw them to screen in random colours. Unfortunately the colours are not stored, so every time you change your selections the colours will be randomly changed.
The route selection is done with this alert dialog which is set to always appear in the top right corner of the screen. This is to allow users on larger devices like Android Tablets to see the changes they are making on the map while they are making them.
These choices are persistently stored in Android’s Shared Preferences as characters in a String, which is my way of getting around the fact that Android does not allow arrays to be stored in Shared Preferences.
Please give Version 0.0.5 a go and let me know if you run into any issues.
If you are interested in how this application works please follow the link to GitHub on the right-hand side of the screen. The full source-code is available there. If any part of it is unclear to you, please let me know.
Note:
- Capture Route has no way of stopping itself yet, and there is no notification to tell you it is running in the background. If you have it running you will see the icon to tell you that GPS is running.
- I’m not filtering or smoothing the routes when placing them on the map, so you will see some very low-accuracy data and jagged, indirect lines.
- Later on I’m going to be changing this so all routes will have a target and the data you record with this version will have to be discarded, so don’t record anything you want to keep forever!
What’s Next:
- I need to work on getting information about the routes to pop-up when you tap on them.
- I’ll also be looking at cleaning up the routes when they are displayed. (I think not displaying the very poor accuracy fixes will be a good starting place).