Friday, May 15, 2015

Working More on Collision Detection (5/15)

Today I worked more on collision detection. I couldn't quite get it working, so I posted a StackOverflow question and pretty much continued attempting different functions all of class. Nothing has worked so far, but I'll continue trying and see if I can figure out the source of the problem. Once I can fix this bug, I can get back to feature adding!

Unfortunately I don't have any good step-by-step tutorials for today, but once I get collision detection working I'll be sure to add that in. Some of the recommendations for collision detection I've heard of are quadtrees and other Javascript libraries such as three.js. I haven't really used three.js however, because that's mainly for 3d rendering in Javascript.

EDIT (5/16): I finally got collision detection working! It wasn't anything to do with using the right algorithm, rather I had been passing an integer into my method instead of an array. It works great now! I'm now going to get started on velocities.

I also helped Aki on the tutorial today, so here's a link to his blog.

Thursday, May 14, 2015

Really Getting Into Socket.io! (5/14)

So, half of this was done yesterday. But I decided to bunch it all up into one blog post today, because it's quite a bit of progress and there's a lot of cool stuff going on, so I thought I might as well put it together!

Yesterday and today, I've completed quite a bit of small milestones for my game project. They're not really huge features, but basic things that are required for every game. Surprisingly, a lot of them were pretty tough to get working. Sure, I had the amazing tutorial from yesterday, but the main issue is that I'm working on a multiplayer game. Therefore, a LOT more server interactions are going to have to be made. Anyways, that all aside, the features added include the following:

-You can now move! That's right, using W, A, S and D, or the arrow keys, your little character will move on screen.
-Other players can see you moving! And you can see them too. This is done via NodeJS. Here's how I did it:

I essentially have my game refresh at a rate of 60 frames per second, like most games. Obviously, if you can't achieve that framerate it's fine, but it might not look as good. On each of these updates, the socket emits a current player position. That position is then sent to the server, who bounces it back to all of the clients so that they can all update other players' positions. In essence, this is done like the following:


-You can shoot tiny pellets with the space key! And other players can see them! My whole concept of pellet travel is the exact same as above, but speed of the pellets is [obviously] faster than speed of the players. I want it to be kind of like Galaga in that sense. Interaction with these should be coming soon, that takes collision calculations which I'm going to get started on tonight.

Some features planned for this week:
-A changelog [I like the idea of live-updating things]
-Collision detection
-A background map

Wednesday, May 13, 2015

Helping Aki Fix The App (5/13)

Today I helped Aki fix the app from the tutorial. See Aki's post for details.

Tuesday, May 12, 2015

Temporary Project-Hop [Still Working on Android!] (5/12/15)

Today I temporarily hopped to a new interesting project. Aki had shown me a game earlier that used HTML5's canvas element to make an easy-to-understand and simplistic MMO. From what I saw, I knew already that they were using Node.js and Javascript to communicate with a server. An idea popped into my head, and that was that I should try my skills at creating a Node.js-based game for the browser.

For the record, I'm still working daily on my Android project, and I haven't forgotten about it. I'm just adding this to my list of side-projects.

I started doing some research on the Canvas element, and found that it was pretty simple to use, but there's not a whole lot of documentation about it. Then, I found an article on creating a basic game using the canvas element, by a Mozilla developer. Although it's not exactly the concept of what I'm doing, I'm going to look at it to get an idea of what I'm going to try to do.

I then made a basic landing page using Bootstrap, and I started working on an "Upgrades Store".

After just an hour or so, my landing page started to look pretty nice. I'd be happy to show an example, I just don't want to upload any images yet since I think my game idea is pretty nice :)

It got even better when I started handling user connections, and mentioned their names. Since I'm on a Mac, it even featured Emoji support:

I then went ahead and setup multiple server support, like so:
I can't wait to get players to load tomorrow! I think it's going to be an interesting concept. I'm also going to work more on my Android project tomorrow. Unfortunately I couldn't do so tonight because I need to use multiple devices to test and have access to the internet while doing so.


Monday, May 11, 2015

Continuing Work on Android (5/11)

Today I finalized my server for my Android app. Once again, involving socket.io. However, I came into the issue that each client needs a specific ID. So, after some thought, I made it such that each client listens from the socket only on a very specific ID event. That way, the client will only listen to information pertaining to what it needs to know, without having to listen to information from a lot of other sources.

I did it by assigning a listen event to a variable, like so:

socket.on(idVariable, eventFunction);

Then, the eventFunction would be called, and we could send and receive data from the server to the client.

Friday, May 8, 2015

Working more with sockets and runnables (5/8/15)

Today I worked on a Runnable class for my Android app that sends data every 10 seconds. I added some methods to cancel and start it as well, but I haven't been able to test them yet. This method will allow me to continuously send data when I need to, and cancel it when I need to stop [onAppClosed, etc.]. It uses the CountDownTimer interface for Android to handle this.
I also worked a bit on planning and pulling the repo for the expo tomorrow, and doing some planning on how our internet connection, etc. will work.

Wednesday, May 6, 2015

Working more with NodeJS/SocketIO (5/5)

Today I started on one of my other projects and integrating Socket.io into it. I now have a go-to Socket.io script, as seen below.

As you can see, using the NodeJS modules http, express, and socket.io, a server is created. I then went and implemented this into my Android app like so:


And just like that (granted the Android device has an internet connection), the socket works! You can now use this as a server to send and receive data to one or multiple devices. I decided to change the event for each device, so the event is sent like 'socket.emit('deviceEvent ' + deviceId, informationHere)'. That way, the server can talk to individual Android devices. The Android code is as follows:

Monday, May 4, 2015

Starting out with NodeJS, Socket.io, and more server-side Javascript

So, recently out-of class I've been working on quite a few projects, many of which are relating to Javascript. A lot of them have been specifically aimed at websites that are using APIs to communicate, then connecting the client-end code to NodeJS on the server-side.

So, for a quick overview:
I've been using NodeJS on my server-end to handle things such as saving files, getting data, and doing other stuff that Javascript can't. A good example of this is that I'm using a bot that connects to the SteamAPI, and I can show information about this on the client-side through sockets.

Sockets are essentially the main thing we use to connect client-side code to server-side code. I've come to learn that they're extremely helpful, as lots of time Javascript code lacks certain features due to security restrictions. I've been writing my sockets in PHP recently. Here's a small example of a socket I used in my code recently:

Client-End
Server-End
Since a lot of new things were mentioned in this post, I'll try to get more into detail about them throughout the next week.

As you can see above, the Client-End is coded in PHP, while the Server-End is coded in NodeJS. Essentially, our Server-End is listening constantly on port 5501, while our Client-End is occasionally sending data to it. We can send the data as JSON, and then later parse it on the server-end, and send more information back based on what the sent information was.

This is all good, however, I found a new library yesterday called Socket.io. It's still doing the same things, but when you see how much time it saves, it's ultimately worth the switch. I'm going to be switching all my code to Socket.io based code over the next few weeks.

Socket.io makes socket communication amazingly simple. Their example of a simple chat server showed how you could easily have socket-based communication and an entire chat server in just a few lines. I thought that was amazing, especially thinking back to our old AndroidRPG project from earlier this year - we could have saved all that time with a simple plugin. The best thing is, it's been ported to all sorts of mobile platforms, including Android, and it's pretty efficient.

I've also been working with a few more libraries:
-Progressbar.js - Truly amazing progress bars. Allows for really nice ways of showing loading of items, live item counts, etc.
-net module for NodeJS - Allows for socket connections. However, I'm currently in the process of merging to socket.io as previously stated.
-Spotify Android SDK - I'm also in the process of making a music app for Android. I use Spotify to authenticate and play music.
-Steam Web API - I'm working on a bot that is 'talking' to the Steam Web API to grab virtual item information
-Bootstrap - Quite possibly the best API I've ever dealt with. It makes all your pages look amazing, it's open source, and so many people use it.

