Results 1 to 6 of 6
 10222012, 12:25 AM #1Member
 Join Date
 Oct 2012
 Posts
 2
 Rep Power
 0
Benfords Law Java Quesiton please help :)
Okay this problem is about benfords law.
the current part im on is this:
Question 4: Calculating the Percentages (20 points)
Write a method calculateLeadingDigitProportions which takes as input a double[] numbers and returns a double[]. Your method should analyze the array numbers and return an array representing for each digit, the proportion of times it occurred as a leading digit. In the produced array, the value at the 0th index should represent the proportion of times that a 0 was a leading digit (only occurs when the number is 0 after truncation to an int), the value at the 1st index would contain the proportion of times that a 1 was a leading digit, and so on, up until the 9th index.
For example, if numbers contains:
{ 100, 200.1, 9.3, 10}
then 1 occurs as a leading digit 50 % of the time, 2 occurs 25% of the time, and 9 occurs 25 % of the time, so your produced array should contain:
{0, .5, .25, 0, 0, 0, 0, 0, 0, .25}
You may use the method calculateLeadingDigit to do this, but note that that method expects as input an int, and so you will need to cast or perform a conversion in some other way. Note that if the number is less than 1 but greater than 0 it is fine to call the leading digit 0 after a truncation.
Hint: This method is fairly involved. You may find it useful to write a helper method called, for example, countLeadingDigits which returns an array of counts for each digit and only then calculate the percentages
The rest of the problem and the code I have so far is on the bottom of this post but its super long. :/
I am very confused about how to approach question four :/
My CODE:
Java Code:public class BenfordsLaw { public static void main(String[] args) { calculateLeadingDigit(2094928); generateBenfordNumbers(100, 0.1, 4); } public static int calculateLeadingDigit(int number) { while (number>9) { number /= 10; //divide by 10 until there is only the leading digit left } return number; } public static double[] generateBenfordNumbers(double initialAmount, double growthRate, int numberPeriods) { double[] benfordArray = new double[numberPeriods]; //benfordArray is an array of size numberPeriods int x; //counter variable for(x=0;x<numberPeriods;x++) { benfordArray[x] = initialAmount; initialAmount *= (1 + growthRate); //changes initialAmount to initialAmount*(1+growthRate) } for(x=0; x<numberPeriods; x++) //prints all values of benfordArray up until numberPeriods { System.out.println(benfordArray[x]); } return benfordArray; } } public static int[] countLeadingDigits(double[] countsArray) { double[] countsArray; countsArray = BenfordsLaw.generateBenfordNumbers(100,0.1,4); int [] frequencies = BenfordsLaw.countLeadingDigits(countsArray); System.out.println(frequencies); }/* public static double[] calculateLeadingDigitProportions(double[] numbers) { } public static double calculateDistance(double[] array1, double[] array2) { double distance = Math.sqrt(Math.pow((array1[x]  array2[x]),2)) } }*/
ASSIGNMENT:
Benfords Law
The rest of these questions involve something called Benford’s Law and should be put into a file BenfordsLaw.java and a class BenfordsLaw. You will be asked to write a series of methods, which due to their independence, can mostly be written one at a time.
Background Information
Benford’s law is an unusual observation that numbers produced in systems governed by exponential growth start with the number 1 the more often than any other digit. That is to say, when a system increases by a certain roughly fixed percentage over time, there tend to be ones at the beginning of the numbers.
Consider the following example. Suppose you start with $100 and you put your money in a bank account which pays you an interest rate that will cause the money to double every 20 years. (This assumption of a fixed amount of time to double is the exponential growth part). After 20 years, your $100 will have turned into $200 and after another 20 years, your $200 will have turned into $400. The amount of time that you had an amount of money in the “one hundreds” was twenty years, since for the whole first twenty years you had more than $100 and less than $200. The amount of time you had your money in the $200s is less, however, as the second twenty year interval is partly in the $200s and partly in the $300s. Interestingly, this phenomenon can be observed throughout all digits and it turns out that in numbers generated in this sort of way, the approximate percentage of leading digits is given in the graph in Figure 1.
As most prices and incomes tend to grow roughly exponentially over time (due to inflation), our prices and incomes follow the same phenomenon. This knowledge has been used by people to detect tax fraud in cases where people randomly generated numbers without following this pattern. The idea is if you uniformly randomly choose numbers your numbers will start with each of the 9 digits 1/9 of the time. This technique by forensic accountants to clear Bill Clinton of tax fraud one time that he was accused of this as his returns DID obey Benford’s law.
In this question, you will write several methods that will culminate in contrasting the distance from the Benford’s law distribution of two sets: one generated via an exponential growth model and the other generated via a uniformly random distribution.
Page 4
￼Figure 1: The proportion of occurrences of each digit as a first nonzero digit of a number
Question 2: Leading digits (10 points)
Write a method called calculateLeadingDigit which takes as input an int and returns an int rep resenting the first nonzero digit of the number. Your method header should look like public static int calculateLeadingDigit(int number)
If we call the method calculateLeadingDigit() from a different method, you will provide it with an int and get in return an int
• calculateLeadingDigit(103) would return 1 • calculateLeadingDigit(0) would return 0
• calcualteLeadingDigit(41) would return 4 • etc
(If you use Scanner inside your method you will NOT be able to do this correctly for different numbers. As such you should have NO use of Scanner in this method.)
There are several ways to do this. One way is by recalling that dividing a number by 10 shifts the decimal point over by one place. So you could start with your initial number and continue dividing by 10 until the number is a one digit number (i.e. greater than 0 and less than 10). You will need to keep in mind the rules of integer division and also consider what happens if the number is negative in the first place. There are also ways to do this with String as well. (You should know how to do both and study the solutions when they are posted.)
Question 3: Generating a Benford Sequence (20 points)
Write a method generateBenfordNumbers that takes as input two doubles and an int and returns a double[]. The first double initialAmount represents the initial amount of money you start with. The second double growthRate represents the amount of growth per period. The int numberPeriods represents the amount of periods to look at. Your method should return an array of values storing the amount of money after each period of time if initialAmount grows by growthRate proportion in each step.
For example if the amount of money you start with is $100 and the interest is .1 (i.e. 10 %) and taken over 4 periods, then you should return an array with the contents:
{ 100.0 , 110.0, 121.0, 133.1 }
Note that the first number of the array is the amount you started with. To go from one number to the next, you can multiply the current number by 1 + growthRate
Page 5
Hint: Your method header should be
public static double[] generateBenfordNumbers(double initialAmount, double growthRate, int numberPeriods)
Question 4: Calculating the Percentages (20 points)
Write a method calculateLeadingDigitProportions which takes as input a double[] numbers and returns a double[]. Your method should analyze the array numbers and return an array representing for each digit, the proportion of times it occurred as a leading digit. In the produced array, the value at the 0th index should represent the proportion of times that a 0 was a leading digit (only occurs when the number is 0 after truncation to an int), the value at the 1st index would contain the proportion of times that a 1 was a leading digit, and so on, up until the 9th index.
For example, if numbers contains:
{ 100, 200.1, 9.3, 10}
then 1 occurs as a leading digit 50 % of the time, 2 occurs 25% of the time, and 9 occurs 25 % of the time, so your produced array should contain:
{0, .5, .25, 0, 0, 0, 0, 0, 0, .25}
You may use the method calculateLeadingDigit to do this, but note that that method expects as input an int, and so you will need to cast or perform a conversion in some other way. Note that if the number is less than 1 but greater than 0 it is fine to call the leading digit 0 after a truncation.
Hint: This method is fairly involved. You may find it useful to write a helper method called, for example, countLeadingDigits which returns an array of counts for each digit and only then calculate the percentages
Question 5: Calculate Distance (15 points)
The final method you should write will involve a comparison of two arrays to calculate how similar they are to each other. Write a method called calculateDistance which takes as input two double[] and returns a double representing the Euclidean distance between the two arrays.
The Euclidean distance can be computed by first calculating the sum of the square distances between the two arrays and then taking the square root of the entire thing (essentially the Pythagorean theorem). For example, if your arrays are acalled array1 and array2 and had size of 3 you could calculate the Euclidean distance by the following:
ﰀ(array1[0] − array2[0])2 + (array1[1] − array2[1])2 + (array1[2] − array2[2])
Since you don’t know ahead of time how large the arrays will be, however, you need to use a loop. Your
method should return this Euclidean distance.
Your method may assume for simplicity that the size of the arrays will always be the same. That is, you do not need to add extra logic to handle that case.
Question 6: Putting it all together (10 points)
The final thing you will do is put everything together using a library function provided for you and putting it into a main method. On the course webpage, you will find a file called BenfordSupportCode.java. This has two methods provided. One method is called generateRandomNumbers and takes as input an int count and returns a double[] filled with count “random” integers. (As you’ll see they are not truly random as the same sequence will occur again and again. This can be changed but was done so that you can reproduce your results more easily). The second method is called getBenfordProbabilities() and returns a double[] representing the Benford’s law distribution of leading digits.
To be able to use these library methods, you must make sure to save the file BenfordSupportCode.java inside the same folder as BenfordsLaw.java . In Eclipse you will need to add it to the project as well. In Dr Java it should be sufficient to simply open the file as well. In notepad, you should compile it by writing javac BenfordsLaw.java BenfordSupportCode.java instead of the usual javac BenfordsLaw.java
￼Page 6
Write a main method that does the following:
1. Generateanarrayof1000numbersusingthemethodyouwrote previouslygenerateBenfordSequence. You should print the parameters you are using (the initial amount of money, the number of steps and the rate of growth at each step). (Note: If you increase the size of the array to be much larger than 1000 you may run into issue with reaching the maximum integer in Java)
2. Generate an array of 1000 numbers using the provided method in the BenfordSupportCode class. Remember that you will need to call these methods by writing the name of the class first (as you do for methods in the Math library).
3. Call your method for getting the distribution of leading numbers on each set.
4. For each set, print the proportion of digits in each.
5. Print the distance between the 2 numbers and the “ideal” Benford distribution. If you have coded everything correctly, the “random” numbers will have a further distance than the Benford distri bution. (So if this were part of a larger forensic accounting program and you saw the distance was too high, you would realize they had not been generated via a real process but rather an artificial one)Last edited by pbrockway2; 10222012 at 12:58 AM. Reason: code tags added
 10222012, 12:48 AM #2Member
 Join Date
 Sep 2012
 Posts
 70
 Rep Power
 0
Re: Benfords Law Java Quesiton please help :)
wow half a text book.
 10222012, 01:03 AM #3Moderator
 Join Date
 Feb 2009
 Location
 New Zealand
 Posts
 4,643
 Rep Power
 13
Re: Benfords Law Java Quesiton please help :)
Hi smith999, welcome to the forums!
I have added "code" tags to your post. The idea is you put [code] at the start of a section of code and [/code] at the end to tell the forum software that it is code and should be rendered with the indentation intact. There are other tags like that I used for "is" in the previous sentence: [b]this would appear bold[/b]. See BB Code List  Java Programming Forum for a list.
 10222012, 02:11 AM #4Moderator
 Join Date
 Feb 2009
 Location
 New Zealand
 Posts
 4,643
 Rep Power
 13
Re: Benfords Law Java Quesiton please help :)
You posted the assignment instructions (the whole thing is here) but do you understand the question? I ask because  with such a wordy assignment  it's easy to lose sight of the objective.

This is something of a digression from what you actually asked...
The assignment makes a couple of points that you should bear in mind. First, introducing the Benford's Law set of questions "You will be asked to write a series of methods, which due to their independence, can mostly be written one at a time". And I would add that each part can, and should, be tested before you move on to the next. In other words after you have written each method (and found that your code compiles) you should try very, very hard to break it: that is, supply it with different input, and verify (or not) that it returns the result you expect.
The assignment questions are sequential (in practice they depend on the values returned by previous parts). So don't move on until your code has survived the testing attack you mount on it.
Secondly, just before question 1 and in bold, "You should not use Scanner or have print statements in any of the required methods." The code you posted *does* have println() statements. That's OK so you can more easily see what's going on while testing things, but you ought to recognise the general form of each of the questions:
Write a method <method_name> which takes as input a <type> <variable> and returns a <type>
There's nothing in the problems that asks for anything to be printed. So nothing should be printed. (Specifications of methods are almost neurotically strict about this: there should be no "public" or "visible" effects of your method beyond those described in the specification. When we write code we depend on this lack of side effects  if methods did things additional to what they were documented to do we couldn't depend on anything being the case after a method was called.)

Java Code:public static int[] countLeadingDigits(double[] countsArray) { double[] countsArray; countsArray = BenfordsLaw.generateBenfordNumbers(100,0.1,4); int [] frequencies = BenfordsLaw.countLeadingDigits(countsArray); System.out.println(frequencies); }
As an illustration of how the code for countLeadingDigits() should look, consider the following
Java Code:/** * Returns an array of counts of the leading digits in a given array of numbers. * * The ith element in the returned array is the number of times i occurred * as the leading digit. (for i from 0 to 9). * * This is a helper method for question 4. * * @param numbers an array of numbers whose leading digits are being counted */ private static int[] countLeadingDigits(double[] numbers) { int[] frequencies = new int[???]; // Some magic goes here that (1) looks at each element of the // supplied numbers array, (2) figures out what the leading digit // is (maybe truncating it first?) and (3) updates the frequencies // array based on what the leading digit was found to be. /**/for(int ndx = 0; ndx < frequencied.length; ndx++) { /**/ System.out.print(frequencies[ndx] + " "); /**/} /**/System.out.println(); return frequencies; }
(1) It's documented. This repeats the information in the hint to q4 which talks about the method  ie what it is given and what it returns. And it adds a note about this being a helper method which is not strictly needed, but may be useful when you reread the code 6 months later.
(2) It's private. Because it's a helper method.
(3) The parameter variable is numbers not countsArray. Both because it was called "numbers" in the hint to q4, and because it is not an array of counts. (that's what frequencies iwill be)
(4) The parameter variable is not redeclared in the body of the method. (as you did with countsArray). This is basically a mistake and will do bad things. You have never seen an example of this in code you were given.
(5) How big should the frequencies array be?
(6) Does the general algorithm in the // comment make sense?
(7) There are things printed, but they are flagged for eventual deletion. Because they are not what the method is supposed to do.
(8) There is a return statement. That's because the method is declared to return something. "int[] countLeadingDigits(double[] numbers)" means "taking a double[] and returning an int[]".
So many things to think about for so little code (and most of that comment)! That's how it goes. I hope it isn't overwhelming. There is some general unfamiliarity in your whole class (who've been posting all over teh internet!) about methods and the general "flow" of data  about how methods receive data as parameter arguments, and return data via the return statement. Review your notes about this. (all of you!  again this was hinted at in the assignment instructions.)

Good luck, and post back if you hit a stumbling block. Especially (6) above which is the kernel of the answer to your original question. Say if the algorithm suggested there doesn't make sense, or you can't implement it in code.

@killutch: Now, that's half a textbook...Last edited by pbrockway2; 10222012 at 02:22 AM.
 10222012, 02:39 AM #5
Re: Benfords Law Java Quesiton please help :)
Benford's Law Computer assignment!
Duplicate post.
 10222012, 02:54 AM #6Moderator
 Join Date
 Feb 2009
 Location
 New Zealand
 Posts
 4,643
 Rep Power
 13
Re: Benfords Law Java Quesiton please help :)
Thanks Junky. The points I made here are more or less orthogonal to those made by Zaphod et al in the other thread. I won't be following this thread further.
@OP: If you post in multiple places, please post a link in each to the others. (as Junky has done for you). When I contribute to a discussion I appreciate knowing what else is being said. Many consider cross posting a faux pas, see for instance this post at javaprogrammingforums.
Similar Threads

Advice on a homework quesiton
By jazzermonty in forum Threads and SynchronizationReplies: 4Last Post: 04112012, 11:03 PM 
Specimen exam quesiton
By elliotHenry in forum New To JavaReplies: 14Last Post: 06142011, 09:18 PM
Bookmarks