Histogram from grade array list in Java - java

I'm trying to make a histogram from an arrayList containing student grades. I have already made a grade breakdown as shown here:
/**
* Returns a simple, 5-element array with the counts for each of the letter grades,
* (A, B, C, D, and F), based on the 10-point scale
* #return 5-element array
*/
private int[] calculateGradingBreakdown() {
int[] breakdown;
breakdown = new int[7];
for (Student kids: this.students) {
int grade = kids.getNumericGrade();
if (grade >= 90) {
breakdown[0] += 1;
} else if (grade >= 80) {
breakdown[1] += 1;
} else if (grade >= 70) {
breakdown[2] += 1;
} else if (grade >= 60) {
breakdown[3] += 1;
} else {
breakdown[4] += 1;
}
}
return breakdown;
}
/**
* Returns a string that lists the grade letter and the count of students
* receiving the grade on the roster
* #return grade breakdown
*/
public String getGradeBreakdown() {
String gradeBreakdown = null;
int[] breakdown = this.calculateGradingBreakdown();
gradeBreakdown = ("A: " + breakdown[0] + "\nB: " + breakdown[1] + "\nC: " + breakdown[2]
+ "\nD: " + breakdown[3] + "\nF: " + breakdown[4]);
return gradeBreakdown;
}
The code I have for the histogram has changed a few times, but needs to include the methods listed below. I have left my current code in, but am struggling as to how to get the histogram to work as listed.
/**
* Accepts a number of stars (*) to be created, creates a String with that
* number of *'s side-by-side, and then returns that string.
*/
private String makeStarRow(int number) {
int[] breakdown = this.calculateGradingBreakdown();
number = breakdown[];
String stars =
}
/**
* Returns a string holding a horizontal histogram of *'s
*/
public String getGradeHistogram() {
String gradeHistogram = null;
int[] breakdown = this.calculateGradingBreakdown();
gradeHistogram = (this.makeStarRow(breakdown[0]));
gradeHistogram += (this.makeStarRow(breakdown[1]));
gradeHistogram += (this.makeStarRow(breakdown[2]));
gradeHistogram += (this.makeStarRow(breakdown[3]));
gradeHistogram += (this.makeStarRow(breakdown[4]));
return gradeHistogram;
}
The output should look like this to end for the grade breakdown and histogram (with the numbers being according to the input in another class):
A: 2
B: 2
C: 2
D: 0
F: 1
**
**
**
*

For your interest and reference, here's a solution using Java 8 streams:
void printHistogram(List<Integer> scores) {
scores.stream().collect(Collectors.groupingBy(n -> n < 60 ? 5 : n / 10));
.entrySet().stream().sorted(Map.Entry::comparingByKey)
.map(entry -> entry.getValue().size());
.map(size -> Stream.iterate(() -> "*").limit(size).collect(Collectors.joining()))
.forEach(System.out::println);
}

One of the ways to create the string of repeating symbols is to use Arrays.fill:
private String makeStarRow(int number) {
char[] starChars = new char[number];
Arrays.fill(starChars, '*');
String stars = new String(starChars) + '\n';
return stars;
}
Note that according to the getGradeHistogram method it's likely that you need a '\n' appended to the end of the stars String.

Thanks for the help guys. I actually got a working solution:
/**
* Accepts a number of stars (*) to be created, creates a String with that
* number of *'s side-by-side, and then returns that string.
*/
private String makeStarRow(int number) {
while (number > 0) {
System.out.print("*");
number--;
}
if (number < 1) {
System.out.println();
}
return null;
}
/**
* Returns a string holding a horizontal histogram of *'s
* #return histogram
*/
public String getGradeHistogram() {
int[] histogram = this.calculateGradingBreakdown();
for (int xi = 0; xi < this.students.size(); xi++) {
int meh = histogram[xi];
this.makeStarRow(meh);
}
return "";
}
It prints out what I was looking for. Hopefully this helps someone in the future.
A: 2
B: 2
C: 2
D: 0
F: 1
**
**
**
*

Related

how to find number of pages and number of lines on the current page respect to speed after a specified interval of time?