I'm also working with several more APIs [at least 5-10 more], but my progress with them isn't as far. As you can see, I've really been working hard on API-based programming and Javascript/NodeJS in my spare time, mainly because I'm surprised at how much things they can do!

Monday, April 20, 2015

Working with GitHub Remotes, Pull Requests, Starting Bug Fixing (4/20)

Today I started out with making a pull request to your GitHub project. Luckily the fix wasn't too intensive - I managed to fix it with a few changes to the manifest.

The Geolocation API wasn't working, so I decided to check the manifest. Luckily, the fix was that the app wasn't allowing the Geolocation APIs, so by allowing these in the manifest, the app was able to access such libraries.

Making a pull request was pretty easy after we figured it out. My issue was that I was trying to clone your repo and make a pull request into it. What I needed to do was fork the repository, then change the origin:

git remote remove origin
git remote add origin [fork repository url]

After that I could push into my forked repository, which I could then create a pull request to fix it.

I also worked awhile on fixing contacts. Our only issue was that it wasn't continuing through the loop. We were using:

this.continue;

Instead of:

this.continue();

This resulted in only being able to get the first item of the result array, when there were a lot more available. By having a continue afterwards, we were able to successfully loop through the array.

Monday, April 13, 2015

Brackets! (4/13/15)

I've been recently going home and starting a few experiments of my own with Javascript. A few days ago, one of my friends told me about a new program called Brackets. It's written and hosted by Adobe, and so far is one of the greatest web development programs I've ever used. It's open source, too, so I'm sure it is going to be something that quite a bit of people are going to use!

It's similar to a Java IDE in that it has auto-completion of tags, code completion, etc. The main reason I installed it, however, was a directory structure on the left. I couldn't use Firefox's WebIDE for my personal projects, since they weren't FirefoxOS apps.

Anyway, I thought I'd introduce it. I love to use it so far, and it's saving me quite a bit of time!

On a side note, I've started to look into the Chapters bug. While I haven't found anything obvious that's creating this bug yet, I'll continue to look into it tomorrow and see if I can make some progress.

Sunday, April 12, 2015

Working with Scaled Vector Graphics and App Logo (4/10/15)

On Friday, I worked on the app's logo and scaled vector graphics. I thought it would be a good time to step back a bit from the specific bug and get something done that was a bit more important.

I learned a lot about SVGs! One of the coolest things I found out was that if you opened it in a text editor, it showed all of the properties about the SVG, such as default width, height, colors, etc. I found that really interesting, because you're able to easily change any specific property of the image just by changing a line of text, rather than manually drawing it in.

Another thing that I found interesting was that it was so easy to scale. All I had to do was drop it in the app's icons folder and it instantaneously scaled for all device sizes, which made it a whole lot easier to make, rather than individual png images which we would have had to resize.

On Monday, I plan to code the base for a few new features. I'm not going to make too much, however, because I want to continue condensing the app as much as possible.

I also have to start working on a bug that relates to chapter objects. Apparently, our app was denied from the marketplace until we fix a bug that has to do with chapters being one greater than we should. While I don't ever remember noticing this, it's possible that it was a result of our refactoring. I'll have to look into it a bit more.

Wednesday, April 8, 2015

Refactoring and Bugfixes

To start today, I fixed the README file so that it states that it's an audiobook player, rather than a port.

I then began to start refactoring for the book.html page. I noticed that it wasn't saving information for the slider, specifically CSS code. I'm still trying to fix this, and I'm not exactly sure why it's occurring. It's either a JQueryMobile issue or an issue with the page refreshing.

I also noticed that the method can be shortened by quite a bit. There's a lot of useless lines of code that can be changed, and I'll go into detail on that after I can fix this bug.

Tuesday, March 24, 2015

Three more packages we needed to install. They were required for describe() functions in our test code, and also allowed our different testing frameworks to talk to each other. I decided to install them all globally, just to make it all easier to access. In addition, you need to have a config file for Karma, in the directory you're working in. Ours is available on GitHub right here. Once you've navigated to the directory, you open two terminal windows: one in which you type "karma start", and another one you type "karma run" to run all tests you have created. You can double-check that karma is running by going to localhost:9876 in your browser. From here, you can edit and add to tests! Our test files are available here for an example. We'll continue to add to them, so I decided not to link to today's commit, rather to our files, as they will grow a lot over time, and provide a perfect example of how to write unit tests.

I also started working on some unit test code myself. I wrote a full test for Book objects, most of which is still in development. However, everything is already defined as to what the function is supposed to do, so we just need to put assert methods under each it() statement to complete the test! Tomorrow I hope to have full testing of both Book() and Chapter() objects.

Monday, March 23, 2015

Installing Mocha, Karma, and setting up Unit Tests

Today we worked a lot on setting up unit testing. While it could be done in Javascript, there's a lot of tools available that allow the process to be done more quickly and efficiently. We decided to use Mocha and Karma. The setup was simple, however I ran into a lot of issues, so I decided to make a shell script that will automate the process for anyone on a Mac with Homebrew. Comments are included so that anyone knows what it is doing.


After some research, we got Mocha working. We created a /tests/ directory on our GitHub repo, which we use to create and test working code. Our first test function, stripHTMLTags, isn't working yet, because we are still working with issues related to Mocha detecting our window variable from Firefox OS. A fix will hopefully come tomorrow.

The function so far looks like this.

It can be tested by using the following code:

mocha . -r "js/app"

Mocha . runs all tests in the directory you're in, so you have to be in the tests/ directory. -r is equivalent to "require", which is a function that tells the test what Javascript file you're testing. For some reason, using require("js/app") as a function in our test isn't working. It's likely due to a directory structure issue.

We also are awaiting an email response as to what we can use Karma for. Hopefully a response will come tomorrow, but otherwise we can always do some more research. Tests will start tomorrow, since our setup is done.

Sunday, March 22, 2015

A LibriFox Website, Starting Unit Testing (3/22)

So today I made some progress! One of the major things I did today was using GitHub Pages to create a basic website for LibriFox. A Jekyll installation will come later this week when I go on vacation. From what I've learned, Jekyll is great, and works amazingly with blogging. I was thinking of somehow linking our Blogger posts to the website sometime later on. Anyways, with some DNS changes, I was able to route the site to the GitHub pages branch, which actually is in the LibriFox project but on a different branch [can be changed later if needed]. The best thing is, it's completely free, and we can modify the code of the website whenever we want. I plan to change it to a custom website, instead of its current template, sometime later on. The main reason I got the website done today was because I didn't want to jump ahead with unit testing without discussing everything first tomorrow, and also due to the fact that librifox.com was available and I just had to go for it :)

But for now, we need to focus on unit testing. I actually just did some minor testing today, and I've already found a few issues! One of the main ones was with our stripHTMLTags method. It's very, very specific, but who knows, it might pop up in a few of the books' descriptions, causing some issues.

Basically, the name of stripHTMLTags is what we use it for. LibriVox's API and RSS feeds provide descriptions of each book. In our search results, I have previously coded it such that short bits of the description are displayed below each book. This is fine, until you notice that all descriptions have HTML tags in them - bold, italics, links, etc. and this ruins JQueryMobile's list. As such, we need a way to remove the HTML tags so that the list displays nicely, and for the most part, this method performs that well. However, under very specific circumstances, the method will result in large blocks of text being accidentally excluded from the description.

