Question
[Java] I'm keep getting an error and having no idea why. Please fix my code. The grader bot will give you 90 points for a
[Java] I'm keep getting an error and having no idea why.
Please fix my code.
The grader bot will give you 90 points for a perfectly working app.
RecordFormatException
This class should extend Exception (not RuntimeException, because we want it to be
checked). Provide one constructor whose arg is a String. Pass the String to the superclass
constructor that takes a single String arg.
DNARecord
This interface doesn't need to be changed. Just read it and understand it.
FastqRecord
This class should implement DNARecord and should have:
3 String instance variables: defline, sequence, and quality.
A constructor that initializes the instance variables. If the defline does not start
with the correct character, the ctor should throw RecordFormatException with a
helpful message. (If you're not sure how to get the 1st character of a string, check
out the charAt(int) method of String on the API page.) Yes, ctors can throw
exceptions just like methods; be sure to add "throws RecordFormatException" to
the ctor declaration. Here are some possible messages, in increasing order of
helpfulness:
o An empty or null string
o Zzup yo?
o Oops
o Bad fastq record
o Bad defline in fastq record
o Bad 1st char in defline in fastq record
o Bad 1st char in defline in fastq record: saw X, expected @
Methods that satisfy the DNARecord interface.
An equals() method that checks for deep equality of all 3 instance variables.
A boolean qualityIsLow() method that returns true if and only if the quality
contains at least one exclamation mark (!). In real life this method would be a lot
more complicated.
A hashCode() method that returns the sum of the hash codes of defline, sequence,
and quality.
FastaRecord
This class should implement DNARecord and should have:
2 String instance variables: defline and sequence.
A constructor that takes 2 args - the defline and the sequence - and initializes the
instance variables. As with FastqRecord, check to make sure the defline starts with
the correct character (it's '>' for fasta records). Throw RecordFormatException if it
doesn't.
Another ctor with 1 arg - a FastqRecord - that initializes the instances variables
with values from the FastqRecord. You'll have to change the 1st char of the defline.
If you're not sure how to do this, look up the substring() methods on the String API
page.
Methods that satisfy the DNARecord interface.
An equals() method that checks for deep equality of the 2 instance variables.
A hashCode() method that returns the sum of the hash codes of defline, and
sequence.
FastqReader
FastqReader should not extend any superclasses or implement any interfaces. It should
have one instance variable: a BufferedReader named theBufferedReader.
This class should provide a single-arg ctor that initializes theBufferedReader from the ctor
arg.
The class should also have the following method:
public FastqRecord readRecord() throws IOException, RecordFormatException
This method should read a line from the buffered reader. If that line is null, the input file is
at the end, and the method should return null. Otherwise the method should read 3 more
lines and return a FastqRecord. The method should throw a RecordFormatException with
a useful message if the 4 input lines don't constitute a valid fastq record. Note that this
happens automatically if you call the FastqRecord ctor with invalid args. You can assume
that the + line is ok.
FastaWriter
FastaWriter should not extend any superclasses or implement any interfaces. It should
have one instance variable: a PrintWriter named thePrintWriter.
This class should provide a single-arg ctor that initializes thePrintWriter from its arg. The
class should also have the following method:
public void writeRecord(FastaRecord rec) throws IOException
This method should write the fasta record, in correct fasta format, to thePrintWriter.
FileConverter
This class should have 2 instance variables of type File, named fastq and fasta. Provide a
ctor that has 2 File args and initializes the instance variables.
The class should have a convert() method and a main() method.
To import the fastq file, drag the icon for HW4.fastq into the icon of the data folder. A
dialog box will ask you if you want to copy files or link to files; choose "copy files". Open
the data folder by clicking on its triangle; you should see HW4.fastq.
Testing
Run the app. If it runs correctly, it will create a file called HW4.fasta in the data folder.
Unfortunately, when you do this the first time, you won't see HW4.fasta in the data folder.
Eclipse doesn't know when an app writes a new data file. Right-click on the data icon and
select Refresh in the popup menu. Now if you don't see HW4.fasta it's because something
went wrong in your program.
Check your work. Double-click on the fastq file to open it. Look at the records and decide
which ones are high-quality and valid. Then open the fasta file, and verify that it only
contains fasta versions of the high-quality valid records.
You might want to use assertions to help develop your code. To enable assertions, select
FileConverter in the Package Explorer. Go to the main Eclipse menu and select Run -> Run
Configurations... Then click on the Arguments tab. Be sure that FileConverter is selected in
the list on the left. If it isn't selected, select it there. Type -ea into the VM Arguments field
(not the Program Arguments field) as shown below, and click Apply. Now when you run
FileConverter as an app, "assert" statements will work.
Run the DNAGrader app to see what your grade will be. The grader pops up a little
window that the TAs will use to grade your comments and style. Just click the "ok" button.
The convert() method should declare that it throws IOException. Any other exception
types thrown in the body of convert() should be caught and handled inside convert(). The
method should
1) Create a FastqReader that reads from the fastq file specified by the fastq
instance variable.
2) Create a FastaWriter that writes to the fasta file specified by the fasta
instance variable.
3) Read each fastq record until the end of the fastq file is reached. Do
nothing with any invalid records (i.e. records where the defline didn't
start with @). For valid records where the quality isn't low, create a fasta
record and write it using the FastaWriter.
4) Close all readers and writers that have close() methods, in reverse order
of creation.
The main() method is provided for you. It reads and converts the fastq file that you
downloaded with this assignment. The next section tells you what to do with the fastq file.
The Input File
Notice that the main() method reads a fastq file in a directory called data, and writes a
fasta file in the same directory. You will need to create this directory in Eclipse, and import
HW4.fastq into it.
To create the data directory, right-click on your project name in the package explorer and
select New -> Folder in the popup menu. When prompted for the folder name, enter
"data". You should see the new directory in the Package Explorer, at the same level as src.
If it isn't at the right level, delete it and start again; it has to be in the right place for main()
and the grader bot to find it.
---------------------------------------------------------------
DNAGrader.java
----------------------------------------------------------------
package dna;
import java.io.*;
import java.lang.reflect.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class DNAGrader
{
private final static Class[] EMPTY_ARGSLIST = { };
private final static Class[] STRING_ARGSLIST = { String.class };
private final static Class[] STRING_2_ARGSLIST = { String.class, String.class };
private final static Class[] STRING_3_ARGSLIST = { String.class, String.class, String.class };
private final static Class[] BR_ARGSLIST = { BufferedReader.class };
private final static Class[] PW_ARGSLIST = { PrintWriter.class };
private Class fastqRecordClass;
private Map> catToDeductions = new LinkedHashMap<>();
private int commentDeduction;
private int styleDeduction;
private String gradersNotes;
private enum Category
{
// For each category, student can't lose > maxDeductions.
DNARecord(10),
FastqException(10),
FastqRecord(18),
FastaRecord(10),
FastqReader(10),
FastaWriter(10),
FileConverter(24),
Style(5),
Comments(3);
private int maxDeductions;
Category(int maxDeductions)
{
this.maxDeductions = maxDeductions;
}
int getMaxDeductions()
{
return maxDeductions;
}
}
static
{
int maxPoints = 0;
for (Category cat: Category.values())
maxPoints += cat.getMaxDeductions();
assert maxPoints == 100 : maxPoints;
}
private class Deduction
{
private String reason;
private int pointsOff;
Deduction(String reason, int pointsOff)
{
this.reason = reason;
this.pointsOff = pointsOff;
}
public String toString()
{
return reason + ": -" + pointsOff;
}
}
private void deduct(Category cat, String reason, int pointsOff)
{
ArrayList dedsForCat = catToDeductions.get(cat);
if (dedsForCat == null)
catToDeductions.put(cat, (dedsForCat= new ArrayList<>()));
dedsForCat.add(new Deduction(reason, pointsOff));
}
private void deductMax(Category cat, String reason)
{
deduct(cat, reason, cat.getMaxDeductions());
}
private void grade()
{
gradeFormatException();
gradeDNARecord();
gradeFastqRecord();
gradeFastaRecord();
gradeFastqReader();
gradeFastaWriter();
gradeConverter();
testSubjective();
int score = 100;
for (Category cat: catToDeductions.keySet())
{
if (cat == Category.Style || cat == Category.Comments)
continue;
ArrayList dedns = catToDeductions.get(cat);
if (dedns.isEmpty())
continue;
sop("--------");
sop(cat + ":");
int totalDeductionsThisCategory = 0;
for (Deduction dedn: dedns)
{
sop(dedn);
totalDeductionsThisCategory += dedn.pointsOff;
}
totalDeductionsThisCategory = Math.min(totalDeductionsThisCategory, cat.maxDeductions);
sop("TOTAL DEDUCTIONS THIS CATEGORY (max=-" + cat.maxDeductions + "): -" + totalDeductionsThisCategory);
score -= totalDeductionsThisCategory;
}
if (styleDeduction > 0)
sop("Style: -" + styleDeduction);
score -= styleDeduction;
if (commentDeduction > 0)
sop("Comments: -" + commentDeduction);
score -= commentDeduction;
sop("--------------------------- ");
sop("SCORE: " + score);
sop(" " + gradersNotes);
}
private Class getClass(String name)
{
if (!name.startsWith("dna."))
name = "dna." + name;
try
{
return Class.forName(name);
}
catch (ClassNotFoundException x)
{
return null;
}
}
private void gradeFormatException()
{
// Does class exist?
Class clazz = getClass("dna.RecordFormatException");
if (clazz == null)
{
deductMax(Category.FastqException, "No dna.RecordFormatException class");
return;
}
// Does FastqException(String) ctor exist?
try
{
clazz.getConstructor(STRING_ARGSLIST);
}
catch (NoSuchMethodException x)
{
deduct(Category.FastqException, "No RecordFormatException(String) constructor", 8);
}
}
private void gradeDNARecord()
{
// Does class exist?
Class clazz = getClass("dna.DNARecord");
if (clazz == null)
{
deductMax(Category.DNARecord, "No dna.DNARecord class");
return;
}
// Does class define getDefline() and getSequence()?
String[] names = { "getDefline", "getSequence" };
for (String name: names)
{
try
{
Method m = clazz.getDeclaredMethod(name, EMPTY_ARGSLIST);
if (m.getReturnType() != String.class)
deduct(Category.DNARecord, name + "() does not return String", 4);
}
catch (NoSuchMethodException x)
{
deduct(Category.DNARecord, "No " + name + "() method", 5);
}
}
}
private void gradeFastqRecord()
{
String err;
// Does class exist?
fastqRecordClass = getClass("dna.FastqRecord");
if (fastqRecordClass == null)
{
deductMax(Category.FastqRecord, "No dna.FastqRecord interface");
return;
}
// Does class declare it implements DNARecord?
boolean implementsDNARecord = false;
for (Class c: fastqRecordClass.getInterfaces())
{
if (c.getName().equals("dna.DNARecord"))
{
implementsDNARecord = true;
break;
}
}
if (!implementsDNARecord)
{
deduct(Category.FastqRecord, "DNARecord doesn't declare that it implements DNARecord.", 2);
}
// Does class define getDefline() and getSequence()?
String[] names = { "getDefline", "getSequence" };
for (String name: names)
{
try
{
Method m = fastqRecordClass.getDeclaredMethod(name, EMPTY_ARGSLIST);
if (m.getReturnType() != String.class)
deduct(Category.FastqRecord, name + "() does not return String", 4);
}
catch (NoSuchMethodException x)
{
deduct(Category.FastqRecord, "No " + name + "() method", 5);
}
}
// Does class have instance vars defline, sequence, and quality?
String[] expectedFields = { "defline", "sequence", "quality" };
for (String s: expectedFields)
{
try
{
fastqRecordClass.getDeclaredField(s);
}
catch (NoSuchFieldException x)
{
deduct(Category.FastqRecord, "No field " + s, 4);
}
}
// Does class have (String, String, String) ctor that throws RecirdFormatException?
Constructor ctor = null;
try
{
ctor = fastqRecordClass.getConstructor(STRING_3_ARGSLIST);
Class[] exceptionTypes = ctor.getExceptionTypes();
switch (exceptionTypes.length)
{
case 0:
deduct(Category.FastqRecord, "FastqRecord ctor should throw checked type RecordFormatException", 5);
break;
case 1:
if (!exceptionTypes[0].getName().endsWith("RecordFormatException"))
deduct(Category.FastqRecord, "FastqRecord ctor should throw checked type RecordFormatException", 5);
break;
default:
err = "FastqRecord ctor throws multipl exception types, should only throw RecordFormatException";
deduct(Category.FastqRecord, err, 5);
break;
}
}
catch (NoSuchMethodException x)
{
deduct(Category.FastqRecord, "No (String,String,String) constructor", 5);
}
// Check ctor.
FastqRecord rec1AX = null;
try
{
rec1AX = new FastqRecord("@Rec1", "AAAA", "XXXX");
}
catch (RecordFormatException x)
{
deduct(Category.FastqRecord, "FastqRecord ctor threw exception on valid input (@Rec1, AAAA, XXXX)", 3);
}
try
{
new FastqRecord(">Rec1", "AAAA", "XXXX");
deduct(Category.FastqRecord, "FastqRecord ctor did not throw exception on invalid input (>Rec1, AAAA, XXXX)", 3);
}
catch (RecordFormatException x)
{
// Should get here.
}
// Check equals.
FastqRecord rec2AX = null;
FastqRecord rec1CX = null;
FastqRecord rec1AY = null;
FastqRecord rec2TY = null;
FastqRecord anotherRec1AX = null;
FastqRecord hiQualRec = null;
try
{
rec2AX = new FastqRecord("@Rec2", "AAAA", "XXXX");
rec1CX = new FastqRecord("@Rec1", "CCCC", "XXXX");
rec1AY = new FastqRecord("@Rec1", "AAAA", "YYYY");
rec2TY = new FastqRecord("@Rec2", "TTTT", "YYYY");
anotherRec1AX = new FastqRecord("@Rec1", "AAAA", "XXXX");
hiQualRec = new FastqRecord("@RecN", "ACGT", "!!!!");
}
catch (RecordFormatException x) { }
if (rec1AX == null || rec2AX == null || rec1CX == null || rec1AY == null || rec2TY == null)
{
err = "FastqRecord ctor is incorrect, can't create test instances to test equals()";
deduct(Category.FastqRecord, err, 6);
}
else
{
if (rec1AX.equals(rec2AX))
{
err = "equals returned true for (@Rec1, AAAA, XXXX) : (@Rec2, AAAA, XXXX)";
deduct(Category.FastqRecord, err, 2);
}
if (rec1AX.equals(rec1CX))
{
err = "equals returned true for (@Rec1, AAAA, XXXX) : (@Rec1, CCCC, XXXX)";
deduct(Category.FastqRecord, err, 2);
}
if (rec1AX.equals(rec1AY))
{
err = "equals returned true for (@Rec1, AAAA, XXXX) : (@Rec1, AAAA, YYYY)";
deduct(Category.FastqRecord, err, 2);
}
if (rec1AX.equals(rec2TY))
{
err = "equals returned true for (@Rec1, AAAA, XXXX) : (@Rec2, TTTT, YYYY)";
deduct(Category.FastqRecord, err, 2);
}
if (!rec1AX.equals(anotherRec1AX))
{
err = "equals returned false for 2 deeply equal instances (@Rec1, AAAA, XXXX)";
deduct(Category.FastqRecord, err, 2);
}
}
// Check qualityIsLow.
if (!hiQualRec.qualityIsLow())
deduct(Category.FastqRecord, "qualityIsLow is false for (@RecN, ACGT, !!!!)", 2);
if (rec1AX.qualityIsLow())
deduct(Category.FastqRecord, "qualityIsLow is true for (@Rec1, AAAA, XXXX)", 2);
// Check hash code.
int expected = "@Rec1".hashCode() + "AAAA".hashCode() + "XXXX".hashCode();
if (rec1AX.hashCode() != expected)
deduct(Category.FastqRecord, "hashCode() is not exactly as specified", 3);
}
public void gradeFastaRecord()
{
// Does class exist?
Class clazz = getClass("dna.FastaRecord");
if (clazz == null)
{
deductMax(Category.FastaRecord, "No dna.FastaRecord class");
return;
}
// Does class declare it implements DNARecord?
boolean implementsDNARecord = false;
for (Class c: clazz.getInterfaces())
{
if (c.getName().equals("dna.DNARecord"))
{
implementsDNARecord = true;
break;
}
}
if (!implementsDNARecord)
{
deduct(Category.FastaRecord, "DNARecord doesn't declare that it implements DNARecord.", 2);
}
// Does class define getDefline() and getSequence()?
String[] names = { "getDefline", "getSequence" };
for (String name: names)
{
try
{
Method m = clazz.getDeclaredMethod(name, EMPTY_ARGSLIST);
if (m.getReturnType() != String.class)
deduct(Category.FastaRecord, name + "() does not return String", 4);
}
catch (NoSuchMethodException x)
{
deduct(Category.FastaRecord, "No " + name + "() method", 5);
}
}
// Check (String, String) and (FastqRecord) ctors.
try
{
clazz.getConstructor(STRING_2_ARGSLIST);
}
catch (NoSuchMethodException x)
{
deduct(Category.FastaRecord, "No FastaRecord(String, String) constructor", 5);
}
try
{
clazz.getConstructor(new Class[] { fastqRecordClass });
}
catch (NoSuchMethodException x)
{
deduct(Category.FastaRecord, "No FastaRecord(FastqRecord) constructor", 5);
}
}
private void gradeFastqReader()
{
// Just make sure the class exists and has the right methods.
Class clazz = getClass("dna.FastqReader");
if (clazz == null)
{
deductMax(Category.FastqReader, "No dna.FastqReader class");
return;
}
// Check for (BufferedReader) ctor
try
{
clazz.getConstructor(BR_ARGSLIST);
}
catch (NoSuchMethodException x)
{
deduct(Category.FastqReader, "No FastqReader(BufferedReader) constructor", 5);
}
// Check for readRecord() method.
try
{
Method readRecordMethod = clazz.getDeclaredMethod("readRecord",EMPTY_ARGSLIST);
boolean throwsIOException = false;
boolean throwsFastqException = false;
for (Class xtype: readRecordMethod.getExceptionTypes())
{
if (xtype == java.io.IOException.class)
throwsIOException = true;
else if (xtype == dna.RecordFormatException.class)
throwsFastqException = true;
}
if (!throwsIOException)
deduct(Category.FastqReader, "readRecord() doesn't throw IOException", 3);
if (!throwsFastqException)
deduct(Category.FastqReader, "readRecord() doesn't throw RecordFormatException", 3);
}
catch (NoSuchMethodException x)
{
deduct(Category.FastqReader, "No readRecord() method", 5);
}
}
private void gradeFastaWriter()
{
// Just make sure the class exists and has the right methods.
Class clazz = getClass("dna.FastaWriter");
if (clazz == null)
{
deductMax(Category.FastaWriter, "No dna.FastaWriter class");
return;
}
// Check for (PrintWriter) ctor
try
{
clazz.getConstructor(PW_ARGSLIST);
}
catch (NoSuchMethodException x)
{
deduct(Category.FastaWriter, "No FastaWriter(PrintWriter) constructor", 5);
}
// Check for writeRecord()
Class[] argtype = new Class[] { FastaRecord.class };
try
{
clazz.getDeclaredMethod("writeRecord", argtype);
}
catch (NoSuchMethodException x)
{
deduct(Category.FastaWriter, "No writeRecord(FastaRecord) method", 5);
}
}
private final static String[] GOLDEN_FASTA_LINES =
{
">Record3",
"TATTAATCTGACT",
">Record4",
"TATTAATCTGACT",
">Record5",
"GTGATATCGACGTACGTACGTCATGCATGACTGCAGTCAGTACGTCATCAG",
">Record7",
"GTACTACGTACGTTGGACTAGTACGTACGT",
};
private void gradeConverter()
{
// Convert.
File fasta = null;
try
{
File ifile = new File("data/HW4.fastq");
if (!ifile.exists())
{
sop("Can't find HW4.fastq. Please put it in . or ./data");
System.exit(1);
}
File parent = ifile.getParentFile();
fasta = new File(parent, "HW4.fasta");
FileConverter converter = new FileConverter(ifile, fasta);
converter.convert();
}
catch (Exception x)
{
if (x instanceof IOException)
{
sop("IO Exception while converting ... shouldn't happen");
sop(x.getMessage());
x.printStackTrace();
System.out.println(x);
}
else
{
String err = "convert() throws unexpected " + x.getClass().getName() + " exception";
deduct(Category.FileConverter, err, 10);
}
}
// Check output. All records should be fasta (2 lines), with no duplicates. Don't check
// anything else.
Set observedDeflines = new HashSet<>();
try
(
FileReader fr = new FileReader(fasta);
BufferedReader br = new BufferedReader(fr);
)
{
String defline;
while ((defline = br.readLine()) != null)
{
if (defline == null || defline.trim().isEmpty())
break;
br.readLine();
if (observedDeflines.contains(defline))
{
String err = "Duplicate defline in fasta file: " + defline;
deduct(Category.FileConverter, err, 10);
break;
}
observedDeflines.add(defline);
}
}
catch (IOException x)
{
sop("Trouble reading fasta file, please run grader again.");
sop(x.getMessage());
x.printStackTrace();
System.exit(2);
}
// Check content of output.
ArrayList lines = new ArrayList<>();
try
(
FileReader fr1 = new FileReader(fasta);
BufferedReader br1 = new BufferedReader(fr1);
)
{
String line;
while ((line = br1.readLine()) != null)
lines.add(line);
}
catch (IOException x)
{
sop("Trouble reading fasta file, please run grader again.");
sop(x.getMessage());
x.printStackTrace();
System.exit(2);
}
if (lines.size() != GOLDEN_FASTA_LINES.length)
{
String err = "Wrong number of lines in HW4.fasta: saw " + lines.size() + ", expected " + GOLDEN_FASTA_LINES.length;
deduct(Category.FileConverter, err, 10);
}
else
{
for (int i=0; i
{
if (lines.get(i).equals(GOLDEN_FASTA_LINES[i]))
continue;
String err = "Unexpected line " + (i+1) + " in output: saw "+ lines.get(i) + ", expected " + GOLDEN_FASTA_LINES[i];
deduct(Category.FileConverter, err, 10);
}
}
}
private void testSubjective()
{
SubjectiveDialog dia = new SubjectiveDialog();
dia.setModal(true);
dia.setVisible(true);
gradersNotes = dia.getSubjectivePanel().getNotes();
int readabilityScore = dia.getSubjectivePanel().getReadabilityScore();
styleDeduction = Category.Style.getMaxDeductions() - readabilityScore;
int commentsScore = dia.getSubjectivePanel().getCommentsScore();
commentDeduction = Category.Comments.getMaxDeductions() - commentsScore;
}
private class SubjectivePanel extends JPanel
{
private ArrayList sliders;
private JTextArea notesTA;
SubjectivePanel()
{
sliders = new ArrayList<>();
setLayout(new BorderLayout());
setLayout(new GridLayout(1, 3));
Category[] cats = { Category.Style, Category.Comments };
for (Category cat: cats)
{
JPanel pan = new JPanel(new BorderLayout());
pan.add(new JLabel(cat.name()), BorderLayout.NORTH);
JSlider slider = new JSlider(0, cat.getMaxDeductions(), cat.getMaxDeductions());
slider.setMajorTickSpacing(1);
slider.setPaintTicks(true);
slider.setPaintLabels(true);
slider.setSnapToTicks(true);
pan.add(slider, BorderLayout.SOUTH);
sliders.add(slider);
add(pan);
}
notesTA = new JTextArea(10, 25);
JPanel commentsPan = new JPanel(new BorderLayout());
commentsPan.add(new JLabel("Your notes"), BorderLayout.NORTH);
commentsPan.add(notesTA, BorderLayout.CENTER);
add(commentsPan);
}
int getReadabilityScore()
{
return sliders.get(0).getValue();
}
int getCommentsScore()
{
return sliders.get(1).getValue();
}
String getNotes()
{
return notesTA.getText().trim();
}
}
private class SubjectiveDialog extends JDialog implements ActionListener
{
private SubjectivePanel subjPan;
SubjectiveDialog()
{
subjPan = new SubjectivePanel();
add(subjPan, BorderLayout.CENTER);
JPanel okPan = new JPanel();
JButton okBtn = new JButton("Ok");
okBtn.addActionListener(this);
okPan.add(okBtn);
add(okPan, BorderLayout.SOUTH);
pack();
}
public void actionPerformed(ActionEvent e)
{
setVisible(false);
}
SubjectivePanel getSubjectivePanel()
{
return subjPan;
}
}
private static void sop(Object x)
{
System.out.println(x);
}
public static void main(String[] args)
{
new DNAGrader().grade();
}
}
---------------------------------------------------------------
DNARecord.java
----------------------------------------------------------------
package dna;
// // FastqRecord and FastaRecord should implement this. // // Remember that in implementing classes, the methods // listed in the interface have to be public. //
public interface DNARecord { String getDefline(); String getSequence(); }
---------------------------------------------------------------
FastaRecord.java
----------------------------------------------------------------
package dna;
public class FastaRecord implements DNARecord { private String defline; private String sequence; // // Add a precondition check: throw FastqException if the 1st char of the defline is // not '>'. You will have to change the ctor declaration to say that it throws // the exception. The exception should contain a useful informative message. // //ctor public FastaRecord(String defline, String sequence) throws RecordFormatException { if(defline.charAt(0) != '>') { throw new RecordFormatException("Bad 1st char in defline in fasta record: Saw" + defline.charAt(0) + " expected >"); } this.defline = defline; this.sequence = sequence; } // Initialize defline and sequence from the input record. The defline should be the // defline of the fastq record, but with a '>' in the first position rather than a '@'. //ctor public FastaRecord(FastqRecord fastqRec) { this.defline = ">" + fastqRec.getDefline().substring(1); this.sequence = fastqRec.getSequence(); }
// // Provide the 2 methods that satisfy the interface. //
//returns the variable defline public String getDefline() { return defline; }
//returns the variable sequence public String getSequence() { return sequence; } // // Provide an equals() method. // //checks to see that both FastaRecor are deep equal to each other public boolean equals(Object x) { FastaRecord that = (FastaRecord) x; return this.defline.equals(that.defline) && this.sequence.equals(that.sequence); }
// // Provide a toString () method. // //returns the variables in string form public String toString() { return this.defline + " " + this.sequence + " "; }
// // Provide a hashCode() method that returns the sum of the hashcodes of // defline and sequence. // public int hashCode() { return this.defline.hashCode() + this.sequence.hashCode(); } }
---------------------------------------------------------------
FastaWriter.java
----------------------------------------------------------------
package dna;
import java.io.*;
// // Writes a fasta record to a print writer. //
public class FastaWriter {
private PrintWriter thePrintWriter; //ctor public FastaWriter(PrintWriter thePrintWriter) { this.thePrintWriter = thePrintWriter; } // Write the rec as 2 separate lines: first the defline, then the sequence. // To write something on a separate line, use the println() method of PrintWriter. public void writeRecord(FastaRecord rec) throws IOException { thePrintWriter.println(rec.getDefline()); thePrintWriter.println(rec.getSequence()); } }
---------------------------------------------------------------
FastqReader.java
----------------------------------------------------------------
package dna;
import java.io.*;
// // Reads lines from a BufferedReader and builds a FastqReader. //
public class FastqReader { private BufferedReader theBufferedReader; //ctor public FastqReader(BufferedReader theBufferedReader) { this.theBufferedReader = theBufferedReader; } // Returns next record in the file, or null if EOF. public FastqRecord readRecord() throws IOException, RecordFormatException { // Read the defline from the BufferedReader. Return null if you read null, // indicating end of file. String one = theBufferedReader.readLine(); if(one == null) { return null; } // Read the next 3 lines from the buffered reader. Construct and return // a FastqRecord. String d = theBufferedReader.readLine(); theBufferedReader.readLine(); String q = theBufferedReader.readLine(); FastqRecord r = new FastqRecord(one, d, q); return r; } }
---------------------------------------------------------------
FastqRecord.java
----------------------------------------------------------------
package dna; public class FastqRecord implements DNARecord
{
private String defline;
private String sequence;
private String quality;
public FastqRecord(String defline, String sequence, String quality) throws RecordFormatException
{
if(defline.charAt(0) != '@') {
throw new RecordFormatException("Bad 1st char in defline in fastq record: Saw" + defline.charAt(0) + " expected @");
}
this.defline = defline;
this.sequence = sequence;
this.quality = quality;
}
//
// Provide the 2 methods that satisfy the interface.
//
//returns the variable defline
public String getDefline() {
return defline;
}
//returns the variable sequence
public String getSequence() {
return sequence;
}
//
// Provide an equals() method that checks for deep equality of all 3 instance variables.
// When checking string variables, be sure to do it like this:
// this.defline.equals(that.defline)
// and not like this:
// this.defline == that.defline
//
public boolean equals(Object x) {
FastqRecord that = (FastqRecord) x;
return this.defline.equals(that.defline) && this.sequence.equals(that.sequence) && this.quality.equals(that.quality);
}
//
// Provide a hashCode() method that returns the sum of the hashcodes of
// defline, sequence, and quality.
//
public int hashCode() {
return this.defline.hashCode() + this.sequence.hashCode() + this.quality.hashCode();
}
//
// Complete this. Return true if quality contains at least 3 '!' chars.
//
public boolean qualityIsLow()
{
int counter = 0;
for(int i = 0; i < quality.length(); i++) {
if(quality.charAt(i) == '!') {
counter++;
}
}
return counter >= 3;
}
//
// Complete this.
//
//returns the variables in string form
public String toString()
{
return this.defline + " " + this.sequence + " + " + this.quality + " ";
}
}
---------------------------------------------------------------
FileConverter.java
----------------------------------------------------------------
package dna;
import java.io.*; import java.util.*;
public class FileConverter { private File fastq; private File fasta; //ctor public FileConverter(File fastq, File fasta) { this.fastq = fastq; this.fasta = fasta; } // // Writes a fasta file consisting of conversion of all records from the fastq with // sufficient quality and unique defline. // // Use a HashSet to check for unique deflines. When you read a fastq record, // check if its defline is in the set. If it's in the set, don't do anything with the // record. If the defline isn't in the set, add it to the set, build a fasta record, // and write the fasta record using the fasta writer. // public void convert() throws IOException { // Build chain of readers. FileReader fr = new FileReader(fastq); BufferedReader br = new BufferedReader(fr); FastqReader fqr = new FastqReader(br);
// Build chain of writers. FileWriter fw = new FileWriter(fasta); PrintWriter pw = new PrintWriter(fw); FastaWriter faw = new FastaWriter(pw); // Read, translate, write. HashSet records = new HashSet(); FastqRecord tem = null; try { tem = fqr.readRecord(); } catch (RecordFormatException x) { } while(tem != null) { if(tem.qualityIsLow() && records.add(tem.getDefline())) { faw.writeRecord(new FastaRecord(tem)); } try { tem = fqr.readRecord(); } catch (RecordFormatException x) { } } // Close fr, br, fw, and pw in reverse order of creation. br.close(); fr.close(); pw.close(); fw.close(); } public static void main(String[] args) { System.out.println("Starting"); try { File fastq = new File("data/HW4.fastq"); if (!fastq.exists()) { System.out.println("Can't find input file " + fastq.getAbsolutePath()); System.exit(1); } File fasta = new File("data/HW4.fasta"); FileConverter converter = new FileConverter(fastq, fasta); converter.convert(); } catch (IOException x) { System.out.println(x.getMessage()); } System.out.println("Done"); } }
---------------------------------------------------------------
RecordFormatException.java
----------------------------------------------------------------
package dna;
public class RecordFormatException extends Exception
{
// Complete this.
public RecordFormatException(String message)
{
super(message);
}
}
---------------------------------------------------------------
HW4.fastq
----------------------------------------------------------------
@Record1 ACGTACGTACGTACGTACGT + !82r8!!efidfiuwfgw77 @Record2 ACGTATTCGACGACTCGTACGTACGT + !!!!!!!!!!!!!!!!!!!!!!!!!! @Record3 TATTAATCTGACT + +880%^$^^*877 @Record4 TATTAATCTGACT + +*%^$^^^^*877 @Record5 GTGATATCGACGTACGTACGTCATGCATGACTGCAGTCAGTACGTCATCAG + 8887876987678#$%^#876585#$6758758753327857657576578 >Record6 GTACTACGTACGTTGGACTAGTACGTACGT + !@67898687IUTUYT86!!%66%%^^%^^ @Record7 GTACTACGTACGTTGGACTAGTACGTACGT + [@678922287IUTUYT869%%66%%^^%^^
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started