CSE 11 Programming Assignment 4
Due Date: Tuesday, April 26, 10:00PM Pacific Time
Learning Goals
- Practice working with interfaces
- Practice with creating objects and classes
Collaboration
Different assignments in this course have different collaboration policies. On this assignment, you can collaborate with anyone in the course, but you must create your own memory diagrams and descriptions for answers. In your submission, give credit to all students and course staff who helped you with this assignment by noting their name and how you used their ideas or work. Note that using someone’s work without giving credit to them is a violation of academic integrity.
You can get the starter code at
https://github.com/ucsd-cse11-sp22/cse11-pa4-starter
Submission Checklist
- Tweets.java
- TextTweet + ReplyTweet class
- isReplyTo method
- totalLikes method
- allAuthors method
- textAppearsOnThread method
- countPopularTweets method
- 2 additional test per method, total 10, using tester library
- 1 thread
- 3 different authors
- 5 different tweets
- TextTweet + ReplyTweet class
- Numbers.java
- WholeNumber + Fraction + Decimal
- numerator method
- denominator method
- add method
- multiply method
- toText method
- toDouble method
- Exploration task
- WholeNumber + Fraction + Decimal
Tweets
In a file Tweets.java
, write an interface
called Tweet
with five
methods:
public boolean isReplyTo(Tweet other);
public int totalLikes();
public String allAuthors();
public boolean textAppearsOnThread(String text);
public int countPopularTweets(int minNumLikes);
Then, write three classes:
-
User
, just as in PA2 TextTweet
, implementsTweet
and has three fields:contents
, aString
author
, aUser
likes
, an int
This class should implement the methods as follows:
isReplyTo
should returnfalse
no matter what Tweet it receivestotalLikes
should return the number of likes on thisTextTweet
objectallAuthors
should return the username of the author of thisTextTweet
textAppearsOnThread
should returntrue
when the given text is in the contents of thisTextTweet
,false
otherwise.countPopularTweets
should return1
if the number of likes on this tweet is strictly greater than the given int,0
otherwise.
ReplyTweet
, which should implementTweet
and has four fields:contents
, aString
author
, aUser
likes
, an intreplyTo
, aTweet
This class should implement the methods as follows:
isReplyTo
should returntrue
if thereplyTo
of thisReplyTweet
is the givenTweet
, as compared by==
.totalLikes
should return the total number of likes on thisReplyTweet
object plus thetotalLikes
of itsreplyTo
Tweet. For example, a thread of tweets that is 4 replies long should sum the likes on all 4 of those tweets.allAuthors
should return the username of the author of thisReplyTweet
followed by a semicolon (";"
), followed byallAuthors
of itsreplyTo
Tweet.textAppearsOnThread
should returntrue
when the given text appears in thecontents
of thisReplyTweet
, or if it appears on the thread of thereplyTo
Tweet.countPopularTweets
should return the number of tweets in the thread that have like counts strictly greater than the given number of likes.
Add constructors as appropriate to initialize the fields on objects of these classes.
Some tests you can start with are here; you can copy them to your program as you implement the various methods.
User greg = new User("gregory_miranda", "Greg Miranda", 9999);
User sanmi = new User("sanmi_adeleye", "Sanmi Adeleye", 999);
User sangeetha = new User("sangeetha_viswanathan_sakthivel", "Sangeetha Viswanathan Sakthivel", 1000000);
Tweet t1 = new TextTweet("Java 17 has a cool feature called records", this.sanmi, 77);
Tweet t2 = new ReplyTweet("Hmm I wonder if we could use it for CSE11", this.greg, 12, this.t1);
Tweet t3 = new ReplyTweet("Thought about this more, probably not yet, too new.", this.greg, 73, this.t2);
Tweet t4 = new ReplyTweet("Yeah, good point. Maybe in 2022.", this.sanmi, 10, this.t3);
Tweet t5 = new ReplyTweet("Yeah... I don't want to rewrite the book right this minute", this.sangeetha, 1005, this.t2);
void testIsReplyTo(Tester t) {
t.checkExpect(this.t1.isReplyTo(this.t2), false);
t.checkExpect(this.t2.isReplyTo(this.t1), true);
t.checkExpect(this.t5.isReplyTo(this.t2), true);
t.checkExpect(this.t2.isReplyTo(this.t2), false);
t.checkExpect(this.t4.isReplyTo(this.t3), true);
}
void testTotalLikes(Tester t) {
t.checkExpect(this.t5.totalLikes(), 1005 + 12 + 77);
t.checkExpect(this.t4.totalLikes(), 10 + 73 + 12 + 77);
t.checkExpect(this.t1.totalLikes(), 77);
}
void testAllAuthors(Tester t) {
t.checkExpect(this.t1.allAuthors(), "sanmi_adeleye");
t.checkExpect(this.t2.allAuthors(), "gregory_miranda;sanmi_adeleye");
t.checkExpect(this.t3.allAuthors(), "gregory_miranda;gregory_miranda;sanmi_adeleye");
t.checkExpect(this.t5.allAuthors(), "sangeetha_viswanathan_sakthivel;gregory_miranda;sanmi_adeleye");
}
void testTextAppearsOnThread(Tester t) {
t.checkExpect(this.t1.textAppearsOnThread("sanmi_adeleye"), false);
t.checkExpect(this.t1.textAppearsOnThread("2022"), false);
t.checkExpect(this.t1.textAppearsOnThread("cool"), true);
t.checkExpect(this.t4.textAppearsOnThread("wonder"), true);
t.checkExpect(this.t4.textAppearsOnThread("Java"), true);
t.checkExpect(this.t4.textAppearsOnThread("rewrite"), false);
t.checkExpect(this.t4.textAppearsOnThread("2022"), true);
}
void testCountPopularTweets(Tester t) {
t.checkExpect(this.t1.countPopularTweets(100), 0);
t.checkExpect(this.t2.countPopularTweets(10), 2);
t.checkExpect(this.t3.countPopularTweets(70), 2);
t.checkExpect(this.t5.countPopularTweets(0), 3);
}
Additional Testing and Exploration
You must also add your own tests. Construct your own (made-up or real) Tweet thread with at least 3 different authors and at least 5 different Tweets, and write at least 2 additional tests for each method – try to think of cases we may have not thoroughly tested in what’s provided.
Put these in an easily-found area of the ExampleTweets
to help us review your
code; don’t add them to the existing methods we provided.
Numbers
This code will go in the file Numbers.java
, any tests in a class called
ExampleNumbers
that you add to that file.
Remember that you will not be nesting any interfaces or classes. Doing so will cause the autograder to fail.
We saw in our reading that representing fractional numbers like 0.6 with
doubles can be fraught. Some languages and libraries do support exact
fractions, and we can implement classes that act like them in Java. We won’t
be able to use the built-in +
and *
operators, because these are only
defined for numbers and strings, but we can define methods for the operations
we care about. We can represent numbers with an interface:
interface Number {
int numerator();
int denominator();
Number add(Number other);
Number multiply(Number other);
String toText();
double toDouble();
}
Your task is to create three classes that implement the interface above. One
should be called WholeNumber
and represent whole integers. The second should be called Fraction
and represent mixed
numbers. The third should be called Decimal
and represent decimals
WholeNumber
should have:
- A field
int n
and a constructor that takes a singleint
- An implementation of all the methods above.
numerator
should return the value ofn
denominator
should return1
add
should return a newNumber
that represents adding this whole number to the one provided as an argument. Note that the argument could be either aWholeNumber
,Fraction
, orDecimal
multiply
should return a newNumber
that represents multiplying this whole number to the one provided as an argument. Note that the argument could be either aWholeNumber
,Fraction
, orDecimal
toText
should return the value ofn
as aString
, so ifn
is500
, it should return"500"
toDouble
should return the value ofn
as adouble
Fraction
should have:
- A field
int n
representing the numerator - A field
int d
representing the denominator - An implementation of all the methods above:
numerator
should return the value ofn
denominator
should return the value ofd
add
should return a newNumber
that represents adding this fraction to the one provided as an argument. Note that the argument could be either aWholeNumber
,Fraction
, orDecimal
multiply
should return a newNumber
that represents multiplying this fraction by the one provided as an argument. Note that the argument could be either aWholeNumber
,Fraction
, orDecimal
toText
should return aString
in the format"n/d"
wheren
andd
are the corresponding fields. So ifn
andd
were1
and2
, this should be"1/2"
toDouble
should return the value ofn/d
as adouble
. So ifn
is 1 andd
is 2, this should return0.5
Decimal
should have:You may find it helpful to use
Integer.parseInt()
to convert a string to an integer.- A field
int mantissa
representing the mantissa of the decimal when expressed in scientific notation - A field
int exponent
representing the exponent of the decimal when expressed in scietific notation - An implementation of all the methods above:
numerator
should return the numerator of the decomal when expressed as a fractiondenominator
should return the denominator of the decimal when expressed as a fractionadd
should return a newNumber
that represents adding this decimal to the one provided as an argument. Note that the argument could be either aWholeNumber
,Fraction
, orDecimal
multiply
should return a newNumber
that represents multiplying this decimal to the one provided as an argument. Note that the argument could be either aWholeNumber
,Fraction
, orDecimal
toText
should return aString
in the format#.#
. So ifmantissa
is314
andexponent
is-2
, this should be"3.14"
. However, ifmantissa
is12345
andexponent
is-3
, then the result should be"12.345"
. The amount of numbers before and after the decimal point will depend on the original input.toDouble
should return the value of the number expressed by the mantissa and exponent as a double. So ifmantissa
is314
andexponent
is-2
, this should be3.14
A reminder about arithmetic and fractions:
\[n = \frac{n}{1}\] \[\frac{n}{d_1} + \frac{m}{d_2} = \frac{d_1m + d_2n}{d_1d_2}\] \[\frac{n}{d_1} \cdot \frac{m}{d_2} = \frac{nm}{d_1d_2}\]Some example tests that you can use are below. You can copy-paste these into your solution as you implement the various methods. All of these tests must pass on your implementation.
Number n1 = new WholeNumber(5);
Number n2 = new WholeNumber(7);
Number n3 = new Fraction(7, 2);
Number n4 = new Fraction(1, 2);
Number n5 = new Decimal("3.25");
Number n6 = new Decimal("5.5");
void testAdd(Tester t) {
t.checkExpect(this.n1.add(this.n2).toDouble(), 12.0);
t.checkExpect(this.n1.add(this.n3).toDouble(), 5 + 7.0/2.0);
t.checkExpect(this.n3.add(this.n3).toDouble(), 7.0);
t.checkExpect(this.n5.add(this.n4).toDouble(), 3.75);
}
void testMultiply(Tester t) {
t.checkExpect(this.n1.multiply(this.n4).toDouble(), 2.5);
t.checkExpect(this.n3.multiply(this.n4).toDouble(), 7.0/4.0);
t.checkExpect(this.n6.multiply(this.n1).toDouble(), 27.5);
}
void testNumDem(Tester t) {
t.checkExpect(this.n3.numerator(), 7);
t.checkExpect(this.n1.numerator(), 5);
t.checkExpect(this.n5.numerator(), 325);
t.checkExpect(this.n4.denominator(), 2);
t.checkExpect(this.n2.denominator(), 1);
t.checkExpect(this.n6.denominator(), 10);
}
void testToString(Tester t) {
t.checkExpect(this.n4.toText(), "1/2");
t.checkExpect(this.n3.toText(), "7/2");
t.checkExpect(this.n2.toText(), "7");
t.checkExpect(this.n5.toText(), "3.25");
}
Exploration
At the end of the ExamplesNumbers
class in a place marked clearly with a
comment that says // Exploration
, write code to perform four calculations:
- The result of
0.1 + 0.2 + 0.3
using built-indouble
arithmetic in Java - The result of
0.1 + (0.2 + 0.3)
using built-indouble
arithmetic in Java - The result of (1) using your exact fractions, showing the result of
add()
viatoText()
- The result of (2) using your exact fractions, showing the result of
add()
viatoText()
Submission
Then you will submit all of your files to the PA4
assignment on Gradescope:
Numbers.java
Tweets.java
Tests and exploration sections will be graded manually. In addition, we may give you feedback on any part of the code, including automatically graded parts, that we want you to respond to after grading.