-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSearchClient.java
More file actions
175 lines (150 loc) · 6.78 KB
/
SearchClient.java
File metadata and controls
175 lines (150 loc) · 6.78 KB
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
import java.io.*;
import java.util.*;
// This class allows users to find and rate books within BOOK_DIRECTORY
// containing certain terms
public class SearchClient {
public static final String BOOK_DIRECTORY = "./books";
private static final Random RAND = new Random();
// Some class constants you can play around with to give random ratings to the uploaded books!
public static final int MIN_RATING = 1;
public static final int MAX_RATING = 5;
public static final int MIN_NUM_RATINGS = 1;
public static final int MAX_NUM_RATINGS = 100;
public static void main(String[] args) throws FileNotFoundException {
Scanner console = new Scanner(System.in);
List<Media> media = new ArrayList<>(loadBooks());
Map<String, Set<Media>> index = createIndex(media);
System.out.println("Welcome to the CSE 123 Search Engine!");
String command = "";
while (!command.equalsIgnoreCase("quit")) {
System.out.println("What would you like to do? [Search, Rate, Quit]");
System.out.print("> ");
command = console.nextLine();
if (command.equalsIgnoreCase("search")) {
searchQuery(console, index);
} else if (command.equalsIgnoreCase("rate")) {
addRating(console, media);
} else if (!command.equalsIgnoreCase("quit")) {
System.out.println("Invalid command, please try again.");
}
}
System.out.println("See you next time!");
}
public static Map<String, Set<Media>> createIndex(List<Media> docs) {
Objects.requireNonNull(docs, "docs cannot be null");
Map<String, Set<Media>> index = new TreeMap<>();
for (Media media : docs) {
if (media != null) {
List<String> tokens = media.getContent();
if (tokens != null) {
for (String token : tokens) {
if (token != null && !token.isEmpty()) {
String normalized = token.toLowerCase();
Set<Media> entries = index.get(normalized);
if (entries == null) {
entries = new HashSet<>();
index.put(normalized, entries);
}
entries.add(media);
}
}
}
}
}
return index;
}
public static Set<Media> search(Map<String, Set<Media>> index, String query) {
Objects.requireNonNull(index, "index cannot be null");
Objects.requireNonNull(query, "query cannot be null");
Set<Media> results = new TreeSet<>();
if (query.isEmpty()) {
return results;
}
Scanner scanner = new Scanner(query);
Set<String> processed = new HashSet<>();
while (scanner.hasNext()) {
String token = scanner.next().toLowerCase();
if (!processed.contains(token)) {
processed.add(token);
Set<Media> matches = index.get(token);
if (matches != null) {
results.addAll(matches);
}
}
}
scanner.close();
return results;
}
// Allows the user to search a specific query using the provided 'index' to find appropraite
// Media entries.
//
// Parameters:
// console - the Scanner to get user input from. Should be non-null
// index - an inverted index mapping terms to the Set of media containing those terms.
// Should be non-null
public static void searchQuery(Scanner console, Map<String, Set<Media>> index) {
System.out.println("Enter query:");
System.out.print("> ");
String query = console.nextLine();
Set<Media> result = search(index, query);
if (result.isEmpty()) {
System.out.println("\tNo results!");
} else {
for (Media m : result) {
System.out.println("\t" + m.toString());
}
}
}
// Allows the user to add a rating to one of the options wthin 'media'
//
// Parameters:
// console - the Scanner to get user input from. Should be non-null.
// media - list of all media options loaded into the search engine. Should be non-null.
public static void addRating(Scanner console, List<Media> media) {
for (int i = 0; i < media.size(); i++) {
System.out.println("\t" + i + ": " + media.get(i).toString());
}
System.out.println("What would you like to rate (enter index)?");
System.out.print("> ");
int choice = Integer.parseInt(console.nextLine());
if (choice < 0 || choice >= media.size()) {
System.out.println("Invalid choice");
} else {
System.out.println("Rating [" + media.get(choice).getTitle() + "]");
System.out.println("What rating would you give?");
System.out.print("> ");
int rating = Integer.parseInt(console.nextLine());
media.get(choice).addRating(rating);
}
}
// Loads all books from BOOK_DIRECTORY. Assumes that each book starts with two lines -
// "Title: " which is followed by the book's title
// "Author: " which is followed by the book's author
//
// Returns:
// A list of all book objects corresponding to the ones located in BOOK_DIRECTORY
public static List<Media> loadBooks() throws FileNotFoundException {
List<Media> ret = new ArrayList<>();
File dir = new File(BOOK_DIRECTORY);
for (File f : dir.listFiles()) {
Scanner sc = new Scanner(f, "utf-8");
String title = sc.nextLine().substring("Title: ".length());
List<String> author = List.of(sc.nextLine().substring("Author: ".length()));
Media book = new Book(title, author, sc);
// Adds random ratings to 'book' based on the class constants.
// Feel free to comment this out.
int minRating = RAND.nextInt(MAX_RATING - MIN_RATING + 1) + MIN_RATING;
addRatings(minRating, Math.min(MAX_RATING,RAND.nextInt(MAX_RATING - minRating + 1) + minRating),
RAND.nextInt(MAX_NUM_RATINGS - MIN_NUM_RATINGS) + MIN_NUM_RATINGS, book);
ret.add(book);
}
return ret;
}
// Adds ratings to the provided media numRatings amount of times. Each rating is a random int
// between minRating and maxRating (inclusive).
private static void addRatings(int minRating, int maxRating, int numRatings, Media media) {
for (int i = 0; i < numRatings; i++) {
media.addRating(RAND.nextInt(maxRating - minRating + 1) + minRating);
}
}
}