Commit ea496c5a authored by MoutazDebbaneh's avatar MoutazDebbaneh

Add question 2 solution

parent bd03036c
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>
\ No newline at end of file
This diff is collapsed.
package org.example; package hiast.hw.question1;
import java.util.Arrays; import java.util.Arrays;
import java.util.concurrent.RecursiveAction; import java.util.concurrent.RecursiveAction;
......
package hiast.hw.question2;
/**
* A class representing a single student in a single class.
*/
public final class Student {
/**
* First name of the student.
*/
private final String firstName;
/**
* Surname of the student.
*/
private final String lastName;
/**
* Age of the student.
*/
private final double age;
/**
* Grade the student has received in the class so far.
*/
private final int grade;
/**
* Whether the student is currently enrolled, or has already completed the
* course.
*/
private final boolean isCurrent;
/**
* Constructor.
* @param setFirstName Student first name
* @param setLastName Student last name
* @param setAge Student age
* @param setGrade Student grade in course
* @param setIsCurrent Student currently enrolled?
*/
public Student(final String setFirstName, final String setLastName,
final double setAge, final int setGrade,
final boolean setIsCurrent) {
this.firstName = setFirstName;
this.lastName = setLastName;
this.age = setAge;
this.grade = setGrade;
this.isCurrent = setIsCurrent;
}
/**
* Get the first name of this student.
* @return The student's first name.
*/
public String getFirstName() {
return firstName;
}
/**
* Get the last name of this student.
* @return The student's last name.
*/
public String getLastName() {
return lastName;
}
/**
* Get the age of this student.
* @return The student's age.
*/
public double getAge() {
return age;
}
/**
* Get the grade this student has achieved in this course so far.
* @return The student's current grade.
*/
public int getGrade() {
return grade;
}
/**
* Check if this student is active, or has taken the course in the past.
* @return true if the student is currently enrolled, false otherwise
*/
public boolean checkIsCurrent() {
return isCurrent;
}
}
package hiast.hw.question2;
import java.util.*;
import java.util.stream.Collectors;
/**
* A simple wrapper class for various analytics methods.
*/
public final class StudentAnalytics {
/**
* Sequentially computes the average age of all actively enrolled students
* using loops.
*
* @param studentArray Student data for the class.
* @return Average age of enrolled students
*/
public double averageAgeOfEnrolledStudentsImperative(
final Student[] studentArray) {
List<Student> activeStudents = new ArrayList<Student>();
for (Student s : studentArray) {
if (s.checkIsCurrent()) {
activeStudents.add(s);
}
}
double ageSum = 0.0;
for (Student s : activeStudents) {
ageSum += s.getAge();
}
return ageSum / (double) activeStudents.size();
}
/**
* TODO compute the average age of all actively enrolled students using
* parallel streams. This should mirror the functionality of
* averageAgeOfEnrolledStudentsImperative. This method should not use any
* loops.
*
* @param studentArray Student data for the class.
* @return Average age of enrolled students
*/
public double averageAgeOfEnrolledStudentsParallelStream(
final Student[] studentArray) {
var result = Arrays.stream(studentArray).parallel().filter(s -> s.checkIsCurrent()).mapToDouble(s -> s.getAge()).average();
return (result.isPresent() ? result.getAsDouble() : 0.0);
}
/**
* Sequentially computes the most common first name out of all students that
* are no longer active in the class using loops.
*
* @param studentArray Student data for the class.
* @return Most common first name of inactive students
*/
public String mostCommonFirstNameOfInactiveStudentsImperative(
final Student[] studentArray) {
List<Student> inactiveStudents = new ArrayList<Student>();
for (Student s : studentArray) {
if (!s.checkIsCurrent()) {
inactiveStudents.add(s);
}
}
Map<String, Integer> nameCounts = new HashMap<String, Integer>();
for (Student s : inactiveStudents) {
if (nameCounts.containsKey(s.getFirstName())) {
nameCounts.put(s.getFirstName(),
new Integer(nameCounts.get(s.getFirstName()) + 1));
} else {
nameCounts.put(s.getFirstName(), 1);
}
}
String mostCommon = null;
int mostCommonCount = -1;
for (Map.Entry<String, Integer> entry : nameCounts.entrySet()) {
if (mostCommon == null || entry.getValue() > mostCommonCount) {
mostCommon = entry.getKey();
mostCommonCount = entry.getValue();
}
}
return mostCommon;
}
/**
* TODO compute the most common first name out of all students that are no
* longer active in the class using parallel streams. This should mirror the
* functionality of mostCommonFirstNameOfInactiveStudentsImperative. This
* method should not use any loops.
*
* @param studentArray Student data for the class.
* @return Most common first name of inactive students
*/
public String mostCommonFirstNameOfInactiveStudentsParallelStream(
final Student[] studentArray) {
return Arrays.stream(studentArray).parallel()
.filter(s -> !s.checkIsCurrent())
.collect(Collectors.groupingBy(s -> s.getFirstName(), Collectors.counting()))
.entrySet().stream().parallel()
.max((x, y) -> (int)(x.getValue() - y.getValue()))
.get().getKey();
}
/**
* Sequentially computes the number of students who have failed the course
* who are also older than 20 years old. A failing grade is anything below a
* 65. A student has only failed the course if they have a failing grade and
* they are not currently active.
*
* @param studentArray Student data for the class.
* @return Number of failed grades from students older than 20 years old.
*/
public int countNumberOfFailedStudentsOlderThan20Imperative(
final Student[] studentArray) {
int count = 0;
for (Student s : studentArray) {
if (!s.checkIsCurrent() && s.getAge() > 20 && s.getGrade() < 65) {
count++;
}
}
return count;
}
/**
* TODO compute the number of students who have failed the course who are
* also older than 20 years old. A failing grade is anything below a 65. A
* student has only failed the course if they have a failing grade and they
* are not currently active. This should mirror the functionality of
* countNumberOfFailedStudentsOlderThan20Imperative. This method should not
* use any loops.
*
* @param studentArray Student data for the class.
* @return Number of failed grades from students older than 20 years old.
*/
public int countNumberOfFailedStudentsOlderThan20ParallelStream(
final Student[] studentArray) {
return (int)Arrays.stream(studentArray).parallel()
.filter(s -> !s.checkIsCurrent() && s.getGrade() < 65 && s.getAge() > 20)
.count();
}
}
package hiast.hw.question1;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.example.ArrayOccurrencesCount; import hiast.hw.question1.ArrayOccurrencesCount;
import java.util.Random; import java.util.Random;
import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinPool;
import java.util.stream.IntStream; import java.util.stream.IntStream;
......
package hiast.hw.question2;
import java.util.Random;
import junit.framework.TestCase;
public class StudentAnalyticsTest extends TestCase {
final static int REPEATS = 10;
private final static String[] firstNames = {"Sanjay", "Yunming", "John", "Vivek", "Shams", "Max"};
private final static String[] lastNames = {"Chatterjee", "Zhang", "Smith", "Sarkar", "Imam", "Grossman"};
private static int getNCores() {
String ncoresStr = System.getenv("COURSERA_GRADER_NCORES");
if (ncoresStr == null) {
return Runtime.getRuntime().availableProcessors();
} else {
return Integer.parseInt(ncoresStr);
}
}
private Student[] generateStudentData() {
final int N_STUDENTS = 2000000;
final int N_CURRENT_STUDENTS = 600000;
Student[] students = new Student[N_STUDENTS];
Random r = new Random(123);
for (int s = 0; s < N_STUDENTS; s++) {
final String firstName = firstNames[r.nextInt(firstNames.length)];
final String lastName = lastNames[r.nextInt(lastNames.length)];
final double age = r.nextDouble() * 100.0;
final int grade = 1 + r.nextInt(100);
final boolean current = (s < N_CURRENT_STUDENTS);
students[s] = new Student(firstName, lastName, age, grade, current);
}
return students;
}
private double averageAgeOfEnrolledStudentsHelper(final int repeats) {
final Student[] students = generateStudentData();
final StudentAnalytics analytics = new StudentAnalytics();
final double ref = analytics.averageAgeOfEnrolledStudentsImperative(students);
final long startSequential = System.currentTimeMillis();
for (int r = 0; r < repeats; r++) {
analytics.averageAgeOfEnrolledStudentsImperative(students);
}
final long endSequential = System.currentTimeMillis();
final double calc = analytics.averageAgeOfEnrolledStudentsParallelStream(students);
final double err = Math.abs(calc - ref);
final String msg = "Expected " + ref + " but found " + calc + ", err = " + err;
assertTrue(msg, err < 1E-5);
final long startParallel = System.currentTimeMillis();
for (int r = 0; r < repeats; r++) {
analytics.averageAgeOfEnrolledStudentsParallelStream(students);
}
final long endParallel = System.currentTimeMillis();
return (double)(endSequential - startSequential) / (double)(endParallel - startParallel);
}
/*
* Test correctness of averageAgeOfEnrolledStudentsParallelStream.
*/
public void testAverageAgeOfEnrolledStudents() {
averageAgeOfEnrolledStudentsHelper(1);
}
/*
* Test performance of averageAgeOfEnrolledStudentsParallelStream.
*/
public void testAverageAgeOfEnrolledStudentsPerf() {
final int ncores = getNCores();
final double speedup = averageAgeOfEnrolledStudentsHelper(REPEATS);
String msg = "Expected parallel version to run at least 1.2x faster but speedup was " + speedup;
assertTrue(msg, speedup > 1.2);
}
private double mostCommonFirstNameOfInactiveStudentsHelper(final int repeats) {
final Student[] students = generateStudentData();
final StudentAnalytics analytics = new StudentAnalytics();
final String ref = analytics.mostCommonFirstNameOfInactiveStudentsImperative(students);
final long startSequential = System.currentTimeMillis();
for (int r = 0; r < repeats; r++) {
analytics.mostCommonFirstNameOfInactiveStudentsImperative(students);
}
final long endSequential = System.currentTimeMillis();
final String calc = analytics.mostCommonFirstNameOfInactiveStudentsParallelStream(students);
assertEquals("Mismatch in calculated values", ref, calc);
final long startParallel = System.currentTimeMillis();
for (int r = 0; r < repeats; r++) {
analytics.mostCommonFirstNameOfInactiveStudentsParallelStream(students);
}
final long endParallel = System.currentTimeMillis();
return (double)(endSequential - startSequential) / (double)(endParallel - startParallel);
}
/*
* Test correctness of mostCommonFirstNameOfInactiveStudentsParallelStream.
*/
public void testMostCommonFirstNameOfInactiveStudents() {
mostCommonFirstNameOfInactiveStudentsHelper(1);
}
/*
* Test performance of mostCommonFirstNameOfInactiveStudentsParallelStream.
*/
public void testMostCommonFirstNameOfInactiveStudentsPerf() {
final int ncores = getNCores();
final double speedup = mostCommonFirstNameOfInactiveStudentsHelper(REPEATS);
final double expectedSpeedup = (double)ncores * 0.5;
String msg = "Expected speedup to be at least " + expectedSpeedup + " but was " + speedup;
assertTrue(msg, speedup >= expectedSpeedup);
}
private double countNumberOfFailedStudentsOlderThan20Helper(final int repeats) {
final Student[] students = generateStudentData();
final StudentAnalytics analytics = new StudentAnalytics();
final int ref = analytics.countNumberOfFailedStudentsOlderThan20Imperative(students);
final long startSequential = System.currentTimeMillis();
for (int r = 0; r < repeats; r++) {
analytics.countNumberOfFailedStudentsOlderThan20Imperative(students);
}
final long endSequential = System.currentTimeMillis();
final int calc = analytics.countNumberOfFailedStudentsOlderThan20ParallelStream(students);
assertEquals("Mismatch in calculated values", ref, calc);
final long startParallel = System.currentTimeMillis();
for (int r = 0; r < repeats; r++) {
analytics.countNumberOfFailedStudentsOlderThan20ParallelStream(students);
}
final long endParallel = System.currentTimeMillis();
return (double)(endSequential - startSequential) / (double)(endParallel - startParallel);
}
/*
* Test correctness of countNumberOfFailedStudentsOlderThan20ParallelStream.
*/
public void testCountNumberOfFailedStudentsOlderThan20() {
countNumberOfFailedStudentsOlderThan20Helper(1);
}
/*
* Test performance of countNumberOfFailedStudentsOlderThan20ParallelStream.
*/
public void testCountNumberOfFailedStudentsOlderThan20Perf() {
final int ncores = getNCores();
final double speedup = countNumberOfFailedStudentsOlderThan20Helper(REPEATS);
String msg = "Expected parallel version to run at least 1.2x faster but speedup was " + speedup;
assertTrue(msg, speedup > 1.2);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment