JAVA SCRIPT - Going Beyond the Math Object’s Capability

Going Beyond the Math Object’s Capability


Problem

The Math object provides good, basic mathematical functionality, but lacks advanced or business-specific math functionality that you need. In addition, Math does everything in floating point, and you need functions that work to a higher degree of precision.

Solution

Use a library that expands on the Math object’s capability. Examples of these libraries and their usage are covered in the discussion.

EXPLAIN 

Most of our math functionality is satisfied by the built-in Math object. However, there are instances where what it provides, or doesn’t provide, leaves gaps. That’s where a small but powerful set of Math libraries and/or modules comes in. I’ll cover some options in this section.

Math.js 


The Math.js library can be installed using npm or Bower, downloaded directly from its website, or accessed via content delivery network (CDN). It can be used in the browser, or in Node applications. It provides a set of functions to perform operations, such as add() and multiply(), that have the added advantage of being chainable:

var result = math.select(9)
 .add(3)
 .subtract(6)
 .multiply(23)
 .done(); // get value
console.log(result); //{ value: 138 }


It also provides functionality to parse a mathematical expression, with its own version of eval():

var exp = "4 + 3 * 10 / 8";
console.log(math.eval(exp)); // 7.75

In addition, it supports matrices. For example, to create a [3,3] matrix:

var m = math.matrix([[4,3,2],[6,6,8],[7,4,5]]);
console.log(m.valueOf()); //[ [ 4, 3, 2 ], [ 6, 6, 8 ], [ 7, 4, 5 ] ]

Note that the matrix arrays are contained within an outer array. Use the following to create a zero-filled matrix:

var z = math.zeros(2,2);
console.log(z.valueOf()); // [ [ 0, 0 ], [ 0, 0 ] ]

Most of the Math.js functions require the valueOf() or done() function to actually get the value of the operation, as noted in the code snippets. Math.js also provides support for BigNumbers, numbers that have arbitrary precision, as well as complex numbers, with both real and imaginary parts:

var b = math.complex('4 - 2i');
b.re = 5;
console.log(b.valueOf()); // 5 - 2i

Accounting

There are several libraries and modules for providing accounting capability, but argu‐ ably the most popular is Accounting.js, maintained by Open Exchange Rates (whose currency conversion API is introduced ). Like many other libraries, it can be downloaded from its main site, accessed via CDN, or installed using npm:

npm install accounting

You can use Accounting.js to format a number into a currency format:

var options = {
 symbol : "$",
 decimal : ".",
 thousand: ",",
 precision : 2,
 format: "%s%v"
};
// Example usage:
var m = accounting.formatMoney(45998307);
console.log(m);// $45,998,307.00


You can also format entire columns of numbers:


var list = [[456, 12, 3], [99, 23,3],[667,902,12]];
var c = accounting.formatColumn(list);
console.log(c);[ [ '$456.00', '$ 12.00', '$ 3.00' ],
 [ '$99.00', '$23.00', '$ 3.00' ],
 [ '$667.00', '$902.00', '$ 12.00' ] ]


The formatting isn’t all U.S. dollar–based either:


var p = accounting.formatMoney(4899.49, "€", 2, ".", ",");
console.log(p); // €4.899,49


The Accounting.js functionality isn’t extensive, but what it does, it does well.
Advanced Mathematics and Statistics-A popular advanced math module in Node is Numbers, installed as:


npm install numbers

You can also download or install it on the client using Bower. The library provides advanced calculus functions, matrix math, and even some statistics. From the documentation:

numbers.statistic.mean(array);
numbers.statistic.median(array);
numbers.statistic.mode(array);
numbers.statistic.standardDev(array);
numbers.statistic.randomSample(lower, upper, n);
numbers.statistic.correlation(array1, array2);

I’ll leave it for the more mathematically inclined to explore all the functionality.

JAVA SCRIPT - Testing for Features with Modernizr.load

Testing for Features with Modernizr load


Problem

You’re using newer technologies, and you want to make sure the client can support the technologies before you load them.

Solution

You can use a library such as Modernizr to handle basic HTML5/CSS differences be‐ tween browsers. But you can also use a companion tool, Modernizr.load, to test to see if an existing technology is supported

As an example, if you want to incorporate touch events in your application, you can use Modernizr to test whether they’re supported in an environment and only load the ap‐ plication script if they are. In the following code, the application is testing to see if the touch events, covered in Chapter 18, are supported. If they are, the application script is loaded:


Modernizr.load({
 test: Modernizr.touch,
 yep : 'touchtest.js'
});


EXPLAIN


Modern browser makers are highly competitive, which means that most of the modern technologies we want to use are already part of the browser your user is most likely using. Unfortunately, we can’t take it as given that every user is using the most modern browser, and that’s where a concept like feature detection enters. 

Years ago, when testing for browser differences, we’d check browser versions because browser companies didn’t release new versions all that often. The idea of doing this nowadays, when some of the companies seemingly release a new version every week, is ludicrous. 

Feature detection is a way of guaranteeing that the environment will support your application, regardless of browser version or client. Feature detection can be tedious, though, and tricky. That’s where a feature detection tool like Modernizr.load comes in. It comes with a set of feature detection tests already built in, as demonstrated in the solution. 

And you can use Modernizer.load plugins to check for others, or even create your own. To use Modernizr.load, go to the Modernizr site, check the features you want to test and/or support, and the site builds a custom library. To use the library, include the script in the page (in the head element, preferably after your style elements), and then include the links to your test scripts.


 You can also use the software to load a polyfill library to manage differences:


Modernizr.load({
 test: Modernizr.websockets,
 nope : 'websockets.js'
});

You can list multiple JavaScript files, separated by commas, for both the yep and nope properties.

Java Rounding Floating-Point Numbers

Java Rounding Floating-Point Numbers

Problem

You need to round floating-point numbers to integers or to a particular precision.

Solution

If you simply cast a floating value to an integer value, Java truncates the value. A
value like 3.999999 cast to an int or long becomes 3, not 4. To round floating-point
numbers properly, use Math.round( ) . It has two forms: if you give it a double , you get
a long result; if you give it a float , you get an int .

What if you don’t like the rounding rules used by round ? If for some bizarre reason
you wanted to round numbers greater than 0.54 instead of the normal 0.5, you could
write your own version of round( ) :

/*
* Round floating values to integers.
* @Return the closest int to the argument.
* @param d A non-negative values to be rounded.
*/
static int round(double d) {
if (d < 0) {
throw new IllegalArgumentException("Value must be non-negative");
}
int di = (int)Math.floor(d);
// integral value below (or ==) d
if ((d - di) > THRESHOLD) {
return di + 1;
} else {
return di;
}
}

If you need to display a number with less precision than it normally gets, you proba- bly want to use a DecimalFormat object or a Formatter object.

JAVA SCRIPT - Finding the Perfect Library

 Finding the Perfect Library


Problem

You need functionality in your application, and you’re pretty sure someone somewhere must have already created it. So, other than using a search engine, how can you find good modules, libraries, and tools?

Solution

Look for resource sites that not only provide a listing of libraries, modules, and tools, but also provide information about their use, their popularity, and how active the sup‐ port is for them.

EXPLAIN

First of all, don’t knock search engines for finding good JavaScript source. By using Google’s Search tools and restricting results to the past year, I can easily find recent and up-to-date code, as well as interesting newcomers that haven’t yet achieved a high level of popularity. 

Still, you’re also just as likely to run into pages of Stack Overflow results rather than a library when searching for JavaScript functionality, so another option when looking for a new library is to search popular script resources sites.

 GitHub is a good resource for JavaScript libraries, modules, and tools, and you’ll also be able to see at a glance if the code is being maintained and how popular it is. You can search for specific functionality, or you can use the GitHub Explore page to find new and interesting 

GitHub projects by category. I especially recommend the Data Visual‐ ization category. Micro.js is a site featuring a small set of what it calls micro-frameworks. These are smaller, more purposed JavaScript libraries, all displayed in a fun little site. JSDB.io calls itself “the definitive source of the best JavaScript libraries, frameworks, and plugins,” and it is an excellent resource. 

Again, just search for the general type of functionality you need, such as canvas chart, and then peruse the results. The results even give you an approval percentage, and the returned page also provides information such as GitHub watchers, average time between commits, average forks, and average number of contributors. 

Java Comparing Floating-Point Numbers

Java Comparing Floating-Point Numbers

Problem

You want to compare two floating-point numbers for equality.

Solution

Based on what we’ve just discussed, you probably won’t just go comparing two
floats or doubles for equality. You might expect the floating-point wrapper classes,

Float and Double , to override the equals( ) method, which they do. The equals( )
method returns true if the two values are the same bit for bit, that is, if and only if
the numbers are the same or are both NaN . It returns false otherwise, including if the
argument passed in is null, or if one object is +0.0 and the other is –0.0.

If this sounds weird, remember that the complexity comes partly from the nature of
doing real number computations in the less-precise floating-point hardware, and
partly from the details of the IEEE Standard 754, which specifies the floating-point
functionality that Java tries to adhere to, so that underlying floating-point processor
hardware can be used even when Java programs are being interpreted.

To actually compare floating-point numbers for equality, it is generally desirable to
compare them within some tiny range of allowable differences; this range is often
regarded as a tolerance or as epsilon. Example shows an equals( ) method you
can use to do this comparison, as well as comparisons on values of NaN . When run, it
prints that the first two numbers are equal within epsilon:

$ java FloatCmp
True within epsilon 1.0E-7
$

Example. FloatCmp.java
}/**
* Floating-point comparisons.
*/
public class FloatCmp {
final static double EPSILON = 0.0000001;
public static void main(String[] argv) {
double da = 3 * .3333333333;
double db = 0.99999992857;
// Compare two numbers that are expected to be close.
if (da == db) {
System.out.println("Java considers " + da + "==" + db);
// else compare with our own equals method
} else if (equals(da, db, 0.0000001)) {
System.out.println("True within epsilon " + EPSILON);
} else {
System.out.println(da + " != " + db);
}
// Show that comparing two NaNs is not a good idea:
double d1 = Double.NaN;
double d2 = Double.NaN;
if (d1 == d2)
System.err.println("Comparing two NaNs incorrectly returns true.");
if (!new Double(d1).equals(new Double(d2)))
System.err.println("Double(NaN).equal(NaN) incorrectly returns false.");
}

/** Compare two doubles within a given epsilon */
public static boolean equals(double a, double b, double eps) {
if (a==b) return true;
// If the difference is less than epsilon, treat as equal.
return Math.abs(a - b) < eps;
}
/** Compare two doubles, using default epsilon */
public static boolean equals(double a, double b) {
if (a==b) return true;
// If the difference is less than epsilon, treat as equal.
return Math.abs(a - b) < EPSILON * Math.max(Math.abs(a), Math.abs(b));
}
}

Note that neither of the System.err messages about “incorrect returns” prints. The point of this example with NaN s is that you should always make sure values are not NaN before entrusting them to Double.equals( ).

JAVA SCRIPT - Creating an Accessible Automatically Updated Region

Creating an Accessible Automatically Updated Region


Problem

You have a section of a web page that is updated periodically, such as a section that lists recent updates to a file, or one that reflects recent Twitter activity on a subject. You want to ensure that when the page updates, those using a screen reader are notified of the new information.

Solution 

Use WAI-ARIA region attributes on the element being updated:

<ul aria-alive="polite" aria-atomic="true" aria-relevant="additions" id="update" role="log">
</ul>

EXPLAIN

A section of the web page that can be updated after the page is loaded, and without direct user intervention, calls for WAI-ARIA Live Regions. These are probably the sim‐ plest ARIA functionality to implement, and they provide immediate, positive results. And there’s no code involved, other than the JavaScript you need to create the page updates.

updates the web page based on the contents of a text file on the server that the application retrieves using Ajax. I modified the code that polls for the updates to check how many items have been added to the unordered list after the update. If the number is over 10, the oldest is removed from the page: 


// process return
function processResponse() {
 if(xmlhttp.readyState == 4 &amp;&amp; xmlhttp.status == 200) {
 var li = document.createElement("li");
 var txt = document.createTextNode(xmlhttp.responseText);
 li.appendChild(txt);
 var ul = document.getElementById("update");
 ul.appendChild(li);
 // prune top of list
 if (ul.childNodes.length &gt; 10) {
 ul.removeChild(ul.firstChild);
 }
 } else if (xmlhttp.readyState == 4 &amp;&amp; xmlhttp.status != 200) {
 console.log(xmlhttp.responseText);
 }
}


With this change, the list doesn’t grow overly long. I made one more change, adding the ARIA roles and states to the unordered list that serves as the updatable live region:

<ul aria-atomic="false" aria-live="polite" aria-relevant="additions s" id="update" role="log">
</ul>

From left to right: the role is set to log, because I’m polling for log updates from a file, and only displaying the last 10 or so items. Other options include status, for a status update, and a more general region value, for an undetermined purpose. The aria-live region attribute is set to polite, because the update isn’t a critical update.

The polite setting tells the screen reader to voice the update, but not interrupt a current task to do so. If I had used a value of assertive, the screen reader would interrupt whatever it is doing and voice the content. Always use polite, unless the information is critical. The aria-atomic is set to false, so that the screen reader only voices new additions, based on whatever is set with aria-relevant.

It could get very annoying to have the screen reader voice the entire set with each new addition, as would happen if this value is set to true. Lastly, the aria-relevant is set to additions, as we don’t care about the entries being removed from the top. This setting is actually the default setting for this attribute, so, technically, it isn’t needed. In addition,

AT devices don’t have to support this attribute. Still, I’d rather list it than not. Other values are removals, text, and all (for all events). You can specify more than one, separated by a space. This WAI-ARIA–enabled functionality was probably the one that impressed me the most.

One of my first uses for Ajax, years ago, was to update a web page with information. It was frustrating to test the page with a screen reader (JAWS, at the time) and hear nothing but silence every time the page was updated. I can’t even imagine how frus‐ trating it was for those who needed the functionality. Now we have it, and it’s so easy to use. It’s a win-win.


Java Ensuring the Accuracy of Floating-Point Numbers

Java Ensuring the Accuracy of Floating-Point
Numbers

Problem

You want to know if a floating-point computation generated a sensible result.

Solution

Compare with the INFINITY constants, and use isNaN( ) to check for “not a number.”
Fixed-point operations that can do things like divide by zero result in Java notifying
you abruptly by throwing an exception. This is because integer division by zero is
considered a logic error.

Floating-point operations, however, do not throw an exception because they are
defined over an (almost) infinite range of values. Instead, they signal errors by pro-
ducing the constant POSITIVE_INFINITY if you divide a positive floating-point num-
ber by zero, the constant NEGATIVE_INFINITY if you divide a negative floating-point
value by zero, and NaN (Not a Number), if you otherwise generate an invalid result.
Values for these three public constants are defined in both the Float and the Double wrapper classes.

The value NaN has the unusual property that it is not equal to itself,
that is, NaN != NaN . Thus, it would hardly make sense to compare a (possibly sus-
pect) number against NaN , because the expression:

x == NaN

can never be true. Instead, the methods Float.isNaN(float) and Double. isNaN(double) must be used:

// InfNaN.java
public static void main(String argv[]) {
double d = 123;
double e = 0;
if (d/e == Double.POSITIVE_INFINITY)
System.out.println("Check for POSITIVE_INFINITY works");
double s = Math.sqrt(-1);
if (s == Double.NaN)
System.out.println("Comparison with NaN incorrectly returns true");
if (Double.isNaN(s))
System.out.println("Double.isNaN( ) correctly returns true");
}

Note that this, by itself, is not sufficient to ensure that floating-point calculations have been done with adequate accuracy. For example, the following program dem- onstrates a contrived calculation—Heron’s formula for the area of a triangle—both in float and in double . The double values are correct, but the floating-point value comes out as zero due to rounding errors. This happens because, in Java, operations involving only float values are performed as 32-bit calculations. Related languages such as C automatically promote these to double during the computation, which can eliminate some loss of accuracy.

/** Compute the area of a triangle using Heron's Formula.
* Code and values from Prof W. Kahan and Joseph D. Darcy.
* See http://www.cs.berkeley.edu/~wkahan/JAVAhurt.pdf.
* Derived from listing in Rick Grehan's Java Pro article (October 1999).
* Simplified and reformatted by Ian Darwin.
*/
public class Heron {
public static void main(String[] args) {
// Sides for triangle in float
float af, bf, cf;
float sf, areaf;
// Ditto in double
double ad, bd, cd;
double sd, aread;
af
bf
cf
//Area of triangle in float
= 12345679.0f;
= 12345678.0f;
= 1.01233995f;
sf = (af+bf+cf)/2.0f;
areaf = (float)Math.sqrt(sf * (sf - af) * (sf - bf) * (sf - cf));
System.out.println("Single precision: " + areaf);
//
ad
bd
cd
Area of triangle in double
= 12345679.0;
= 12345678.0;
= 1.01233995;
sd = (ad+bd+cd)/2.0d;
aread =
Math.sqrt(sd * (sd - ad) * (sd - bd) * (sd - cd));
System.out.println("Double precision: " + aread);
}
}

Let’s run it. To ensure that the rounding is not an implementation artifact, I’ll try it both with Sun’s JDK and with Kaffe:

$ java Heron
Single precision:
Double precision:
$ kaffe Heron
Single precision:
Double precision:
0.0
972730.0557076167
0.0
972730.05570761673

If in doubt, use double ! To ensure consistency of very large magnitude double computations on different Java implementations, Java provides the keyword strictfp , which can apply to classes, interfaces, or methods within a class. * If a computation is Strict-FP, then it must always, for example, return the value INFINITY if a calculation would overflow the value of Double.MAX_VALUE (or underflow the value Double.MIN_VALUE ). Non-Strict- FP calculations—the default—are allowed to perform calculations on a greater range and can return a valid final result that is in range even if the interim product was out of range. This is pretty esoteric and affects only computations that approach the bounds of what fits into a double.

JAVA SCRIPT - Highlighting Errors Accessibly

 Highlighting Errors Accessibly


Problem

You want to highlight form field entries that have incorrect data, and you want to ensure the highlighting is effective for all web page users.

Solution

Use CSS to highlight the incorrectly entered form field, and use WAI-ARIA (Accessible Rich Internet Applications) markup to ensure the highlighting is apparent to all users:


[aria-invalid] {
 background-color: #ffeeee;
}

For the fields that need to be validated, assign a function to the form field’s onchange event handler that checks whether the field value is valid. If the value is invalid, pop up an alert with information about the error at the same time that you highlight the field:

document.getElementById("elemid").onchange=validateField;
...
function validateField() {
 // check for number
 if (isNaN(this.value)) {
 this.setAttribute("aria-invalid, "true");
 generateAlert("You entered an invalid value for A. Only numeric values
 such as 105 or 3.54 are allowed");
 }
}

For the fields that need a required value, assign a function to the field’s onblur event handler that checks whether a value has been entered:

document.getElementById("field").onblur=checkMandator;
...
function checkMandatory() {
 // check for data
 if (this.value.length == 0) {
 this.setAttribute("aria-invalid", "true");
 generateAlert("A value is required in this field");
 }
}

If any of the validation checks are performed as part of the form submission, make sure to cancel the submission event if the validation fails.

EXPLAIN

The WAI-ARIA (Accessible Rich Internet Applications) provides a way of marking cer‐ tain fields and behaviors in such a way that assistive devices do whatever is the equivalent behavior for people who need these devices. 

If a person is using a screen reader, setting the aria-attribute attribute to true (or adding it to the element) should trigger a visual warning in the screen reader—comparable to a color indicator doing the same for people who aren’t using assistive technologies. 

In addition, the role attribute can be set to several values of which one, “alert”, triggers a comparable behavior in screen readers (typically saying out the field contents). Providing these cues are essential when you’re validating form elements. 

You can vali‐ date a form before submission and provide a text description of everything that’s wrong. A better approach, though, is to validate data for each field as the user finishes, so they’re not left with a lot of irritating error messages at the end. 

As you validate the field, you can ensure your users know exactly which field has failed by using a visual indicator. They shouldn’t be the only method used to mark an error, but they are an extra courtesy. If you highlight an incorrect form field entry with colors, avoid those that are hard to differentiate from the background. 

If the form background is white, and you use a dark yellow, gray, red, blue, green, or other color, there’s enough contrast that it doesn’t matter if the person viewing the page is color blind or not. In the example, I used a darker pink in the form field. I could have set the color directly, but it makes more sense to handle both updates— setting aria-invalid and changing the color—with one CSS setting. 

Luckily, CSS at‐ tribute selectors simplify our task in this regard. In addition to using color, you also need to provide a text description of the error, so there’s no question in the user’s mind about what the problem is. How you display the information is also an important consideration. None of us really like to use alert boxes, if we can avoid them. 

Alert boxes can obscure the form, and the only way to access the form element is to dismiss the alert with its error message. A better approach is to embed the information in the page, near the form. We also want to ensure the error message is available to people who are using assistive technologies,

such as a screen reader. This is easily accomplished by assigning an ARIA alert role to the element containing the alert for those using screen readers or other AT devices. One final bonus to using aria-invalid is it can be used to discover all incorrect fields when the form is submitted. Just search on all elements where the attribute is present and if any are discovered, you know there’s still an invalid form field value that needs correcting. 

Demonstrates how to highlight an invalid entry on one of the form ele‐ ments, and highlight missing data in another. The example also traps the form submit, and checks whether there are any invalid form field flags still set. Only if everything is clear is the form submission allowed to proceed.

Providing visual and other cues when validating form fields 


<head>
<title>Validating Forms</title>
<style>
[aria-invalid] {
 background-color: #ffeeee;
}
[role="alert"]
{
 background-color: #ffcccc;
 font-weight: bold;
 padding: 5px;
 border: 1px dashed #000;
}
div
{
 margin: 10px 0;
 padding: 5px;
 width: 400px;
 background-color: #ffffff;
}
</style>
</head>
<body>
<form id="testform">
 <div>
<label for="firstfield">*First Field:</label>

 <input aria-required="true" id="firstfield" name="firstfield" required="" type="text" />
 </div>
<div>
<label for="secondfield">Second Field:</label>

 <input id="secondfield" name="secondfield" type="text" />
 </div>
<div>
<label for="thirdfield">Third Field (numeric):</label>

<input id="thirdfield" name="thirdfield" type="text" />
 </div>
<div>
<label for="fourthfield">Fourth Field:</label>

 <input id="fourthfield" name="fourthfield" type="text" />
 </div>
<input type="submit" value="Send Data" />
</form>
<script>
 document.getElementById("thirdfield").onchange=validateField;
 document.getElementById("firstfield").onblur=mandatoryField;
 document.getElementById("testform").onsubmit=finalCheck;
 function removeAlert() {
 var msg = document.getElementById("msg");
 if (msg) {
 document.body.removeChild(msg);
 }
 }
 function resetField(elem) {
 elem.parentNode.setAttribute("style","background-color: #ffffff");
 var valid = elem.getAttribute("aria-invalid");
 if (valid) elem.removeAttribute("aria-invalid");
 }
 function badField(elem) {
 elem.parentNode.setAttribute("style", "background-color: #ffeeee");
 elem.setAttribute("aria-invalid","true");
 }
 function generateAlert(txt) {
 // create new text and div elements and set
 // Aria and class values and id
 var txtNd = document.createTextNode(txt);
 msg = document.createElement("div");
 msg.setAttribute("role","alert");
 msg.setAttribute("id","msg");
 msg.setAttribute("class","alert");
 // append text to div, div to document
 msg.appendChild(txtNd);
 document.body.appendChild(msg);
 }
 function validateField() {
 // remove any existing alert regardless of value
removeAlert();
 // check for number
 if (!isNaN(this.value)) {
 resetField(this);
 } else {
 badField(this);
 generateAlert("You entered an invalid value in Third Field. " +
 "Only numeric values such as 105 or 3.54 are allowed");
 }
 }
 function mandatoryField() {
 // remove any existing alert
 removeAlert();
 // check for value
 if (this.value.length > 0) {
 resetField(this);
 } else {
 badField(this);
 generateAlert("You must enter a value into First Field");
 }
 }
 function finalCheck() {
 removeAlert();
 var fields = document.querySelectorAll("[aria-invalid='true']");
 if (fields.length > 0) {
 generateAlert("You have incorrect fields entries that must be fixed " +
 "before you can submit this form");
 return false;
 }
 }
</script>
</body>

If either of the validated fields is incorrect in the application, the aria-invalid attribute is set to true in the field, and an ARIA role is set to alert on the error message, as shown in Figure 6-8. When the error is corrected, the aria-invalid attribute is re‐ moved, as is the alert message. Both have the effect of changing the background color for the form field.

Notice in the code that the element wrapping the targeted form field is set to its correct state when the data entered is correct, so that when a field is corrected it doesn’t show up as inaccurate or missing on the next go-round.

I remove the existing message alert regardless of the previous event, as it’s no longer valid with the new event. When the form is submitted, the application uses the querySelectorAll() method call to check for all instances of aria-invalid set to true, and rejects the submission until these are corrected.


var badFields = document.querySelectorAll("[aria-invalid='true']");

You can also disable or even hide the correctly entered form elements, as a way to accentuate those with incorrect or missing data. However, I don’t recommend this ap‐ proach. Your users may find as they fill in the missing information that their answers in other fields are incorrect. If you make it difficult for them to correct the fields, they’re not going to be happy with the experience—or the company, person, or organization providing the form.

Another approach you can take is to only do validation when the form is submitted. Many built-in libraries operate this way. Rather than check each field for mandatory or correct values as your users tab through, you only apply the validation rules when the form is submitted. This allows users who want to fill out the form in a different order to do so without getting irritating validation messages as they tab through.

This ap‐ proach is a friendlier technique for those people using a keyboard, rather than a mouse, to tab through the form. Or you can use a mix of both: field-level validation for correct data type and format, form-level validation for required values. Using JavaScript to highlight a form field with incorrect and missing data is only one part of the form submission process.

You’ll also have to account for JavaScript being turned off, which means you have to provide the same level of feedback when processing the form information on the server, and providing the result on a separate page. It’s also important to mark if a form field is required ahead of time.

Use an asterisk in the form field label, with a note that all form fields with an asterisk are required. Use the aria-required attribute to ensure this information is communicated to those using assistive devices. I also recommend using the HTML5 required attribute when using aria-required.


Java Taking a Fraction of an Integer Without Using Floating Point

Java Taking a Fraction of an Integer Without
Using Floating Point

Problem

You want to multiply an integer by a fraction without converting the fraction to a
floating-point number.

Solution

Multiply the integer by the numerator and divide by the denominator.
This technique should be used only when efficiency is more important than clarity,
as it tends to detract from the readability—and therefore the maintainability—of
your code.

Explained

Since integers and floating-point numbers are stored differently, it may sometimes be
desirable and feasible, for efficiency purposes, to multiply an integer by a fractional
value without converting the values to floating point and back, and without requiring a “cast”:

/** Compute the value of 2/3 of 5 */
public class FractMult {
public static void main(String u[]) {
double d1 = 0.666 * 5;
// fast but obscure and inaccurate: convert
System.out.println(d1); // 2/3 to 0.666 in programmer's head
double d2 = 2/3 * 5;
// wrong answer - 2/3 == 0, 0*5 = 0
System.out.println(d2);
double d3 = 2d/3d * 5;
System.out.println(d3);
double d4 = (2*5)/3d;
System.out.println(d4);
int i5 = 2*5/3;
System.out.println(i5);
// "normal"
// one step done as integers, almost same answer
// fast, approximate integer answer
}
}

Running it looks like this:
$ java FractMult
3.33
0.0
3.333333333333333
3.3333333333333335
3
$

Java Converting Numbers to Objects and Vice Versa

Java Converting Numbers to Objects
and Vice Versa

Problem

You need to convert numbers to objects and objects to numbers.

Solution

Use the Object Wrapper classes listed in Table at the beginning.

Explained

Often you have a primitive number and you need to pass it into a method where an
Object is required. This frequently happens when using the Collection classes and earlier.

To convert between an int and an Integer object, or vice versa, you can use the
following:

// IntObject.java
// int to Integer
Integer i1 = new Integer(42);
System.out.println(i1.toString( )); // or just i1
// Integer to int
int i2 = i1.intValue( );
System.out.println(i2);

JAVA SCRIPT - Performance Testing Different Coding Techniques

Performance Testing Different Coding Techniques



Problem

In JavaScript there are, typically, multiple ways you can code a solution. The problem then becomes determining which of the different ways performs best across different environments.

Solution

One approach is to use a performance testing tool, such as jsPerf, to try out the different approaches and then proceed accordingly. For instance. I wanted to determine which had better performance—using an anonymous function or a named function—when passed as a callback function in an Array method. In jsPerf, I set up an array of string elements and created the named function, rpl(), in the Preparation code section:


var charSet = ["**","bb","cd","**","cc","**","dd","**"];
function rpl (element) {
 return (element !== "**");
};

My first test case was using the anonymous function:

var newArray = charSet.filter(function(element) {
 return (element !== "**");
});

My second test case was using the named function:

var newArray = charSet.filter(rpl);

EXPLAIN

There are variations of performance testing, from the simple alternative testing demon‐ strated in the solution, to complex, involved load testing of entire systems. These types of testing aren’t used to discover whether there are bugs in the code, or if the code meets use requirements—unit testing should find the former, and some form of user compli‐ ance testing finds the latter. Performance testing is specifically for finding the best, most efficient approach to cre‐ ating your application, and then making sure it meets the demands placed on it when running at peak usage.  

Another approach to performance testing is profiling. Most browser debuggers have a built-in profiling capability. As an example, the popular Firebug debugger for Firefox has profiling built in and available with the click of the “Profile” button, 

Once you turn profiling on, you can run your user compliance tests as a way of generating good usage statistics, and then click the “Profile” button again. Firebug then generates a listing of functions called any time for them to respond.

Chrome also has extensive profiling capability, . To use it, open up the JavaScript Console, click the Profiles tab, and then start whichever profiling type you want to start. After you’ve used your application for some time, click the Profiles “Stop” button and view the results.


Java Storing a Larger Number in a Smaller Number

Java Storing a Larger Number
in a Smaller Number

Problem

You have a number of a larger type and you want to store it in a variable of a smaller
type.

Solution

Cast the number to the smaller type. (A cast is a type listed in parentheses before a
value that causes the value to be treated as though it were of the listed type.)
For example, to cast a long to an int , you need a cast. To cast a double to a float ,
you also need a cast.

Explained

This causes newcomers some grief, as the default type for a number with a decimal
point is double , not float . So code like:

float f = 3.0;

won’t even compile! It’s as if you had written:

double tmp = 3.0;
float f = tmp;

You can fix it by making f a double , by making the 3.0 a float , by putting in a cast, or by assigning an integer value of 3:

double f = 3.0;
float f = 3.0f;
float f = 3f;
float f = (float)3.0;
float f = 3;

The same applies when storing an int into a short , char , or byte :

// CastNeeded.java
public static void main(String argv[]) {
int i;
double j = 2.75;
i = j;
// EXPECT COMPILE ERROR
i = (int)j;
// with cast; i gets 2
System.out.println("i =" + i);
byte b;
b = i;
// EXPECT COMPILE ERROR
b = (byte)i;
// with cast, i gets 2
System.out.println("b =" + b);
}

The lines marked EXPECT COMPILE ERROR do not compile unless either com- mented out or changed to be correct. The lines marked “with cast” show the correct forms.

JAVA SCRIPT - Testing Your Application in Various Environments

Testing Your Application in Various Environments


Problem

You have a set of environments (operating system and browser) you need to support, but you don’t have enough machines to test your application or library in each environment.

Solution

Use an emulating tool or browser testing service that can test your application in all of your environments. These aids help you not only test the integrity of the code, but the appearance and behavior of your user interface.

EXPLAIN

In-house testing works if your customer uses a finite set of machines and you can easily re-create the environments, or you work for a large enough corporation that can afford to set up one of everything. For most other situations, you either need to use some form of emulation tool or a service. 

This is especially critical when you’re testing client-side JavaScript. Web or mobile de‐ velopment environments are undergoing rapid change, and a technology you think is safe to use may end up blowing up in your face when you test the functionality in environments other than the ones you use for development. Emulators are a favorite for mobile developers. 

Some are specific to a browser, such as Ripple for Chrome. Others are standalone tools like Opera Mobile Classic Emulator, shown in or the Android Emulator (part of the Android SDK). 

A variation for testing mobile applications is a simulator, which simulates some of the environment but doesn’t fully emulate it at the hardware level. An example of a simulator is Apple’s iOS Simulator.

If you’re more interested in testing how the client interface works in different browsers and different environments, then you’ll want to look for a cross-browser testing service (BrowserStack or Sauce Labs), or an application like Ghostlab .

You might also consider automated testing services, where you create a script that’s automatically run (Selenium is an example). The key is to look for a service or tool that provides interactive testing—not one that is primarily used to check out the design of the page in different environments. 

One advantage to some of these tools is they provide testing in both browser and mobile environments. The disadvantage is cost: either a one-time cost for an application, or a monthly or annual fee for a service. The only tool that didn’t have a price tag attached is IE NetRenderer, which allows you to test your website in every variation of IE, from versions.

One of the services I have used is BrowserStack. It, like most of the other tools and services, provides a trial period for testing the service. In addition, it also works with testing environments, such as QUnit, demonstrated earlier in the chapter. 

BrowserStack offers a variety of services, including screenshots of your site across sev‐ eral devices—desktop or mobile. From a client-side JavaScript developer’s perspective, the service we’re most interested in is the Live testing, where we can pick an OS and a browser and test our client application, directly.  demonstrates running an application in Safari on OS X—an environment I don’t have access to.

BrowserStack also provides automated cloud-testing of JavaScript applications. The testing is free for open source software, and available for a fee for commercial and nonopen source testing. You can incorporate automated testing with various tools, such as Yeti and TestSwarm. However, it’s primarily focused on testing Node.js applications.

Java Checking Whether a String Is a Valid Number

Java Checking Whether a String
Is a Valid Number


Problem

You need to check whether a given string contains a valid number, and, if so, con-
vert it to binary (internal) form.

Solution

Use the appropriate wrapper class’s conversion routine and catch the
NumberFormatException . This code converts a string to a double :


// StringToDouble.java
public static void main(String argv[]) {
String aNumber = argv[0];
// not argv[1]
double result;
try {
result = Double.parseDouble(aNumber);
} catch(NumberFormatException exc) {
System.out.println("Invalid number " + aNumber);
return;
}
System.out.println("Number is " + result);
}

Explained Of course, that lets you validate only numbers in the format that the designers of the wrapper classes expected. If you need to accept a different definition of numbers, you could use regular expressions to make the determination. There may also be times when you want to tell if a given number is an integer num- ber or a floating-point number. One way is to check for the characters . , d , e , or f in the input; if one of these characters is present, convert the number as a double . Otherwise, convert it as an int :

// Part of GetNumber.java
private static Number NAN = new Double(Double.NaN);
/* Process one String, returning it as a Number subclass
*/
public Number process(String s) {
if (s.matches(".*[.dDeEfF]")) {
try {
double dValue = Double.parseDouble(s);
System.out.println("It's a double: " + dValue);
return new Double(dValue);
} catch (NumberFormatException e) {
System.out.println("Invalid a double: " + s);
return NAN;
}
} else // did not contain . d e or f, so try as int.
try {
int iValue = Integer.parseInt(s);
System.out.println("It's an int: " + iValue);
return new Integer(iValue);
} catch (NumberFormatException e2) {
System.out.println("Not a number:" + s);
return NAN;
}
}

See Also 

A more involved form of parsing is offered by the DecimalFormat class. JDK 1.5 also features the Scanner class.

JAVA SCRIPT - Unit Testing Your Code with QUnit

Unit Testing Your Code with QUnit


Problem

You want to ensure the robustness of your application or library. A part of this is per‐ forming unit testing, but you don’t want to create the tests manually

Solution

Use a tool such as QUnit to incorporate unit testing into your application at the earliest possible stage. For instance, we’re interested in testing a new function, addAndRound():

function addAndRound(value1,value2) {
 return Math.round(value1 + value2);
}


A QUnit test case could look like the following, which performs two assertion tests: equal, to test whether the function returns a value given as the first parameter, and ok which just checks the truthfulness (the truthy value) of the function’s return:


test( "testing addAndRound", function() {
 equal(6, addAndRound(3.55, 2.33), "checking valid");
 ok(addAndRound("three", "4.12"), "checking NaN");
});


The first test succeeds because both parameters are numbers, or can be coerced into being numbers, and the function result is 6. The second fails when the function call returns NaN because the first parameter can’t be coerced into a number.

EXPLAIN


 There are multiple types of tests, such as tests for security, usability, and performance, but the most basic form of testing is unit testing. Unit testing consists of performing tests of discrete source code units, verifying that the unit behaves as expected, and that operations on data provided to or returned from the unit also meet expectations. In JavaScript, a unit is typically a function.

A good rule of thumb when it comes to unit testing is that every requirement or use case for a function should have an associated test case (or cases). The unit test checksthat the requirement is met, and the function performs as expected. You can develop your own tests, but using something like QUnit simplifies the test writing.


Depending on how you’re using QUnit, you’ll need to add links to the library to your test page. If you’re using something like JS Bin, selecting the QUnit option adds all relevant script source files. At a minimum, you’ll need to add a link to the QUnit CSS file, as well as the script.

You’ll also need to add two div elements for the QUnit output. QUnit gives the following as a minimum QUnit test page:
 
 <html>
 <head>
 
 <title>QUnit Example</title>
 <link href="qunit.css" rel="stylesheet"></link>
 </head>
 <body>
 <div id="qunit">
</div>
<div id="qunit-fixture">
</div>
<script src="qunit.js"></script>
 <script src="tests.js"></script>
 </body>
 </html>


The unit tests will be in the tests.js file. The QUnit website provides very good documentation on using the product, so I’m only going to touch on some of the more common components, demonstrated in the solution. The tests are included within an outer function named test(). This is the most com‐ monly used way to trigger the QUnit testing, and is used to perform a synchronous test.

The first parameter is a label for the test results, the second a callback function that includes the tests. QUnit supports several assertion tests, including the two demonstrated in the solution:

• deepEqual: Tests for deep, strict equality
• equal: Tests for standard equality
• notDeepEqual: The inversion of deepEqual testing for deep, strict nonequality
• notEqual: The inversion of equal testing for standard nonequality
• notPropEqual: Tests an object’s properties for inequality
• notStrictEqual: Tests for strict inequality
• ok: Tests whether first argument equates to true
• propEqual: Tests an object’s properties for equality
• strictEqual: Tests for strict equality
• throws: Tests if callback throws an exception, and can optionally compare thrown error When the QUnit test is run, a display is output to the page specifying which tests failed and succeeded, each associated with the test label passed to the assertions.

Writing Tests First

(((programming, TDD vs. BDD approach))Modern development practices have em‐ braced the idea of writing the tests before much of the functionality for the application (and libraries) is written. This Test-Driven Development (TDD) is a component of the Agile development paradigm. TDD takes some getting used to. 

Rather than a more formal structured programming or waterfall project design, with TDD you define the tests, do some coding, run the tests, do some refacturing to remove duplicate code, and then repeat the process until the entire functionality is finished. 

Previous approaches incorporated testing only at the very end of the process, when much of the code has already been created. The Microsoft Developer Network has a page describing a typical scenario. In addition, there are several books and publications online describing both TDD and Agile software development. In addition, another well-known Agile component is behavior-driven development (BDD), developed by Dan North. If you’re interested in utilizing BDD with your Java‐ Script applications, there is a tool, Cucumber.js, specifically designed for BDD in JS. 


Java Numbers

Java Numbers


Numbers are basic to just about any computation. They’re used for array indexes,
temperatures, salaries, ratings, and an infinite variety of things. Yet they’re not as
simple as they seem. With floating-point numbers, how accurate is accurate? With
random numbers, how random is random? With strings that should contain a num-
ber, what actually constitutes a number?

Java has several built-in types that can be used to represent numbers, summarized in
Table. Note that unlike languages such as C or Perl, which don’t specify the size
or precision of numeric types, Java—with its goal of portability—specifies these
exactly and states that they are the same on all platforms.


As you can see, Java provides a numeric type for just about any purpose. There are
four sizes of signed integers for representing various sizes of whole numbers. There
are two sizes of floating-point numbers to approximate real numbers. There is also a
type specifically designed to represent and allow operations on Unicode characters.

When you read a string from user input or a text file, you need to convert it to the
appropriate type. The object wrapper classes in the second column have several

functions, but one of the most important is to provide this basic conversion functionality—replacing the C programmer’s atoi/atof family of functions and the
numeric arguments to scanf.

Going the other way, you can convert any number (indeed, anything at all in Java) to
a string just by using string concatenation. If you want a little bit of control over
numeric formatting, Recipe 5.8 shows you how to use some of the object wrappers’
conversion routines. And if you want full control, it also shows the use of
NumberFormat and its related classes to provide full control of formatting.

As the name object wrapper implies, these classes are also used to “wrap” a number
in a Java object, as many parts of the standard API are defined in terms of objects.
Later on, Recipe 10.16 shows using an Integer object to save an int ’s value to a file
using object serialization, and retrieving the value later.

But I haven’t yet mentioned the issues of floating point. Real numbers, you may
recall, are numbers with a fractional part. There is an infinity of possible real num-
bers. A floating-point number—what a computer uses to approximate a real num-
ber—is not the same as a real number. The number of floating-point numbers is
finite, with only 2^32 different bit patterns for float s, and 2^64 for double s. Thus,
most real values have only an approximate correspondence to floating point. The
result of printing the real number 0.3 works correctly, as in:


// RealValues.java
System.out.println("The real value 0.3 is " + 0.3);

results in this printout:

The real value 0.3 is 0.3

But the difference between a real value and its floating-point approximation can accumulate if the value is used in a computation; this is often called a rounding error. Continuing the previous example, the real 0.3 multiplied by 3 yields:

The real 0.3 times 3 is 0.89999999999999991

Surprised? More surprising is this: you’ll get the same output on any conforming Java implementation. I ran it on machines as disparate as a Pentium with OpenBSD, a Pentium with Windows and Sun’s JDK, and on Mac OS X with JDK 1.4.1. Always the same answer.

And what about random numbers? How random are they? You have probably heard the expression “pseudo-random numbers.” All conventional random number genera- tors, whether written in Fortran, C, or Java, generate pseudo-random numbers. That is, they’re not truly random! True randomness comes only from specially built hard- ware: an analog source of Brownian noise connected to an analog-to-digital con- verter, for example. * This is not your average PC! However, pseudo-random number generators (PRNG for short) are good enough for most purposes, so we use them. Java provides one random generator in the base library java.lang.Math , and several others; we’ll examine these in Recipe 5.13. 

The class java.lang.Math contains an entire “math library” in one class, including trigonometry, conversions (including degrees to radians and back), rounding, trun- cating, square root, minimum, and maximum. It’s all there. Check the Javadoc for java.lang.Math . 

The package java.Math contains support for “big numbers”—those larger than the normal built-in long integers, for example. See Recipe 5.19. Java works hard to ensure that your programs are reliable. 

The usual ways you’d notice this are in the common requirement to catch potential exceptions—all through the Java API—and in the need to “cast” or convert when storing a value that might or might not fit into the variable you’re trying to store it in. I’ll show examples of these. Overall, Java’s handling of numeric data fits well with the ideals of portability, reli- ability, and ease of programming. 

See Also 

The Java Language Specification. The Javadoc page for java.lang.Math .

JAVA SCRIPT - Cleaning Up Your Code with JSHint

Cleaning Up Your Code with JSHint


Problem

You want to check your code for any gotchas that may not trigger a failure, but also aren’t the best coding practices.

Solution

Use a lint tool such as JSHint to highlight potential problems or less than optimal code.

EXPLAIN

The simplest approach to ensuring your code meets a minimum standard of acceptable coding standards is to use the strict setting at the beginning of your code or function:

This setting ensures certain programming standards are met, such as always defining variables, and never using eval(). And of course, the most reliable way of ensuring your code meets standards is whatever error mechanism is built into the tools you’re using to run the code, typically explored in depth using your favorite debugging tool. 

There are a set of coding practices, though, that don’t typically trigger an error or warn‐ ing, but should be avoided because they may introduce unwanted application behaviors or results that are hard to discover. That’s where a linting tool comes in. And the most popular of the JavaScript lint tools is JSHint. JSHint is a fork of a previously popular lint tool named JSLint. JSHint is now more popular because it is more configurable and less rigid—as well as being actively maintained. 

JSHint can be installed using npm, part of the world of Node.js that is covered in

npm install jshint -g

When JSHint is installed using npm, you can run it against any JavaScript using command-line syntax such as the following:

jshint scriptfile.js


Though workable, running JSHint at the command line is a bit tedious. A preferred option is to use a plug-in or browser tool. Both of the JavaScript online playgrounds— JS Bin and jsFiddle—I used to test most of the examples for this book either use JSHint by default or provide an option to run the tool. When running JSHint, you’re running with a default group of settings. Among some of the default settings are those that prevent bitwise operators from being used, requiring curly brackets ({}) for every block, and the use of strict equality (“===”).

You can see all of the options in the .jshintrc file. If you want to change a default setting, use one of four techniques:

• From the command line you can use the --config flag and specify the name of the file containing the configuration settings.

• Create a local version of the .jshintrc file.
• Add settings to your project’s package.json file
• Embed JSHint settings directly in your code. When you’re using an integrated tool that may not provide a way to add an override file for changing JSHint options, you can embed JSHint comments to change default settings directly in the JavaScript. For instance, one of my chronic code foibles is mixing quotes (single and double) in the same code. To prevent this, I can add the following to my JavaScript:

/*jshint quotmark:true */

And I’ll get a warning that I used both types of quotes in the code. If I want to use standard equality operators without warnings, I can use the following:

/*jshint quotmark:true, eqeqeq:false */
var test1 = "today";
var test2 = 'tomorrow';
if (test == tomorrow)
 console.log("nope");

Using a linting tool such as JSHint doesn’t mean you have to create perfect code based on some arbitrary standard. However, it does help ensure that when you decide to write code that bucks the standards, you do so deliberately, rather than accidentally

Java Program: Full Grep

Java Program: Full Grep


Now that we’ve seen how the regular expressions package works, it’s time to write
Grep2 , a full-blown version of the line-matching program with option parsing.
Table lists some typical command-line options that a Unix implementation of
grep might include.

Table  Grep command-line options

Option                                                             Meaning

-c                                                     Count only: don’t print lines, just count them.

-C                                                Context; print some lines above and below each line that matche(not                                                                           implemented in this version; left
                                                                        as an exercise for the reader).

-f                                                    pattern Take pattern from file named after -f instead of from                                                                                       command line.

-h                                                     Suppress printing filename ahead of lines.

-i                                                                       Ignore case.

-l                                                List filenames only: don’t print lines, just the names they’re found in.

-n                                                              Print line numbers before matching lines.

-s                                                  Suppress printing certain error messages.

-v                                           Invert: print only lines that do NOT match the pattern.

We discussed the GetOpt class. Here we use it to control the operation
of an application program. As usual, since main( ) runs in a static context but our
application main line does not, we could wind up passing a lot of information into
the constructor. Because we have so many options, and it would be inconvenient to
keep expanding the options list as we add new functionality to the program, we use a
kind of Collection called a BitSet to pass all the true / false arguments: true to print
line numbers, false to print filenames, etc. A BitSet is much like a Vector  but is specialized to store only Boolean values and is ideal for handling command-line arguments.

The program basically just reads lines, matches the pattern in them, and, if a match
is found (or not found, with -v ), prints the line (and optionally some other stuff,
too). Having said all that, the code is shown in Example

Example. Grep2.java
import com.darwinsys.util.*;
import java.io.*;
import java.util.*;
/** A command-line grep-like program. Accepts some options and takes a pattern
* and a list of text files.
*/
public class Grep2 {
/** The pattern we're looking for */
protected Matcher pattern;
/** The Reader for the current file */
protected BufferedReader d;
/** Are we to only count lines, instead of printing? */
protected boolean countOnly = false;
/** Are we to ignore case? */
protected boolean ignoreCase = false;
/** Are we to suppress printing of filenames? */
protected boolean dontPrintFileName = false;
/** Are we to only list names of files that match? */
protected boolean listOnly = false;
/** are we to print line numbers? */
protected boolean numbered = false;
/** Are we to be silent about errors? */
protected boolean silent = false;
/** are we to print only lines that DONT match? */
protected boolean inVert = false;
/** Construct a Grep object for each pattern, and run it
* on all input files listed in argv.
*/
public static void main(String[] argv) throws RESyntaxException {
if (argv.length < 1) {
System.err.println("Usage: Grep2 pattern [filename...]");
System.exit(1);
}
String pattern = null;
GetOpt go = new GetOpt("cf:hilnsv");
BitSet args = new BitSet( );
char c;
while ((c = go.getopt(argv)) != 0) {
switch(c) {
case 'c':
args.set('C');
break;
case 'f':
try {
BufferedReader b = new BufferedReader
(new FileReader(go.optarg( )));
pattern = b.readLine( );
b.close( );
} catch (IOException e) {
System.err.println("Can't read pattern file " +
go.optarg( ));
System.exit(1);
}
break;
case 'h':
args.set('H');
break;
case 'i':
args.set('I');
break;
case 'l':
args.set('L');
break;
case 'n':
args.set('N');
break;
case 's':
args.set('S');
break;
case 'v':
args.set('V');
break;
}
}
int ix = go.getOptInd( );
if (pattern == null)
pattern = argv[ix-1];
Grep2 pg = new Grep2(pattern, args);
if (argv.length == ix)
pg.process(new InputStreamReader(System.in), "(standard input)");
else
for (int i=ix; i<argv.length; i++) {
try {
pg.process(new FileReader(argv[i]), argv[i]);
} catch(Exception e) {
System.err.println(e);
}
}
}
/** Construct a Grep2 object.
*/
public Grep2(String patt, BitSet args) {
// compile the regular expression
if (args.get('C'))
countOnly = true;
if (args.get('H'))
dontPrintFileName = true;
if (args.get('I'))
ignoreCase = true;
if (args.get('L'))
listOnly = true;
if (args.get('N'))
numbered = true;
if (args.get('S'))
silent = true;
if (args.get('V'))
inVert = true;
int caseMode = ignoreCase ? Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE : 0;
pattern = Pattern.compile(patt, caseMode);
matcher = pattern.matcher("");
}
/** Do the work of scanning one file
* @param
ifile
Reader
Reader object already open
* @param
fileName String
Name of the input file
*/
public void process(Reader ifile, String fileName) {
String line;
int matches = 0;
try {
d = new BufferedReader(ifile);
while ((line = d.readLine( )) != null) {
if (pattern.match(line)) {
if (countOnly)
matches++;
else {
if (!dontPrintFileName)
System.out.print(fileName + ": ");
System.out.println(line);
}
} else if (inVert) {
System.out.println(line);
}
}
if (countOnly)
System.out.println(matches + " matches in " + fileName);
d.close( );
} catch (IOException e) { System.err.println(e); }
}
}

Java Program: Data Mining

Java Program: Data Mining


Suppose that I, as a published author, want to track how my book is selling in com-
parison to others. This information can be obtained for free just by clicking on the
page for my book on any of the major bookseller sites, reading the sales rank num-
ber off the screen, and typing the number into a file—but that’s too tedious. As I
wrote in the book that this example looks for, “computers get paid to extract rele-
vant information from files; people should not have to do such mundane tasks.” This
program uses the Regular Expressions API and, in particular, newline matching to
extract a value from an HTML page on the hypothetical QuickBookShops.web web
site. It also reads from a URL object . The pattern to look for is
something like this (bear in mind that the HTML may change at any time, so I want
to keep the pattern fairly general):

<b>QuickBookShop.web Sales Rank: </b>
26,252
</font><br>

As the pattern may extend over more than one line, I read the entire web page from the URL into a single long string using my FileIO.readerToString( ) method (see Recipe 10.8) instead of the more traditional line-at-a-time paradigm. I then plot a graph using an external program; this could (and should) be changed to use a Java graphics program. The com- plete program is shown in Example

Example. BookRank.java
// Standard imports not shown
import com.darwinsys.io.FileIO;
import com.darwinsys.util.FileProperties;
/** Graph of a book's sales rank on a given bookshop site.
* @author Ian F. Darwin, http://www.darwinsys.com/, Java Cookbook author,
*
originally translated fairly literally from Perl into Java.
* @author Patrick Killelea <p@patrick.net>: original Perl version,
*
from the 2nd edition of his book "Web Performance Tuning".
* @version $Id: ch04,v 1.4 2004/05/04 20:11:27 ian Exp $
*/
public class BookRank {
public final static String DATA_FILE = "book.sales";
public final static String GRAPH_FILE = "book.png";
/** Grab the sales rank off the web page and log it. */
public static void main(String[] args) throws Exception {
Properties p = new FileProperties(
args.length == 0 ? "bookrank.properties" : args[1]);
String title = p.getProperty("title", "NO TITLE IN PROPERTIES");
// The url must have the "isbn=" at the very end, or otherwise
// be amenable to being string-catted to, like the default.
String url = p.getProperty("url", "http://test.ing/test.cgi?isbn=");
// The 10-digit ISBN for the book.
String isbn = p.getProperty("isbn", "0000000000");
// The regex pattern (MUST have ONE capture group for the number)
String pattern = p.getProperty("pattern", "Rank: (\\d+)");
// Looking for something like this in the input:
//
<b>QuickBookShop.web Sales Rank: </b>
//
26,252
//
</font><br>
Pattern r = Pattern.compile(pattern);
// Open the URL and get a Reader from it.
BufferedReader is = new BufferedReader(new InputStreamReader(
new URL(url + isbn).openStream( )));
// Read the URL looking for the rank information, as
// a single long string, so can match regex across multi-lines.
String input = FileIO.readerToString(is);
// System.out.println(input);

// If found, append to sales data file.
Matcher m = r.matcher(input);
if (m.find( )) {
PrintWriter pw = new PrintWriter(
new FileWriter(DATA_FILE, true));
String date = // 'date +'%m %d %H %M %S %Y'`;
new SimpleDateFormat("MM dd hh mm ss yyyy ").
format(new Date( ));
// Paren 1 is the digits (and maybe ','s) that matched; remove comma
Matcher noComma = Pattern.compile(",").matcher(m.group(1));
pw.println(date + noComma.replaceAll(""));
pw.close( );
} else {
System.err.println("WARNING: pattern `" + pattern +
"' did not match in `" + url + isbn + "'!");
}
//Whether current data found or not, draw the graph, using external plotting program against all historical data. Could use gnuplot, R, any other math/graph program. Better yet: use one of the Java plotting APIs.

String gnuplot_cmd =
"set term png\n" +
"set output \"" + GRAPH_FILE + "\"\n" +
"set xdata time\n" +
"set ylabel \"Book sales rank\"\n" +
"set bmargin 3\n" +
"set logscale y\n" +
"set yrange [1:60000] reverse\n" +
"set timefmt \"%m %d %H %M %S %Y\"\n" +
"plot \"" + DATA_FILE +
"\" using 1:7 title \"" + title + "\" with lines\n"
;
Process proc = Runtime.getRuntime( ).exec("/usr/local/bin/gnuplot");
PrintWriter gp = new PrintWriter(proc.getOutputStream( ));
gp.print(gnuplot_cmd);
gp.close( );
}
}