├── .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 | --------------------------------------------------------------------------------