Saturday, 29 November 2014

"Dependencies" Troubles with Android Gradle, and How to Even Use Terminal in Android Studio

I have only started Android development during my last internship which was almost a year ago. Since then, I have migrated to Android Studio, and in all honesty, this new IDE is amazing compared to the Eclipse IDE with the Android ADT.

There are a few differences, though getting the hang of this new IDE should be simple enough - except for one thing.

Let's say you had a lot of dependencies - a.k.a., external libraries for your application. This has been honestly the most annoying thing ever for me as a newbie at Gradle, but basically, if one of your library projects has its own dependency called A, and you have the same kind of dependency in your main application project, then those two dependencies will conflict with each other.

When you have this kind of conflict, the error that you will normally get is:

UNEXPECTED TOP-LEVEL EXCEPTION:
com.android.dx.util.DexException: Multiple dex files define ...

Now, obviously, when one first comes across this issue, one uses StackOverflow - which is what I did, and this should be the best answer:

http://stackoverflow.com/a/21100040/3324013

However, usually, newbies at Gradle such as myself will not realize that these commands only work if you have Gradle installed - I only installed Android Studio, that has a Gradle wrapper.

To summarize, all I and anyone who does not have Gradle installed should do is:

for any gradle command that we see that we can copy and paste in the terminal, replace the word "gradle" with "gradlew", because we do not actually have Gradle installed.

This made my life so much easier.

So, e.g., use:

gradlew -q :projectName:dependencies

not

gradle -q :projectName:dependencies

I hope this teaches some newbs such as myself about Gradle in terms of Android Studio.

Wednesday, 26 November 2014

ADT-1 Development Story - Part 0

This will be a blog series on my progress of developing on the ADT-1, a media player and game controller by Google! I got it from a very kind person working at Google Japan. He gave it to me, even though I am still just a student.



Sorry if this blog post is short, more will come very soon, as I can't wait to get started on this!

Saturday, 8 November 2014

Ramblings on Project Euler and How to Determine if a Number is Prime

Yesterday and today, I was trying to do problem 3 from Project Euler. If you don't know what Project Euler is, it is a neat site where there are math/programming questions that can only be solved if you write a computer program that will output the right mathematical number/answer. From there, you can just input the answer for the particular question on the site, and it will tell you if you got the right number/answer or not. If you did, then you will gain access to community discussions and even a pdf on how to properly code a program to solve that question you answered. The questions are all ranked based on how many people solved it, so you can start on the easiest questions and work your way down to the ones where less than a hundred people even solved it worldwide.

I already answered first two questions, which are the two that people answered the most (and thus, the easiest two questions). But then came question 3. The question was to find the largest prime factor of a number. The hard part is to actually determine the primality of a factor of the number. If you don't know what primality is, it's basically "whether or not the number is a prime number". Now the thing is, you could answer question 3 easily if you used certain pre-defined methods in standard libraries for a variety of programming languages. For example, I know that in Java, there is a function called isProbablePrime. (You might be wondering why it's called isProbablePrime instead of isPrime. I will explain that later). And of course, with Python and Ruby, you can write a couple lines of code and just be done with it as they have a lot of those mathematical/scientific functions. I can't really go into detail about them though, as I am not familiar with either programming languages.

As for me, I used C++ to answer all my questions, including question 3, and did not use any sort of already existing function that is similar to isProbablePrime like in Java. At most, for question 3, I used the rand function. to generate a random number.

Below is my short story of how I learned how to test the primality of a number.

1. Use trial division.

What is trial division? Well, you can read more about it here: http://www.counton.org/explorer/primes/checking-if-a-number-is-prime/

It's basically an efficient way to test all numbers between 1 and n-1, where n is the number that we want to know if it's prime or not, and see if any of the numbers between 1 and n-1 divide into n evenly. If any one of them does, then n is not a prime number. Obviously, 1 to n-1 is O(n). If you don't know what O(n) is, go take an Intro to Data Structures and Algorithms course in your university.

So, trial division makes it from 1 to n-1, to 1 to sqrt(n). Why sqrt(n)? If you read the link, you would find out that:

Suppose one number is a factor of N and that it is smaller than the square-root of the number N. Then the second factor must be larger than the square-root.


Think of all the factors of 20. 1x20, 2x10, 4x5. 1 and 20 are on opposite sides of the spectrum, if the spectrum was a number line from 1 to 20. So are 2 and 10, and 4 and 5. So, all you really need to do is to look at the smaller numbers and not care about their larger counterparts. What I mean by this is, if you already tested if 20 mod 2 == 0, then you don't need to test if 20 mod 10 == 0. Thus, you only check the ranges of numbers from >1 and <sqrt(n).

Also, considering that n should be an odd number (because if it was an even number you would automatically know it's NOT a prime), then that means you also don't need to check if any even numbers are factors of n, so you only need to iterate sqrt(n)/2.

So, an implementation of trial division is:
You have an ODD NUMBER, n, and you want to check its primality.

//start at 3 because you don't need to check if even numbers, e.g. 2, are a factor of the odd number.
//go up until rounded up sqrt(n) (you should round it up)
//iterate by i+=2 because you don't need to check any of the even numbers
for (int i = 3; i < ceil(sqrt(n)); i+=2)
{
    if (n % i == 0)
    {
        return false; //it's not a prime
    }
}
/*after you check all of the numbers and you know none of them are factors of n then n must be prime.*/
return true;

If you try to answer question 3 of project euler using this implementation, I guarantee that the program runtime will be over an hour. I'm on a Macbook Pro that I bought in August 2014. And it took over an hour pretty much.

I think this frustration improved me for the better though. Project Euler, it is certainly frustrating, challenging, but still a lot of fun. When you get the right solution to a problem, you definitely want to come back to that question and see if you can improve your algorithm to be more efficient (a.k.a. not run for over an hour just to get the answer). It certainly makes me realize how I take for granted the power of modern computers computing powers.

I have since improved my trial division implementation, and am using the miller rabin algorithm. The Java method, isProbablePrime, actually uses this algorithm. It is not a deterministic algorithm though, and recently in 2006, there was a deterministic and polynomial time algorithm for primality called AKS primality algorithm. Perhaps I will read more into AKS later.

How to use Github Pages (your github.io page) as a server/host for your Gandi Domain

Recently, I bought a domain from Gandi. You can see it here: my website. Making my website from Bootstrap, HTML, CSS, and a bit of javascript wasn't that hard. I just coded, and then pushed to the master branch of my Github page repository (which is phantomkirby.github.io). However, what stumped me a lot was how to make it so that when a user types in my domain website name (cherryzhang.net), he or she will see my github website.

In order to do this, you will need to make github pages your server/host, and your domain will be provided by Gandi. Here is the best blog post about how to do this exactly: http://spector.io/how-to-set-up-github-pages-with-a-custom-domain-on-gandi/

If you do everything he tells you to do, you will be able to also use your Github pages with your website name!