Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Help with python lab assignment 9, please Assignment 9 - Changing Sort Keys Unde

ID: 3902984 • Letter: H

Question

Help with python lab assignment 9, please

Assignment 9 - Changing Sort Keys

Understand the Application

Sort Flexibility (Student class)

In week 8, we saw an example of a Student class that provided a static compare_strings_ignore_case() method. We needed to define such a method because our sort algorithm (which was in the StudentArrayUtilities (SAU) class) had to have a basis for comparing two Student objects, the foundation of SAUs sorting algorithm. Since a Student is a compound data type, not a float or a string, there was no pre-defined less-than, <, operation available, so we created our own compare_strings_ignore_case(), which was based on the spelling of the last name. You can review those notes to see its definition.

We want to make the sort more flexible in this assignment. Sometimes we want to sort on last name, as we did in the lectures, but other times we may choose to sort on the first name (useful for informal communication) or total points (useful for analyzing statistics). We could go into the compare_strings_ignore_case()method and change its definition to work on first name. Or, we could rename it to compare_two_numbers() and base it on total points (or for that possibility just change SAU's float_largest_to_top()so that compare the points itself < or <=, no method call needed. But, such "solutions" only replace the inflexibility of last name with the inflexibility of some other criteria.

So here's the plan: we will provide class Student with a new class method set_sort_key() which will establish a new sort criteria. A client will invoke it whenever it wants to switch to a new basis for comparison. The client will pass an argument to set_sort_key() telling it which one of the three Student attributes it wants future sort algorithms to use. The Student class will keep its compare_strings_ignore_case() static method, but add a new class method called compare_two_students() (which can use the older method as a helper). This name doesn't commit to string vs. number, plus it gives the SAU class a unified method to invoke,Student.compare_two_students(), inside its float_largest_to_top(). The current sort key will inform compare_two_students() how to make the comparison.

No Output (SAU class)

Another change we'll make affects the output modality. Rather than displaying the array directly in the SAU class, we want to make the class "U.I. neutral." So we will replace SAU's print_array() method with a to_string() method and let the client choose how to use that. In our example main program we will be sending the string array to the console.

Median (SAU class)

We'll add one more class method to SAU: double get_median_destructive( cls, array, array_size). This method will return the median of the total_toints values in an array. Look up median. It is defined as the "middle-value" and is easily computed, but you first have to sort the array in order to find it. Fortunately, you already have the sort method.

Client

Our client will declare three Student arrays to make sure our median works: one array that has an odd number of students (15), one that has an even number of students (16) and one that has a single student.

We'll test the sort_key and sort algorithm only on the even numbered array, and then we will test our median computation on all three arrays.

The Program Spec

These changes should not be complicated as long as you read carefully and follow directions. New and modified members/methods are all very short, so stay focused and apply what you learned back in week 8.

Additions to the Student Class

We will add the following static members to the class in the modules.

static int consts:

SORT_BY_FIRST = 88

SORT_BY_LAST = 98

SORT_BY_POINTS = 108

These are the three sort keys that will be used by the client and the class, alike, to keep track of, or set, the sort key.   If the client wants to establish a new sort key, it will pass one of these tokens (say Student.SORT_BY_FIRST) to the setter described next.    I have intentionally made the literal values non-contiguous so you would not rely on their particular values in your logic.   You should be able to change the values without breaking your program (but you don't have to change them; use the three values above).

static int:

sort_key - this will always have one of the three constants above as its value. Make sure it initially has SORT_BY_LAST in it, but after the client changes it, it could be any of the above constants.

You should supply the following simple static methods:

def set_sort_key(cls, key): -- a mutator for the member sortKey.

def get_sort_key(cls): -- an accessor for sortKey.

A new class comparison method:

def compare_two_students(cls, first_stud, second_stud):-- This method has to look at the sort_key and compare the two Students based on the currently activesort_key. It will return a number as follows:

If sort_key is SORT_BY_FIRST it will use the two students' first members to make the comparison. It will do this by passing those two values to compare_strings_ignore_case(), and "passing up" the returned value directly to the client.

If sort_key is SORT_BY_LAST it will use the two students' lastmembers to make the comparison. It will do this by passing those two values to compare_strings_ignore_case(), and "passing up" the returned value directly to the client.

If sort_key is SORT_BY_POINTS it will use the two students' total_points members to make the comparison. It will do this by subtracting the second student's points from the first student's points and returning that number.

Notice that whatever value the current Student.sort_key has,Student.compare_two_students() returns a value value that's negative if first_stud "comes before" second_stud, positive if first_stud "comes after" second_stud and 0 if they are the same -- interpreted through the current value of sort_key. (It doesn't matter what the the exact value returned besides its being +, - or 0.)

Change to the StudentArrayUtilities Class

Replace print_array() with to_string(). Generate the same kind of string, but instead of sending it to the screen, return it to the client.

Adjust float_largest_to_top() to call compare_two_students()rather than compare_strings_ignore_case(). Make adjustments required by this change.

Add a class method get_median_destructive(cls, array, array_size): - This computes and returns the median of the total scores of all the students in the array The details are simple, but you have to take them each carefully:

Dispose of the case of a one-element array. A one-element array returns its one and only Student's total_points. (This case can actually be skipped if you handle the next cases correctly, but it doesn't hurt to do it separately, here.)