A student has created a software which will read from one book and write into another book . Both books may have different dimensions.
Software first reads from the book fully then process the format to write into another book.
Yours task is to identify after a specified interval of time , if software is reading or writing. for each of these activities how much read and write activity has happened needs to be captured in terms of page and number of lines on the current page.
Input
pn1 -> number of pages in first book
ln1 -> number of lines per page in first book
pn2 -> number of pages in second book
ln2 -> number of lines per pages in second book
rs -> reading speed in lines/seconds
ws -> writing speed in lines/seconds
t -> time in seconds at which the result is to be processed
Output
print current activity (READ or WRITE),page number and line number
Example
Input
100
10
500
6
8
4
145
Output
WRITE 13 2
Code :
import java.util.*;
public class MyClass {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
int pn1 = sc.nextInt();
int ln1 = sc.nextInt();
int pn2 = sc.nextInt();
int ln2 = sc.nextInt();
int rs = sc.nextInt();
int ws = sc.nextInt();
int t = sc.nextInt();
int i,j,s1,s2,s3=0;
s1 = pn1 * ln1;
s2 = s1/rs;
if(s2<t)
{
System.out.print("WRITE ");
for(i=1;i<=pn2;i++)
{
for(j=1;j<=ln2;j=j+ws)
{
if(s2==t)
{
break;
}
s2++;
}
if(j<=ln2)
{
System.out.print(i+ " " +j);
break;
}
}
}
else
{
System.out.print("READ ");
for(i=1;i<=pn1;i++)
{
for(j=1;j<=ln1;j=j+rs)
{
if(s3==t)
{
break;
}
s3++;
}
if(j<=ln1)
{
System.out.print(i+ " " +j);
break;
}
}
}
}
}
My output : WRITE 11 1
Can anyone please help where I m going wrong , Because in my if else statement j value is not incrementing it will always print 1 as it will be initialized as 1 in for loop .
Thank you in advanced .
The calculations in the nested loops are incorrect because they do not take into account the case when the page is not processed completely within a second.
For the input data, the writing process is as follows:
sec 1: total lines 4: page 1, line 4
sec 2: total lines 8: page 2, line 2
sec 3: total lines 12: page 2, line 6
etc.
Thus, it's better to have a single loop by the time parameter and modify the page/line information using modulo operation:
if(s2<t) {
for (int tt = s2 + 1; tt <= t; tt++) {
j += ws;
if (j >= ln2) {
i++;
j = j % ln2;
}
}
if (j == 0) { // correct page number if it's been completely written within a second
i--;
j = ln2;
}
System.out.print("WRITE " + i + " " + j);
} else { // fix reading in similar way
for (int tt = 0; tt < t; tt++) {
j += rs;
if (j >= ln1) {
i++;
j = j % ln1;
}
}
if (j == 0) { // correct page number if it's been completely read within a second
i--;
j = ln1;
}
System.out.print("READ " + i + " " + j);
}
This task could also be resolved without loops using modulo arithmetics and a separate function to define current page and line:
// reusing all the variables defined in main
int totalReadLines = pn1 * ln1;
int timeToRead = (int) Math.ceil(totalReadLines / rs);
if (t <= timeToRead) {
printState("READ", totalReadLines, rs, t, ln1);
} else {
t -= timeToRead;
int totalWriteLines = pn2 * ln2;
int timeToWrite = (int) Math.ceil(totalWriteLines / ws);
if (t <= timeToWrite) {
printState("WRITE", totalWriteLines, ws, t, ln2);
} else {
System.out.println("DONE");
}
}
private static void printState(String state, int totalLines, int speed, int time, int linesPerPage) {
int linesProcessed = time * speed;
int pagesProcessed = linesProcessed / linesPerPage;
int remLines = linesProcessed % linesPerPage;
int currentPage;
int currentLine;
if (remLines == 0) {
currentPage = pagesProcessed;
currentLine = linesPerPage;
} else {
currentPage = pagesProcessed + 1;
currentLine = remLines;
}
System.out.printf("%s %d %d%n", state, currentPage, currentLine);
}

How would format this in a single while loop so that it would print as four columns?

I need to make this into four separate columns
public class Lab7aCelsiustoFahrenheit
{
public static void main(String[] args)
{
//variables
double orig = -40.0;
double cels = orig;
double fahr = cels;
final int MAX_TEMP = -1;
//loop that prints asingle column on celsius to F conversions
while(cels <= MAX_TEMP)
{
System.out.println(cels + "C " + "is " + fahr + "F" + "\t");
cels++;
fahr = (((9.0 * cels) + 160) / 5);
}
}
}
You can make a linebreak after 4 entries, in counting how many items u wrote and then start in the next line.
Also to have each "cell" below the other you should use System.out.printf for writing the entry to format the double-values
If you really want to do this in a single while-loop, a possibilty would be:
int column = 1;
while(cels <= MAX_TEMP) {
fahr = (((9.0 * cels) + 160) / 5);
System.out.printf("%8.2fC is %8.2fF" + "\t", cels, fahr);
cels++;
column++;
if(column > 4) {
column = 1;
System.out.println();
}
}
I think you should also do the calculation before System.out.printf(...)