Imagine you had text like this for your description:

"<b>The left angle bracket, also known as <, is often used as a less than sign. On the other hand, the right angle bracket, known as >, is often used as a greater than sign.</b>"

You'd expect something like:
"The left angle bracket, also known as <, is often used as a less than sign. On the other hand, the right angle bracket, known as >, is often used as a greater than sign."

to be your output. However, our method is outputting:
"The left angle bracket, also known as , is often used as a greater than sign."

And this can easily be seen why, we're using this code for our stripHTMLTags method:

It's quick, easy, and for the most part does well. However, if any of these characters are used in a way similar to that shown above, it could cause issues for displaying descriptions.

Anyways, that's it for today; I hope to find more bugs tomorrow!

Friday, March 20, 2015

Working with Trello and GitHub Integration (3/20)

Today we setup our new Trello board, you can access it here! I also integrated it with GitHub so that our feature request and issue creation processes are easily controlled. I'll explain how I did that below.

I found a website called Zapier, which served as a middleman between hundreds of websites that have public APIs. Luckily, it had events usable with both Trello and GitHub, so that they could be linked extremely easily.

I setup one link that fired an event when issues were posted on GitHub. On that event, it will post a card to our Trello board under the "Requested Features" section.

I also setup another link that fired an event when Trello cards were created in the "Approved Features" section. On this event, it will post the same thing to an issue on our GitHub repo. This will be useful for user stories - if we approve for a feature to be created, it'll be posted as an issue to be handled and then we can easily see what we have to add into the app.

These two links will make user stories and feature requests much easier to handle, and the entire process will be automated.

EDIT: I also added a link to the Trello board on the top right!

Thursday, March 19, 2015

More Refactoring (3/19)

Today we continued to work on refactoring. Originally I had found that our download function wasn't working, so we made some changes to that so that it's no longer using localStorage - it's now using objects like the rest of the code. Here's an example of that:
It still needs a lot of fixing, mainly with individual parts of chapters. Also something that will need fixing is our file manager. We plan to store books in folders named by IDs, then have a user access downloads with a listView that converts the book IDs into titles, therefore allowing them to access their books without modifying the file system. Other than that, we didn't make any significant changes today, it was mainly refactoring and experimenting with code to check for errors.

Wednesday, March 18, 2015

More Refactoring, Fixing Bugs (3/18)

Today we have made more improvements to refactoring. It's funny, we made so many code changes, but no real feature was changed. However, we did fix some bugs.

The first bug we fixed was audio not saving after load. We completely removed our timeupdate event function, which allowed us to recode it into a simple 4-line function which saves our audio data. We then added a .position variable to the Chapter class, and allowed the app to save to this variable when the timeupdate event was fired. You can see Alex's explanation of this here.
Another bug that was fixed today was the descriptions in search not being formatted properly. This bug was also a simple fix, I had run into it earlier and I showed Alex the code from previously. We determined that it was not parsing the HTML properly. [See line "this.description"]

All that was required was JQuery's parseHTML method, followed by a text() method. This allowed for the app to remove all HTML formatting from the description, which had resulted in weird, random spaces, and bolded/hyperlinked text that we didn't want.

That was about it for today! Refactoring can be time consuming, but in the end it's making it a lot easier to add things on.

EDIT: After further testing, it seems as if we're no longer getting "not well formed" errors, and the page change bug [you had to restart the app to search for a different book] is no longer there!

Tuesday, March 17, 2015

Looking Into the LibriVox App (3/17)

*Long post warning*

Today I got back late to school, so I decided to work not on refactoring but to check into the LibriVox apps for Android. After all, not only will they provide a good example of how our app should work, but it will also give us insight into what features we should add. I took some notes on it below.

How it works

  • Starts with an asking for rating screen. While I don't think we should do this immediately, I think that we should ask the user to eventually rate our app, as an app with more ratings is better for us and users. We can improve on certain features, while new users finding the app for the first time can see what people think about it.
  • Immediately, it starts you off at a home screen that displays Top Free, Top Paid, and New apps. I like this feature - it reminds me of some other apps I have used. All of the top books' covers are shown, which is also possible to do via RSS or the API. It adds a clean UI interface to this with a nice color scheme.
  • I had to look over this a few times, but I realized there was a "Top Paid" category. I thought LibriVox's goal was free and public domain audiobooks...?
  • There is a search icon as well, at the top, just like our app.
  • You can go into more books on the top sections, and also view them, with their covers shown.
  • Clicking on the app gives it some time to load, instead of immediately going to the next screen. The player has a clean interface, and also allows you to look at the description, similar books, and go to chapter selection. There's a share icon, favorite icon, and sleep icon.
  • All search results are conducted without a loading screen, and all books are shown with their covers.
My Opinion

The LibriVox app is full of features, and as an Android app it's very well put together. I am in no way saying that we should have all these features, or none of them, but I'd like to go over a few and say how I liked and disliked them. That way, we can adapt certain features, maybe with better methods. As a result, we can help towards making a better app!

  • I loved the cover-based UI for books on the home screen. The "Top Free", etc. categories were very nice as well. However, once we got to search results, I found that covers just got in the way. I much prefer our search results with simple title and description. I'm thinking, however, that some people will like the cover in search results. As a result, I have proposed a few solutions. One is that we allow for different types of results, similar to how in Windows and OSX (Linux too, possibly?) you can switch the way you look at your search results - IE if you're looking at images, and you just want to see the filename, or want to see the image, or both, you can choose either. I'd also like to propose having a ListView with Thumbnails via JQuery Mobile. That way, we could have a small icon of the book's cover, along with a name and description, so the user can have more information on the novel if needed.
  • I like the idea of share and favorite buttons. After all, if you really like a book, I'm sure anyone would want to recommend it to friends, especially if it's completely free to listen to. Not only is this a helpful feature for users, but it also allows your app to be shared more if both users are on FirefoxOS. We should look into different methods of sharing, and include linking to the LibriFox App/LibriVox when the book is shared. Favoriting is also great, and we could make a feature such that a user can access their favorited books with ease [possibly a folder]. A "download favorites" button would be an interesting feature to look into as well.
  • I also appreciated the "Similar" category when you were listening to a book. I'm not exactly sure how this would be done, however we should look into it.
  • I think we need to look into more UI coding as well (with CSS). Using a non-default JQuery Mobile theme would be nicer in my opinion.
  • The loading screen was nice, but I'm not really sure if it was needed. I hate seeing loading screens on my phone when I'm using apps, so maybe it would be best to just not have one. A splash screen, however, would be nice.
  • Bookmarks were really nice. These would be an easy feature to add.
  • Reviews were also nice, I'm not sure how they would be implemented without some sort of hosting (possibly a database?), but they would be nice as well.
  • One thing it seemed that this app lacked was a full file manager and a download file option. Maybe I didn't do enough exploring. Sure, the LibriVox Downloader app does this, but why split it into two? I feel as if it's easy enough to implement, so we might as well have one and keep it all in one app.
That's all the notes I have for now, I think they will be very helpful after we refactor a bit more! I will be taking more notes on the LibriVox Downloader app soon, possibly tomorrow. I was also very surprised to see that the Android app has 1-5 million installs, 60 thousand reviews, and offers in-app purchases. While I don't think in-app purchases in a LibriVox app makes sense, I would like to do some experimentation with Kumar's library!

The downloader, on the other hand, only had 50 thousand to 100 thousand installs. Regardless, this is still a very large amount of people, and shows that a feature should be added to the main LibriVox app to implement the feature! I hope that our app will include it, as I've now realized how important it is to have one.

