├── .gitignore
├── README.md
├── pom.xml
└── src
├── main
└── java
│ ├── edu
│ └── duke
│ │ ├── DirectoryResource.java
│ │ ├── FileResource.java
│ │ ├── FileSelector.java
│ │ ├── ImageFrame.java
│ │ ├── ImageResource.java
│ │ ├── Pixel.java
│ │ ├── RangeResource.java
│ │ ├── ResourceException.java
│ │ ├── StorageResource.java
│ │ ├── TextIterable.java
│ │ ├── URLResource.java
│ │ └── package-info.java
│ ├── week2
│ ├── FindingAllGenes.java
│ ├── FindingAllLinks.java
│ ├── FindingGene.java
│ └── FindingLinks.java
│ ├── week3
│ ├── ParsingExportData.java
│ └── WeatherCSVProblem.java
│ └── week4
│ └── BabyNames.java
└── test
└── java
├── week3
├── ParsingExtraDataTests.java
└── WeatherCSVProblemTests.java
└── week4
└── BabyNamesTests.java
/.gitignore:
--------------------------------------------------------------------------------
1 | ##############################
2 | ## Java
3 | ##############################
4 | .mtj.tmp/
5 | *.class
6 | *.jar
7 | *.war
8 | *.ear
9 | *.nar
10 | hs_err_pid*
11 |
12 | ##############################
13 | ## Maven
14 | ##############################
15 | target/
16 | pom.xml.tag
17 | pom.xml.releaseBackup
18 | pom.xml.versionsBackup
19 | pom.xml.next
20 | pom.xml.bak
21 | release.properties
22 | dependency-reduced-pom.xml
23 | buildNumber.properties
24 | .mvn/timing.properties
25 | .mvn/wrapper/maven-wrapper.jar
26 |
27 | ##############################
28 | ## Gradle
29 | ##############################
30 | bin/
31 | build/
32 | .gradle
33 | .gradletasknamecache
34 | gradle-app.setting
35 | !gradle-wrapper.jar
36 |
37 | ##############################
38 | ## IntelliJ
39 | ##############################
40 | out/
41 | .idea/
42 | .idea_modules/
43 | *.iml
44 | *.ipr
45 | *.iws
46 |
47 | ##############################
48 | ## Eclipse
49 | ##############################
50 | .settings/
51 | bin/
52 | tmp/
53 | .metadata
54 | .classpath
55 | .project
56 | *.tmp
57 | *.bak
58 | *.swp
59 | *~.nib
60 | local.properties
61 | .loadpath
62 | .factorypath
63 |
64 | ##############################
65 | ## NetBeans
66 | ##############################
67 | nbproject/private/
68 | build/
69 | nbbuild/
70 | dist/
71 | nbdist/
72 | nbactions.xml
73 | nb-configuration.xml
74 |
75 | ##############################
76 | ## Visual Studio Code
77 | ##############################
78 | .vscode/
79 | .code-workspace
80 |
81 | ##############################
82 | ## OS X
83 | ##############################
84 | .DS_Store
85 |
86 | ##############################
87 | ## Other
88 | ##############################
89 |
90 | data/
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Java-Programming-Solving-Problems-with-Software
2 | Assignments of Coursera Course "Java Programming: Solving Problems with Software".
3 |
4 | ##### Assignments:
5 |
6 | **Week 1**: Iterables in Java; It was too easy. I decided not to create a branch.
7 |
8 | [**Week 2**](src/main/java/week2): Strings in Java;
9 |
10 | [**Week 3**](src/main/java/week3): CSV Files and Basic Statistics in Java;
11 |
12 | [**Week 4**](src/main/java/week4): MiniProject: Baby Names;
13 |
14 | [**Tests**](src/test/java/): available for week 3 and week 4.
15 |
16 | ---
17 | Good luck.
18 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | coursera.solving.problems
8 | solving-problem
9 | 1.0-SNAPSHOT
10 |
11 | 1.8
12 | 1.8
13 | UTF-8
14 | UTF-8
15 |
16 |
17 |
18 |
19 | junit
20 | junit
21 | 4.13
22 | test
23 |
24 |
25 | org.apache.commons
26 | commons-csv
27 | 1.4
28 | compile
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/src/main/java/edu/duke/DirectoryResource.java:
--------------------------------------------------------------------------------
1 | package edu.duke;
2 |
3 | import java.io.File;
4 | import java.util.ArrayList;
5 | import java.util.Arrays;
6 |
7 |
8 | /**
9 | * The DirectoryResource
class allows the user to choose one or more files from a
10 | * directory (or folder) with a file selection dialog box by using the method
11 | * selectedFiles
. These files can then be iterated over using a for
loop.
12 | *
13 | *
14 | * Example usage:
15 | *
16 | *
17 | * DirectoryResource dr = new DirectoryResource();
18 | * for (File f : dr.selectedFiles()) {
19 | * ImageResource ir = new ImageResource(f);
20 | * ir.draw();
21 | * }
22 | *
23 | *
24 | *
25 | * This software is licensed with an Apache 2 license, see
26 | * http://www.apache.org/licenses/LICENSE-2.0 for details.
27 | *
28 | * @author Duke Software Team
29 | */
30 | public class DirectoryResource {
31 | /**
32 | * Create a DirectoryResource
object.
33 | *
34 | * Creating a DirectoryResource
object does not open a dialog box for selecting
35 | * files.
36 | */
37 | public DirectoryResource () {
38 | // do nothing
39 | }
40 |
41 | /**
42 | * Open a file selection dialog box to allow the user to navigate to a directory and select one
43 | * or more files from the chosen directory (or folder).
44 | *
45 | * The file selection dialog box opened starts in the current project folder.
46 | *
47 | * @return an Iterable
that accesses the chosen files one at a time
48 | */
49 | public Iterable selectedFiles () {
50 | File[] files = FileSelector.selectFiles();
51 | // guaranteed to have at least one item
52 | if (files[0] == null) {
53 | // return empty list rather than null, so others can throw the exception if needed
54 | return new ArrayList();
55 | }
56 | else {
57 | return Arrays.asList(files);
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/edu/duke/FileResource.java:
--------------------------------------------------------------------------------
1 | package edu.duke;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Arrays;
5 | import java.net.URL;
6 | import java.io.BufferedReader;
7 | import java.io.InputStream;
8 | import java.io.InputStreamReader;
9 | import java.io.PrintWriter;
10 | import java.io.File;
11 | import java.io.FileInputStream;
12 | import java.io.FileWriter;
13 | import java.io.Reader;
14 | import java.io.StringReader;
15 | import org.apache.commons.csv.CSVFormat;
16 | import org.apache.commons.csv.CSVParser;
17 |
18 |
19 | /**
20 | * The FileResource
class represents a file and allows access to its contents a line at
21 | * a time, using the method lines
, or a word at a time, using the method
22 | * words
. These strings can then be iterated over using a for
loop.
23 | *
24 | *
25 | * Example usage:
26 | *
27 | *
28 | * FileResource fr = new FileResource();
29 | * for (String s : fr.words()) {
30 | * // print or process s
31 | * }
32 | *
33 | *
34 | *
35 | * If each line of the file represents separated data values, because its a CSV file, then the user
36 | * can get a getCSVParser
object to access that data more directly, using one of the
37 | * getCSVParser
methods.
38 | *
39 | *
40 | * Example CSV usage:
41 | *
42 | *
43 | * FileResource fr = new FileResource("food.csv");
44 | * for (CSVRecord record : fr.getCSVParser()) {
45 | * // print or process fields in record
46 | * String name = record.get("Name");
47 | * // other processing
48 | * }
49 | *
50 | *
51 | *
52 | * This software is licensed with an Apache 2 license, see
53 | * http://www.apache.org/licenses/LICENSE-2.0 for details.
54 | *
55 | * @author Duke Software Team
56 | */
57 | public class FileResource {
58 | private String myPath;
59 | private String mySource;
60 | private File mySaveFile;
61 |
62 | /**
63 | * Create a FileResource
object that opens the file chosen by the user using a file
64 | * selection dialog box.
65 | *
66 | * @throws exception if no file is selected by the user
67 | */
68 | public FileResource () {
69 | initRead();
70 | }
71 |
72 | /**
73 | * Create a FileResource
object that opens a file represented by the File object
74 | * passed as a parameter.
75 | *
76 | * Useful, for example, when used in conjunction with the DirectoryResource
class.
77 | *
78 | * @param file the file to be represented by this resource
79 | * @throws exception if the file cannot be accessed
80 | */
81 | public FileResource (File file) {
82 | initRead(file);
83 | }
84 |
85 | /**
86 | * Create a FileResource
object that opens a file whose name is passed as a
87 | * parameter.
88 | *
89 | * The named file should be on the current class path to be found.
90 | *
91 | * @param filename the name of the file to be opened
92 | * @throws exception if the filename cannot be accessed
93 | */
94 | public FileResource (String filename) {
95 | initRead(filename);
96 | }
97 |
98 | /**
99 | * Create a FileResource
object that opens the file chosen by the user using a file
100 | * selection dialog box, possibly to write to it.
101 | *
102 | * If the user wants to change the contents of the open file by using the method
103 | * write
to add new strings to it, pass true
as the second parameter.
104 | * Otherwise it is assumed the user will only iterate over the existing contents of the file.
105 | *
106 | * @param writable allow changes to this file only if true
107 | * @throws exception if no file is selected by the user
108 | */
109 | public FileResource (boolean writable) {
110 | if (writable) {
111 | initWrite();
112 | }
113 | else {
114 | initRead();
115 | }
116 | }
117 |
118 | /**
119 | * Create a FileResource
object that opens a file represented by the File object
120 | * passed as a parameter, possibly to write to it.
121 | *
122 | * If the user wants to change the contents of the open file by using the method
123 | * write
to add new strings to it, pass true
as the second parameter.
124 | * Otherwise it is assumed the user will only iterate over the existing contents of the file.
125 | *
126 | * Useful, for example, when used in conjunction with the DirectoryResource
class.
127 | *
128 | * @param file the file to be represented by this resource
129 | * @param writable allow changes to this file only if true
130 | * @throws exception if the file cannot be accessed
131 | */
132 | public FileResource (File file, boolean writable) {
133 | if (writable) {
134 | initWrite(file);
135 | }
136 | else {
137 | initRead(file);
138 | }
139 | }
140 |
141 | /**
142 | * Create a FileResource
object that opens a file whose name is passed as a
143 | * parameter, possibly to write to it.
144 | *
145 | * If the user wants to change the contents of the open file by using the method
146 | * write
to add new strings to it, pass true
as the second parameter.
147 | * Otherwise it is assumed the user will only iterate over the existing contents of the file.
148 | *
149 | * The named file should be on the current class path to be found.
150 | *
151 | * @param filename the name of the file to be opened
152 | * @param writable allow changes to this file only if true
153 | * @throws exception if the filename cannot be accessed
154 | */
155 | public FileResource (String filename, boolean writable) {
156 | if (writable) {
157 | initWrite(filename);
158 | }
159 | else {
160 | initRead(filename);
161 | }
162 | }
163 |
164 | /**
165 | * Allow access to this opened file one line at a time.
166 | *
167 | * @return an Iterable
that will allow access to contents of opened file one line
168 | * at a time.
169 | */
170 | public Iterable lines () {
171 | return new TextIterable(mySource, "\\n");
172 | }
173 |
174 | /**
175 | * Allow access to this opened file one word at a time, where words are separated by
176 | * white-space. This means any form of spaces, like tabs or newlines, can delimit words.
177 | *
178 | * @return an Iterable
that will allow access to contents of opened file one word
179 | * at a time.
180 | */
181 | public Iterable words () {
182 | return new TextIterable(mySource, "\\s+");
183 | }
184 |
185 | /**
186 | * Return entire contents of this opened file as one string.
187 | *
188 | * @return a String
that is the contents of the open file
189 | */
190 | public String asString () {
191 | return mySource;
192 | }
193 |
194 | /**
195 | * Returns a CSVParser
object to access the contents of an open file.
196 | *
197 | * Each line of the file should be formatted as data separated by commas and with a header row
198 | * to describe the column names.
199 | *
200 | * @return a CSVParser
that can provide access to the records in the file one at a
201 | * time
202 | * @throws exception if this file does not represent a CSV formatted data
203 | */
204 | public CSVParser getCSVParser () {
205 | return getCSVParser(true);
206 | }
207 |
208 | /**
209 | * Returns a CSVParser
object to access the contents of an open file, possibly
210 | * without a header row.
211 | *
212 | * Each line of the file should be formatted as data separated by commas and with/without a
213 | * header row to describe the column names.
214 | *
215 | * @param withHeader uses first row of data as a header row only if true
216 | * @return a CSVParser
that can provide access to the records in the file one at a
217 | * time
218 | * @throws exception if this file does not represent a CSV formatted data
219 | */
220 | public CSVParser getCSVParser (boolean withHeader) {
221 | return getCSVParser(withHeader, ",");
222 | }
223 |
224 | /**
225 | * Returns a CSVParser
object to access the contents of an open file, possibly
226 | * without a header row and a different data delimiter than a comma.
227 | *
228 | * Each line of the file should be formatted as data separated by the delimiter passed as a
229 | * parameter and with/without a header row to describe the column names. This is useful if the
230 | * data is separated by some character other than a comma.
231 | *
232 | * @param withHeader uses first row of data as a header row only if true
233 | * @param delimiter a single character that separates one field of data from another
234 | * @return a CSVParser
that can provide access to the records in the file one at a
235 | * time
236 | * @throws exception if this file does not represent a CSV formatted data
237 | * @throws exception if delimiter.length() != 1
238 | */
239 | public CSVParser getCSVParser (boolean withHeader, String delimiter) {
240 | if (delimiter == null || delimiter.length() != 1) {
241 | throw new ResourceException("FileResource: CSV delimiter must be a single character: " + delimiter);
242 | }
243 | try {
244 | char delim = delimiter.charAt(0);
245 | Reader input = new StringReader(mySource);
246 | if (withHeader) {
247 | return new CSVParser(input, CSVFormat.EXCEL.withHeader().withDelimiter(delim));
248 | }
249 | else {
250 | return new CSVParser(input, CSVFormat.EXCEL.withDelimiter(delim));
251 | }
252 | }
253 | catch (Exception e) {
254 | throw new ResourceException("FileResource: cannot read " + myPath + " as a CSV file.");
255 | }
256 | }
257 |
258 | /**
259 | * Allows access to the column names of the header row of a CSV file (the first line in the
260 | * file) one at a time. If the CSV file did not have a header row, then an empty
261 | * Iterator
is returned.
262 | *
263 | * @param parser the CSVParser
that has been created for this file
264 | * @return an Iterable
that allows access one header name at a time
265 | */
266 | public Iterable getCSVHeaders (CSVParser parser) {
267 | return parser.getHeaderMap().keySet();
268 | }
269 |
270 | /**
271 | * Writes a string to the end of this file.
272 | *
273 | * @param s the string to saved to the file
274 | */
275 | public void write (String s) {
276 | ArrayList list = new ArrayList<>();
277 | list.add(s);
278 | write(list);
279 | }
280 |
281 | /**
282 | * Writes a list of strings to the end of this file, one element per line.
283 | *
284 | * @param list the strings to saved to the file
285 | */
286 | public void write (StorageResource list) {
287 | // we know it is an ArrayList underneath
288 | write((ArrayList)(list.data()));
289 | }
290 |
291 | /**
292 | * Writes a list of strings to the end of this file, one element per line.
293 | *
294 | * @param list the strings to saved to the file
295 | */
296 | public void write (String[] list) {
297 | // BUGBUG: yuck :(
298 | write(new ArrayList(Arrays.asList(list)));
299 | }
300 |
301 | /**
302 | * Writes a list of strings to the end of this file, one element per line.
303 | *
304 | * @param list the strings to saved to the file
305 | */
306 | public void write (ArrayList list) {
307 | if (mySaveFile != null) {
308 | // build string to save
309 | StringBuilder sb = new StringBuilder();
310 | for (String s : list) {
311 | sb.append(s);
312 | sb.append("\n");
313 | }
314 | // save it locally (so it can be read later)
315 | mySource += sb.toString();
316 | // save it externally to the file
317 | try (PrintWriter writer = new PrintWriter(new FileWriter(mySaveFile, true))) {
318 | writer.println(sb.toString());
319 | }
320 | catch (Exception e) {
321 | throw new ResourceException("FileResource: cannot change " + mySaveFile);
322 | }
323 | }
324 | }
325 |
326 | // Prompt user for file to open
327 | private void initRead () {
328 | File f = FileSelector.selectFile();
329 | if (f == null) {
330 | throw new ResourceException("FileResource: no file choosen for reading");
331 | }
332 | else {
333 | initRead(f);
334 | }
335 | }
336 |
337 | // Create from a given File
338 | private void initRead (File f) {
339 | try {
340 | initRead(f.getCanonicalPath());
341 | }
342 | catch (Exception e) {
343 | throw new ResourceException("FileResource: cannot access " + f);
344 | }
345 | }
346 |
347 | // Create from the name of a File
348 | private void initRead (String fname) {
349 | try {
350 | myPath = fname;
351 | InputStream is = getClass().getClassLoader().getResourceAsStream(fname);
352 | if (is == null) {
353 | is = new FileInputStream(fname);
354 | }
355 | mySource = initFromStream(is);
356 | }
357 | catch (Exception e) {
358 | throw new ResourceException("FileResource: cannot access " + fname);
359 | }
360 | }
361 |
362 | // store data (keep in sync with URLResource)
363 | private String initFromStream (InputStream stream) {
364 | try (BufferedReader buff = new BufferedReader(new InputStreamReader(stream, "UTF-8"))) {
365 | StringBuilder contents = new StringBuilder();
366 | String line = null;
367 | while ((line = buff.readLine()) != null) {
368 | contents.append(line + "\n");
369 | }
370 | return contents.toString();
371 | }
372 | catch (Exception e) {
373 | throw new ResourceException("FileResource: error encountered reading " + myPath, e);
374 | }
375 | }
376 |
377 | // prompt user for file for writing
378 | private void initWrite () {
379 | File f = FileSelector.saveFile();
380 | if (f == null) {
381 | throw new ResourceException("FileResource: no file choosen for writing");
382 | }
383 | else {
384 | initWrite(f);
385 | }
386 | }
387 |
388 | // create file for writing
389 | private void initWrite (File f) {
390 | try {
391 | mySaveFile = f;
392 | if (f.exists() && f.canWrite()) {
393 | initRead(f);
394 | }
395 | else {
396 | mySource = "";
397 | myPath = f.getCanonicalPath();
398 | }
399 | }
400 | catch (Exception e) {
401 | throw new ResourceException("FileResource: cannot access " + f, e);
402 | }
403 | }
404 |
405 | // create file for writing
406 | private void initWrite (String fname) {
407 | try {
408 | URL loc = getClass().getClassLoader().getResource(fname);
409 | if (loc != null) {
410 | fname = loc.toString();
411 | }
412 | initWrite(new File(fname));
413 | }
414 | catch (Exception e) {
415 | throw new ResourceException("FileResource: cannot access " + fname);
416 | }
417 | }
418 | }
419 |
--------------------------------------------------------------------------------
/src/main/java/edu/duke/FileSelector.java:
--------------------------------------------------------------------------------
1 | package edu.duke;
2 |
3 | import java.io.File;
4 | import java.lang.reflect.InvocationTargetException;
5 | import javax.swing.JFileChooser;
6 | import javax.swing.JOptionPane;
7 | import javax.swing.SwingUtilities;
8 | import javax.swing.filechooser.FileFilter;
9 |
10 |
11 | /**
12 | * This utility class creates a thread safe file dialog box for loading and
13 | * saving files.
14 | *
15 | * @author Duke Software Team
16 | *
17 | * This software is licensed with an Apache 2 license, see
18 | * http://www.apache.org/licenses/LICENSE-2.0 for details.
19 | */
20 | class FileSelector {
21 | // result of selection
22 | private static File[] ourFiles;
23 | // BUGBUG: I think this is the right behavior, remembers where user left it last
24 | private static JFileChooser ourChooser = new JFileChooser();
25 | static {
26 | ourChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
27 | ourChooser.setCurrentDirectory(new File(System.getProperty("user.dir")));
28 | }
29 |
30 |
31 | /**
32 | * Pops up a dialog box to select only one file.
33 | *
34 | * @return
35 | */
36 | public static File selectFile () {
37 | // guaranteed to have one element, though it may be null
38 | return selectFiles(null, false, true)[0];
39 | }
40 |
41 | /**
42 | * Pops up a dialog box to select only one file with given extensions.
43 | */
44 | public static File selectFile (String[] extensionAccepted) {
45 | // guaranteed to have one element, though it may be null
46 | return selectFiles(extensionAccepted, false, true)[0];
47 | }
48 |
49 | /**
50 | * Pops up a dialog box to select multiple files.
51 | */
52 | public static File[] selectFiles () {
53 | return selectFiles(null, true, true);
54 | }
55 |
56 | /**
57 | * Pops up a dialog box to select multiple files with given extensions.
58 | * @return
59 | */
60 | public static File[] selectFiles (String[] extensionAccepted) {
61 | return selectFiles(extensionAccepted, true, true);
62 | }
63 |
64 | /**
65 | * Pops up a dialog box to save file with any extension.
66 | */
67 | public static File saveFile () {
68 | // guaranteed to have one element, though it may be null
69 | return selectFiles(null, false, false)[0];
70 | }
71 |
72 | /**
73 | * Pops up a dialog box to save file with given extensions.
74 | */
75 | public static File saveFile (String[] extensionAccepted) {
76 | // guaranteed to have one element, though it may be null
77 | return selectFiles(extensionAccepted, false, false)[0];
78 | }
79 |
80 |
81 | // BUGBUG: one general function, but lots of booleans :(
82 | private static File[] selectFiles (String[] extensionAccepted, boolean allowMultiple, boolean openForRead) {
83 | ourChooser.setMultiSelectionEnabled(allowMultiple);
84 | ourChooser.setFileFilter(new ChooserFilter(extensionAccepted));
85 |
86 | try {
87 | ourFiles = null;
88 | SwingUtilities.invokeAndWait(new Runnable() {
89 | @Override
90 | public void run () {
91 | int result = 0;
92 | if (openForRead) {
93 | result = ourChooser.showOpenDialog(null);
94 | }
95 | else {
96 | result = ourChooser.showSaveDialog(null);
97 | }
98 | if (result == JFileChooser.CANCEL_OPTION) {
99 | ourFiles = new File[] { null };
100 | } else {
101 | try {
102 | if (allowMultiple) {
103 | ourFiles = ourChooser.getSelectedFiles();
104 | } else {
105 | ourFiles = new File[] { ourChooser.getSelectedFile() };
106 | }
107 | } catch (Exception e) {
108 | JOptionPane.showMessageDialog(null, e.toString());
109 | }
110 | }
111 | }
112 | });
113 | return ourFiles;
114 | } catch (InvocationTargetException | InterruptedException e) {
115 | // it is still an exception, just not one required to be handled
116 | throw new RuntimeException(e);
117 | }
118 | }
119 |
120 |
121 | // This class implements a filter for image file names.
122 | static class ChooserFilter extends FileFilter {
123 | private String myExtensions;
124 |
125 | public ChooserFilter (String[] extensionsAccepted) {
126 | if (extensionsAccepted != null) {
127 | myExtensions = String.format("(?i).*\\.(%s)", String.join("|", extensionsAccepted));
128 | }
129 | }
130 | @Override
131 | public boolean accept (File f) {
132 | if (myExtensions != null) {
133 | return f.getName().matches(myExtensions) || f.isDirectory();
134 | } else {
135 | return true;
136 | }
137 | }
138 | @Override
139 | public String getDescription () {
140 | // BUGBUG: useful?
141 | return "Files";
142 | }
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/src/main/java/edu/duke/ImageFrame.java:
--------------------------------------------------------------------------------
1 | package edu.duke;
2 |
3 | import java.awt.Color;
4 | import java.awt.Container;
5 | import java.awt.Dimension;
6 | import java.awt.Graphics;
7 | import java.awt.Image;
8 | import javax.swing.JFrame;
9 | import javax.swing.JPanel;
10 |
11 |
12 | /**
13 | * This utility class implements a panel for displaying an image.
14 | *
15 | * @author Duke Software Team
16 | *
17 | * This software is licensed with an Apache 2 license, see
18 | * http://www.apache.org/licenses/LICENSE-2.0 for details.
19 | */
20 | class ImageFrame extends JFrame {
21 | private static final long serialVersionUID = 1L;
22 | private ImagePanel myPanel;
23 |
24 | /**
25 | * Creates an ImageFrame.
26 | */
27 | public ImageFrame (String fileName, Image image) {
28 | setTitle(fileName);
29 | // setResizable(false);
30 | setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
31 | }
32 |
33 | /**
34 | * Displays an image in this frame.
35 | */
36 | void show (Image image) {
37 | if (myPanel == null) {
38 | myPanel = new ImagePanel(image, image.getWidth(this), image.getHeight(this));
39 | Container c = getContentPane();
40 | c.setBackground(Color.WHITE);
41 | c.add(myPanel);
42 | pack();
43 | } else {
44 | myPanel.setImage(image, image.getWidth(this), image.getHeight(this));
45 | }
46 | setVisible(true);
47 | }
48 |
49 |
50 | // This class implements a panel for displaying an image.
51 | static class ImagePanel extends JPanel {
52 | private static final long serialVersionUID = 1L;
53 | private Image myImage;
54 |
55 | /**
56 | * Creates an ImagePanel.
57 | */
58 | public ImagePanel (Image image, int width, int height) {
59 | setBackground(Color.white);
60 | setPreferredSize(new Dimension(width, height));
61 | myImage = image;
62 | }
63 |
64 | /**
65 | * Resets the image and redraws it in the panel.
66 | */
67 | public void setImage (Image image, int width, int height) {
68 | this.myImage = image;
69 | setPreferredSize(new Dimension(width, height));
70 | repaint();
71 | }
72 |
73 | /**
74 | * Draws the image in the panel if the image is not null.
75 | */
76 | @Override
77 | public void paintComponent (Graphics g) {
78 | super.paintComponent(g);
79 | if (myImage != null) {
80 | g.drawImage(myImage, 0, 0, Color.white, this);
81 | }
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/main/java/edu/duke/ImageResource.java:
--------------------------------------------------------------------------------
1 | package edu.duke;
2 |
3 | import java.awt.Image;
4 | import java.awt.image.BufferedImage;
5 | import java.awt.image.ImageObserver;
6 | import java.awt.image.PixelGrabber;
7 | import javax.imageio.ImageIO;
8 | import java.io.File;
9 | import java.util.Arrays;
10 |
11 |
12 | /**
13 | * The ImageResource
class represents an image as a grid of Pixel
objects
14 | * and allows access to all of them, using the method pixels
. These pixels can then be
15 | * iterated over using a for
loop.
16 | *
17 | *
18 | * Note, no changes made to the pixels in this image affect the original image opened unless you use
19 | * the method save
.
20 | *
21 | *
22 | * Example usage:
23 | *
24 | *
25 | * ImageResource image = new ImageResource();
26 | * for (Pixel p : image.pixels()) {
27 | * int red = p.getRed();
28 | * int green = p.getGreen();
29 | * int blue = p.getBlue();
30 | * int average = (red + green + blue) / 3;
31 | * p.setRed(average);
32 | * p.setGreen(average);
33 | * p.setBlue(average);
34 | * }
35 | * image.draw();
36 | *
37 | *
38 | *
39 | * This is open-source software released under the terms of the GPL
40 | * (http://www.gnu.org/licenses/gpl.html).
41 | */
42 | public class ImageResource {
43 | // Default width and height of blank images
44 | static final int WIDTH = 200;
45 | static final int HEIGHT = 200;
46 |
47 | private Pixel[] myPixels;
48 | private BufferedImage myImage;
49 | // The file name info or empty if no file yet
50 | private String myFileName;
51 | private String myPath;
52 | // The image's display window
53 | private ImageFrame myDisplay;
54 |
55 | /**
56 | * Create an ImageResource
object that represents the file chosen by the user using
57 | * a file selection dialog box.
58 | *
59 | * @throws exception if no file is selected by the user
60 | */
61 | public ImageResource () {
62 | File file = FileSelector.selectFile(ImageIO.getReaderFileSuffixes());
63 | if (file == null) {
64 | throw new ResourceException("ImageResource: No image file choosen");
65 | }
66 | else {
67 | init(file);
68 | }
69 | }
70 |
71 | /**
72 | * Create an ImageResource
object whose size is the width and height passed as
73 | * parameters and whose pixels are all black.
74 | *
75 | * @param width the width of the image in pixels
76 | * @param height the height of the image in pixels
77 | * @throws exception if the width or height are not positive values
78 | */
79 | public ImageResource (int width, int height) {
80 | if (width <= 0 || height <= 0) {
81 | throw new ResourceException("ImageResource: witdh and height values must be positive [" + width + "x" + height + "]");
82 | }
83 | else {
84 | init("", getBlankImage(width, height));
85 | }
86 | }
87 |
88 | /**
89 | * Create an ImageResource
object from the file name passed as a parameter.
90 | *
91 | * @param fileName the name of the file
92 | * @throws exception if the file cannot be accessed or is not in an image format
93 | */
94 | public ImageResource (String fileName) {
95 | init(fileName, getImageFromFile(fileName));
96 | }
97 |
98 | /**
99 | * Create an ImageResource
object from a file given as a parameter.
100 | *
101 | * @param file the file representing an image
102 | * @throws exception if the file cannot be accessed or is not in an image format
103 | */
104 | public ImageResource (File file) {
105 | init(file);
106 | }
107 |
108 | /**
109 | * Create an ImageResource
object that is a copy of another image.
110 | *
111 | * @param other the original image being copied
112 | */
113 | public ImageResource (ImageResource other) {
114 | init(other.myPath + other.myFileName, other.myImage);
115 | }
116 |
117 | /**
118 | * Returns the width of the image in pixels.
119 | *
120 | * @return the image's width in pixels
121 | */
122 | public int getWidth () {
123 | return myImage.getWidth(myDisplay);
124 | }
125 |
126 | /**
127 | * Returns the height of the image in pixels.
128 | *
129 | * @return the image's height in pixels
130 | */
131 | public int getHeight () {
132 | return myImage.getHeight(myDisplay);
133 | }
134 |
135 | /**
136 | * Allow access to this image one pixel at a time.
137 | *
138 | * @return an Iterable
that will allow access to each pixel in this image
139 | */
140 | public Iterable pixels () {
141 | if (myPixels == null) {
142 | throw new ResourceException("ImageResource: not ready to iterate over pixels");
143 | }
144 | return Arrays.asList(myPixels);
145 | }
146 |
147 | /**
148 | * Displays this image in a separate window.
149 | */
150 | public void draw () {
151 | updateImage();
152 | myDisplay.show(myImage);
153 | }
154 |
155 | /**
156 | * Returns the file name associated with this image.
157 | *
158 | * @return the name of the file used to create this image or an empty string if it was created
159 | * as a sized image
160 | */
161 | public String getFileName () {
162 | return myFileName;
163 | }
164 |
165 | /**
166 | * Resets the file name associated with this image.
167 | *
168 | * Useful, for example, when saving the results of changes to this image in a different file
169 | * than the original.
170 | *
171 | * @param name the new name for the file
172 | */
173 | public void setFileName (String name) {
174 | if (!name.equals("")) {
175 | myFileName = name;
176 | myDisplay.setTitle(myFileName);
177 | }
178 | }
179 |
180 | /**
181 | * Returns the pixel at the (x, y) coordinates passed as a parameter.
182 | *
183 | * @param x the column position of the pixel
184 | * @param y the row position of the pixel
185 | * @return the Pixel at the given (x, y) coordinates
186 | */
187 | public Pixel getPixel (int x, int y) {
188 | // System.out.printf("get %d %d\n",x,y);
189 | return myPixels[y * getWidth() + x];
190 | }
191 |
192 | /**
193 | * Resets the pixel at the given (x, y) coordinates but does not redraw it.
194 | *
195 | * @param x the column position of the pixel
196 | * @param y the row position of the pixel
197 | * @param p the new pixel values to use
198 | */
199 | public void setPixel (int x, int y, Pixel p) {
200 | if (0 <= x && x < getWidth() && 0 <= y && y < getHeight()) {
201 | myPixels[y * getWidth() + x] = p;
202 | }
203 | }
204 |
205 | /**
206 | * Returns a string representation of the image (file name, width, and height).
207 | *
208 | * @return a string representation of the image
209 | */
210 | public String toString () {
211 | if (myImage == null) {
212 | return "";
213 | }
214 | else {
215 | return "IMAGE\n" + "File name: " + myFileName + "\n" + "Width: " + getWidth() + "\n" + "Height: " + getHeight();
216 | }
217 | }
218 |
219 | /**
220 | * Saves the image as a JPEG using its current file name or opens a file selection dialog box to
221 | * allow the user to choose a name if no file name set (for example if this image was created as
222 | * a blank sized image).
223 | *
224 | * @throws exception if the current filename cannot be accessed for saving
225 | */
226 | public void save () {
227 | if (myFileName.equals("")) {
228 | saveAs();
229 | }
230 | try {
231 | updateImage();
232 | File file = new File(myPath + myFileName);
233 | ImageIO.write(myImage, "jpg", file);
234 | }
235 | catch (Exception e) {
236 | throw new ResourceException("ImageResource: unable to save image to a file ", e);
237 | }
238 | }
239 |
240 | /**
241 | * Saves the image as a JPEG by opening a file selection dialog box to allow the user to choose
242 | * the new name for the file.
243 | *
244 | * @throws exception if no file is selected by the user
245 | */
246 | public void saveAs () {
247 | File f = FileSelector.saveFile(ImageIO.getWriterFileSuffixes());
248 | if (f == null) {
249 | throw new ResourceException("ImageResource: no file chosen for save.");
250 | }
251 | else {
252 | try {
253 | setPath(f.getCanonicalPath());
254 | save();
255 | }
256 | catch (Exception e) {
257 | // should never happen because we got the file from a dialog box
258 | throw new ResourceException("ImageResource: unable to save image to " + f, e);
259 | }
260 | }
261 | }
262 |
263 | // Maps the image into the array of pixels
264 | private Pixel[] imageToPixels (Image image) {
265 | int w = getWidth();
266 | int h = getHeight();
267 | int[] pixels = new int[w * h];
268 | PixelGrabber pg = new PixelGrabber(image, 0, 0, w, h, pixels, 0, w);
269 | try {
270 | pg.grabPixels();
271 | }
272 | catch (InterruptedException e) {
273 | System.err.println("Interrupted waiting for pixels!");
274 | return null;
275 | }
276 | if ((pg.getStatus() & ImageObserver.ABORT) != 0) {
277 | System.err.println("Image fetch aborted or errored");
278 | return null;
279 | }
280 | // System.out.printf("creating pixels %d\n", pixels.length);
281 | return intsToPixels(pixels, w, h);
282 | }
283 |
284 | // Maps an array of int to an array of pixels
285 | private Pixel[] intsToPixels (int[] pixels, int width, int height) {
286 | if (pixels == null) {
287 | throw new ResourceException(String.format("ImageResource: no pixels for %d %d\n", width, height));
288 | }
289 | Pixel[] pix = new Pixel[pixels.length];
290 | // System.out.printf("creating %d pixels on %d
291 | // %d\n",pix.length,width,height);
292 | for (int i = 0; i < pixels.length; i++) {
293 | // System.out.printf("pix at %d %d %d\n", i/width,i%width,i);
294 | pix[i] = new Pixel(pixels[i], i % width, i / width);
295 | }
296 | // System.out.printf("returning %d\n", pix.length);
297 | return pix;
298 | }
299 |
300 | // Maps an array of pixels to an array of int
301 | private int[] pixelsToInts (Pixel[] pixels) {
302 | int[] pix = new int[pixels.length];
303 | for (int i = 0; i < pixels.length; i++)
304 | pix[i] = pixels[i].getValue();
305 | return pix;
306 | }
307 |
308 | // update Java image to reflect pixel values
309 | private void updateImage () {
310 | int width = getWidth();
311 | int height = getHeight();
312 | myImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
313 | myImage.setRGB(0, 0, width, height, pixelsToInts(myPixels), 0, width);
314 | }
315 |
316 | // Creates an image of width w and height h with black pixels
317 | private BufferedImage getBlankImage (int width, int height) {
318 | return new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
319 | }
320 |
321 | // Reads an image from a file and updates the pixels array
322 | private BufferedImage getImageFromFile (String fileName) {
323 | try {
324 | File file = new File(fileName);
325 | BufferedImage image = ImageIO.read(file);
326 | while (image.getWidth(null) < 0) {
327 | // wait for size to be known
328 | }
329 | return image;
330 | }
331 | catch (Exception e) {
332 | System.err.println(e);
333 | return null;
334 | }
335 | }
336 |
337 | // breaks the path into the root and simple file name
338 | private void setPath (String fileName) {
339 | int index = fileName.lastIndexOf(File.separator);
340 | if (index == -1) {
341 | myPath = "";
342 | }
343 | else {
344 | myFileName = fileName.substring(index + 1);
345 | myPath = fileName.substring(0, index + 1);
346 | }
347 | // System.err.printf("full = %s\nshort = %s\n", myPath, myFileName);
348 | }
349 |
350 | // creates an image from the given file
351 | private void init (File f) {
352 | try {
353 | String path = f.getCanonicalPath();
354 | init(path, getImageFromFile(path));
355 | }
356 | catch (Exception e) {
357 | throw new ResourceException("ImageResource: unable to find " + f);
358 | }
359 | }
360 |
361 | // associates the given image with the given filename
362 | private void init (String fileName, BufferedImage image) {
363 | try {
364 | setPath(fileName);
365 | myImage = image;
366 | myDisplay = new ImageFrame(fileName, image);
367 | myPixels = imageToPixels(myImage);
368 | // System.out.printf("init: %d %d %s\n", getWidth(), getHeight(), myPath);
369 | }
370 | catch (Exception e) {
371 | throw new ResourceException("ImageResource: not an image file " + fileName);
372 | }
373 | }
374 | }
375 |
--------------------------------------------------------------------------------
/src/main/java/edu/duke/Pixel.java:
--------------------------------------------------------------------------------
1 | package edu.duke;
2 |
3 |
4 | /**
5 | * The Pixel
class represents a color as its component values of
6 | * red, green, blue, as well as alpha (for transparency).
7 | *
8 | *
9 | * Each of the component values of a pixel must have a value between 0 and 255.
10 | * If a value is given outside that range, it is changed to be within that range.
11 | * As such, a negative value would be set to 0 and a value greater than 255 would
12 | * be set to 255.
13 | *
14 | *
15 | * Example usage:
16 | *
17 | *
18 | * ImageResource image = new ImageResource();
19 | * for (Pixel p : image.pixels()) {
20 | * int red = p.getRed();
21 | * int green = p.getGreen();
22 | * int blue = p.getBlue();
23 | * int average = (red + green + blue) / 3;
24 | * p.setRed(average);
25 | * p.setGreen(average);
26 | * p.setBlue(average);
27 | * }
28 | * image.draw();
29 | *
30 | *
31 | *
32 | * This is open-source software released under the terms of the GPL
33 | * (http://www.gnu.org/licenses/gpl.html).
34 | */
35 | public class Pixel {
36 | static final int MAX_VALUE = 255;
37 | private int alpha = MAX_VALUE, red = 0, green = 0, blue = 0;
38 | private int myX;
39 | private int myY;
40 |
41 | /**
42 | * Creates a Pixel from an integer value.
43 | *
44 | * @param i the integer value representing all the color components
45 | * @param x the x-coordinate of this pixel in the image
46 | * @param y the y-coordinate of this pixel in the image
47 | */
48 | Pixel (int i, int x, int y) {
49 | myX = x;
50 | myY = y;
51 | setValue(i);
52 | }
53 |
54 | /**
55 | * Creates a Pixel from RGB values and an Alpha value (for transparency).
56 | *
57 | * @param r the red value
58 | * @param g the green value
59 | * @param b the blue value
60 | * @param a the Alpha value
61 | * @param x the x-coordinate of this pixel in the image
62 | * @param y the y-coordinate of this pixel in the image
63 | */
64 | Pixel (int r, int g, int b, int a, int x, int y) {
65 | red = r;
66 | green = g;
67 | blue = b;
68 | alpha = a;
69 | myX = x;
70 | myY = y;
71 | }
72 |
73 | /**
74 | * Creates a Pixel from RGB values.
75 | *
76 | * @param r the red value
77 | * @param g the green value
78 | * @param b the blue value
79 | * @param x the x-coordinate of this pixel in the image
80 | * @param y the y-coordinate of this pixel in the image
81 | */
82 | Pixel (int r, int g, int b, int x, int y) {
83 | this(r, g, b, MAX_VALUE, x, y);
84 | }
85 |
86 | /**
87 | * Creates a new Pixel from with the same values as the other pixel passed
88 | * as a parameter.
89 | *
90 | * @param other another pixel
91 | */
92 | public Pixel (Pixel other) {
93 | this(other.getRed(), other.getGreen(), other.getBlue(),
94 | other.getAlpha(), other.getX(), other.getY());
95 | }
96 |
97 | /**
98 | * Returns the pixel's x-coordinate within the image.
99 | *
100 | * @return the x-coordinate of this pixel.
101 | */
102 | public int getX () {
103 | return myX;
104 | }
105 |
106 | /**
107 | * Returns the pixel's y-coordinate within the image.
108 | *
109 | * @return the y-coordinate of this pixel.
110 | */
111 | public int getY () {
112 | return myY;
113 | }
114 |
115 | /**
116 | * Returns the value of the pixel's red component.
117 | *
118 | * @return the pixel's red value within the range 0-255
119 | */
120 | public int getRed () {
121 | return red;
122 | }
123 |
124 | /**
125 | * Returns the value of the pixel's green component.
126 | *
127 | * @return the pixel's green value within the range 0-255
128 | */
129 | public int getGreen () {
130 | return green;
131 | }
132 |
133 | /**
134 | * Returns the value of the pixel's blue component.
135 | *
136 | * @return the pixel's blue value within the range 0-255
137 | */
138 | public int getBlue () {
139 | return blue;
140 | }
141 |
142 | /**
143 | * Returns the value of the pixel's alpha (or transparency) component.
144 | *
145 | * @return the pixel's alpha value within the range 0-255
146 | */
147 | public int getAlpha () {
148 | return alpha;
149 | }
150 |
151 | /**
152 | * Resets the value of the pixel's red component to the value passed as a parameter.
153 | * If it is not in the range of 0-255 it is changed to be in that range.
154 | *
155 | * @param r the red value
156 | */
157 | public void setRed (int r) {
158 | red = clamp(r);
159 | }
160 |
161 | /**
162 | * Resets the value of the pixel's green component to the value passed as a parameter.
163 | * If it is not in the range of 0-255 it is changed to be in that range.
164 | *
165 | * @param g the green value
166 | */
167 | public void setGreen (int g) {
168 | green = clamp(g);
169 | }
170 |
171 | /**
172 | * Resets the value of the pixel's blue component to the value passed as a parameter.
173 | * If it is not in the range of 0-255 it is changed to be in that range.
174 | *
175 | * @param b the blue value
176 | */
177 | public void setBlue (int b) {
178 | blue = clamp(b);
179 | }
180 |
181 | /**
182 | * Resets the value of the pixel's alpha (or transparency) component to the value passed as a parameter.
183 | * If it is not in the range of 0-255 it is changed to be in that range.
184 | *
185 | * @param a the alpha value
186 | */
187 | public void setAlpha (int a) {
188 | alpha = clamp(a);
189 | }
190 |
191 | /**
192 | * Returns the string representation of the of the pixel.
193 | *
194 | * @return a string containing the RGB values
195 | */
196 | public String toString () {
197 | return "Pixel R: " + red + " G: " + green + " B: " + blue;
198 | }
199 |
200 | // returns the integer value of the pixel.
201 | int getValue () {
202 | return (alpha << 24) | (red << 16) | (green << 8) | blue;
203 | }
204 |
205 | // resets the pixel to an integer value.
206 | void setValue (int pixel) {
207 | alpha = (pixel >> 24) & 0xff;
208 | red = (pixel >> 16) & 0xff;
209 | green = (pixel >> 8) & 0xff;
210 | blue = (pixel) & 0xff;
211 | }
212 |
213 | // clamps the given value to a valid pixel value
214 | private int clamp (int value) {
215 | return Math.max(0, Math.min(value, MAX_VALUE));
216 | }
217 | }
218 |
--------------------------------------------------------------------------------
/src/main/java/edu/duke/RangeResource.java:
--------------------------------------------------------------------------------
1 | package edu.duke;
2 |
3 | import java.util.List;
4 | import java.util.ArrayList;
5 |
6 |
7 | /**
8 | * The RangeResource
class represents a range of integer (or whole) numbers and allows
9 | * access to these numbers using the method sequence
. The integers can then be iterated
10 | * over using a for
loop
11 | *
12 | *
13 | * Example usage:
14 | *
15 | *
16 | * // this prints the square number sequence for the first 9 numbers:
17 | * // 1, 4, 9, 16, 25, 36, 49, 64, 81
18 | * RangeResource rr = new RangeResource(1, 10);
19 | * for (int value : rr.sequence()) {
20 | * System.out.println(value * value);
21 | * }
22 | *
23 | *
24 | *
25 | * Another example usage:
26 | *
27 | *
28 | * // this prints the odd numbers in decreasing order within the given range:
29 | * // 37, 35, 33, 31, 29, 27, 25, 23
30 | * RangeResource rr = new RangeResource(37, 21, -2);
31 | * for (int value : rr.sequence()) {
32 | * System.out.println(value);
33 | * }
34 | *
35 | *
36 | *
37 | * This software is licensed with an Apache 2 license, see
38 | * http://www.apache.org/licenses/LICENSE-2.0 for details.
39 | *
40 | * @author Duke Software Team
41 | */
42 | public class RangeResource {
43 | private int myStart;
44 | private int myEnd;
45 | private int myIncrement;
46 | private List myValues;
47 |
48 | /**
49 | * Create a RangeResource
object, starting at 0 and going up to but not including
50 | * end, [0 - end), that increments by 1.
51 | *
52 | * @param end when to stop the range, not included as one of the values
53 | * @throws exception if the end is negative
54 | */
55 | public RangeResource (int end) {
56 | this(0, end, 1);
57 | }
58 |
59 | /**
60 | * Create a RangeResource
object, starting at start and going up to but not
61 | * including end, [start - end), that increments by 1.
62 | *
63 | * @param start the first value in the range, included as one of the values
64 | * @param end when to stop the range, not included as one of the values
65 | * @throws exception if the end is less than the start
66 | */
67 | public RangeResource (int start, int end) {
68 | this(start, end, 1);
69 | }
70 |
71 | /**
72 | * Create a RangeResource
object, starting at start and going up to but not
73 | * including end, [start - end), that increments by the amount passed as a parameter.
74 | *
75 | * @param start the first value in the range, included as one of the values
76 | * @param end when to stop the range, not included as one of the values
77 | * @param increment how much to add to get the next value in the range's sequence
78 | * @throws exception if increment is negative when the end is greater than the start
79 | * @throws exception if increment is positive when the end is less than the start
80 | * @throws exception if increment is 0
81 | */
82 | public RangeResource (int start, int end, int increment) {
83 | if (increment == 0) {
84 | throw new ResourceException("RangeResource: invalid increment, cannot be 0");
85 | }
86 | if (end < start && increment > 0) {
87 | throw new ResourceException("RangeResource: invalid increment, cannot be positive when end (" + end
88 | + ") is less than start (" + start + ")");
89 | }
90 | if (end > start && increment < 0) {
91 | throw new ResourceException("RangeResource: invalid increment, cannot be negative when end (" + end
92 | + ") is greater than start (" + start + ")");
93 | }
94 | myStart = start;
95 | myEnd = end;
96 | myIncrement = increment;
97 | myValues = makeValues(start, end, increment);
98 | }
99 |
100 | /**
101 | * Create an RangeResource
object that is a copy of another range.
102 | *
103 | * @param other the original range being copied
104 | */
105 | public RangeResource (RangeResource other) {
106 | this(other.myStart, other.myEnd, other.myIncrement);
107 | }
108 |
109 | /**
110 | * Return string representation of this range, with each value in the sequence separated by a
111 | * comma.
112 | *
113 | * @return a String
containing all the values in the range
114 | */
115 | @Override
116 | public String toString () {
117 | // System.out.println("RANGE: [" + myStart + ".." + myEnd + ") by " + myIncrement);
118 | return myValues.toString();
119 | // old iteration way
120 | // StringBuilder result = new StringBuilder();
121 | // result.append("[ ");
122 | // for (int k : this.sequence()) {
123 | // result.append(k + " ");
124 | // }
125 | // result.append("]");
126 | // return result.toString();
127 | }
128 |
129 | /**
130 | * Allow access to the numbers in this range one at a time.
131 | *
132 | * @return an Iterable
that will allow access to each number in this range
133 | */
134 | public Iterable sequence () {
135 | return myValues;
136 | // left in case we want to show another example of an iterator
137 | // return new Iterable() {
138 | // @Override
139 | // public Iterator iterator () {
140 | // return new Iterator() {
141 | // private int place = myStart;
142 | // @Override
143 | // public boolean hasNext () {
144 | // if (myIncrement > 0) {
145 | // return place < myEnd;
146 | // }
147 | // else {
148 | // return place > myEnd;
149 | // }
150 | // }
151 | // @Override
152 | // public Integer next () {
153 | // int result = place;
154 | // place += myIncrement;
155 | // return result;
156 | // }
157 | // };
158 | // }
159 | // };
160 | }
161 |
162 | // generate the values in the range (much simpler than building an Iterator)
163 | private List makeValues (int start, int end, int increment) {
164 | List result = new ArrayList<>();
165 | while (true) {
166 | if (increment > 0 && start >= end) {
167 | break;
168 | }
169 | else if (increment < 0 && start <= end) {
170 | break;
171 | }
172 | result.add(start);
173 | start += increment;
174 | }
175 | return result;
176 | }
177 | }
178 |
--------------------------------------------------------------------------------
/src/main/java/edu/duke/ResourceException.java:
--------------------------------------------------------------------------------
1 | package edu.duke;
2 |
3 |
4 | /**
5 | * A general exception for Resource objects.
6 | *
7 | *
8 | * Note, this is a RuntimeException so that it does not HAVE to be caught,
9 | * but still gives useful information about the error.
10 | *
11 | *
12 | * This software is licensed with an Apache 2 license, see
13 | * http://www.apache.org/licenses/LICENSE-2.0 for details.
14 | *
15 | * @author Duke Software Team
16 | */
17 | public class ResourceException extends RuntimeException {
18 | private static final long serialVersionUID = 1L;
19 |
20 | public ResourceException (String message) {
21 | super(message);
22 | }
23 |
24 | public ResourceException (String message, Throwable cause) {
25 | super(message, cause);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/edu/duke/StorageResource.java:
--------------------------------------------------------------------------------
1 | package edu.duke;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Arrays;
5 | import java.util.List;
6 |
7 |
8 | /**
9 | * The StorageResource
class stores any number of String
objects and
10 | * allows access to these stored values one at a time, using the method data
. These
11 | * strings can then be iterated over in the order they were added using a for
loop.
12 | *
13 | *
14 | * This class mirrors an ArrayList<String>
in some functionality, but is simpler
15 | * to use and fits the Duke/Coursersa model of creating and using iterables.
16 | *
17 | *
18 | * Example usage:
19 | *
20 | *
21 | * FileResource fr = new FileResource();
22 | * StorageResource store = new StorageResource();
23 | * for (String s : fr.words()) {
24 | * store.add(s);
25 | * }
26 | * // can process store here, e.g.,
27 | * // get number of strings stored
28 | * int x = store.size();
29 | * for (String s : store.data()) {
30 | * // print or process s
31 | * }
32 | *
33 | *
34 | *
35 | * This software is licensed with an Apache 2 license, see
36 | * http://www.apache.org/licenses/LICENSE-2.0 for details.
37 | *
38 | * @author Duke Software Team
39 | */
40 | public class StorageResource {
41 | private List myStrings;
42 |
43 | /**
44 | * Create an empty StorageResource
object
45 | */
46 | public StorageResource () {
47 | myStrings = new ArrayList<>();
48 | }
49 |
50 | /**
51 | * Create a StorageResource
object, loaded with the Strings passed as parameters.
52 | */
53 | StorageResource (String... data) {
54 | myStrings = new ArrayList<>(Arrays.asList(data));
55 | }
56 |
57 | /**
58 | * Create an StorageResource
object that is a copy of another list.
59 | *
60 | * @param other the original list being copied
61 | */
62 | public StorageResource (StorageResource other) {
63 | myStrings = new ArrayList<>(other.myStrings);
64 | }
65 |
66 | /**
67 | * Remove all strings from this object so that .size() == 0
.
68 | */
69 | public void clear () {
70 | myStrings.clear();
71 | }
72 |
73 | /**
74 | * Adds a string to this storage object.
75 | *
76 | * @param s the value added
77 | */
78 | public void add (String s) {
79 | myStrings.add(s);
80 | }
81 |
82 | /**
83 | * Returns the number of strings added/stored in this object.
84 | *
85 | * @return the number of strings stored in the object
86 | */
87 | public int size () {
88 | return myStrings.size();
89 | }
90 |
91 | /**
92 | * Determines if a string is stored in this object.
93 | *
94 | * @param s string searched for
95 | * @return true if and only if s is stored in this object
96 | */
97 | public boolean contains (String s) {
98 | return myStrings.contains(s);
99 | }
100 |
101 | /**
102 | * Create and return an iterable for all strings in this object.
103 | *
104 | * @return an Iterable
that allows access to each string in the order stored
105 | */
106 | public Iterable data () {
107 | return myStrings;
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/src/main/java/edu/duke/TextIterable.java:
--------------------------------------------------------------------------------
1 | package edu.duke;
2 |
3 | import java.util.Iterator;
4 |
5 |
6 | /**
7 | * This utility class allows multiple classes to iterate over a text source in
8 | * multiple ways.
9 | *
10 | * It also serves to show how to implement an iterator.
11 | *
12 | * @author Duke Software Team
13 | *
14 | * This software is licensed with an Apache 2 license, see
15 | * http://www.apache.org/licenses/LICENSE-2.0 for details.
16 | */
17 | class TextIterable implements Iterable {
18 | private String[] myStrings;
19 |
20 | /**
21 | * Create from a given string.
22 | */
23 | public TextIterable (String source, String regexp) {
24 | myStrings = source.split(regexp);
25 | }
26 |
27 | /**
28 | * @see java.lang.Iterator
29 | */
30 | @Override
31 | public Iterator iterator () {
32 | return new Iterator() {
33 | private int myCount = 0;
34 |
35 | @Override
36 | public boolean hasNext () {
37 | return myCount < myStrings.length;
38 | }
39 |
40 | @Override
41 | public String next () {
42 | String s = myStrings[myCount];
43 | myCount++;
44 | return s;
45 | }
46 | };
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/edu/duke/URLResource.java:
--------------------------------------------------------------------------------
1 | package edu.duke;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.InputStream;
5 | import java.io.InputStreamReader;
6 | import java.io.Reader;
7 | import java.io.StringReader;
8 | import java.net.URL;
9 | import org.apache.commons.csv.CSVFormat;
10 | import org.apache.commons.csv.CSVParser;
11 |
12 |
13 | /**
14 | * The URLResource
class opens a connection to a URL and allows access to the contents
15 | * of the web page a line at a time, using the method lines
, or a word at a time, using
16 | * the method words
. These strings can then be iterated over using a for
17 | * loop.
18 | *
19 | *
20 | * Example usage:
21 | *
22 | *
23 | * URLResource ur = new URLResource("http://www.dukelearntoprogram.com/");
24 | * for (String s : ur.lines()) {
25 | * // print or process s
26 | * }
27 | *
28 | *
29 | *
30 | * If each line of the web page represents separated data values, because its a CSV file, then the
31 | * user can get a getCSVParser
object to access that data more directly, using one of the
32 | * getCSVParser
methods.
33 | *
34 | *
35 | * Example CSV usage:
36 | *
37 | *
38 | * URLResource ur = new URLResource("http://www.dukelearntoprogram.com/course2/java/food.csv");
39 | * for (CSVRecord record : ur.getCSVParser()) {
40 | * // print or process fields in record
41 | * String name = record.get("Name");
42 | * // other processing
43 | * }
44 | *
45 | *
46 | *
47 | * This software is licensed with an Apache 2 license, see
48 | * http://www.apache.org/licenses/LICENSE-2.0 for details.
49 | *
50 | * @author Duke Software Team
51 | */
52 | public class URLResource {
53 | private String myPath;
54 | private String mySource;
55 |
56 | /**
57 | * Create a URLResource
object bound to the web page whose URL is given as the
58 | * parameter.
59 | *
60 | * Constructing the object opens a connection and reads the contents of the web page.
61 | *
62 | * @param name is the name of the URL, it must start with "http" or "https"
63 | * @throws exception if the URL does not start with "http" or "https"
64 | */
65 | public URLResource (String name) {
66 | if (name.startsWith("http://") || name.startsWith("https://")) {
67 | try {
68 | mySource = initFromStream(new URL(name).openStream());
69 | myPath = name;
70 | }
71 | catch (Exception e) {
72 | throw new ResourceException("URLResource: unable to load URL with name " + name, e);
73 | }
74 | }
75 | else {
76 | throw new ResourceException("URLResource: name must start with http:// or https://" + name);
77 | }
78 | }
79 |
80 | /**
81 | * Allow access to open web page one line at a time.
82 | *
83 | * @return an Iterable
that allows access one line at a time
84 | */
85 | public Iterable lines () {
86 | return new TextIterable(mySource, "\\n");
87 | }
88 |
89 | /**
90 | * Allow access to this open web page one word at a time, where words are separated by
91 | * white-space. This means any form of spaces, like tabs or newlines, can delimit words.
92 | *
93 | * @return an Iterable
that allows access one word at a time
94 | */
95 | public Iterable words () {
96 | return new TextIterable(mySource, "\\s+");
97 | }
98 |
99 | /**
100 | * Return entire open web page as one string.
101 | *
102 | * @return a String
that is the contents of the open web page
103 | */
104 | public String asString () {
105 | return mySource;
106 | }
107 |
108 | /**
109 | * Returns a CSVParser
object to access the contents of an open web page.
110 | *
111 | * Each line of the web page should be formatted as data separated by commas and with a header
112 | * row to describe the column names.
113 | *
114 | * @return a CSVParser
that can provide access to the records in the web page one
115 | * at a time
116 | * @throws exception if this web page does not represent a CSV formatted data
117 | */
118 | public CSVParser getCSVParser () {
119 | return getCSVParser(true);
120 | }
121 |
122 | /**
123 | * Returns a CSVParser
object to access the contents of an open web page, possibly
124 | * without a header row.
125 | *
126 | * Each line of the web page should be formatted as data separated by commas and with/without a
127 | * header row to describe the column names.
128 | *
129 | * @param withHeader uses first row of data as a header row only if true
130 | * @return a CSVParser
that can provide access to the records in the web page one
131 | * at a time
132 | * @throws exception if this web page does not represent a CSV formatted data
133 | */
134 | public CSVParser getCSVParser (boolean withHeader) {
135 | return getCSVParser(withHeader, ",");
136 | }
137 |
138 | /**
139 | * Returns a CSVParser
object to access the contents of an open web page, possibly
140 | * without a header row and a different data delimiter than a comma.
141 | *
142 | * Each line of the web page should be formatted as data separated by the delimiter passed as a
143 | * parameter and with/without a header row to describe the column names. This is useful if the
144 | * data is separated by some character other than a comma.
145 | *
146 | * @param withHeader uses first row of data as a header row only if true
147 | * @param delimiter a single character that separates one field of data from another
148 | * @return a CSVParser
that can provide access to the records in the web page one
149 | * at a time
150 | * @throws exception if this web page does not represent a CSV formatted data
151 | * @throws exception if delimiter.length() != 1
152 | */
153 | public CSVParser getCSVParser (boolean withHeader, String delimiter) {
154 | if (delimiter == null || delimiter.length() != 1) {
155 | throw new ResourceException("URLResource: CSV delimiter must be a single character: " + delimiter);
156 | }
157 | try {
158 | char delim = delimiter.charAt(0);
159 | Reader input = new StringReader(mySource);
160 | if (withHeader) {
161 | return new CSVParser(input, CSVFormat.EXCEL.withHeader().withDelimiter(delim));
162 | }
163 | else {
164 | return new CSVParser(input, CSVFormat.EXCEL.withDelimiter(delim));
165 | }
166 | }
167 | catch (Exception e) {
168 | throw new ResourceException("URLResource: cannot read " + myPath + " as a CSV file.");
169 | }
170 | }
171 |
172 | /**
173 | * Allows access to the column names of the header row of a CSV file (the first line in the
174 | * file) one at a time. If the CSV file did not have a header row, then an empty
175 | * Iterator
is returned.
176 | *
177 | * @param parser the CSVParser
that has been created for this web page
178 | * @return an Iterable
that allows access one header name at a time
179 | */
180 | public Iterable getCSVHeaders (CSVParser parser) {
181 | return parser.getHeaderMap().keySet();
182 | }
183 |
184 | // store data (keep in sync with URLResource)
185 | private String initFromStream (InputStream stream) {
186 | try (BufferedReader buff = new BufferedReader(new InputStreamReader(stream, "UTF-8"))) {
187 | StringBuilder contents = new StringBuilder();
188 | String line = null;
189 | while ((line = buff.readLine()) != null) {
190 | contents.append(line + "\n");
191 | }
192 | return contents.toString();
193 | }
194 | catch (Exception e) {
195 | throw new ResourceException("URLResource: error encountered reading " + myPath, e);
196 | }
197 | }
198 | }
199 |
--------------------------------------------------------------------------------
/src/main/java/edu/duke/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Resource classes for Duke/Coursera course.
3 | */
4 | package edu.duke;
5 |
--------------------------------------------------------------------------------
/src/main/java/week2/FindingAllGenes.java:
--------------------------------------------------------------------------------
1 | package week2;
2 |
3 | import edu.duke.FileResource;
4 | import edu.duke.StorageResource;
5 |
6 | import java.util.ArrayList;
7 | import java.util.Collections;
8 | import java.util.List;
9 |
10 | /**
11 | * Week 2.
12 | */
13 | public class FindingAllGenes {
14 |
15 | public static void main(String[] args) {
16 |
17 | FileResource fr = new FileResource("../data/GRch38dnapart.fa");
18 |
19 | StorageResource sore = FindingAllGenes.findProtein(fr.asString());
20 | FindingAllGenes.printGensInformation(sore);
21 | FindingAllGenes.countCTGCodon(fr.asString());
22 | }
23 |
24 | /**
25 | * prints all the Strings that are longer than 60 characters
26 | * prints the number of Strings that are longer than 60 characters
27 | * prints the Strings whose C-G-ratio is higher than 0.35
28 | * prints the number of strings whose C-G-ratio is higher than 0.35
29 | *
30 | * @param sr
31 | */
32 | public static void printGensInformation(StorageResource sr) {
33 |
34 | int genCount = 0;
35 |
36 | for (String word : sr.data()) {
37 |
38 | if (word.length() > 60) {
39 | // System.out.println("Gene: " + word);
40 | genCount++;
41 | }
42 | }
43 |
44 | System.out.println("Gene 60 count: " + genCount);
45 |
46 | genCount = 0;
47 |
48 | for (String word : sr.data()) {
49 |
50 | if (cgRatio(word) > 0.35) {
51 | // System.out.println("C-G Gen: " + word);
52 | genCount++;
53 | }
54 | }
55 |
56 | System.out.println("C-G Count: " + genCount);
57 |
58 | System.out.println("Longest gene is: " + getLongestGene(sr).length());
59 |
60 | }
61 |
62 | /**
63 | * Find all proteins in a gene
64 | *
65 | * @param dna
66 | */
67 | public static StorageResource findProtein(String dna) {
68 |
69 | dna = dna.toLowerCase();
70 |
71 | //find start position of the codon
72 |
73 | int endPos = 0;
74 |
75 | StorageResource store = new StorageResource();
76 |
77 | while (true) {
78 | // get start position of a codom
79 | int start = dna.indexOf("atg", endPos);
80 |
81 | if (start == -1) {
82 | break;
83 | }
84 |
85 | //find end position of a codon
86 | int end = findEndPosition(dna, start + 3);
87 |
88 | if (end == -1) {
89 | endPos = start + 3;
90 | continue;
91 | }
92 | //
93 | endPos = end + 3;
94 | store.add(dna.substring(start, endPos));
95 |
96 | }
97 |
98 | System.out.println("Total proteins: " + store.size());
99 |
100 | return store;
101 |
102 | }
103 |
104 | /**
105 | * Find end position of the certain protein
106 | *
107 | * @param dna
108 | * @param startPos
109 | * @return
110 | */
111 | public static int findEndPosition(String dna, int startPos) {
112 |
113 | String[] endTags = {"tag", "tga", "taa"};
114 |
115 | List endsPoints = new ArrayList<>();
116 | for (String s : endTags) {
117 |
118 | int index = dna.indexOf(s, startPos);
119 |
120 | int diff = (index - startPos) % 3;
121 |
122 | if (index != -1 && diff == 0) {
123 | endsPoints.add(index);
124 | }
125 | }
126 |
127 | if (endsPoints.isEmpty()) {
128 | return -1;
129 | }
130 | return Collections.min(endsPoints);
131 | }
132 |
133 | /**
134 | * Compute C-G ratio for the certain protein
135 | *
136 | * @param dna
137 | * @return
138 | */
139 | public static float cgRatio(String dna) {
140 |
141 | dna = dna.toLowerCase();
142 |
143 | int dnaLen = dna.length();
144 | int gCount = countLetterInWord('g', dna);
145 | int cCount = countLetterInWord('c', dna);
146 | return (float) (gCount + cCount) / dnaLen;
147 |
148 | }
149 |
150 | /**
151 | * Count number of a letter in a word
152 | *
153 | * @param letter
154 | * @param word
155 | * @return
156 | */
157 | public static int countLetterInWord(char letter, String word) {
158 |
159 | int counter = 0;
160 |
161 | for (int i = 0; i < word.length(); i++) {
162 |
163 | if (word.charAt(i) == letter) {
164 | counter++;
165 | }
166 |
167 | }
168 |
169 | return counter;
170 |
171 | }
172 |
173 | /**
174 | * Find the longest gene in a collection of genes
175 | *
176 | * @param sr is a StorageResource of genes
177 | * @return
178 | */
179 | public static String getLongestGene(StorageResource sr) {
180 |
181 | int maxLen = 0;
182 | String longestGene = "";
183 |
184 | for (String gene : sr.data()) {
185 |
186 | int len = gene.length();
187 |
188 | if (len > maxLen) {
189 | maxLen = len;
190 | longestGene = gene;
191 | }
192 |
193 | }
194 |
195 |
196 | return longestGene;
197 | }
198 |
199 | /**
200 | * Count the codon CTG in a strand of DNA
201 | *
202 | * @param dna is a strand of DNA
203 | * @return count of CTG
204 | */
205 | public static int countCTGCodon(String dna) {
206 | dna = dna.toLowerCase();
207 | int count = dna.length() - dna.replace("ctg", "").length();
208 | System.out.println("CTG Count: " + count / 3);
209 | return count;
210 | }
211 | }
212 |
--------------------------------------------------------------------------------
/src/main/java/week2/FindingAllLinks.java:
--------------------------------------------------------------------------------
1 | package week2;
2 |
3 | import edu.duke.StorageResource;
4 | import edu.duke.URLResource;
5 |
6 | /**
7 | * Created by white on 11/6/15.
8 | */
9 | public class FindingAllLinks {
10 |
11 | public static void main(String[] args) {
12 |
13 |
14 | Iterable words = readURL("http://www.dukelearntoprogram.com/course2/data/newyorktimes.html");
15 |
16 | StorageResource store = findLink(words);
17 |
18 | printUrlsInformation(store);
19 |
20 |
21 | }
22 |
23 | public static Iterable readURL(String url) {
24 |
25 | URLResource ur = new URLResource(url);
26 |
27 | return ur.words();
28 |
29 | }
30 |
31 | public static StorageResource findLink(Iterable words) {
32 |
33 | StorageResource sr = new StorageResource();
34 |
35 | String searchWord = "href=";
36 |
37 |
38 | for (String s : words) {
39 | s = s.toLowerCase().trim().replace(" ", "");
40 |
41 | int pos = s.indexOf(searchWord);
42 |
43 | if (pos != -1) {
44 | int beg = s.indexOf("\"", pos);
45 | int end = s.indexOf("\"", beg + 1);
46 |
47 | if (end == -1) {
48 | end = s.length();
49 | }
50 |
51 | sr.add(s.substring(beg + 1, end));
52 |
53 | }
54 | }
55 |
56 | return sr;
57 |
58 | }
59 |
60 | public static void printUrlsInformation(StorageResource store) {
61 | Iterable data = store.data();
62 | System.out.println("URLS count:\t" + store.size());
63 | System.out.println("Dots count:\t" + countDots(data));
64 | System.out.println("Https count:\t" + countSecure(data));
65 | System.out.println("Coms count:\t" + countCOMs(data));
66 | System.out.println("End with Coms count:\t" + countEndCOMs(data));
67 |
68 | }
69 |
70 | public static int countDots(Iterable store) {
71 |
72 | int dots = 0;
73 |
74 | for (String s : store) {
75 | dots += s.length() - s.replace(".", "").length();
76 | }
77 |
78 | return dots;
79 | }
80 |
81 | public static int countSecure(Iterable store) {
82 |
83 | int https = 0;
84 |
85 | for (String s : store) {
86 | if (s.startsWith("https")) {
87 | https++;
88 | }
89 | }
90 |
91 | return https;
92 | }
93 |
94 | public static int countCOMs(Iterable store) {
95 | int coms = 0;
96 |
97 | for (String s : store) {
98 | if (s.contains(".com")) {
99 | coms++;
100 | }
101 | }
102 |
103 | return coms;
104 | }
105 |
106 | public static int countEndCOMs(Iterable store) {
107 | int coms = 0;
108 |
109 | for (String s : store) {
110 | if (s.endsWith(".com") || s.endsWith(".com/")) {
111 | coms++;
112 | }
113 | }
114 |
115 | return coms;
116 | }
117 |
118 |
119 | }
120 |
--------------------------------------------------------------------------------
/src/main/java/week2/FindingGene.java:
--------------------------------------------------------------------------------
1 | package week2;
2 |
3 | public class FindingGene {
4 |
5 | public static void main(String[] args) throws Exception {
6 |
7 | String testDNA = args[0];
8 |
9 | String codon = findProtein(testDNA);
10 |
11 | String stopPos = stopCodon(codon);
12 |
13 | System.out.format("Protein %s \n", codon);
14 | System.out.format("End Tag %s \n", stopPos);
15 |
16 | }
17 |
18 | /**
19 | * @param dna
20 | */
21 | public static String findProtein(String dna) {
22 |
23 | dna = dna.toLowerCase();
24 |
25 | //find start position of the codon
26 | int start = dna.indexOf("atg");
27 |
28 | if (start == -1) {
29 | System.out.println("Cannot find codon");
30 | return null;
31 | }
32 | //find end position of the codon
33 | int end = findEndPosition(dna, start);
34 |
35 | if (end == -1) {
36 | return null;
37 | }
38 |
39 | System.out.format("End Position: %s \n", end);
40 |
41 | return dna.substring(start, end + 3);
42 | }
43 |
44 | public static int findEndPosition(String dna, int startPos) {
45 |
46 | String[] endTags = {"tag", "tga", "taa"};
47 |
48 | int endPos = -1;
49 |
50 | for (String s : endTags) {
51 |
52 | int i = dna.indexOf(s, startPos + 3);
53 | int diff = (startPos - i) % 3;
54 |
55 | if (i != -1 && diff == 0) {
56 | endPos = i;
57 | break;
58 | }
59 | }
60 |
61 | return endPos;
62 | }
63 |
64 | public static String stopCodon(String codon) {
65 |
66 | if (codon == null) {
67 | return "";
68 | }
69 |
70 | int size = codon.length();
71 |
72 | if (size > 10) {
73 | return codon.substring(size - 3, size);
74 | } else {
75 | return "";
76 | }
77 | }
78 | }
--------------------------------------------------------------------------------
/src/main/java/week2/FindingLinks.java:
--------------------------------------------------------------------------------
1 | package week2;
2 |
3 | import edu.duke.URLResource;
4 |
5 | /**
6 | * Created by white on 11/5/15.
7 | */
8 | public class FindingLinks {
9 |
10 | public static void main(String[] args) {
11 |
12 |
13 | Iterable words = readURL("http://www.dukelearntoprogram.com/course2/data/manylinks.html");
14 |
15 | findLink(words);
16 |
17 |
18 | }
19 |
20 | public static Iterable readURL(String url) {
21 |
22 | URLResource ur = new URLResource(url);
23 |
24 | return ur.words();
25 |
26 | }
27 |
28 | public static void findLink(Iterable words) {
29 |
30 | String searchWord = "youtube.com";
31 |
32 | for (String s : words) {
33 | int pos = s.toLowerCase().indexOf(searchWord);
34 |
35 | if (pos != -1) {
36 |
37 | int beg = s.lastIndexOf("\"", pos);
38 | int end = s.indexOf("\"", pos + 1);
39 | String w = s.substring(beg + 1, end);
40 |
41 | System.out.format("Start: %s, End: %s \n", beg, end);
42 | System.out.println(w);
43 |
44 | }
45 | }
46 |
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/week3/ParsingExportData.java:
--------------------------------------------------------------------------------
1 | package week3;
2 |
3 | import edu.duke.FileResource;
4 | import org.apache.commons.csv.CSVParser;
5 | import org.apache.commons.csv.CSVRecord;
6 |
7 | /**
8 | * Created by white on 11/17/15.
9 | */
10 | public class ParsingExportData {
11 |
12 | public static void main(String[] args) {
13 |
14 | FileResource fr = new FileResource("../../resources/main/exports/exportdata.csv");
15 | CSVParser parser = fr.getCSVParser();
16 |
17 | //test 1
18 | // countryInfo(parser, "Nauru");
19 | // test 2
20 | // listExportersTwoProducts(parser, "gold", "diamonds");
21 | // test 3
22 | // numberOfExporters(parser, "gold");
23 | // test 4
24 | bigExporters(parser, "$999,999,999,999");
25 | }
26 |
27 | /**
28 | * Finds and returns a string of information about the country
29 | *
30 | * @param parser
31 | */
32 | public static void countryInfo(CSVParser parser, String c) {
33 |
34 |
35 | for (CSVRecord record : parser) {
36 | String country = record.get("Country");
37 | if (country.equals(c)) {
38 | String exports = record.get("Exports");
39 | String value = record.get("Value (dollars)");
40 | System.out.println(country + ": " + exports + ", " + value);
41 | }
42 |
43 | }
44 |
45 |
46 | }
47 |
48 | /**
49 | * Prints the names of all the countries that have
50 | *
51 | * @param parser
52 | * @param exportItem1
53 | * @param exportItem2
54 | */
55 | public static void listExportersTwoProducts(CSVParser parser, String exportItem1, String exportItem2) {
56 |
57 | for (CSVRecord record : parser) {
58 |
59 | String country = record.get("Country");
60 | String exports = record.get("Exports");
61 |
62 | if (exports.contains(exportItem1) && exports.contains(exportItem2)) {
63 | System.out.println(country);
64 | }
65 | }
66 |
67 |
68 | }
69 |
70 | /**
71 | * This method returns the number of countries that export exportItem
72 | *
73 | * @param parser
74 | * @param exportItem1
75 | */
76 | public static void numberOfExporters(CSVParser parser, String exportItem1) {
77 |
78 | int counter = 0;
79 |
80 | for (CSVRecord record : parser) {
81 | String exports = record.get("Exports");
82 |
83 | if (exports.contains(exportItem1)) {
84 | counter += 1;
85 | }
86 | }
87 |
88 | System.out.println(counter);
89 |
90 | }
91 |
92 | public static void bigExporters(CSVParser parser, String amount) {
93 |
94 | for (CSVRecord record : parser) {
95 |
96 | String country = record.get("Country");
97 | String value = record.get("Value (dollars)");
98 |
99 | if (value.length() > amount.length()) {
100 | System.out.println(country + ":" + value);
101 | }
102 | }
103 |
104 | }
105 |
106 | }
107 |
--------------------------------------------------------------------------------
/src/main/java/week3/WeatherCSVProblem.java:
--------------------------------------------------------------------------------
1 | package week3;
2 |
3 | import edu.duke.DirectoryResource;
4 | import edu.duke.FileResource;
5 | import org.apache.commons.csv.CSVParser;
6 | import org.apache.commons.csv.CSVRecord;
7 |
8 | import java.io.File;
9 |
10 | /**
11 | * Created by white on 11/18/15.
12 | */
13 |
14 |
15 | public class WeatherCSVProblem {
16 |
17 | final static String filename = "../../resources/main/nc_weather/2014/weather-2014-01-08.csv";
18 |
19 | public static void main(String[] args) {
20 |
21 | FileResource fr = new FileResource(filename);
22 |
23 | CSVParser parser = fr.getCSVParser();
24 |
25 | // test 1
26 | // coldestHourInFile(parser);
27 | // test 2
28 |
29 |
30 | }
31 |
32 | /**
33 | * Returns the CSVRecord with the coldest temperature in the file and
34 | * thus all the information about the coldest temperature
35 | *
36 | * @param parser
37 | */
38 | public static CSVRecord coldestHourInFile(CSVParser parser) {
39 |
40 | CSVRecord resultRecord = null;
41 |
42 | for (CSVRecord record : parser) {
43 |
44 | if (resultRecord == null) {
45 | resultRecord = record;
46 | } else {
47 | double temperatureF = Double.parseDouble(record.get("TemperatureF"));
48 | double coldestTemp = Double.parseDouble(resultRecord.get("TemperatureF"));
49 | resultRecord = (temperatureF < coldestTemp) ? record : resultRecord;
50 | }
51 |
52 | }
53 |
54 | return resultRecord;
55 |
56 | }
57 |
58 | /**
59 | * should return a string that is the name of the file
60 | * from selected files that has the coldest temperature
61 | */
62 | public static String fileWithColdestTemperature() {
63 |
64 | CSVRecord coldestRecord = null;
65 | DirectoryResource dr = new DirectoryResource();
66 | String filename = "";
67 |
68 | for (File f : dr.selectedFiles()) {
69 |
70 | FileResource fr = new FileResource(f);
71 |
72 | CSVRecord record = coldestHourInFile(fr.getCSVParser());
73 |
74 | double recordTemp = Double.parseDouble(record.get("TemperatureF"));
75 |
76 | if (recordTemp == -9999) {
77 | continue;
78 | }
79 |
80 | if (coldestRecord == null) {
81 | coldestRecord = record;
82 | filename = f.getAbsolutePath();
83 | } else {
84 | double coldestTemp = Double.parseDouble(coldestRecord.get("TemperatureF"));
85 |
86 | if (recordTemp < coldestTemp) {
87 | coldestRecord = record;
88 | filename = f.getAbsolutePath();
89 | }
90 | }
91 |
92 | }
93 |
94 | return filename;
95 | }
96 |
97 | /**
98 | * This method returns the CSVRecord that has the lowest humidity
99 | *
100 | * @param parser
101 | */
102 | public static CSVRecord lowestHumidityInFile(CSVParser parser) {
103 |
104 | CSVRecord resultRecord = null;
105 |
106 | for (CSVRecord record : parser) {
107 |
108 | if (record.get("Humidity").equals("N/A")) {
109 | continue;
110 | }
111 |
112 | if (resultRecord == null) {
113 | resultRecord = record;
114 | } else {
115 |
116 | double temperatureF = Double.parseDouble(record.get("Humidity"));
117 | double coldestTemp = Double.parseDouble(resultRecord.get("Humidity"));
118 | resultRecord = (temperatureF < coldestTemp) ? record : resultRecord;
119 |
120 | }
121 |
122 | }
123 |
124 | return resultRecord;
125 | }
126 |
127 | /**
128 | * @param parser
129 | * @return
130 | */
131 | public static double averageTemperatureInFile(CSVParser parser) {
132 |
133 | double averageTemp = 0.0;
134 | double sum = 0;
135 | int counter = 0;
136 | for (CSVRecord record : parser) {
137 |
138 |
139 | double recordTemp = Double.parseDouble(record.get("TemperatureF"));
140 |
141 | if (recordTemp == -9999) {
142 | continue;
143 | } else {
144 | sum += Double.parseDouble(record.get("TemperatureF"));
145 | counter++;
146 | }
147 |
148 |
149 | }
150 |
151 | averageTemp = sum / counter;
152 |
153 | return averageTemp;
154 | }
155 |
156 | /**
157 | * This method returns a double that represents the average temperature of only
158 | * those temperatures when the humidity was greater than or equal to value
159 | *
160 | * @param parser
161 | * @param level
162 | */
163 | public static double averageTemperatureWithHighHumidityInFile(CSVParser parser, double level) {
164 |
165 | double averageTemp;
166 | double sum = 0;
167 | int counter = 0;
168 |
169 | for (CSVRecord record : parser) {
170 |
171 | double humidity = Double.parseDouble(record.get("Humidity"));
172 |
173 | if (humidity >= level) {
174 | sum += Double.parseDouble(record.get("TemperatureF"));
175 | counter++;
176 | }
177 |
178 | }
179 |
180 | averageTemp = sum / counter;
181 |
182 | return averageTemp;
183 |
184 | }
185 |
186 | }
187 |
--------------------------------------------------------------------------------
/src/main/java/week4/BabyNames.java:
--------------------------------------------------------------------------------
1 | package week4;
2 |
3 | import edu.duke.DirectoryResource;
4 | import edu.duke.FileResource;
5 | import org.apache.commons.csv.CSVParser;
6 | import org.apache.commons.csv.CSVRecord;
7 |
8 | import java.io.File;
9 | import java.io.IOException;
10 | import java.util.*;
11 | import java.util.stream.Collectors;
12 |
13 | /**
14 | * Created by white on 11/19/15.
15 | */
16 | public class BabyNames {
17 |
18 | /**
19 | * Print the number of unique girls names , the number of unique boys names and the total names in the file
20 | *
21 | * @param parser
22 | */
23 | public static void totalBirths(CSVParser parser) {
24 |
25 | ArrayList maleNames = new ArrayList<>();
26 | ArrayList femaleNames = new ArrayList<>();
27 |
28 | for (CSVRecord record : parser) {
29 | String name = record.get(0);
30 | String gender = record.get(1);
31 |
32 | if (gender.equals("M")) {
33 | if (!maleNames.contains(name)) {
34 | maleNames.add(name);
35 | }
36 | } else {
37 | if (!femaleNames.contains(name)) {
38 | femaleNames.add(name);
39 | }
40 | }
41 |
42 | }
43 |
44 | System.out.println("Boys names: " + maleNames.size() + ", Girls: " + femaleNames.size());
45 | System.out.println("Total names: " + (maleNames.size() + femaleNames.size()));
46 |
47 | }
48 |
49 | /**
50 | * This method returns the rank of the name in the file for the given gender,
51 | * where rank 1 is the name with the largest number of births.
52 | *
53 | * @param year
54 | * @param name
55 | * @param gender
56 | */
57 | public static int getRank(int year, String name, String gender) throws IOException {
58 |
59 | CSVParser parser = getFileParser(year);
60 |
61 | List babies = parser.getRecords().stream().filter(w -> w.get(1).equals(gender)).collect(Collectors.toList());
62 |
63 | // sort list by rank
64 | babies.sort((o1, o2) -> {
65 | if (Integer.parseInt(o1.get(2)) > Integer.parseInt(o2.get(2)))
66 | return -1;
67 | else
68 | return 1;
69 | });
70 |
71 | int rank = -1;
72 |
73 | for (CSVRecord rec : babies) if (rec.get(0).equals(name)) rank = babies.indexOf(rec) + 1;
74 |
75 | return rank;
76 |
77 | }
78 |
79 | /**
80 | * This method returns the name of the person in the file at this rank, for the given gender,
81 | * where rank 1 is the name with the largest number of births.
82 | * If the rank does not exist in the file, then “NO NAME” is returned.
83 | *
84 | * @param year
85 | * @param rank
86 | * @param gender
87 | * @return
88 | * @throws IOException
89 | */
90 | public static String getName(int year, int rank, String gender) throws IOException {
91 |
92 |
93 | CSVParser parser = getFileParser(year);
94 |
95 | List babyes = parser.getRecords().stream().filter(w -> w.get(1).equals(gender)).collect(Collectors.toList());
96 |
97 | // sort list by rank
98 | babyes.sort((o1, o2) -> {
99 | if (Integer.parseInt(o1.get(2)) > Integer.parseInt(o2.get(2)))
100 | return -1;
101 | else
102 | return 1;
103 | });
104 |
105 | rank = rank - 1;
106 |
107 | if (babyes.size() < rank || rank < 0) {
108 | return "No name";
109 | } else {
110 | return babyes.get(rank).get(0);
111 | }
112 |
113 | }
114 |
115 | /**
116 | * This method determines what name would have been named if they were born in a different year,
117 | * based on the same popularity.
118 | *
119 | * @param name
120 | * @param year representing the year that name was born
121 | * @param newYear
122 | * @param gender
123 | */
124 | public static void whatIsNameInYear(String name, int year, int newYear, String gender) throws IOException {
125 |
126 |
127 | int personRank = BabyNames.getRank(year, name, gender);
128 |
129 | System.out.println(personRank);
130 |
131 | String newName = BabyNames.getName(newYear, personRank, gender);
132 |
133 | System.out.format("%s born in %s would be %s if she was born in %s.", name, year, newName, newYear);
134 |
135 | }
136 |
137 | /**
138 | * This method selects a range of files to process and returns an integer,
139 | * the year with the highest rank for the name and gender
140 | *
141 | * @param name
142 | * @param gender
143 | */
144 | public static int yearOfHighestRank(String name, String gender) throws IOException {
145 |
146 | Map ranks = BabyNames.getAllYearsByNameAndGender(name, gender);
147 |
148 | if (ranks.size() == 0) {
149 | return -1;
150 | }
151 |
152 | // sort by desc
153 | Map sorted = ranks.entrySet().stream().sorted(Map.Entry.comparingByValue((o1, o2) -> {
154 | if (o1 >= o2)
155 | return 1;
156 | else
157 | return -1;
158 |
159 | })).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
160 | System.out.println(sorted.entrySet().toString());
161 | return (int) sorted.keySet().toArray()[0];
162 | }
163 |
164 | public static Double getAverageRank(String name, String gender) throws IOException {
165 |
166 | Map ranks = BabyNames.getAllYearsByNameAndGender(name, gender);
167 |
168 | if (ranks.size() == 0) {
169 | return -1.0;
170 | }
171 |
172 | return (double) ranks.values().stream().mapToInt(Integer::intValue).sum() / ranks.size();
173 |
174 | }
175 |
176 | /**
177 | * This method returns an integer, the total number of births of those names
178 | * with the same gender and same year who are ranked higher than name
179 | *
180 | * @param year
181 | * @param name
182 | * @param gender
183 | */
184 | public static Integer getTotalBirthsRankedHigher(int year, String name, String gender) throws IOException {
185 |
186 | FileResource fr = new FileResource(String.format("../../resources/main/babynames/us_babynames_by_year/yob%s.csv", year));
187 |
188 | CSVParser parser = fr.getCSVParser(false);
189 |
190 | List babies = parser.getRecords().stream().filter(w -> w.get(1).equals(gender)).collect(Collectors.toList());
191 |
192 |
193 | // sort list by rank
194 | babies.sort((o1, o2) -> {
195 | if (Integer.parseInt(o1.get(2)) > Integer.parseInt(o2.get(2)))
196 | return -1;
197 | else
198 | return 1;
199 | });
200 |
201 | int rank = -1;
202 | for (CSVRecord rec : babies) if (rec.get(0).equals(name)) rank = babies.indexOf(rec);
203 |
204 | if (rank == -1) {
205 | return -1;
206 |
207 | }
208 |
209 | List listBabies = babies.subList(0, rank);
210 |
211 |
212 | int sum = listBabies.stream().mapToInt(value -> Integer.parseInt(value.get(2))).sum();
213 |
214 | return sum;
215 |
216 | }
217 |
218 | protected static CSVParser getFileParser(int year) {
219 |
220 | FileResource fr = new FileResource(String.format("../../resources/main/babynames/us_babynames_by_year/yob%s.csv", year));
221 |
222 | return fr.getCSVParser(false);
223 |
224 |
225 | }
226 |
227 | protected static Map getAllYearsByNameAndGender(String name, String gender) throws IOException {
228 |
229 | DirectoryResource dr = new DirectoryResource();
230 |
231 | Map ranks = new HashMap<>();
232 |
233 | for (File file : dr.selectedFiles()) {
234 |
235 | int year = Integer.parseInt(file.getName().replaceAll("[^0-9]", ""));
236 | int rank = BabyNames.getRank(year, name, gender);
237 |
238 | if (rank >= 0) {
239 | ranks.put(year, rank);
240 | }
241 | }
242 |
243 | return ranks;
244 |
245 | }
246 |
247 |
248 | }
249 |
--------------------------------------------------------------------------------
/src/test/java/week3/ParsingExtraDataTests.java:
--------------------------------------------------------------------------------
1 | package week3;
2 |
3 | import edu.duke.FileResource;
4 | import org.apache.commons.csv.CSVParser;
5 | import org.junit.Test;
6 |
7 | /**
8 | * Created by white on 11/18/15.
9 | */
10 | public class ParsingExtraDataTests {
11 |
12 |
13 | @Test
14 | public void testCountryInfo() {
15 | FileResource fr = new FileResource("../../resources/main/exports/exportdata.csv");
16 | CSVParser parser = fr.getCSVParser();
17 |
18 | ParsingExportData.countryInfo(parser, "Nauru");
19 | }
20 |
21 | @Test
22 | public void testListExportersTwoProducts() {
23 | FileResource fr = new FileResource("../../resources/main/exports/exportdata.csv");
24 | CSVParser parser = fr.getCSVParser();
25 |
26 | ParsingExportData.listExportersTwoProducts(parser, "cotton", "flowers");
27 | }
28 |
29 |
30 | @Test
31 | public void testNumberOfExporters() {
32 | FileResource fr = new FileResource("../../resources/main/exports/exportdata.csv");
33 | CSVParser parser = fr.getCSVParser();
34 |
35 | ParsingExportData.numberOfExporters(parser, "cocoa");
36 | }
37 |
38 | @Test
39 | public void testBigExporters() {
40 | FileResource fr = new FileResource("../../resources/main/exports/exportdata.csv");
41 | CSVParser parser = fr.getCSVParser();
42 |
43 | ParsingExportData.bigExporters(parser, "$999,999,999,999");
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/test/java/week3/WeatherCSVProblemTests.java:
--------------------------------------------------------------------------------
1 | package week3;
2 |
3 | import edu.duke.DirectoryResource;
4 | import edu.duke.FileResource;
5 | import org.apache.commons.csv.CSVParser;
6 | import org.apache.commons.csv.CSVRecord;
7 | import org.junit.Test;
8 |
9 | import java.io.File;
10 |
11 |
12 | /**
13 | * Created by white on 11/18/15.
14 | */
15 |
16 | //public interface FastTests { /* category marker */ }
17 |
18 | public class WeatherCSVProblemTests {
19 |
20 |
21 | @Test
22 | public void testColdestHourInFile() {
23 |
24 | FileResource fr = new FileResource("../../resources/main/nc_weather/2014/weather-2014-05-01.csv");
25 | CSVParser parser = fr.getCSVParser();
26 |
27 | CSVRecord rec = WeatherCSVProblem.coldestHourInFile(parser);
28 |
29 | System.out.println("Coldest temperature on that day was " + rec.get("TemperatureF"));
30 | }
31 |
32 | @Test
33 | public void testFileWithColdestTemperature() {
34 |
35 | String filename = WeatherCSVProblem.fileWithColdestTemperature();
36 | System.out.println("Coldest day was in file " + filename);
37 |
38 | FileResource fr = new FileResource(filename);
39 | CSVParser parser = fr.getCSVParser();
40 | CSVRecord rec = WeatherCSVProblem.coldestHourInFile(parser);
41 | System.out.println("Coldest temperature on that day was " + rec.get("TemperatureF") + " at " + rec.get("DateUTC"));
42 |
43 | }
44 |
45 | @Test
46 | public void testLowestHumidityInFile() {
47 |
48 | FileResource fr = new FileResource("../../resources/main/nc_weather/2014/weather-2014-07-22.csv");
49 | CSVParser parser = fr.getCSVParser();
50 |
51 | CSVRecord rec = WeatherCSVProblem.lowestHumidityInFile(parser);
52 |
53 | System.out.println("Lowest Humidity was " + rec.get("Humidity") + " at " + rec.get("DateUTC"));
54 |
55 | }
56 |
57 | @Test
58 | public void testFileLowestHumidity() {
59 |
60 | CSVRecord coldestRecord = null;
61 | DirectoryResource dr = new DirectoryResource();
62 | String filename = "";
63 |
64 | for (File f : dr.selectedFiles()) {
65 |
66 | FileResource fr = new FileResource(f);
67 |
68 | CSVRecord record = WeatherCSVProblem.lowestHumidityInFile(fr.getCSVParser());
69 |
70 | if (coldestRecord == null) {
71 | coldestRecord = record;
72 | } else {
73 | double recordTemp = Double.parseDouble(record.get("Humidity"));
74 | double coldestTemp = Double.parseDouble(coldestRecord.get("Humidity"));
75 |
76 | if (recordTemp < coldestTemp) {
77 | coldestRecord = record;
78 | filename = f.getName();
79 | }
80 | }
81 |
82 | }
83 | System.out.println(filename);
84 | System.out.println("Lowest Humidity " + coldestRecord.get("Humidity") + " at " + coldestRecord.get("DateUTC"));
85 |
86 | }
87 |
88 | @Test
89 | public void testAverageTemperatureInFile() {
90 |
91 | FileResource fr = new FileResource("../../resources/main/nc_weather/2013/weather-2013-08-10.csv");
92 | CSVParser parser = fr.getCSVParser();
93 |
94 | double average = WeatherCSVProblem.averageTemperatureInFile(parser);
95 |
96 | System.out.println("Average temperature in file is " + average);
97 |
98 |
99 | }
100 |
101 | @Test
102 | public void testAverageTemperatureWithHighHumidityInFile() {
103 |
104 | FileResource fr = new FileResource("../../resources/main/nc_weather/2013/weather-2013-09-02.csv");
105 | CSVParser parser = fr.getCSVParser();
106 |
107 | double average = WeatherCSVProblem.averageTemperatureWithHighHumidityInFile(parser, 80);
108 |
109 | if (Double.isNaN(average)) {
110 | System.out.println("No temperatures with that humidity");
111 | } else {
112 | System.out.println("Average Temp when high Humidity is " + average);
113 | }
114 |
115 | }
116 |
117 | }
118 |
--------------------------------------------------------------------------------
/src/test/java/week4/BabyNamesTests.java:
--------------------------------------------------------------------------------
1 | package week4;
2 |
3 | import edu.duke.FileResource;
4 | import org.apache.commons.csv.CSVParser;
5 | import org.junit.Test;
6 |
7 | import java.io.IOException;
8 |
9 | /**
10 | * Created by white on 11/19/15.
11 | */
12 | public class BabyNamesTests {
13 |
14 | @Test
15 | public void testTotalBirths() {
16 |
17 | // FileResource fr = new FileResource("../../resources/main/babynames/us_babynames_by_year/yob1900.csv");
18 | FileResource fr = new FileResource("../../resources/main/babynames/us_babynames_by_year/yob1905.csv");
19 |
20 | CSVParser parser = fr.getCSVParser(false);
21 |
22 | BabyNames.totalBirths(parser);
23 |
24 | }
25 |
26 | @Test
27 | public void testGetRank() throws IOException {
28 |
29 | // int rank = BabyNames.getRank(1960, "Emily", "F");
30 |
31 | int rank = BabyNames.getRank(1971, "Frank", "M");
32 |
33 | System.out.println("Rank : " + rank);
34 |
35 | }
36 |
37 | @Test
38 | public void testGetName() throws IOException {
39 |
40 | // String name = BabyNames.getName(1980, 350, "F");
41 | String name = BabyNames.getName(1982, 450, "M");
42 |
43 | System.out.println("Name : " + name);
44 |
45 | }
46 |
47 | @Test
48 | public void testWhatIsNameInYear() throws IOException {
49 | // BabyNames.whatIsNameInYear("Susan", 1972, 2014, "F");
50 | BabyNames.whatIsNameInYear("Owen", 1974, 2014, "M");
51 | }
52 |
53 | @Test
54 | public void testYearOfHighestRank() throws IOException {
55 | int year = BabyNames.yearOfHighestRank("Genevieve", "F");
56 | // int year = BabyNames.yearOfHighestRank("Mich", "M");
57 |
58 | System.out.println("testYearOfHighestRank : " + year);
59 | }
60 |
61 | @Test
62 | public void testGetAverageRank() throws IOException {
63 | // double average = BabyNames.getAverageRank("Susan", "F");
64 | double average = BabyNames.getAverageRank("Robert", "M");
65 |
66 | System.out.println("testGetAverageRank: " + average);
67 | }
68 |
69 | @Test
70 | public void testGetTotalBirthsRankedHigher() throws IOException {
71 |
72 | int sum = BabyNames.getTotalBirthsRankedHigher(1990, "Emily", "F");
73 | // int sum = BabyNames.getTotalBirthsRankedHigher(1990, "Drew", "M");
74 |
75 | System.out.println("testGetTotalBirthsRankedHigher: " + sum);
76 |
77 | }
78 |
79 | }
80 |
--------------------------------------------------------------------------------