Java - Hangman Game - trouble with charAt on StringBuffer variable

So I am trying to make a hang man game using a website that returns random word. I'm using that random word for the hangman game.
What I am stuck on is validating a guess the user makes. Here is the code, I am just putting everything in main first then making separate methods to do the work for me after this works.
public static void main(String[] args) throws Exception {
randomWord = TestingStuff.sendGet();
int totalTries = 1;
char[] guesses = new char[26];
int length = randomWord.length();
Scanner console = new Scanner(System.in);
System.out.print("* * * * * * * * * * * * * * *"
+ "\n* Welcome to Hangman! *"
+ "\n* * * * * * * * * * * * * * *");
System.out.println("\nYou get 10 tries to guess the word by entering in letters!\n");
System.out.println(randomWord);
/*
Cycles through the array based on tries to find letter
*/
while (totalTries <= 10) {
System.out.print("Try #" + totalTries);
System.out.print("\nWhat is your guess? ");
String guess = console.next();
char finalGuess = guess.charAt(0);
guesses[totalTries - 1] = finalGuess; //Puts finalGuess into the array
for (int i = 0; i < totalTries; i++) { //checks to see if the letter is already guessed
if (finalGuess != guesses[i]) {
for (int j = 0; i < length; j++) { //scans each letter of random word
if (finalGuess.equals(randomWord.charAt(j))) {
}
}
} else {
System.out.println("Letter already guessed, try again! ");
}
}
}
}
What I am stuck on is inside of the while loop where it says:
for (int i = 0; i < totalTries; i++) { //checks to see if the letter is already guessed
if (finalGuess != guesses[i]) {
for (int j = 0; i < length; j++) { //scans each letter of random word
if (finalGuess.equals(randomWord.charAt(j))) {
}
}
} else {
System.out.println("Letter already guessed, try again! ");
}
}
It is giving me an error saying "char cannot be dereferenced". Am I missing something here?
finalGuess is a primitive char - you can't use methods, such as equals on it. You could just compare the two chars using the == operator:
if (finalGuess == randomWord.charAt(j)) {

Printing Diamond Pattern in Correct Format in Java using Recursion

My program reads in values from a file and uses a recursive method to print patterns of asterisks based on those values. I'm just having a problem getting everything to line up properly.
The output is supposed to look like this:
*
* *
* * *
* *
*
Regarding the format of the output, the directions are:
"Note that the pattern is aligned symmetrically (vertically) about the center line. The pattern should be aligned symmetrically on each line (horizontally) as well- hint: use the line value to help space."
But my output looks like this:
*
* *
* * *
* *
*
The code I'm using to get this pattern:
public static void makePattern(int thisRow, int num) {
if(thisRow >= num) {
for(int i = 0; i < num; i++) {
System.out.print(" " + "*" + " ");
}
System.out.println();
}
else {
for(int i = 0; i < thisRow; i++) {
System.out.print(" " + "*" + " ");
}
System.out.println();
makePattern(thisRow + 1, num);
for(int i = 0; i < thisRow; i++) {
System.out.print(" " + "*" + " ");
}
System.out.println();
}
}
Also my main method:
import java.util.Scanner;
import java.io.*;
public class Program3 {
public static void main(String[] args) throws Exception {
int num = 0;
int thisRow = 1;
java.io.File file = new java.io.File("../instr/prog3.dat");
Scanner fin = new Scanner(file);
while(fin.hasNext()) {
num = fin.nextInt();
if(num >=0 && num <= 25)
makePattern(thisRow, num);
System.out.println();
}
fin.close();
}
Any suggestions on how to edit my code to make my output appear like the example pattern I included?
Let's analyse the output first!!
First step is to analyse the output
Conclusions:
The total number of characters on every line is always n (=3)
Number of Spaces has the following pattern:
1st line 3 - 1 spaces
2nd line 3 - 2 spaces
3rd line 3 - 3 spaces
4th line 4 - 3 spaces
5th line 5 - 3 spaces
So
if(num < thisRow) {
numberOfSpaces = thisRow - num;
} else {
numberOfSpaces = num - thisRow;
}
Number of Stars is always [n - the number of spaces]
So
int numberOfStars = num - numberOfSpaces;
And the recursion should end on the 6th line, i.e. when current line number is n*2
So the return condition in your recursive method should be
if(thisRow == num * 2)
return;
Final Code : Putting the peices together
When we put the peices together, we get:
public static void makePattern(int thisRow, int num) {
//the termination condition
if(thisRow == num * 2)
return;
//the number of spaces
int numberOfSpaces = 0;
if(num < thisRow) {
numberOfSpaces = thisRow - num;
} else {
numberOfSpaces = num - thisRow;
}
//the number of stars
int numberOfStars = num - numberOfSpaces;
//compose the string before printing it
StringBuffer outputBuffer = new StringBuffer(num);
for (int i = 0; i < numberOfSpaces; i++){
outputBuffer.append(" ");
}
for (int i = 0; i < numberOfStars; i++){
outputBuffer.append("* ");
}
//print the string
System.out.println(outputBuffer.toString());
//recursion
makePattern(thisRow + 1, num);
}
This is code for printing diamond shaped pattern using recursion technique.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class patternRecursion {
static int n,k;
public static void main(String[] args) throws IOException{
try(Scanner s = new Scanner(System.in)){
n=Integer.parseInt(reader.readLine());
k=n-1;
printPattern(n);
}
}
public static void printChar(int m,char c){
if(m==0) return;
try{
printChar(m-1,c);
System.out.print(c);
}catch(StackOverflowError s){return;}
}
public static void printPattern(int m){
if(m==0){
return ;
}else{
printChar(m-1,' ');
printChar(n-m,'#');
printChar(n-m+1,'#');
System.out.println();
printPattern(m-1);
printChar(m,' ');
printChar(k-m,'#');
printChar(k-m+1,'#');
System.out.println();
}
}
}

Java: Invoking Methods From Class / null logic error

I'm having a hard time wrapping my head around object based programming. Im attempting to invoke a method from a class. However, all I invoke is a variable that has been declared, while I'm trying to pull the variable later. (Im sure my terminology is off - feel free to correct)
Im getting logic errors. Instead of a value, im getting "null".
The Class:
public class NumberOperations {
int number;
String oddsUnder;
String powersTwoUnder;
int isGreater;
String toString;
public NumberOperations(int numberIn) {
number = numberIn;
}
public int getValue() {
return number;
}
public String oddsUnder() {
String output = "";
int i = 0;
while (i < number) {
if (i % 2 != 0) {
output += i + "\t";
}
i++;
}
return output;
}
public String powersTwoUnder() {
String output2 = "";
int powers = 1;
while (powers < number) {
output2 += powers + "\t";
powers = powers * 2;
}
return output2;
}
public int isGreater(int compareNumber) {
if (number > compareNumber) {
return 1;
}
else if (number < compareNumber) {
return -1;
}
else {
return 0;
}
}
public String toString() {
return number + "";
}
}
The Program:
import java.util.Scanner; import java.util.ArrayList;
/** * Demonstrates the NumberOperations class. */ public class NumberOpsDriver {
/**
* Reads a set of positive numbers from the user until the user enters 0. * Prints odds under and powers of 2 under for each number. *
* #param args - Standard commandline arguments
*/ public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// declare and instantiate ArrayList with generic type <NumberOperations>
ArrayList<NumberOperations> numOpsList = new ArrayList<NumberOperations>();
// prompt user for set of numbers
System.out.println("Enter a list of positive integers separated "
+ "with a space followed by 0:");
// get first user input using in.nextInt()
int firstInput = in.nextInt();
// add a while loop as described below:
while (firstInput != 0) {
numOpsList.add(new NumberOperations(firstInput));
firstInput = in.nextInt();
}
// while the input is not "0"
// add NumberOperations object to array based on user input
// get the next user input using in.nextInt()
int index = 0;
while (index < numOpsList.size()) {
NumberOperations num = numOpsList.get(index);
System.out.println("For: " + num);
System.out.println("Odds under: " + num.oddsUnder);
System.out.println("Powers of 2 under: " + num.powersTwoUnder);
// add print statement for odds under num
// add print statement for powers of 2 under num
index++;
} } }
You never assign to your member variables oddsUnder and powersTwoUnder. So of course they are null when you read them, and when you try to print them you have a NullPointerException it prints "null".
You probably actually want to call the methods of the same name instead of taking the variables
System.out.println("Odds under: " + num.oddsUnder());
System.out.println("Powers of 2 under: " + num.powersTwoUnder());
Make your properties as private to avoid this kind of situations and change your properties in System.out... to call the methods not the object fields. For example
System.out.println("Odds under: " + num.oddsUnder()); //<-changed

Categories

Resources