Part 1 where I introduced the concept and did it in CFML:
http://webdeveloperpadawan.blogspot.co.uk/2012/10/hamlets-monkey-code-for-fun.html
Part 2 Where I ported the project into a java class with some JSON file read and writing:
http://webdeveloperpadawan.blogspot.co.uk/2013/03/hamlets-monkey-part-2.html
OK So now this whole project is moving toward where I was really excited to take it. GOOGLE! hahah I want to put this project on Google App Engine (GAE) so it uses cloud computing. That way a GAE cloud instance is like an actual monkey, tapping away at the keyboard and trying to re-write Hamlet! Awesome! This straight away introduces two potential problems:
- I've got to turn the project into a java servlet
- Tracking progress - In part 2 we added file storage, this won't work in the cloud, so we'll need to find a better method.
OK So converting the main crux of the method to a servlet isn't that complicated. The first thing you need to do is install the GAE plugin for eclipse. https://developers.google.com/appengine/docs/java/tools/eclipse Then we'll convert the project we made in Part 2 to a servlet, the public class needs to extend HTTPServlet:
public class Shakespearemonkey extends HttpServlet {
and the main method becomes doGet, which is what is called when the servlet responds to a http get request:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException {
int intCount = 0;
String strSubString = "";
String strShakespeare = Shakespeare.replaceAll("[^a-zA-Z]", ""); //Shakespeare without spaces etc
String strMonkeyString = "";
String strBestSoFar = "";
response.setContentType("text/html");
while (intCount < intNumLoops) {
intCount++;
//generate the random guess, one keystroke at a time
strMonkeyString = strMonkeyString + Character.toString(generateRandomLetter());
strSubString = strShakespeare.substring(0,strMonkeyString.length());
//check if we've guessed correctly so far
if(strMonkeyString.equalsIgnoreCase(strSubString)){
//Is this our best guess so far
if(strSubString.length() > strBestSoFar.length()){
strBestSoFar = strSubString;
}
}else{
//incorrect guess, start again
strMonkeyString = "";
}
}
trackProgress(intCount,strBestSoFar);
//purely for output, re-read the latest and update user on progress
try {
response.getWriter().println("Good Morning, I am your monkey! I will be trying to guess the string: " + strShakespeare + "<br />");
MonkeyResults monkeyresults = readResultsFromFile();
response.getWriter().println("My best guess so far is: ");
response.getWriter().println((String) monkeyresults.getBestGuess());
response.getWriter().println("<br />I have made ");
response.getWriter().println((int) monkeyresults.getKeyStrokes());
response.getWriter().println("keystrokes");
} catch (IOException e) {
e.printStackTrace();
}
}
So what I've done is created an object for storing all our progress data. Possibly not necessary / overkill but its OO and it feels good. It's just two getters and setters, so I won't bore you with the code. What is different in the trackProgress function though is I've replaced the JSON code with this:
MonkeyResults monkeyResults = readResultsFromFile();
if(monkeyResults.getKeyStrokes() != 0 && monkeyResults.getBestGuess() != ""){
strBestGuessFromFile = (String) monkeyResults.getBestGuess();
intKeyStrokesFromFile = (int) monkeyResults.getKeyStrokes();
}
So I'm going to use the GAE datastore to keep track of our progress. The first step is writing to the datastore:
static Key theResultsKey = KeyFactory.createKey("Results","tblMonkeyResults");
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
private void writeResultsToFile(int intKeyStrokes, String strBestGuess){
//I write the number of keystrokes and the best guess so far to the datastore
Entity objDaoOut = new Entity("Results", "tblMonkeyResults");
objDaoOut.setProperty("intKeyStrokes",intKeyStrokes);
objDaoOut.setProperty("strBestGuess", strBestGuess);
datastore.put(objDaoOut);
}
The next of course is the new read function, which returns an implementation of our local object:
private MonkeyResults readResultsFromFile() {
//I read results from the datastore and return an instance of class MonkeyResults
MonkeyResults monkeyResults = new MonkeyResults();
long intStrokes = 0;
String strGuess = "";
try{
Entity objDaoIn = datastore.get(theResultsKey);
intStrokes = (long) objDaoIn.getProperty("intKeyStrokes");
strGuess = (String) objDaoIn.getProperty("strBestGuess");
}catch(EntityNotFoundException e){
//e.printStackTrace();
}finally{
monkeyResults.setKeyStrokes((int)intStrokes);
monkeyResults.setBestGuess(strGuess);
}
return monkeyResults;
}
That's basically it. We have converted our java function to a Java Servlet and modified the file read and write to use the Google Datastore. Simples.
Once you're done, you should be able to test it locally, if it works you right click on the project and goto Google -> Deploy to App Engine. Hey presto google uploads it all for you and you should have a successfully running monkey!
Here's my monkey: http://shakespearmonkey.appspot.com/ http://pastebin.com/1etNP1ge
No comments:
Post a Comment