Monday, March 16, 2015

Refactoring, and Exploration Into the LibriFox Android App

Today I worked with Alex a bit on refactoring, which I had eventually planned on doing - essentially, the code we currently have works, but it's a mess, and it's starting to get to the point where it's much harder than it should be to write code, simply because of how scrambled our code is.

As a result, today we worked on some minor refactoring. Even in an hour or so, only a few lines were changed, and a lot of code was broken - but the result was amazing. We must have removed over 30 lines of useless code (and keep in mind, our app is only around 300 lines of JavaScript and a few hundred lines of HTML) from our app.js. A few minor methods, notably these Chapter and Book methods below, have changed the entire way our app works for the better.


Eliminating localStorage overuse was one of the first things we came to. Alex has changed all basic localStorage access into Objects, which I had never thought of doing [since I'm still very new to JavaScript]. These Objects not only save lots of space in the code, but also make access of variables much easier.

Instead of having something like this:
We have something like this:
You can already see the incredible amount of time and space saved by using these methods, not to mention how much easier it is to add, modify, or remove code!

We will also start refactoring repeated code in our audio handlers, and create a multiclass implementation soon.

Later on this week, after some refactoring, I might look at the LibriVox app for Android. I want to make sure our app is refactored more before we start looking into adding new features!

EDIT: I also did some research about the Firefox Marketplace. Our app should be reviewed soon! In my research, I found that they allow something called "App Preloading". You can read about it here. Basically, it allows developers to submit an app to be included with the phone by default. I think later on in development, this app would be great for that, as it would allow all Firefox OS users to have access to our app immediately, and it's something they could use daily!

Wednesday, March 11, 2015

App Submission and IRC (3/11)

Today I checked the #openwebapps channel on IRC. Turns out I got assistance on my question fairly quickly: JQuery's demos folder was in our app, and it was accessing external scripts very frequently.  This isn't allowed in privileged apps, so it was preventing us from uploading our app to the marketplace! 66 errors were removed after fixing this, and then there were a few more in the manifest that I easily fixed.

After fixing all these issues, I spent the day uploading the app to the marketplace. It took awhile, but I got it rated and it's pending submission. We'll see where it goes from there!

Tuesday, March 10, 2015

Not Well Formed errors and the Defer option (3/10)

Today we did some experimenting with our "not well formed" errors we've been getting. They've become a big issue, because they refer to code errors in our app.js, but don't tell us exactly where.

I experimented a bit with the defer option. According to Mozilla, it means that it will continue loading the app without loading the app.js every single time. While it's good in some cases, in our case we thought it might be causing these errors, so I removed it temporarily to test.

What I found was a bit interesting - it now pointed out specific errors in our HTML code. I quickly fixed all those errors, only to find later that our search didn't work anymore. I turned defer on again, and it worked again. I'm not exactly sure why, so I guess we need to look into this a bit more.

The rest of the day today we had our meeting, so hopefully more progress will be made tomorrow!

Monday, March 9, 2015

Saving Books and a File Manager! (3/9/15)

Today I got the books to fully save, and double checked the file manager I had made earlier to see if it was showing files properly.

Alex helped me by writing more code onto our XMLHttpResponse method such that we can now grab Blobs [or large amounts of bits]. Essentially, these are our files. We then add them to the sdcard with the DeviceStorage.addNamed function, and from there they are saved to the SD card for later access. My file manager [so far] displays all files on the SD card.

At first, we had some issues with the buttons, but Alex put them below the onLoad of our page, and now they work perfectly!

Here's a screenshot of an average page you'd see for a book chapter. You can choose to download the full book [~50MB-2GB] or the individual part [~1MB-50MB]. They both seem to be working perfectly!


Wednesday, March 4, 2015

A Huge Success! (3/4)

Another duplicate post, but I think it's needed.

Today, I got home and realized how close we were to getting the app to fully load the URLs and books, so I decided to start working. I guess I got into the coding zone, because in just an hour or so, I created 100 lines of code which essentially will be the basis for loading all books and all titles.

The way it works is pretty simple. We had already been saving the IDs when a user chooses a book, so I thought, why not save the title and chapter as well? I made localStorage saves for both of these when a user selects a book and chapter, and saved the title as well. I then created a chapter selection page (and I'll create loading methods so the user doesn't have to re-select a chapter soon). From here, all the chapter titles are loaded to a list, which the user may press and it will then provide the app with the book URL to load in an audio tag.

I highlighted the way I did all this on GitHub here. The app.js changes that made the most difference are here, and the chapter index HTML file is here.

I have to say, it was pretty great when I got this message in my console:


I'll start working on audio loading soon, as well as downloads and a file manager! Those three shouldn't be too hard to make.

NEW EDIT: It's now fully working! I did it using an audio tag (via HTML5), and in Javascript I used JQuery to handle the loading and audio functions.

NEW EDIT 2: I made full persistency of audio data. It's not perfect, but it's a great working version. If you have opened a book, and gone to a certain point, the app will automatically bring you to the book page, load all resources, and then bring your audio to your past point (where you last left it). It'll also change this time for later if you seek through the audio.


Starting RSS Work + Finding Audiobook URLs (3/4)

Luckily, we've found a way to get audiobook URLs to load! Unfortunately, we have to use RSS, which (so far) is a LOT tougher to parse through than JSON.


This function will go through the RSS feed, and we can then figure out certain attributes of the code with these lines here.

From there, we've found that there's tags in the RSS feed that will allows us to determine title, URL, etc. with certain indicies. It's pretty much like JSON in that instance, it's just that parsing it can get a bit more complex with the different types of objects.

So far, I've gotten titles to load. I'll start working on audiobook URLs once I have that working perfectly.

Tuesday, March 3, 2015

Audio! ... And some problems (3/3)

This is my second post today, but it's completely different from the last, so I thought it was worth it.

I finally got audio working. Well, at least close. Here's the complete code. As you can see, it references our book.html, and then sets the audio source to a URL. While I haven't fully tested it with the CSP, it should work, or at least be close to working.

But finishing this resulted in a large problem, and that's that LibriVox API doesn't give a direct MP3 link. That means that we can't stream the file. Even worse, it's likely that we'll have to either download each book individually (most books are 1+ GB from my testing), or download ALL the books and host them somewhere as MP3 files. A third option would be to get URLs from LibriVox's site, but they're not constant - they're hosted in random URLs such as this link and this link (notice the large difference in the beginning of the URL). As a result, it's going to be really tough to get each book to load easily.

So, it's going to take a ton of work to finish this last part. We'll have to figure out which option is best! It's going to be massive if we go the MP3 route, according to here there's 8,533 items in the collection, and things are being added constantly. Given that the average filesize is 1GB each, that's over 8.5 terabytes of data.

Getting Books to Load! (3/3)

Today we made a lot of progress! In addition to search bugfixes, we also finally got the variable to pass between pages. It's done via an onClick event.

Basically, when the user clicks on an individual search result, we save the variable of that book to localStorage. Then, I figured out an onPageLoad event via JavaScript. It looks like the following:

$( document ).on( "pagecreate", "#homeSettings", function( event ) {
  console.log("Settings.html loaded");
});

Where #homeSettings is the name of the div that has the data-role of page in the html file.

We then have a method such that when book.html is loaded, it loads the ID, and can therefore then get JSON and other information about the book. From there, it should be extremely easy to load the audiobook, and the user can later go back and choose a new one!

I also setup some basic sliders for the book time, as well as play, pause, volume, and stop buttons. I'll add functionality to them hopefully tomorrow.

Monday, March 2, 2015

Yay! Search and More! (3/2)

So today Alex managed to get search working! Props to him for that; it was a 'return false;' statement right below our loop. Turns out the form we were using was messing up our page - it was a result of refreshing, which was removing all the list items we were adding.

So, here's some fancy pictures of the new search functionality we now have. I also added descriptions and links to our search results, so now they'll take you to book.html, which will [soon] play your audio book and have controls as well. I made it pass a variable to the book.html, called ID, which is handling the book ID via JSON. This book ID is used in their API, and should give us enough information to be able to get the audiobook itself!

Side note: Descriptions will contain more information soon, it'll just take some slight modifications!




Sunday, March 1, 2015

Finding the Search Issue (3/1)

So I worked a bit more today on the whole search issue, and the listview that goes along with it. I put some code in JSFiddle here to isolate it, and the list works. Then, I put it back in the loop, and it didn't work. I put it out of the loop (without getting JSON), and it worked perfectly again. So, I've determined that our JSON function is actually refreshing the page, and it's ruining the list, since it's resetting it every single time.

While I'm not sure of exactly how to fix this, hopefully Alex can find the line of code that's causing it. Once we can stop it from refreshing our page, our search results should work perfectly.

Saturday, February 28, 2015

Some Screenshots, SearchBar functionality (2/28)

I thought I would include some screenshots here just to see the app's beginning stages! It's pretty basic, but it looks nice for now. Colors can be easily changed as well, which is nice.




On a side note, I'm still working on some searchbar issues. I've made a post on StackOverflow for now, if it can't be solved soon, I'll just check back Monday. Hopefully it can be fixed this weekend, though!

Friday, February 27, 2015

Working with Search Results, JSON (2/27)

Today we had a lot of progress on the JSON side. We've gotten results working now! They don't display yet, since we're still working on a ListView (via JQueryMobile), but they display in console.

The reason that my JSON wasn't working is because of the fact that it wasn't loading the URL properly. We quickly found a way to fix this - it wasn't using spaces, etc. properly when loading the web page, so we used the method getURIComponent, which basically turns a string into a proper URL.

From there, JSON results were working perfectly, we can now access specific parts of the JSON [Array Books] and then individual properties of those [Book.title].

We made some changes so that it passes a function when XHR loads, so that we're not having issues with null JSON (we weren't able to get it perfectly from the URL after some testing). Hopefully, it'll work perfectly, although it'll still require some major testing.

