please email or whatsapp for Solution
+923432547206
bilalarif63@yahoo.com
1)Testing
The first part of the project focuses on developing the ability
to write test cases for an existing class.
In the project pack, a directory called testme contains multiple
implementations of a simple system to calculate various
salary-related things. One of these implementations is correct,
while the remaining ones all contain bugs. You will write test
cases based on the provided class documentation to discern which
implementation is correct. The correct implementation should pass
all tests while the buggy versions should all fail at least one
test, likely many more. You will earn credit for each wrong
implementation that fails tests (when the correct one is still
passing tests!), and for correctly identifying the correct
version.
Importantly,
you do not have access to the source code
for any of the implementations. Instead, you must rely on the
documentation of the intended purpose of the classes to develop
your tests.
Each implementation is in its own package and subdirectory.
Later sections describe how to run your single testing file against
any particular implementation without copying files around. (hint:
opening and closing files repeatedly in DrJava is
not a good workflow).
Debugging
The second part of the project involves developing your skills
to trace code and utilize the debugger to follow execution.
The debugme directory of the project pack contains DebugMe.java,
a sneaky program which requires a
lot of command
line arguments to be passed into it to run to completion. The first
argument will always be your GMU netID (e.g. gmason76) which will
uniquely use the arguments for you in ways different from other
students.
DebugMe.java is divided into a series of phases with each
requiring different command line input to complete. Your task is to
use the debugger, reverse-engineer what is happening in each
phase-method, and determine what command-line arguments are
necessary in order to satisfy the phase. When missing or improper
inputs are detected in a phase, the program throws exceptions and
escapes back to attempt the next phase. You will earn points for
each phase that you successfully "defuse".
Honor Code for this Project
Honor code policies are in effect for this project as always,
but it bears considering how it relates to specific nature of the
tasks. Keep the following in mind as you work.
You are not allowed to collaborate on projects. They should
reflect your own efforts.
For the Problem 1: Testing, you may not share the test cases you
make with other students.
It is forbidden to discuss whether an implementation is buggy or
proper for the Testing problem.
You
can discuss syntax of what test cases look
like and high-level strategies for what to test (ex:
The docs
says the class is supposed to do this so I'm writing a test that
checks that case).
It is forbidden to directly discuss the "secret" to passing a
particular phase of the Problem 2: Debugging.
You
can discuss how to use the debugger in
public forums and strategies of where to set breakpoints to speed
debugging along
When in doubt, start a piazza post as private, and we can change
it to public after the fact as needed.
https://cs.gmu.edu/~marks/211/projects/p5.html (please download
all file from here)
p5pack/
|
+--ANSWERS.txt : Describe written answers to problems in this file
|
+--debugme/
| |
| +--DebugMe.java
|
+--testme/
|
+--docs/ (javadoc output for an implementation)
| |
| +--index.html
| +--...
|
+--PayrollTest.java (write more tests here)
|
+--junit-4.12.jar
|
+--imp1/
| |
| +--payroll
| |
| +--Dict.class
| |
| +--Payroll.class
|
+--imp2/
| |
| +--payroll
| |
| +--Dict.class
| |
| +--Payroll.class
|
+--remaining impN/ directories: same structure as imp1/ and imp2/ above
|
...
Test Mode Activated
The first task is to add many @Test-annotated methods to
PayrollTest.java and determine which of the many implementations
are bad, and which one is good. Then describe your results in
ANSWERS.txt.
The code we're testing out tries to calculate various
salary-related things based on employees and their (yearly)
salaries. The implementor got a bit carried away and made a very
generic Dict<K,V> class to track the (key,value) pairings
representing (employee-name, yearly-salary), as part of the
calculation.
We linked the Javadoc documentation to this part of the project
at the top of this specification. A copy is also included in
p5pack/testme/docs. You could locally open up the
p5pack/testme/docs/index.html file without being online.
We're only supplying the .class files for each implementation;
you don't get to look for the bugs directly, you have to just think
about what the purpose of the code is, and then write test cases
based on that purpose. (You're writing "black box" test cases).
Running Your Tests
Note that running one test file against many implementations can
be tedious if we're not smart about it. A typical (but bad) novice
approach is to make many copies of the file which will quickly get
out of sync as changes are made to one and the copies are not
updated.
Instead, utilize the ability of the compiler and runtime of java
to set a
class path on the command line to cause a search
for classes in the specified locations. Navigate to the testme/
directory and run commands like the following which runs tests on
implementation 1 only:
demo$ javac -cp .:imp1/:junit-4.12.jar *.java
demo$ java -cp .:imp1/:junit-4.12.jar PayrollTest
These commands tell Java that it should first compile all .java
files it finds when looking in the current directory (.), in the
imp1/ directory, and it should also look through the junit-4.12.jar
file while compiling; then, it again needs access to code in all
three of those locations, but it should run the main method of
PayrollTest.
If you want to run tests on a different implementation, just
change the imp1 to a different directory, as in
demo$ javac -cp .:imp2/:junit-4.12.jar *.java
demo$ java -cp .:imp2/:junit-4.12.jar PayrollTest
For this task, the command line is likely superior to most IDEs.
For instance, these commands will not work in DrJava. It's likely
that most IDEs will struggle with this task. Take this as an
opportunity to beef up your command line skills. It offers the
ultimate flexibility and the only price to unlock that is a little
practice (on the order of cut-pasting some ready-made
commands).
Scripts to run tests
To ease the task of testing on the command line, two scripts are
provided which will compile and run all implementations.
On Unix/Mac OS X use the unix-compile-test.sh
script in a terminal.
> cd testme
> unix-compile-test.sh
Results of testing all implementations are summarized by only
showing how many tests failed (or that it was OK!). If you need to
understand why a particualr implementation is behaving some way,
then don't use the script here, use the just-one-implementation
commands shown above!
On Windows use the windows-compile-test.cmd
script in the cmd.exe terminal.
> cd testme
> windows-compile-test.cmd
Results will be left in the results.txt text file due to the
lack of a good grep on the Windows platform.
Goals for the Testing Problem
Multiple implementations of the payroll package are provided.
One of these is correct while the remainder are crap. It is known
that implementations imp2, imp8, and imp11 are broken.
To complete this project, do the following:
Create enough tests that all implementations but one are failing
at least one test.
Write tests for both the Dict and Payroll classes. Problems may
exist in one, the other, or both.
Document your test cases to indicate what they are testing. Part
of your grade will be assigned based on the documentation of test
cases.
Submit your PayrollTest.java file which we will run against all
implementations.
Identify the general flaws in the behavior of
each of the known broken implementations. Describe these flaws in a
few sentences in the provided ANSWERS.txt file which will be
submitted with your code.
Demo of Dict
The Dict class provides a quite simple dictionary
implementation. Below is a demonstration of creating one and
calling some of its methods.
> import payroll.*;
> Dict<String,Integer> d = new Dict<String,Integer>();
> d.put("one",1);
> d
{(one:1)}
> d.size()
1
> d.put("two",2);
> d.put("three",3);
> d.size()
3
> d.get("one")
1
> d.get("350")
java.util.NoSuchElementException: "350" key not in dict.
at payroll.Dict.complainNoKey(Dict.java:147)
at payroll.Dict.get(Dict.java:70)
> d.pop("two")
2
> d.toString()
"{(one:1),(three:3)}"
> d.keys()
[one, three]
> d.clear()
> d
{}
>
Demo of Payroll
The Payroll class uses the Dict class in its implementation of
some salary-related calculations. Below is a demonstration of some
basic uses of Payroll.
> import payroll.*;
> Payroll p = new Payroll()
> p.hire("A",120);
> p.hire("A",120)
> p.hire("B",240)
> p.employees()
[A, B]
> p.topSalary()
240
> p.hire("C",1500)
> p.topSalary()
1500
> p.fire("C")
true
> p.employees()
[A, B]
> p.fire("C")
false
> p.giveRaise("A",0.5)
> p.getSalary("A")
180
> p.giveRaise(1.0) // everyone gets 100% raise!
> p.getSalary("A")
360
> p.getSalary("B")
480
> p.monthlyExpense() // for one month of twelve.
70
>
DebugMe!
A Programming Puzzle
The file debugme/DebugMe.java is provided in the code pack and
contains a puzzle. The main() method in this program accepts a
series of command line arguments that, when correctly specified,
will cause the program to run to completion. If the command line
arguments are not specified correctly, the program will fail
prematurely. The purpose of this problem is to determine the
correct inputs to cause the program to run to completion.
DebugMe is arranged in "stages" and passing stages earns points.
After each run the program prints the points earned based on the
stages "passed". Example:
> java DebugMe msnyde14 0 0 0
Let the games... BEGIN!
Phase One, let's have some fun!
Double debugger burger, order up!
oops! Game Over... >:(
* Score: 0/55 pts *
Notice that
the first argument is always your
NetID. Don't use msnyde14 unless you are Prof. Snyder.
DebugMe uses your NetID to create a unique set of conditions which
you must pass so that your experience with the program will likely
be different from other students.
This task is actually kinder to you - if you fail one phase, you
are able to continue to the next.
The stages in DebugMe are intentionally obscure. This is code
that is meant to be a puzzle rather than easily readable and to
that end,
you are strongly encouraged to use a
debugger while analyzing the program. Debuggers allow you
to stop execution at any point and examine variables, step forward
line by line, and ultimately identify which kinds of command line
arguments will make it through a stage and which will cause the
dreaded failure() method to be invoked ending the run. A primary
goal of this problem is to gain experience with debuggers as they
are incredibly useful tool for a programmer to have in their
utility belt. Credit for the problem is entirely based on how many
stages are passed.
Command Line Arguments
The only artifact of your efforts will be the specific
command-line invocation of the program, as your only inputs are
given as command-line arguments.
the first command-line argument must be your GMU
netID,
e.g. gmason76. Many of the phases will use this to randomize and
personalize the code for you - you've got your very own unique
project!
each phase (method) will read the next few arguments (however
many it needs), and use them in more and more quirky ways.
towards the end of each phase, there will be some check and a
guarded call to failure(). Your goal is to figure out what
command-line arguments will cause these failures to never
happen.
if you need to include spaces in a single argument,
please use double-quotes.
Running DebugMe through the Debugger
How can we use the debugger with command-line arguments? It's
surprisingly easy in DrJava:
Compile
DebugMe.java
Set a breakpoint in the phase you're working on
Turn on debugging mode under the debugging menu
In the Interactions Pane, run a command like this to launch
DebugMe with command line arguments.
> java DebugMe msnyde14 0 0 0
Let the games... BEGIN!
Phase One, let's have some fun!
oops! Game Over... >:(
error msg: Failure! Double debugger burger, order up!
* Score: 0/55 pts.
If you've turned on debugging, though, you get to step through
and see what's happening.
Most IDEs have a means of running a program through a debugger.
Learn about your tool if you are not using DrJava.
For the brave, there is also a command line debugger, command
jdb which should be installed with every JDK. This is somewhat less
convenient as it provides only limited source code display but can
work with some classic unix tools.
Regardless of how you access the debugger, you will want to
familiarize yourself with features such setting breakpoints to stop
the running program, stepping forward line by line, and displaying
the values of variables.
DebugMe is not a "real" program as it is intentionally obscure.
However, as an exercise to learn how to analyze running programs it
will provide invaluable experience. Happy bug squashing.
package pack5;
import java.util.*;
public class DebugMe {
public static void main(String[] args){
int argsNeeded = 29;
if (args.length<argsNeeded){
String[] temp = new
String[argsNeeded];
for (int i=0; i<argsNeeded;
i++){
if (i<args.length){
temp[i] = args[i]; }
else { temp[i] = "";
}
}
args = temp;
}
String userID = args[0];
int hash = Math.abs(userID.hashCode());
hash %= 20000;
int score = 0;
int[] points = {5,5,5,6,6,6,7,7,8};
int pi = 0;
int maxScore = 0; for (int p : points) {
maxScore += p; }
boolean lost = false;
try {
System.out.println("Let the games...
BEGIN!");
System.out.println("Phase One, let's
have some fun!");
phase1(hash, args,1);
score+=points[0];
}
catch (Exception e){
lost = true;
}
try {
if (!lost){
System.out.println("Good
for you, time for phase two!");
}
phase2(hash, args,4);
score+=points[1];
}
catch (Exception e){
lost = true;
}
try {
if (!lost){
System.out.println("O-M-G, here's phase three!");
}
phase3(hash, args,7);
score+=points[2];
}
catch (Exception e){
lost = true;
}
try {
if (!lost){
System.out.println("time
for more, here's phase four.");
}
phase4(hash, args,11);
score+=points[3];
}
catch (Exception e){
lost = true;
}
try {
if (!lost){
System.out.println("still alive? Here's phase five.");
}
phase5(hash, args,15);
score+=points[4];
}
catch (Exception e){
lost = true;
}
try {
if (!lost){
System.out.println("watch out, here comes a wall of bricks! It's
time for you to solve phase six.");
}
phase6(hash, args,17);
score+=points[5];
}
catch (Exception e){
lost = true;
}
try {
if (!lost){
System.out.println("next
it's phase eleven! oops, seven.");
}
phase7(hash, args,21);
score+=points[6];
}
catch (Exception e){
lost = true;
}
try {
if (!lost){
System.out.println("youre doing great - now try phase
eight!");
}
phase8(hash, args,24);
score+=points[7];
}
catch (Exception e){
lost = true;
}
try {
if (!lost){
System.out.println("finally, the finish line - I hope that you can
solve phase nine!");
}
phase9(hash, args,27);
score+=points[8];
}
catch (Exception e){
lost = true;
}
if (!lost){
System.out.println("Hey, neat - the
task's complete!");
}
else {
System.out.println("oops! Game
Over... >:( ");
}
System.out.printf("\n * Score: %s/%s pts
*\n",score,maxScore);
}
// 3 args
public static void phase1(int hash, String[] args, int
argStart){
int a =
Integer.parseInt(args[argStart+0]);
int b =
Integer.parseInt(args[argStart+1]);
int c =
Integer.parseInt(args[argStart+2]);
a += hash % 40;
if (a<b && b>c && a<c)
{ return; }
failure("Double debugger burger, order
up!");
}
// 3 args
public static void phase2(int hash, String[] args, int
argStart){
int a =
Integer.parseInt(args[argStart+0]);
int b =
Integer.parseInt(args[argStart+1]);
int c =
Integer.parseInt(args[argStart+2]);
a += hash%26;
int v = a+b;
v *= a;
v /= b;
v += 14;
if (c!=v){ failure("these are not the ints
you're searching for..."); }
}
// 4 args
public static void phase3(int hash, String[] args, int
argStart){
int a =
Integer.parseInt(args[argStart+0]);
int b =
Integer.parseInt(args[argStart+1]);
int c =
Integer.parseInt(args[argStart+2]);
int d =
Integer.parseInt(args[argStart+3]);
if (hash%13 > 4) {
c += hash%13;
}
else {
a *= hash%5 + 1;
}
int temp = 0;
do {
temp += a;
temp *= b;
} while (c --> 0);
if (temp != d) failure("count around, products
abound; what's that there - an arrow? uh-oh...");
}
// 4 args
public static void phase4(int hash, String[] args, int
argStart){
String s = args[argStart+0];
int a =
Integer.parseInt(args[argStart+1]);
int b =
Integer.parseInt(args[argStart+2]);
int c =
Integer.parseInt(args[argStart+3]);
String temp1 = s.substring(a,b);
String temp2 = s.substring(b,c);
int temp3 = 0;
while (temp3<temp1.length() &&
temp3<temp2.length()){
if (temp1.charAt(temp3) !=
temp2.charAt(temp3)){
break;
}
temp3++;
}
if (temp3!=6) failure("over here and over there,
I need a certain kind of pair...");
}
// helperfor phase 5.
public static String collatzString(int n){
String s = "[";
while (n!=1){
s += n+", ";
if (n%2==0){
n/=2;
}
else {
n = n*3+1;
}
}
s += "1]";
return s;
}
// 2 args
public static void phase5(int hash, String[] args, int
argStart){
int a =
Integer.parseInt(args[argStart+0]);
int b =
Integer.parseInt(args[argStart+1]);
String s = collatzString(a);
if (b != s.length()) {
failure("collecting strings and
lengths of things in one big batch; so what should match?");
}
}
// 4 args
public static void phase6(int hash, String[] args, int
argStart){
// TODO: remove
// use hash and % to look into a many-way
switch;
// each one calls another function with
different args.
// those args are used to loop around code with
some
// bizarre if-conditions that modify a target or
check
// the target, figuring out when to jump ship.
Some
// branches failure() out. Students need to
change one
// of their inputs to guarantee that an
escapable path
// is chosen (they should be able to guarantee
it as
// all those function-calls' args are variants
on their
// provided CLI args).
int a =
Integer.parseInt(args[argStart+0]);
int b =
Integer.parseInt(args[argStart+1]);
int c =
Integer.parseInt(args[argStart+2]);
int v = 0;
int temp = 6;
switch (a + hash%11){
case 1: v = helper3
(hash,a+12,b,temp++); break;
case 2: v = helper3
(hash,a*20,b-a,5); break;
case 3: v = helper3
(hash,a-310,a-b,5); break;
case 4: v = helper3
(hash,(int)Math.pow(a,2),b,5); break;
case 5: v = helper3
(hash,(int)Math.pow(2,a),b,5); break;
case 6: v = helper3
(hash,b,a,temp--); break;
case 7: v = helper3
(hash,a,b+a,temp*2); break;
case 8: v = helper3
(hash,a+temp,b-temp,temp%temp); break;
case 9: case 10: case 11:
v = helper3
(hash,a,b,temp+10); break;
default: v = -1;
}
if ( ! secretMessages[c].equals(args[v])) {
failure("wrong message!"); }
}
private static String[] secretMessages = {
"a closed mouth gathers no feet",
"a waist is a terrible thing to mind",
"out of my mind - back in five minutes",
"the harder I work, the luckier I become",
"with great power comes a big electricity
bill",
"time flies like an arrow; fruit flies like a
banana",
"five exclamation marks, the sure sign of an
insane mind",
"I do not like green eggs and ham, I do not like
them, Sam-I-am.",
"CS majors need to take ENGH302*N*, not just any
section of ENGH302",
"+++Divide By Cucumber Error. Please Reinstall
Universe And Reboot +++",
"there are 10 kinds of people in the world,
those who understand binary and those who don't"
};
public static int helper3(int hash, int x, int y, int z){
// TODO: remove.
// goal: return a number from 10 to 20.
for (int j=0; j<y; j++){
if (prime(j)){
z+=1;
}
}
if (z<10 || z>20){ failure("uh-oh!");
}
return z;
}
public static boolean prime(int n){
if (n<2) return false;
for (int i=2; i<n; i++){
if (n%i==0) { return false; }
}
return true;
}
/*
* TODO: remove.
* give them a recursive function, like fibonacci, and
they need an input that drives
* a match to another value (either another argument or
just something hardcoded based
* on their hash)
*
*/
public static int sumRange(int start, int stop){
if (start > stop) { return 0; }
return start + (sumRange(start+1, stop));
}
// 3 args
public static void phase7(int hash, String[] args, int
argStart){
int a =
Integer.parseInt(args[argStart+0]);
int b =
Integer.parseInt(args[argStart+1]);
int c =
Integer.parseInt(args[argStart+2]);
int d = sumRange(a,b);
if (c!=d) { failure("round and round and round
she goes, but where she stops, nobody knows!"); }
}
// With all this randomness, surely you want to step through with
the
// debugger, yes?
// 3 args
public static void phase8(int hash, String[] args, int argStart)
{
Random r = new Random(hash);
int a =
Integer.parseInt(args[argStart+0]);
int b =
Integer.parseInt(args[argStart+1]);
int c =
Integer.parseInt(args[argStart+2]);
int s = 0;
for (int i=0; i<a; i+= b){
if (r.nextInt(hash)%c==0){
s += 1;
}
}
if (s!=10) { failure("level one, as yet undone!
"+s); }
}
// Generating so much data, how can you find a reliable
answer?
// Remember, you can't change the source code for your
submitted
// solution...
// 2 args
public static void phase9(int hash, String[] args, int
argStart){
createWaldoPage(args,argStart);
}
private static String letters =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
// hmmm, what happens if this is true??? not that you can change
it
// for the final submission...
public static final boolean DEBUG = false;
public static void debug(Object msg){ if (DEBUG) {
System.out.print(""+msg); } }
public static void debugln(Object msg){ debug(msg+"\n"); }
public static String[] createWaldoPage(String[] args, int
argStart){
int hash = Math.abs(args[0].hashCode()) ;
debugln("hash = "+hash);
int n =
Integer.parseInt(args[argStart+0]);
int maxChanges =
Integer.parseInt(args[argStart+1]);
debug(String.format("n=%s,
maxChanges=%s\n",n,maxChanges));
String[] crowd = new String[n];
for (int i = 0; i<n; i++){
crowd[i] = mutate("waldo",
maxChanges, hash++);
}
checkWaldoPage(crowd);
return crowd;
}
public static void checkWaldoPage(String[] crowd){
ArrayList<Integer> indexes = new
ArrayList<Integer>();
for (int i=0; i<crowd.length; i++){
debugln("c[i] = "+crowd[i]);
if (crowd[i].equals("waldo")){
debugln(i);
indexes.add(i);
}
}
if (indexes.size()
< 1) DebugMe.failure("couldn't find waldo!");
else if (indexes.size() > 1)
DebugMe.failure("highlander rule: there can be only one (waldo)!
"+indexes.size());
}
public static String mutate(String s, int n, int seed){
debug(String.format("mutation(%s#): %s
(hash=%s)\n",n,s,seed));
Random r = new Random(seed);
for (int i=0; i<n; i++){
s = attemptChange(s, seed++);
}
debugln(" --> "+s);
return s;
}
public static String attemptChange(String s, int seed){
debug(String.format("\tattempt(seed=%d):
%s\n",seed,s));
Random r = new Random(seed);
int i = r.nextInt(s.length()+5);
switch(r.nextInt(3)){
case 0:
try{
debug(String.format("\t\t%s(%s)%s\n",s.substring(0,i),letters.charAt(i),s.substring(i)));
s =
String.format("%s%s%s",s.substring(0,i),letters.charAt(i),s.substring(i));
} catch
(StringIndexOutOfBoundsException e) { }
break;
case 1:
try{
debug(String.format("\t\t%s(%s/%s)%s\n",s.substring(0,i),letters.charAt(i),s.charAt(i),s.substring(i+1)));
s =
String.format("%s%s%s",s.substring(0,i),letters.charAt(i),s.substring(i+1));
} catch
(StringIndexOutOfBoundsException e) { }
break;
case 2:
try{
s =
s.substring(0,i)+s.substring(i+1);
} catch
(StringIndexOutOfBoundsException e) { }
break;
default:
debugln("\n\n\n\t --> DEFAULT!\n\n\n");
}
return s;
}
// any time the program has wandered into the wrong spot, we call
this
// to indicate the phase was not successfully passed.
public static void failure(String msg){
System.out.println("\n\t"+msg+"\n");
throw new RuntimeException("Failure!
"+msg);
}
}
Here is link of project
https://cs.gmu.edu/~marks/211/projects/p5.html