Even-numbered arrays >= 2 elements: find the two middle elements and return their average of their total points.

Odd-numbered arrays >= 3 elements: return the total points of the exact middle element.

Special Note: This method has to do the following. It must sort the array according to total_points in order to get the medians, and that's easy since we already have the sort method. Then it has to find the middle-student's score (e.g., if the array is size 21, the middle element is the score inarray[10], after the sort). But, before doing the sort, it also has to change the sort_key of the Student class to SORT_BY_POINTS. One detail, that you may not have thought of, is that, at the very start of the method, it needs to save the client's sort key. Then, before returning, restore the client's sort key. This method doesn't know what that sort key might be, but there is an accessor get_sort_key() that will answer that question.

This method has the word "Destructive" in its name to remind the client that it may (and usually will) modify the order of the array, since it is going to sort the array by total points in the process of computing the median. However, it will not destroy or modify the client's sort_key when the method returns to client (see previous bullet).

If the user passes in a bad arraySize (< 1) return a 0.

The Main Program

Our client will declare three Student arrays: using direct initialization, as in the modules: no user input. The array sizes should be 15, 16 and 1. The second array can be the same as the first with one extra Student tagged onto the end. Each array should be initialized in no particular order: unsorted in all fields.

Using the largest, even numbered, array:

display the array immediately before calling a sort method,

sort the array using the default (initial) sort key and display,

change the sort key to first name, sort and display,

change the sort key to total score, sort and display,

set_sort_key() to first name, call the get_median_destructive()method and display the median score. and finally

call get_sort_key() to make sure that the get_median_destructive() method preserved the client's sort_keyvalue of first name that was just set prior to the get_median_destructive() call.

Using each of the two other arrays:

get the median of each array and display. No other testing needed in this part.

Here's a sample output, but you must not use my arrays. Make your own as per the spec above.

Explanation / Answer

Solution:

################Array.java###################

public class Array

{

public static void main (String[] args)

{

int k;

Student student;

Student[] myClass = { new Student("Mills","Oby", 95),

new Student("Stark","Tony",123),

new Student("Civi","Sal", 195),

new Student("Tartan","Rain",148),

new Student("Tilous","Marly", 108),

new Student("Billon","Brittney",225),

new Student("Lockland","Jaime", 44),

new Student("Sylvester","Honey",452),

new Student("Black","Sirius", 295),

new Student("Montgomery","Ansley",321),

};

//Adding extra object to make it odd array i.e Oddman

Student[] oddClass = { new Student("Mills","Oby", 95),

new Student("Stark","Tony",123),

new Student("Civi","Sal", 195),

new Student("Tartan","Rain",148),

new Student("Tilous","Marly", 108),

new Student("Billon","Brittney",225),

new Student("Lockland","Jaime", 44),

new Student("Sylvester","Honey",452),

new Student("Black","Sirius", 295),

new Student("Montgomery","Ansley",321),

new Student("Oddman","out",100),

};

//Creating smallClass with one member

Student[] smallClass = { new Student("Mills","Oby", 95) };

//Creating noclass with no members

Student[] noClass = { };

StudentArrayUtilities myStuds = new StudentArrayUtilities();

for (k = 0; k < myClass.length; k++)

myStuds.addStudent( myClass[k] );

System.out.println( myStuds.toString("Before: ", myClass));

System.out.println("Sorting by default ---------------");

StudentArrayUtilities.arraySort(myClass);

System.out.println( myStuds.toString("After: ", myClass));

System.out.println("Sorting by first name ---------------");

Student.setSortKey(Student.SORT_BY_FIRST);

StudentArrayUtilities.arraySort(myClass);

System.out.println( myStuds.toString("After: ", myClass));

System.out.println("Sorting by total points ---------------");

Student.setSortKey(Student.SORT_BY_POINTS);

StudentArrayUtilities.arraySort(myClass);

System.out.println( myStuds.toString("After: ", myClass));

// test median

Student.setSortKey(Student.SORT_BY_LAST);

System.out.println( "Median of evenClass = "

+ myStuds.getMedianDestructive(myClass));

if ( Student.getSortKey() == Student.SORT_BY_LAST )

System.out.println("Successfully preserved sort key.");

else

System.out.println("Problem.");   

// test odd class

System.out.println( "Median of oddClass = "

+ StudentArrayUtilities.getMedianDestructive(oddClass));

// test one-student class

System.out.println( "Median of smallClass = "

+ StudentArrayUtilities.getMedianDestructive(smallClass));

// test no-student class

System.out.println( "Median of noClass = "

+ StudentArrayUtilities.getMedianDestructive(noClass));

}

}

#######################Student.java#################

class Student

{

private String lastName;

private String firstName;

private int totalPoints;

public static final String DEFAULT_NAME = "zz-error";

public static final int DEFAULT_POINTS = 0;

public static final int MAX_POINTS = 1000;

public static final int SORT_BY_FIRST = 88;

public static final int SORT_BY_LAST = 98;

public static final int SORT_BY_POINTS = 108;

private static int sortKey = SORT_BY_LAST;

public Student( String last, String first, int points)

{

if ( !setLastName(last) )

lastName = DEFAULT_NAME;

if ( !setFirstName(first) )

firstName = DEFAULT_NAME;

if ( !setPoints(points) )

totalPoints = DEFAULT_POINTS;

}

public String getLastName() { return lastName; }

public String getFirstName() { return firstName; }

public int getTotalPoints() { return totalPoints; }

public static int getSortKey() { return sortKey; }

public boolean setLastName(String last)

{

if ( !validString(last) )

return false;

lastName = last;

return true;

}

public boolean setFirstName(String first)

{

if ( !validString(first) )

return false;

firstName = first;

return true;

}

public boolean setPoints(int pts)

{

if ( !validPoints(pts) )

return false;

totalPoints = pts;

return true;

}

public static boolean setSortKey(int inputtedKey)

{

if ( !(inputtedKey == SORT_BY_FIRST || inputtedKey == SORT_BY_LAST

|| inputtedKey == SORT_BY_POINTS) )

return false;

sortKey = inputtedKey;

return true;

}

public static int compareTwoStudents( Student firstStud, Student secondStud )

{

int result;

switch (sortKey)

{

case SORT_BY_POINTS:

result = firstStud.totalPoints - secondStud.totalPoints;

break;

case SORT_BY_FIRST:

result = firstStud.firstName.compareToIgnoreCase(secondStud.firstName);

break;

default:

result = firstStud.lastName.compareToIgnoreCase(secondStud.lastName);

break;

}

return result;

}

public String toString()

{

String resultString;

resultString = " "+ lastName

+ ", " + firstName

+ " points: " + totalPoints

+ " ";

return resultString;

}

private static boolean validString( String testStr )

{

if (testStr != null && Character.isLetter(testStr.charAt(0)))

return true;

return false;

}

private static boolean validPoints( int testPoints )

{

if (testPoints >= 0 && testPoints <= MAX_POINTS)

return true;

return false;

}

}