Thursday, February 26, 2015

Working on Savable Settings (2/26)

I know it was a snow day, but I felt the need to at least put some time towards LibriFox. I felt as if there was a lot of stuff that we were so close to creating, and so I decided to work on it a bit!

Today, I accomplished something I find important: savable settings.

We already have JSON and search functionality will hopefully come tomorrow, so I did some research into how I could get the settings to save, and return as soon as a user comes back in the app.

At first, I messed around with creating files manually. I couldn't find anything on Mozilla's website about savable settings (maybe I didn't look enough?) so I worked on some very large and complicated methods to do it for me. I was able to get settings to save, but I couldn't add settings to the file. I tried help from various websites. I was ending up in the same place every time, the FileHandle API. Which, I now understand, but I don't really need it [yet].

I then did some more research and found that it was a lot more simpler. In fact, it's just a single line. This line involves a variable called localStorage, which looks like it's pretty much on every app - however I include checks to make sure it exists in my methods to make sure the file is saving.

LocalStorage defines the settings file. You basically just code:

localStorage.setItem(key, value)

And the settings are saved. You can later go back:

localStorage.getValue(key)

And get the value of any key you have previously set.

Here's my two usable methods that I have tested:

  function writeToSettings(key, value){ // Writes a key, value pair to settings
    if(window.localStorage){
      localStorage.setItem(key, value);
    }
  }
  function getValue(key){ // Gets a value based on a key provided
    if(window.localStorage){
      localStorage.getItem(key);
    }
  }

However, I'm currently having an issue as to it not saving when the app closes. I'll look into this more tomorrow.

Wednesday, February 25, 2015

Searchbar Functionality, Blog Changes, and Themes (2/25)

To start out, I fixed some things with this blog today. New title and new GitHub link (on the right!).

I also added searchbar functionality with JQuery. It took a lot of googling, but I finally found a StackOverflow post with a person with the similar issue. Instead of calling the text() method of my searchbar, it was the var() method that I needed to call. Now, I have a searchbar that calls a method when the user presses enter, and the text that is inputted is stored in a variable for searching! Once Alex figures out how to use JSON requests with permissions, we should have a stable first release.

I also started looking around for themes. I really want to use the Graphite theme in blue. I think it matches the LibriVox's colors best, and I also believe that it looks clean and simplistic. Sadly, I've figured out that this theme was abandoned years ago, so it looks as if we're going to have to do another theme.

So, I decided to make my own theme. I started out with some help from Aki; we created a header and a div that created a menu-like theme, using data-role. I then created buttons to go to a settings menu, created a new settings.html page, and then buttons to go from the settings menu back to home. I tested the button and it works great, and looks nice as well! Alex got the JSON working, so an early version might be possible by tomorrow! It had to do with app permissions, and a few lines fixed it.

I worked on a volume slider as well. As we're working with audiobooks, this function is key for our app. I'm still working on getting its value, but I'm pretty close to that - so volume should be working tomorrow as well, provided we can get permissions working!

Tuesday, February 24, 2015

GitHub issues and some progress (2/24)

Today we setup a basic GitHub repo such that we can both push into the same repository. However, we're working on setting up a better situation - currently, our app is very small and doesn't have much code. As a result, we have to manually merge lines, line-by-line. Hopefully we'll find a solution tomorrow.

I also made a search bar :)

I know it's not too much, it was just a first test. It also has a function that's called when the user searches. I'm working on getting it's input, and then searching through the database.

JSON is also having some issues with accessing the database and Content Security Policy. We'll work a bit more on that tomorrow as well.

Friday, February 20, 2015

Switching from "Download Failed" to "Download Stopped" (2/20)

Well, I guess I made some progress.

At the beginning of this period, I was having issues with a "download failed" error. I found this post on StackOverflow, which said that it was a result of a manifest error. I then found a place on Mozilla's website where I could check the manifest. Slowly, I removed all the errors from it, and now my packaged app has no errors according to their website here. (I uploaded the .zip every time I wanted to check for errors)

Now, both Alex and I are facing another issue: "Download Stopped". Once again, it's the same process, although now our manifests are perfect, and our .zip files are also perfect, according to their checker. I'm still experimenting with different possibilities of removing this, such as different ways of zipping the file, etc., but nothing is working so far. This time, there is no information on Google as of yet. I'm just getting directed to StackOverflow posts from the "Download Failed" issue. While it could be OS-based, I'm thinking that it has something to do with how our packages are compressed or the file structure of our apps.

I'll continue trying; hopefully I can solve this issue soon!

Thursday, February 19, 2015

Working with installation of the app (2/19)

Today I attempted to self-host and self-publish the app. Although the instructions to do so looked very simple, it turned out to be a very difficult process.

Alex and I tried as many options as we could think of. I decided to start by self-hosting the app on the students server, so it's now there in zipped format. We installed a manifest file, as well as an index file that triggers the installation. We've gotten to the point where the user can accept the install. The device even says that the install succeeds. However, once it downloads the file, it quickly fails, and there's no way to check exactly why the errors are occurring. I checked ADB and the console in the WebIDE, and there's no display of the error, no logs at all.

To back up a bit and go over the basics:


There's two options for the install: install and installPackage. Both would be run in <script> tags in the index.html file. We are going with installPackage, since our app is a self-hosted, self-published app. If it was a simple webapp, it'd be install. However, the install method is installing the app, but when we click on it, it's redirecting us to the students.gctaa.net homepage...

