Java Notes
switch Example - Random Insults
The following class could be useful for generating random insults in response to erroneous user input. Source code formatting. Some of the cases are formatted on a single line. This is a common style when they do similar short actions. It makes the switch statements much easier to read. |
Separate model (logic) from user interface. This program is separated into two classes: one contains the logic (or "model" as it's more often called) for generating an insult as a string. It knows nothing about the user interface, and could equally well be used in a dialog program (as in the test program below), console I/O, a GUI program, or a web-based application.
Random Insult Model
This is the logic of the program, and does no I/O so it would be equally suitable as the logic behind a console program, GUI program, or web server program.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
// File : flow-switch/insult/InsultGenerator1.java // Purpose: Generates random insults. // Author : Fred Swartz 2006 Aug 23 Placed in public domain // Comments: This switch statements were written in the // most conservative style -- a default clause // and no returns in them. // // The structure of the random generation is // entirely in executable code, // A much better way to write this is as a // data-Driven program, where this information is // represented by data structures, with a // simple program to process the data. // // The data-driven style allows the data to be // read in from user-editable files for example, // so the program need not be recompiled for changes. public class InsultGenerator1 { //============================================ badInputInsult public static String badInputInsult() { String insult; switch (rand(2)) { case 0: insult = "What kind of " + infoAdjective() + " " + infoNoun() + " is this, you " + personAdjective() + " " + person() + "?"; break; case 1: insult = "Never enter this kind of " + infoAdjective() + " " + infoNoun() + " again!!!!"; break; default:insult = "Oops -- bad switch statement"; } return insult; } //==================================================== person private static String person() { String name; switch (rand(3)) { case 0 : name = "idiot" ; break; case 1 : name = "imbecile"; break; case 2 : name = "moron" ; break; default: name = "bad value from person???"; } return name; } //=========================================== personAdjective private static String personAdjective() { String adj; switch (rand(4)) { case 0 : adj = "clueless"; break; case 1 : adj = "witless" ; break; case 2 : adj = "stupid" ; break; case 3: adj = "hopeless"; break; default: adj = "bad value from infoAdjective???"; } return adj; } //============================================= infoAdjective private static String infoAdjective() { String adj; switch (rand(5)) { case 0: adj = "revolting" ; break; case 1: adj = "insulting" ; break; case 2: adj = "meaningless"; break; case 3: adj = "useless" ; break; case 4: adj = "idiotic" ; break; default:adj = "bad value from infoAdjective???"; } return adj; } //================================================== infoNoun private static String infoNoun() { String noun; switch (rand(4)) { case 0: noun = "nonsense"; break; case 1: noun = "crap" ; break; case 2: noun = "swill" ; break; case 3: noun = "garbage" ; break; default:noun = "bad value from infoNoun???"; } return noun; } //===================================================== rand // Utility method to generate random numbers in range 0..bound-1. // Starting the range at zero was simply to match the typical // Java ranges (eg, switch, subscripts) that start at zero. // Returns random int in range 0...bound-1 private static int rand(int bound) { return (int) (Math.random() * bound); } } |
Main program
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// File : flow-switch/insult/TestTextGenerator1.java // Purpose: Show some random insults. // Author : Fred Swartz // License: public domain // Date : 2006 May 3 import javax.swing.*; public class TestTextGenerator1 { public static void main(String[] args) { String display; do { display = InsultGenerator1.badInputInsult() + "\n\nWould you like another opinion?"; } while (JOptionPane.showConfirmDialog(null, display) == JOptionPane.YES_OPTION); } } |
Data-driven programming
Replace methods with data structure? This version is written with executable Java code. It is usually very desirable to replace executable code with some kind of data structure. There are several reasons for this.
- Data can be stored in user-editable files, which allows modifying the functioning of the program without recompiling, or even having access to the source code.
- Every line of code is a liability! Keeping code small is a very good goal. It looks like nothing can go wrong here, but surely it will sometime when the program is updated.
Programming problems
- Problem (using arrays): Get rid of the methods, and replace them with arrays of strings.
You'll find it useful to define a method to choose a random element from
an array of Strings.
To keep this problem simple don't read the data in from files.
It might look like
private static String chooseRandom(String[] words)
- Problem (using Map and File I/O): Another way to think about this problem is to have a special
syntax to denote something that should be replaced -- I'll use "angle brackets"
to surround terms that should be replaced by a something that is dynamically generated.
For example, the starting element could be the string "<insult>".
The program would then look up the definition of "insult" in something like
HashMap<String, ArrayList<String>>
and randomly choose one of the strings from the array list. For example, it might replace "<insult>" with "Never enter this kind of <infoAdj> <infoNoun> again!!!!"The program would then find each thing surrounded by angle brackets and replace it with a randomly chosen values from its associated arrays. This process is repeated until all angle bracketted symbols have been replaced.
Read data in from a file. One plausible format would be to have the the "meta-symbols" start in column 1, and all possible definitions follow on lines that start with a blank. For example,
<insult> Never enter this kind of <infoAdj> <infoNoun> again!!!! What kind of <infoAdj> <infoNoun> is this, you <personAdj> <person>? <infoAdj> revolting insulting meaningless useless idiotic . . .