1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.example.android.newsreader;
18 import java.util.ArrayList;
19 import java.util.List;
20 import java.util.Random;
21 
22 /** Generator of random news. More fun than "lorem ipsum", isn't it?
23  *
24  * This generator can construct headlines and news articles by randomly composing sentences.
25  * Any resemblance to actual events (or, actually, any resemblance to anything that makes sense)
26  * is merely coincidental!
27  */
28 public class NonsenseGenerator {
29     Random mRandom;
30 
31     static final String[] THINGS = { "bottle", "bowl", "brick", "building",
32             "bunny", "cake", "car", "cat", "cup", "desk", "dog", "duck",
33             "elephant", "engineer", "fork", "glass", "griffon", "hat", "key", "knife", "lawyer",
34             "llama", "manual", "meat", "monitor", "mouse", "tangerine", "paper", "pear", "pen",
35             "pencil", "phone", "physicist", "planet", "potato", "road", "salad", "shoe", "slipper",
36             "soup", "spoon", "star", "steak", "table", "terminal", "treehouse", "truck",
37             "watermelon", "window" };
38 
39     static final String[] ADJECTIVES = { "red", "green", "yellow", "gray", "solid", "fierce",
40             "friendly", "cowardly", "convenient", "foreign", "national", "tall",
41             "short", "metallic", "golden", "silver", "sweet", "nationwide", "competitive",
42             "stable", "municipal", "famous" };
43 
44     static final String[] VERBS_PAST = { "accused", "threatened", "warned", "spoke to",
45             "has met with",
46             "was seen in the company of", "advanced towards", "collapsed on",
47             "signed a partnership with", "was converted into", "became", "was authorized to sell",
48             "sold", "bought", "rented", "allegedly spoke to", "leased", "is now investing on",
49             "is expected to buy", "is expected to sell", "was reported to have met with",
50             "will work together with", "plans to cease fire against", "started a war with",
51             "signed a truce with", "is now managing", "is investigating" };
52 
53     static final String[] VERBS_PRESENT = { "accuses", "threatens", "warns", "speaks to",
54             "meets with",
55             "seen with", "advances towards", "collapses on",
56             "signs partnership with", "converts into", "becomes", "is authorized to sell",
57             "sells", "buys", "rents", "allegedly speaks to", "leases", "invests on",
58             "expected to buy", "expected to sell", "reported to have met with",
59             "works together with", "plans cease fire against", "starts war with",
60             "signs truce with", "now manages" };
61 
NonsenseGenerator()62     public NonsenseGenerator() {
63         mRandom = new Random();
64     }
65 
66     /** Produces something that reads like a headline. */
makeHeadline()67     public String makeHeadline() {
68         return makeSentence(true);
69     }
70 
71     /** Produces a sentence.
72      *
73      * @param isHeadline whether the sentence should look like a headline or not.
74      * @return the generated sentence.
75      */
makeSentence(boolean isHeadline)76     public String makeSentence(boolean isHeadline) {
77         List<String> words = new ArrayList<String>();
78         generateSentence(words, isHeadline);
79         words.set(0, String.valueOf(Character.toUpperCase(words.get(0).charAt(0))) +
80                 words.get(0).substring(1));
81         return joinWords(words);
82     }
83 
84     /** Produces news article text.
85      *
86      * @param numSentences how many sentences the text is to contain.
87      * @return the generated text.
88      */
makeText(int numSentences)89     public String makeText(int numSentences) {
90         StringBuilder sb = new StringBuilder();
91         while (numSentences-- > 0) {
92             sb.append(makeSentence(false) + ".");
93             if (numSentences > 0) {
94                 sb.append(" ");
95             }
96         }
97         return sb.toString();
98     }
99 
100     /** Generates a sentence.
101      *
102      * @param words the list of words to which the sentence will be appended.
103      * @param isHeadline whether the sentence must look like a headline or not.
104      */
generateSentence(List<String> words, boolean isHeadline)105     private void generateSentence(List<String> words, boolean isHeadline) {
106         if (!isHeadline && mRandom.nextInt(4) == 0)
107             generateTimeClause(words, isHeadline);
108         generateAgent(words, isHeadline);
109         generatePredicate(words, isHeadline);
110     }
111 
generateTimeClause(List<String> words, boolean isHeadline)112     private void generateTimeClause(List<String> words, boolean isHeadline) {
113         if (mRandom.nextInt(2) == 0) {
114             words.add(pickOneOf("today", "yesterday", "this afternoon", "this morning",
115                     "last evening"));
116         }
117         else {
118             words.add(pickOneOf("this", "last"));
119             words.add(pickOneOf("Monday", "Tuesday", "Wednesday", "Thursday"));
120             words.add(pickOneOf("morning", "afternoon", "evening"));
121         }
122     }
123 
generateAgent(List<String> words, boolean isHeadline)124     private void generateAgent(List<String> words, boolean isHeadline) {
125        if (!isHeadline) {
126            words.add(pickOneOf("a", "the"));
127        }
128        if (mRandom.nextInt(3) != 0) {
129            words.add(pickOneOf(ADJECTIVES));
130        }
131        words.add(pickOneOf(THINGS));
132     }
133 
generatePredicate(List<String> words, boolean isHeadline)134     private void generatePredicate(List<String> words, boolean isHeadline) {
135         words.add(pickOneOf(isHeadline ? VERBS_PRESENT : VERBS_PAST));
136         if (!isHeadline)
137             words.add(pickOneOf("a", "the"));
138         if (mRandom.nextInt(3) != 0) {
139             words.add(pickOneOf(ADJECTIVES));
140         }
141         words.add(pickOneOf(THINGS));
142 
143         if (mRandom.nextInt(3) == 0) {
144             words.add(isHeadline ? pickOneOf(", claims", ", says") :
145                  pickOneOf(", claimed", ", said", ", reported"));
146             if (!isHeadline)
147                 words.add(pickOneOf("a", "the"));
148             if (mRandom.nextInt(3) != 0) {
149                 words.add(pickOneOf(ADJECTIVES));
150             }
151             words.add(pickOneOf(THINGS));
152         }
153     }
154 
pickOneOf(String .... options)155     private String pickOneOf(String ... options) {
156         return options[mRandom.nextInt(options.length)];
157     }
158 
joinWords(List<String> words)159     private static String joinWords(List<String> words) {
160         int i;
161         if (words.size() == 0) {
162             return "";
163         }
164         StringBuilder sb = new StringBuilder();
165         sb.append(words.get(0));
166         for (i = 1; i < words.size(); i++) {
167             if (!words.get(i).startsWith(",")) {
168                 sb.append(" ");
169             }
170             sb.append(words.get(i));
171         }
172         return sb.toString();
173     }
174 }
175