I guess I'll try more options tomorrow. Hopefully, it'll work, but it will definitely take a lot more trial and error!

Wednesday, February 18, 2015

Self-Hosted Apps & A Very Complex Process (2/18)

Today I did some research on self-hosting apps. Basically, there's two types of apps: a web app and a packaged app.

Web apps are hosted by the developer on his/her own server, such that they are like mobile websites. For a more in-depth explanation, a YouTube video is provided here.

Packaged apps are installable, which is the main difference from a web app. It's similar to android in that you can simply download it on your phone and install it, which is exactly what we need in our situation.

Since we needed a packaged app, I began to read a tutorial on "Publishing Apps Yourself". While we could publish our apps to the marketplace, we're far from that, and since these are more... test applications, it's better to publish them by ourselves and self-host them. However, this is a bit of a complex process.

It starts off easy. First, you just .zip up your project folder. Then, it gets a bit more complex - you need to create a manifest file for your app. This manifest file is a bit smaller than the FirefoxOS manifest, but contains basic information about the app - developer name, website, app name, etc.

So far, so good. However, it's getting a bit complicated when I start looking around on how exactly to host my app. I'm thinking I'll host it on the students server, but I'm not exactly sure how it should be hosted, whether it should be zipped, or follow a specific file structure, etc. Tomorrow I'll look at this more in-depth and see how exactly I can approach this. Hopefully, we'll have a readily-packaged app by the end of the day tomorrow.

Friday, February 13, 2015

Settings Menu! (2/13)

Today I mainly worked on implementing a settings menu. I had done this yesterday, but the code needed some cleaning up.

I now have it so that you can press a gear icon in the top-right of the app. This gear icon will redirect you to the settings menu when you press it, and I've also included a back button to go back to the main game from the settings menu. Both buttons work via the <a> tag in HTML. No Javascript is used (yet), but I plan to change them to Javascript so I can work on their design a bit more.

Here's a code example of the settings button:

    <a href="settings.html"><img id="settingsButton" src="settings.png"></img></a>

And the back button:

    <a href="index.html"><img id="proBackButton" src="settings.png"></img></a>

Together, they work very well. On Monday I'll work on saving data, and hopefully getting some background sounds!

Thursday, February 12, 2015

Working with Buttons / Menus (2/12)

Today I worked with some buttons and menus. It's pretty different on FirefoxOS, since you cannot have objects float to the bottom for some reason. Jack, Dylan, Aki, and I all tried to modify this, but had no success. I decided to have the settings menu button at the top of the page instead.

I also worked on an interesting concept: getting text to change size based on how many characters it has. I successfully got that working with the following function in Javascript:

function checkText(newtext){
  console.log("Newtext.length is " + newtext.length);
  if(newtext.length >= 15){
    if(newtext.length >= 30){
      if(newtext.length >= 40){
        $("#textId").animate({
        "font-size":"5pt"
      });
      console.log("setsize to 5");
      $("#textId").text(newtext);
      }
      else{
        $("#textId").animate({
        "font-size":"7pt"
      });
      console.log("setsize to 7");
      $("#textId").text(newtext);
      }
    }
    else{
      $("#textId").animate({
        "font-size":"10pt"
      });
      $("#textId").text(newtext);
      console.log("setsize to 10");
    }
  }
  else{
    $("#textId").text(newtext);
  }
}

Probably not the best way to get it to work, but it does the job. I just check to see how many characters the text has, and then based on how long it is, I change its size. That way, my elements won't shift down, if it's done correctly. It still needs some experimentation, but it's working well so far.

Tuesday, February 10, 2015

Working with a master branch (2/10)

Today we came into an issue when we added Aki into GitHub, and that was the realization that my code wasn't pushing to the right repo. Instead of our shared repo, it was pushing to a repo with the same name on my account, while Aki's was pushing straight to the shared repo. We fixed this on my machine with the following commands:

git remote add upstream "giturlhere"
git pull upstream master
git push upstream master

My code can now be pushed to the shared repo by the following:

git commit -a
git push upstream master

And if I want it only to go to my repo:

git commit -a
git push

Thursday we're going to setup Aki for this.

In other news, I also setup JQueryMobile. I haven't really used the library yet, however I plan to implement a settings menu using this, and possibly a store. It looks fairly simply to use!

Monday, February 9, 2015

Setting Up GitHub and Pushing Changes (2/9)

Today I mainly worked on setting up GitHub on my Mac. I started out with installing Git (using Homebrew):

brew install git

Then I set it up with my username and email:

git config --global user.name "YOUR NAME"
git config --global user.email "YOUR EMAIL ADDRESS"

After that, I cloned the repository in my project's folder:

git clone "url" - replacing URL with our repo's url

Then I cd'd into the repository's new folder.

cd FXOS_Experimentation

... and committed all my files

git commit -A

... then pushed them all!

git push

It was fairly simple, and now I can commit and push whenever I like. Our repo is now available here.

I also got custom fonts working in my app!

Thursday, February 5, 2015

Working with Aki and BuddyUp (2/5)

Today I mainly worked with Aki on setting up BuddyUp. I had originally intended to work on setting up Google Fonts on my app, but after asking the question on IRC, I didn't really get enough help towards that, so I decided to do something else. Edit: I got a lot of help in the last few minutes! I'll attempt a fix tomorrow.

Anyways, the setup of BuddyUp was fairly simple. We first downloaded it from the GitHub repo, then added it into the WebIDE. From there, we pretty much were able to launch it right to the device in a few seconds. We even tested asking a question, which worked as well. However, one issue so far is that the app is EXTREMELY laggy. I think it's because it's trying to load all of the questions every single time a character is typed. That, or it's because we're running the app via USB. It'll take a lot of experimentation.

Wednesday, February 4, 2015

More Experimentation with Firefox OS (2/4/15)

Sorry for the lack of blog post yesterday! I was working very hard on my Javascript/HTML code, and I wanted to save the best for last!

I've been experimenting in Javascript for the past few days with a pretty basic app, I'm calling it "Project Push The Button" at the moment. Basically, it's a 'game' in which the user of the phone taps the button a ton of times. There's a counter, which displays how many times the button is pressed, as well as messages to encourage the player.

Today, I implemented an EXP and leveling system, as well as animations! I've gotten a lot of help from Aki and Alex, and I almost fully understand Javascript and JQuery now.

I've decided to post my code when it's a bit more finalized. However, I'll post some examples of how I handled EXP, Leveling, and Animations.

All of the variables I write are stored to IDs, I've learned. These IDs show what you're modifying, and you can modify them in all sorts of ways. For the most part, I've been changing their text. I do that with the following code:

$("#idName").text("yourTextHere");

Where idName is the name of your ID.

Animations are just as simple. I've been messing around with both fadeTo and slideToggle, both of which are handled by JQuery.

FadeTo fades a block of text, either to dissolve or to make it more visible. It's done by the following code:

$("#idName").fadeTo(400, 0.01);

Where idName is the name of your ID, 400 is the time of the fade, in MS, and 0.01 is the opacity of the object after the fade. You can fade in with the code below:

$("#idName").fadeTo(400, 1);

Where 1 is setting it's opacity to 100%.

SlideToggles are called with the following code:

$("#idName").slideToggle();

The time slideToggles take by default is 400ms. It can be set by putting a number in the parenthesis. I use slideToggles to handle when a user levels up, as it provides me with a nice little animation.

Monday, February 2, 2015

Experimenting with my first Firefox OS App!

Today I fooled around with Javascript and HTML a bit and got my first app working. It's pretty simplistic. Basically, the user clicks a button a ton of times, and there's a counter. When they reach certain milestones, a text area will display messages. I'm also working on exp, levels, coins, and a reward system. All in one day!

Working with Javascript is really nice for apps, it's much easier to work with than Android, and you can refresh the app in under a second, rather than taking the time to reinstall it a ton of times. I'll post source for my app tomorrow!

Friday, January 30, 2015

YES!!!

I got it working! :)

I found this post on StackOverflow... apparently I wasn't the only one with this issue! I started the phone in Fastboot mode, by holding down Volume Down and then Power to boot up. Then, from my terminal, I used their flash file (also known as flash.sh), to flash version 188, the most recent stable build. Now, I have a baseline which I will have as a backup when I flash a dev build.

EDIT: The phone is now running full 3.0, with nightly dev builds enabled! All developer tools, including ADB debugging, are enabled! In other words, it's fully setup and ready to go.

Updating the FirefoxOS Flame to 2.2!

Today I decided to work on the most important thing I could think of, which was updating the OS of the device. It started out easy, but, as I didn't have a lot of developer tools installed on my Mac, I had to go through a lot of workarounds.

At first, I followed the Updating Your Flame guide. I got to the step after downloading the required packages, and then realized I needed ADB, an important part of the Android SDK.

To install this, I followed this guide. However, that only worked up to the point where I had Homebrew, and couldn't get past there.

I then discovered an easy script to install it. I then ran into this bug, but luckily there was an easy fix posted - running their script with sudo.

I'm working on finalizing the installation of the image. Something isn't going right with it...

Thursday, January 29, 2015

Starting out with Firefox OS

Today I started out with learning more about FirefoxOS. Since it's all HTML, CSS, and JavaScript based, I can hopefully use some of my JavaScript knowledge and WebStorm to fix some bugs!

I also got setup for Firefox Hello, which is their version of Skype or Google Hangouts. It's fairly simplistic, and you can use it with the press of a button, granted you're in Firefox. You can also accept calls from browsers such as Chrome, if you have a link. I tested it out a bit with Aki and it worked perfectly! He doesn't have a webcam, though, so I haven't actually seen how it works with multiple people.

I learned that I can contribute by completing tasks, and the tasks are even tracked to my email. I think that's really cool, because I can keep track of my progress as I go along. I can access it at any time I want here.

I learned how to put the custom developer image on as well - I've actually done something very similar to this on an old Android phone of mine. They had more optimized versions of Android to run, and so I installed a custom image onto it. It's pretty much the same thing here, as we're using the ADB software to install a custom image (developer FirefoxOS) onto the phone. There's a full guide on that available here, and there's video tutorials everywhere as well.

Wednesday, January 28, 2015

A Day in Javascript (1/28/15)

Today I worked a bit on Javascript. It's not very related to what I'm currently doing, but I thought that I should learn a bit of web languages, especially since I decided that I should work on the Firefox phone today. I installed a program called WebStorm, which is an IDE for Javascript (by the creators of IntelliJ). It's similar to Vim in syntax hi-lighting, but also has code completion and some other helpful things.

I fooled around a bit with the basic methods and created some simple scripts. Once I get some more interesting things working, I'll post the code here. It's pretty similar to Java, so I think I'm doing well in it so far!

Monday, January 26, 2015

Heaps and Python (WS) (1/26/15)

Today I worked on the Heaps worksheet. Although I actually haven't written or even seen Python in the past few years, this refreshed my knowledge a bit on it and also allowed me to learn about Heaps a bit more! I finished the worksheet and I got them correct in the end. I learned about the following.

Heap Up - Used when you want to insert a value into a heap. Recursively goes through the current heap to figure out where to put the new value.

Heap Down - Used when you want to remove a value. Recursively goes through the current heap, by rebuilding it without the value.

I also learned about translating a list into a heap. It's fairly simple:

For the left value, you can use 2*i, where i is the index of the value.
For the right value, you can use 2*i+1, where i is the index of the value.

From here, you basically are filling out values from left to right.
For example, if your list is [1, 2, 3, 4, 5, 6, 7], your heap wouldn't be correct. You'd have to use one of the above methods to fix it. In the worksheet example, we recursively used heap_down. From there, it fixed the heap, leaving it to a correct heap. Using the example, our new heap would be [1, 7, 6, 4, 5, 3, 2]. This would be a Min-Heap, and would look like this:

    1
   7      6
  4   5   3  2

The worksheet really helped with a lot of Heap concepts that EIMACS didn't explain to the fullest. I think that it did help me learn a bit more about the basic properties of Heaps and some ways that they can be created and modified.

Friday, January 23, 2015

Experimenting with Android Studio (1/23/15)

Today I experimented with Android Studio. I set it up, and I wrote some code, although then I realized that it was getting a bit over-complex so I decided to remove the project. I was attempting to go back into servers (Sockets), but it's been awhile since I've done Android Java, so I think that it would be better to start again with basic things such as buttons. The next day I have free to go back to Android, I'll start working on the basic concepts that are outlined for the test.

Thursday, January 22, 2015

Test 24 (1/22/15)

Today I worked on the last test of EIMACS: Test 24. I did well, and tomorrow it looks like I'll start working on more problems on Heaps and other ADTs.

Wednesday, January 21, 2015

Abstract Data Types (1/21/15)

I'm still working on figuring ADTs out, but this is my research on them so far.

My definition: An abstract data type is a way of defining certain data structures that act the same, across multiple programming languages. Abstract data types have been evaluated on their completion time and efficiency, and are often looked at for their limitations and their operations that they may perform. They are independent of particular implementation. They are defined mathematically, rather than implemented by the programming language.

Some examples: 
-Stacks
-Queues
-Trees
-Sets
-Maps
-Priority Queues
-Lists

ADTs have set operations that can be done to them. An example of this would be the abstract Stack, in which the only methods that can be done to it would be push and pop, and that its constraint is that "the sequence of operations { push(S,x); V ← pop(S) } is equivalent to { V ← x };" (Wikipedia). It usually also includes the methods of create, empty(create()), and notemptypush(S,x). They mean that a new stack is different from all previously created stacks, a newly created stack is empty, and pushing an object to a stack makes it not empty.


Friday, January 16, 2015

Notes on Heaps (1/16/15)

Today, I worked on learning about Heaps!

A heap, according to EIMACS, is a binary tree, whose values are Comparable objects. Also, a heap has to have met one of the following two properties:

  1. Each node's value is greater than or equal to the parent. [Called the Min-Heap Property]
  2. Each node's value is less than or equal to the parent. [Called the Max-Heap Property]
In heaps, the highest, or lowest, value of the entire tree is already at the root position. This allows for a lot of uses!

A good example of a Max-Heap is shown below:

"Max-Heap" by Ermishin - Own work. Licensed under CC BY-SA 3.0 via Wikimedia Commons - http://commons.wikimedia.org/wiki/File:Max-Heap.svg#mediaviewer/File:Max-Heap.svg
As shown above, heaps need to be complete. An example of an incomplete heap is shown below, courtesy of EIMACS:
For example, the right branch is not fully complete - there is no "F" value. Incomplete heaps can not exist.

There are other reasons as well as to why heaps would not be compatible, for example if they do not meet the Min-Heap or Max-Heap properties.

The following code example below, courtesy of EIMACS, allows for elements to be taken from an array and inserted into a Heap, one-by-one.

public static <T extends Comparable<T>> void heapInsert( ArrayList<T> heap, T value){
    int newValueIndex = heap.size();
    heap.add( newValueIndex, value );

    while ( newValueIndex > 1 ){
        int parentIndex = ( newValueIndex / 2 );
        T parentValue = heap.get( parentIndex );
        if ( value.compareTo( parentValue ) < 0 ){
            heap.set( parentIndex, value );
            heap.set( newValueIndex, parentValue );

            newValueIndex = parentIndex;
        }
        else {
            return;
        }
    }
}

There are many features as to why developers would like to use heaps. Obviously with heaps you are left with two options, as described above. You could go the Min-Heap route, where the smallest value is most easily accessible, or the Max-Heap route, where the largest value is most easily accessible. As a result, it is stated that heaps are often used for priority queues. Sorting is fast and efficient with heaps, completing in only O(nlog(n)) time. This mentioned algorithm is called HeapSort.

How do HeapSorts work? It's fairly simple.
  1. All values are inserted one-by-one into a binary tree. It is made sure that this tree is a heap.
  2. The root of this tree is removed, but a value takes it place such that it stays a heap.
  3. This method is completed several times until all of the values have been checked.
With a time of only O(nlog(n)), it's just as good as a well-run quicksort or merge sort. As a result, it's often used by developers.

The three methods needed for a HeapSort are shown below:
public static <T extends Comparable<T>> void heapInsert( ArrayList<T> heap, T value ){
    int newValueIndex = heap.size();
    heap.add( newValueIndex, value );
    while ( newValueIndex > 1 ){
        int parentIndex = ( newValueIndex / 2 );
        T parentValue = heap.get( parentIndex );
        if ( value.compareTo( parentValue ) < 0 ){
            heap.set( parentIndex, value );
            heap.set( newValueIndex, parentValue );
            newValueIndex = parentIndex;
        }
        else {
            return;
        }
    }
}

public static <T extends Comparable<T>> T heapRemove( ArrayList<T> heap ){
    if ( heap.size() < 3 ){
        return heap.remove( 1 );
    }
    T root = heap.get( 1 );
    T lastValue = heap.remove( heap.size() - 1 );
    int valueIndex = 1;
    heap.set( valueIndex, lastValue );
    int childIndex = ( 2 * valueIndex );
    while ( childIndex < heap.size() ){
        T childValue = heap.get( childIndex );
        if ( childIndex + 1 < heap.size() && childValue.compareTo(heap.get( childIndex + 1 )) > 0 ){
            childIndex++;
            childValue = heap.get( childIndex );
        }
        if ( lastValue.compareTo( childValue ) > 0 ){
            heap.set( childIndex, lastValue );
            heap.set( valueIndex, childValue );
            valueIndex = childIndex;
        }
        else {
            return root;
        }
    }
    return root;
}

public static <T extends Comparable<T>> void heapSort( ArrayList<T> a ){
    ArrayList<T> heap = new ArrayList<T>();
    heap.add( null );
    for ( int i = 0 ; i < a.size(); i++ ){
        heapInsert( heap, a.get( i ) );
    }
    for ( int i = 0 ; i < a.size(); i++ ){
        a.set( i, heapRemove( heap ) );
    }
}


Once these methods are in your class, you can simply call them from your main method and use HeapSorts!

Thursday, January 15, 2015

Notes on Binary Search Trees (1/15/15)

Today I worked on Binary Search Trees.

Binary Search Trees, according to EIMACS, are binary trees whose values are instances of reference types - they implement the Comparable<T> interface. They can never have the same value more than once.

In a Binary Search Tree, each left value is less than the root value, and each right value is greater than the root value. A good picture example of this is this, also from EIMACS:
A perfect example as to why a developer would choose a Binary Search Tree is that it has a very efficient search algorithm, as seen below. This method will return a the TreeNode where the defined value exists, and otherwise, return null. As a result of the compareTo method and the Comparable interface, it is much quicker and efficient than other methods.

static TreeNode searchBST( TreeNode tree, Comparable value )
{
    if ( tree == null ){
        return null;
    }
    Object rootVal = tree.getValue();
    if ( value.equals( rootVal ) ){
        return tree;
    }
    if ( value.compareTo( rootVal ) < 0 ){
        return searchBST( tree.getLeft(), value );
    }
    else
}


As previously stated, this method has a great deal of use if you're working with trees. Granted that your Binary Tree is pre-sorted, this method will allow for fast accessing of data - a perfect reason to use a Binary Tree.

Creating Binary Search Trees isn't all too difficult, as shown in EIMACS, the buildBST and insertLeaf methods, as shown below, can both create and insert data into a Binary Search Tree.

public static TreeNode buildBST( ArrayList<Comparable> values )
{
    TreeNode newTree = null;
    for ( int i = 0 ; i < values.size() ; i++ ){
        newTree = insertLeaf( newTree, values.get( i ) ); 
    }
    return newTree;
}


public static TreeNode insertLeaf( TreeNode tree, Comparable value )
{
    if ( tree == null ){
        return new TreeNode( value );
    }

    if ( value.compareTo( tree.getValue() ) < 0 ){
        tree.setLeft( insertLeaf( tree.getLeft(), value ) );
    }
    else {
        tree.setRight( insertLeaf( tree.getRight(), value ) );
    }
    return tree;
}
Additionally noted in this section is the TreeSet<E> interface. All objects in this must be Comparable<E> objects. It also allows for quick searching, adding, and removing of objects, none of which take more than O(log(n)) time.

TreeMap<K, V> is also a noted interface. All objects in this must be Comparable<K> objects, and the methods available for this interface are get, put, containsKey, and remove. They also can be completed in O(log(n)) time or less, and objects in the TreeMap are stored and retrievable in the same order, which is advantageous in certain situations.

I also began to install Xcode, which apparently can be used for Java. I wanted to experiment with it a bit later on when I go back to Android development, and since I've heard it's a fairly decent IDE, I thought it would be worth a try. It only took two or so minutes, so I didn't lose too much time by doing this either!

Tomorrow I will add information on Heaps!

Wednesday, January 14, 2015

Notes on Binary Traversals (1/14/15)

Today I worked on Binary Traversals and took some notes on them. Basically, there are 7 types of traversals:

Preorder Traversal - Looks at the root value, then the left subtree, then the right subtree.
Reverse Preorder Traversal - Also looks at the root value, then the right subtree, then the left subtree.
Inorder Traversal - Looks at the left subtree, then the root, then the right subtree.
Reverse Inorder Traversal - Looks at the right subtree, then the root, then the left subtree.
Postorder Traversal - Looks at the left subtree, then the right subtree, then the root.
Reverse Postorder Traversal - Looks at the right subtree, then the left subtree, then the root.
Level-by-level Traversal - Looks at all the nodes, level by level, going down one at a time, from left to right.



As can be seen, there are many different ways to traverse Binary Trees. I've added the following example below to look at a Preorder Traversal (taken from EIMACS):

public void printValues(TreeNode tree){
    System.out.print( tree.getValue() );
    if ( tree.getLeft() != null ){
        printValues( tree.getLeft() );
    }
    if (tree.getRight() != null ){
        printValues( tree.getRight() );

    }
}

Although this is more of a simplistic example, you can see that all other types of traversals would be similar to this. For example, a reverse preorder traversal would be the following:

public void printValuesReverse(TreeNode tree){
    System.out.print( tree.getValue() );

    if (tree.getRight() != null ){
        printValuesReverse( tree.getRight() );

    }
    if ( tree.getLeft() != null ){
        printValuesReverse( tree.getLeft() );
    }
}


This can be done for all types of binary tree traversals. Although it is a simplistic concept, it outlines important ways of finding your data via binary trees. Each type of traversal has its own advantages and disadvantages, and is left to the developer to figure out which would be the best method to choose.