| /** |
| * Copyright (c) 2005, 2013, Werner Keil and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Werner Keil - initial API and implementation |
| */ |
| package org.eclipse.uomo.util.test.numbers; |
| |
| /** |
| * Maximum value to handle : 9223372036854775807 |
| * (9,223,372,036,854,775,807) Nine Quintillion, Two Hundred and |
| * Twenty-Three Quadrillion, Three Hundred and Seventy-Two Trillion, |
| * Thirty-Six Billion, Eight Hundred and Fifty-Four Million, Seven |
| * Hundred and Seventy-Five Thousand, Eight Hundred and Seven |
| * |
| * Thanks to 911 Programming |
| */ |
| |
| import java.io.IOException; |
| import java.util.Scanner; |
| |
| import org.eclipse.uomo.util.numbers.SpellException; |
| import org.eclipse.uomo.util.numbers.impl.SpellContext; |
| |
| /** |
| * A multiple demo program to test SpellContext class. |
| * |
| * @author Werner Keil |
| * |
| */ |
| public class SpellDemos { |
| |
| /** |
| * The main program of this demo runs five demos one after the other with a |
| * pause between each two of them. |
| * |
| * @param args |
| * Not used in this demo. |
| */ |
| public static void main(String[] args) { |
| |
| /* |
| * Enables or disables formal hyphen in cent-digit combination like |
| * 'Forty-Five' or 'Forty Five'. |
| */ |
| SpellContext.usingCentHyphen = true; |
| |
| // to disable pause between outputs, set the following variable to |
| // false. |
| pauseBetweenOutputs = false; |
| |
| // Print Introduction: |
| System.out.println("Spelling Number Test Console 0.6"); |
| System.out |
| .println("A Java demo to spell numbers and to parse spelled number text."); |
| System.out.println("Version 0.6"); |
| System.out.println("Eclipse Foundation."); |
| |
| // Run demos one after the other. Pause between them. |
| pause("Demo One - Testing Auto-Generated Numbers"); |
| demoOne(); |
| pause("Demo Two - Testing Auto-Generated Numbers"); |
| demoTwo(); |
| pause("Demo Three - Testing Auto-Generated Numbers"); |
| demoThree(); |
| pause("Demo Max - Testing Maximum Long Value"); |
| demoMax(); |
| pause("Demo Four - Interactive user mode"); |
| demoFour(); |
| } |
| |
| /** |
| * This variable enables or disables extra pauses within each |
| * non-interactive demos. |
| */ |
| private static boolean pauseBetweenOutputs = false; |
| |
| /** |
| * Pause used within each demo. |
| */ |
| private static void pause() { |
| if (pauseBetweenOutputs) { |
| |
| System.out.print("\nPress <RETURN> to continue"); |
| try { |
| while (System.in.read() != '\r') |
| ; |
| } catch (IOException e) { |
| // Auto-generated catch block |
| e.printStackTrace(); |
| } |
| } |
| } |
| |
| /** |
| * Pause used between demos with an introductory caption. |
| * |
| * @param message |
| * The caption of pause. |
| */ |
| private static void pause(String message) { |
| System.out.printf("\nPress <RETURN> to prceed to the next step : %1$s", |
| message); |
| try { |
| while (System.in.read() != '\r') |
| ; |
| } catch (IOException e) { |
| // Auto-generated catch block |
| e.printStackTrace(); |
| } |
| } |
| |
| /** |
| * Demo One : Tests some automatically generated numbers. |
| */ |
| private static void demoOne() { |
| System.out.println("\n\n---- ---- ---- ---- ---- ---- "); |
| System.out.println("Demo One - Auto-Generated Numbers (1)"); |
| |
| long value = 0L; |
| for (long i = 0; i <= 10L; i++) { |
| value = value * 10 + i; |
| dump(value); |
| pause(); |
| } |
| } |
| |
| /** |
| * Demo Two : Tests some automatically generated numbers. |
| */ |
| private static void demoTwo() { |
| System.out.println("\n\n---- ---- ---- ---- ---- ---- "); |
| System.out.println("Demo Two - Auto-Generated Numbers (2)"); |
| |
| for (int i = 0; i < 20; i++) { |
| dump(i * 10000 + i); |
| pause(); |
| } |
| |
| } |
| |
| /** |
| * Demo Three : Tests some automatically generated numbers. |
| */ |
| private static void demoThree() { |
| System.out.println("\n\n---- ---- ---- ---- ---- ---- "); |
| System.out.println("Demo Three - Auto-Generated Numbers (3)"); |
| |
| long value; |
| value = 0L; |
| |
| for (long i = 32; i >= 0L; i--) { |
| value = value * 10 + i; |
| dump(value); |
| pause(); |
| } |
| } |
| |
| /** |
| * Demo Four : The interactive user mode. It gets a numeric value or spelled |
| * number text from user. If it is a numeric value, it spells it. If it is a |
| * spelled text, it parses the text and displays its equivalent numeric |
| * value. All works are displayed in the same format. This demo checks if |
| * the grammar associated with the spelled number entered by user is correct |
| * or not, and if it is not, it prints the formal correct spelling of the |
| * perceived number. |
| * |
| * @see {@link #dump(long)}, {@link #dump(String)}, |
| * {@link #dump(long, String)} and |
| * {@link SpellDemos#DumpSpellText(String)} |
| */ |
| private static void demoFour() { |
| System.out.println("\n\n---- ---- ---- ---- ---- ---- "); |
| System.out.println("Demo Four - User Interactive Mode\n"); |
| |
| // create a scanner for std input (keyboard input). |
| Scanner in = new Scanner(System.in); |
| in.nextLine(); |
| |
| // lineToProcess keeps the user input text. It is specially used for |
| // multi-line text input. |
| String lineToProcess = null; |
| |
| for (;;) { |
| // print prompt only if it is not (still) a multi-line input. |
| if (lineToProcess == null) { |
| System.out |
| .println("Enter 'numeric value' or 'spelled number text' :"); |
| System.out |
| .println("(Type '.' to terminate the loop, type '\\' to continue the text at next line)"); |
| } |
| |
| // read next line as text. |
| String lineText = in.nextLine(); |
| |
| // Check if it is a single dot (.) |
| if (lineText.equals(".")) { |
| // if it is, check if there is some text still to be processed, |
| if (lineToProcess != null) { |
| try { |
| // if it is, dump the line. |
| dump(lineToProcess); |
| } catch (Exception e) { |
| // check errors. |
| System.err.println("\n\n" + e.getMessage() + "\n\n"); |
| } |
| } |
| // break to terminate the demo. |
| break; |
| } else if (lineText.equals("")) |
| // otherwise, If it is an empty line, ignore it. |
| continue; |
| |
| // If it is not either a dot (.) or an empty line, check data. |
| |
| // Check if there is some previous unprocessed text, |
| if (lineToProcess == null) |
| // if it is not, set it as a fresh text. |
| lineToProcess = lineText.replaceAll("\\\\", ""); |
| else |
| // Otherwise, append this line to that (for non-numeric spelled |
| // number text only). |
| lineToProcess += " " + lineText.replaceAll("\\\\", ""); |
| |
| // If this line is not marked to be continued, |
| if (!lineText.endsWith("\\")) { |
| // process it: |
| try { |
| // dump the line of text. |
| dump(lineToProcess); |
| |
| } catch (Exception e) { |
| |
| // Report error is there is any. |
| System.err.println("\n\n" + e.getMessage() + "\n\n"); |
| |
| } finally { |
| // mark the line to be processed as fresh. |
| lineToProcess = null; |
| |
| } |
| |
| } |
| } |
| |
| // close the scanner. |
| in.close(); |
| } |
| |
| /** |
| * Demo Max : Tests the maximum number to handle. |
| */ |
| private static void demoMax() { |
| System.out.println("\n\n---- ---- ---- ---- ---- ---- "); |
| System.out.println("Demo Max - Testing Maximum Value"); |
| |
| System.out.println("\nMaximim value to handle : " + Long.MAX_VALUE); |
| dump(Long.MAX_VALUE); |
| System.out.println(); |
| } |
| |
| /** |
| * Dump the data based on the numeric value. |
| * |
| * @param value |
| * The numeric value to dump |
| * |
| * @see {@link #dump(long, String)} dump the number data based on its |
| * numeric value or spelled text. |
| */ |
| private static void dump(long value) { |
| dump(value, null); |
| } |
| |
| /** |
| * Dump the data based on the spelled text or numeric value represented as |
| * text String format. |
| * |
| * @param line |
| * The text string containing the spelled number or numeric |
| * value. |
| * |
| * @see {@link #dump(long, String)} dump the number data based on its |
| * numeric value or spelled text. |
| */ |
| private static void dump(String line) { |
| long value; |
| |
| try { |
| // first try to dump it as number. |
| value = Long.parseLong(line.replaceAll(",", "")); |
| dump(value, null); |
| |
| } catch (NumberFormatException e) { |
| // If not successful, try it as text. |
| dump(0, line); |
| } |
| } |
| |
| /** |
| * Dump the data based on the spelled text (if not null), otherwise, based |
| * on the numeric value. This is the most basic method which actually tests |
| * the SpellContext class. |
| * |
| * @param value |
| * If spellText is null, this is the numeric value to dump. |
| * @param spellText |
| * If not null, it is the spelled number text to dump. |
| * |
| * @see {@link #DumpSpellText(String)} to check how spelled text is nicely |
| * formatted, possibly in multi-lines. |
| */ |
| private static void dump(long value, String spellText) { |
| |
| // assume user-spelled format which might need correction. |
| boolean userSpelledText = true; |
| |
| // decide which one to choose : the numeric value or spelled text. |
| // if spellText is null, assume numeric value, otherwise, assume spelled |
| // text. |
| if (spellText == null) { |
| // Report to user that it is a numeric value to dump. |
| System.out.printf("%1$d (Numeric)\n", value); |
| try { |
| // create the spelled text from the numeric value. |
| spellText = SpellContext.of().spell(value); |
| // There is no need for formal spelled text because the spelled |
| // text is generated from this program (not user), and it does |
| // not contain any spelling error. |
| userSpelledText = false; |
| } catch (SpellException e) { |
| e.printStackTrace(); |
| } |
| } else { |
| // Otherwise, report to user that it is a spelled number to dump. |
| System.out.println("(Spelled Number)"); |
| } |
| |
| // Now, spellText is the basis of the data dump. |
| |
| try { |
| // If it is user spelled text, evaluate the corresponding value. |
| if (userSpelledText) |
| value = SpellContext.of().parse(spellText); |
| |
| // encode the spelled text |
| String encoded = SpellContext.encode(spellText); |
| // decode the encoded text. |
| String decoded = SpellContext.decode(encoded); |
| |
| // first, assume that the spelling is correct. |
| boolean spellIsCorrect = true; |
| |
| try { |
| // validate the spelling. |
| SpellContext.of().validate(encoded); |
| |
| } catch (SpellException e) { |
| // mark incorrect, if validation failed. |
| spellIsCorrect = false; |
| } |
| |
| // The dump table : |
| |
| // The numeric value |
| System.out.printf("\tNumeric Value : %1$s\n", |
| SpellContext.withSeparator(value)); |
| |
| // The spell text |
| DumpSpellText(spellText); |
| |
| // Decide if it is a user spelled text and needs a formal spelled |
| // text to compare. |
| if (userSpelledText) { |
| String formalSpell = SpellContext.of().spell(value); |
| String formalEncode = SpellContext.encode(formalSpell); |
| |
| if (!formalEncode.equals(encoded)) { |
| System.out.println("\tFormal Spell: "); |
| DumpSpellText(formalSpell); |
| } |
| } |
| |
| // The encoded text: |
| System.out.println("\tEncoded : " + encoded); |
| |
| // The decoded text to compare to the original spelled text. |
| System.out.println("\tDecoded : "); |
| DumpSpellText(decoded); |
| |
| // if user spelled text, check if it is correct or not. |
| if (userSpelledText) |
| System.out.println("\tSpelling : " |
| + (spellIsCorrect ? "Correct" : "Incorrect")); |
| |
| System.out.println(); |
| |
| } catch (SpellException e) { |
| // report spell error if any. |
| System.err.println("\n\n" + e.getMessage() + "\n\n"); |
| } catch (Exception e) { |
| // report general error if any. |
| System.err.println("\n\n" + e.getMessage() + "\n\n"); |
| } |
| } |
| |
| /** |
| * Prints the spelled text in nice width-limited format. |
| * |
| * @param spellText |
| * The spelled text. |
| */ |
| private static void DumpSpellText(String spellText) { |
| String[] tokens = spellText.split("\\s+"); |
| |
| // set it as the first column |
| int columnIndex = 0; |
| |
| // The space chars between words. |
| final String space = " "; |
| |
| // the number of spaces between word. |
| final int spaceCount = space.length(); |
| |
| // prefix the first line with two tabs. |
| System.out.print("\t\t"); |
| |
| // for each word of the spelled text, |
| for (String token : tokens) { |
| // if it goes beyond the line width limit, |
| if (columnIndex + token.length() + spaceCount > 80) { |
| // go to the next line, |
| System.out.println(); |
| // prefix the line with two tabs. |
| System.out.print("\t\t"); |
| // set it as the first column. |
| columnIndex = 0; |
| } |
| |
| // if it is not the first word of the line, print word separator. |
| if (columnIndex > 0) |
| System.out.print(space); |
| |
| // Now, print the word itself. |
| System.out.print(token); |
| |
| // update column index; |
| columnIndex += token.length(); |
| } |
| |
| // print a line-separator. |
| System.out.println(); |
| } |
| } |