######################StudentArrayUtilities.java#######################

class StudentArrayUtilities

{

public static final int MAX_STUDENTS = 20;

private int numStudents = 0;

private Student[] array = new Student[MAX_STUDENTS];

public static String toString(String title, Student[] data)

{

String output = title + " ";

// build the output string from the individual Students:

for (int k = 0; k < data.length; k++)

output += " " + data[k].toString();

// now put it in a JOptionPane

return output;

}

public boolean addStudent(Student stud)

{

if (stud == null || numStudents >= MAX_STUDENTS)

return false;

array[numStudents] = stud;

numStudents++;

return true;

}

public Student removeStudent()

{

Student lastStudent;

if (numStudents == 0)

return null;

lastStudent = array[numStudents - 1];

numStudents--;

return lastStudent;

}

public static double getMedianDestructive(Student[] array)

{

int saveSortKey, arrLen, justBelow, justAbove;

double retVal;

arrLen = array.length;

retVal = 0.;

if (arrLen == 0)

return 0;

if (arrLen == 1)

return array[0].getTotalPoints();

// preserve the client's sortKey

saveSortKey = Student.getSortKey();

// sort by points to prep for computing median

Student.setSortKey( Student.SORT_BY_POINTS );

arraySort( array );

if ( arrLen % 2 == 0 )

{

justBelow = (arrLen/2 - 1);

justAbove = arrLen/2;

retVal = ( array[justBelow].getTotalPoints()

+ array[justAbove].getTotalPoints() ) / 2.0; //need double

}

else

retVal = array[arrLen/2].getTotalPoints();

// restore the sort key to what it was before the call

Student.setSortKey( saveSortKey );

return retVal;

}

private static boolean floatLargestToTop(Student[] data, int top)

{

boolean changed = false;

Student temp;

// compare with client call to see where the loop stops

for (int k = 0; k < top; k++)

if ( Student.compareTwoStudents(data[k], data[k+1]) > 0 )

{

temp = data[k];

data[k] = data[k+1];

data[k+1] = temp;

changed = true;

}

return changed;

}

public static void arraySort(Student[] array)

{

for (int k = 0; k < array.length; k++)

// compare with method def to see where inner loop stops

if ( !floatLargestToTop(array, array.length - 1 - k) )

return;

}

}

Sample RUn:

Before:
Mills, Oby points: 95
Stark, Tony points: 123
Civi, Sal points: 195
Tartan, Rain points: 148
Tilous, Marly points: 108
Billon, Brittney points: 225
Lockland, Jaime points: 44
Sylvester, Honey points: 452
Black, Sirius points: 295
Montgomery, Ansley points: 321

Sorting by default ---------------
After:
Billon, Brittney points: 225
Black, Sirius points: 295
Civi, Sal points: 195
Lockland, Jaime points: 44
Mills, Oby points: 95
Montgomery, Ansley points: 321
Stark, Tony points: 123
Sylvester, Honey points: 452
Tartan, Rain points: 148
Tilous, Marly points: 108

Sorting by first name ---------------
After:
Montgomery, Ansley points: 321
Billon, Brittney points: 225
Sylvester, Honey points: 452
Lockland, Jaime points: 44
Tilous, Marly points: 108
Mills, Oby points: 95
Tartan, Rain points: 148
Civi, Sal points: 195
Black, Sirius points: 295
Stark, Tony points: 123

Sorting by total points ---------------
After:
Lockland, Jaime points: 44
Mills, Oby points: 95
Tilous, Marly points: 108
Stark, Tony points: 123
Tartan, Rain points: 148
Civi, Sal points: 195
Billon, Brittney points: 225
Black, Sirius points: 295
Montgomery, Ansley points: 321
Sylvester, Honey points: 452

Median of evenClass = 171.5
Successfully preserved sort key.
Median of oddClass = 148.0
Median of smallClass = 95.0
Median of noClass = 0.0

Note: Before giving negative feedback please do discuss the problem in comment section. If yu really liked the solution don't forget to give a big thumbs up.

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote