IEP/K2 Septembar 2021

Izvor: SI Wiki
< ИЕП
Datum izmene: 20. april 2024. u 19:13; autor: Ilija (razgovor | doprinosi) (→‎Ocene2.java)
(razl) ← Starija izmena | Trenutna verzija (razl) | Novija izmena → (razl)
Pređi na navigaciju Pređi na pretragu

Drugi kolokvijum u septembarskom roku 2021. godine održan je 17. septembra.

Postavka

Posmatra se evidencija o položenim ispitima. U jednom redu se nalaze identifikator studenta i lista ispitima[sic] koje je položio dati student. Svaki rad[sic] sadrži informacije o položenom ispitu kao što su šifra predmeta, šifra roka, i ocena koju je student dobio. Za potrebe navedene evidencije podaci se čuvaju u tekstualnoj datoteci na Hadoop sistemu. Podaci su dati u obliku:

<Student><TAB>{<Exam>{;<Exam>}}

Gde polje <Student> predstavlja identifikator studenta, a polje <Exam> sadrži šifru predmeta, nakon koga dolazi znak ,, pa šifra roka, nakon koga dolazi znak , i na kraju ocena.

  1. U programskom jeziku Java sastaviti Map/Reduce posao koji vraća statističke podatke o ispitima u ispitnim rokovima: šifru predmeta, šifru roka, broj studenata koji su polagali dati ispit, broj studenata koji su dobili ocenu 6, broj studenata koji su dobili ocenu 7, broj studenata koji su dobili ocenu 8, broj studenata koji su dobili ocenu 9, broj studenata koji su dobili ocenu 10. Voditi računa o konkurentnosti.
  2. U programskom jeziku Java sastaviti lanac od dva Map/Reduce posla koji vraća spisak predmeta sa najvišim prosekom (MAX) (prosek nije po roku nego od svih koji su ga ikada polagali), pri čemu je svaki od predmeta položilo barem studenata (, parametar koji se prosleđuje računarima koji rade obradu). Voditi računa o konkurentnosti.

Odgovor[sic] se predaju u vidu dva[sic] java datoteka (Ocene1.java i Ocene2.java).

Ocene1.java

package k2_sept_2021;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaSparkContext;

import scala.Tuple2;

import java.io.Serializable;

import org.apache.log4j.LogManager;
import org.apache.log4j.Level;

import java.util.List;
import java.util.LinkedList;

public class Ocene1 {

	static class Exam implements Serializable {
		String subject;
		String examTerm;
		int grade;

		public Exam(String examString) {
			String[] data = examString.split(",");
			this.subject = data[0];
			this.examTerm = data[1];
			this.grade = Integer.parseInt(data[2]);
		}

		public String getSubject() {
			return subject;
		}

		public void setSubject(String subject) {
			this.subject = subject;
		}

		public String getExamTerm() {
			return examTerm;
		}

		public void setExamTerm(String examTerm) {
			this.examTerm = examTerm;
		}

		public int getGrade() {
			return grade;
		}

		public void setGrade(int grade) {
			this.grade = grade;
		}

		@Override
		public String toString() {
			return "Exam [subject=" + subject + ", examTerm=" + examTerm + ", grade=" + grade + "]";
		}

	}

	static class Student implements Serializable {
		private String name;
		private List<Exam> exams = new LinkedList<>();

		public Student(String line) {
			String[] data = line.split("\t");
			this.name = data[0];
			if (data.length <= 1)
				return;

			for (String examString : data[1].split(";")) {
				exams.add(new Exam(examString));
			}
		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}

		public List<Exam> getExams() {
			return exams;
		}

		public void setExams(List<Exam> exams) {
			this.exams = exams;
		}

	}

	public static void main(String[] args) {
		SparkConf conf = new SparkConf().setAppName("ocene1").setMaster("local");
		LogManager.getRootLogger().setLevel(Level.WARN); // iskljuci nepotrebne poruke
		try (JavaSparkContext sc = new JavaSparkContext(conf)) {
			zadatak(sc, "resources/students_test.tsv");
		}
	}

	public static void zadatak(JavaSparkContext sc, String filename) {
		var result = sc.textFile(filename).map(Student::new).flatMapToPair(student -> {
			System.out.println(student);
			List<Tuple2<String, int[]>> gradeInfo = new LinkedList<Tuple2<String, int[]>>();
			for (Exam exam : student.getExams()) {
				int[] gradeArray = new int[6]; // {0,0,0,0,0,0} - Broj polaganja, broj 6, broj 7, broj 8 , broj 9, broj 10
				String examName = exam.getSubject() + " - " + exam.getExamTerm();
				if (exam.getGrade() <= 5)
					continue;
				gradeArray[0] = 1;
				gradeArray[exam.getGrade() - 5]++;
				gradeInfo.add(new Tuple2<>(examName, gradeArray));
			}
			return gradeInfo.iterator();
		}).reduceByKey((gradeInfo1, gradeInfo2) -> {
			int[] resultGrades = new int[6];
			for (int i = 0; i < gradeInfo1.length; i++) {
				resultGrades[i] = gradeInfo1[i] + gradeInfo2[i];
			}
			return resultGrades;
		}).collectAsMap();

		for (String examName : result.keySet()) {
			int[] gi = result.get(examName);
			System.out.println("Ispit: " + examName + " Br polaganja: "+ gi[0] + " Br 6:" + gi[1] + " Br 7:" + gi[2] + " Br 8:" + gi[3] + " Br 9:"
					+ gi[4] + " Br 10:" + gi[5]);

		}
	}
}

Ocene2.java

package k2_sept_2021;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaSparkContext;

import k2_sept_2021.Ocene1.Exam;
import scala.Tuple2;

import java.io.Serializable;

import org.apache.log4j.LogManager;
import org.apache.log4j.Level;

import java.util.List;
import java.util.LinkedList;

public class Ocene2 {

	static class Exam implements Serializable {
		String subject;
		String examTerm;
		int grade;

		public Exam(String examString) {
			String[] data = examString.split(",");
			this.subject = data[0];
			this.examTerm = data[1];
			this.grade = Integer.parseInt(data[2]);
		}

		public String getSubject() {
			return subject;
		}

		public void setSubject(String subject) {
			this.subject = subject;
		}

		public String getExamTerm() {
			return examTerm;
		}

		public void setExamTerm(String examTerm) {
			this.examTerm = examTerm;
		}

		public int getGrade() {
			return grade;
		}

		public void setGrade(int grade) {
			this.grade = grade;
		}

		@Override
		public String toString() {
			return "Exam [subject=" + subject + ", examTerm=" + examTerm + ", grade=" + grade + "]";
		}

	}

	static class Student implements Serializable {
		private String name;
		private List<Exam> exams = new LinkedList<>();

		public Student(String line) {
			String[] data = line.split("\t");
			this.name = data[0];
			if (data.length <= 1)
				return;

			for (String examString : data[1].split(";")) {
				exams.add(new Exam(examString));
			}
		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}

		public List<Exam> getExams() {
			return exams;
		}

		public void setExams(List<Exam> exams) {
			this.exams = exams;
		}

	}

	public static void main(String[] args) {
		SparkConf conf = new SparkConf().setAppName("ocene1").setMaster("local");
		LogManager.getRootLogger().setLevel(Level.WARN); // iskljuci nepotrebne poruke
		try (JavaSparkContext sc = new JavaSparkContext(conf)) {
			zadatak(sc, "resources/Students_V0.txt", 2);
		}
	}

	public static void zadatak(JavaSparkContext sc, String filename, int N) {
		
		var results = 
				sc.textFile(filename)
				.map(Student::new)
				.flatMapToPair(student->{
					List<Tuple2<String, int[]>> gradeInfo = new LinkedList<Tuple2<String, int[]>>();
					for (Exam exam : student.getExams()) {
						int[] info = new int[2]; // count, grade sum
						info[0] = 1;
						info[1] = exam.getGrade();
						
						gradeInfo.add(new Tuple2<>(exam.getSubject(), info));
						
					}
					return gradeInfo.iterator();
				})
				.reduceByKey((info1, info2)->{
					int[] resultInfo = new int[2];
					resultInfo[0] = info1[0] + info2[0];
					resultInfo[1] = info1[1]+ info2[1];
					return resultInfo;
				})
				.filter(subjectPair->subjectPair._2()[0] >= N)
				.map(subjectPair->{
					double averageGrade = subjectPair._2()[1] *1.0 / subjectPair._2()[0];
					return new Tuple2<>(subjectPair._1(), averageGrade);
				})
				.sortBy(avgGradePair->avgGradePair._2(), false, N)
				.collect();
		
		double maxAvg = results.get(0)._2();
		double tolerance = 10e-6;
		for (Tuple2<String, Double> result:results) {
			double avg = result._2();
			if (maxAvg <= avg+tolerance) {
				System.out.println("Predmet: "+result._1() +", prosek: "+avg);
			}
		}
		
		
	}
}

Provera

Sledeći sadržaj datoteke koja se prosleđuje kao prvi argument oba programa može se koristiti za testiranje:

Pera Peric	predmet1,rok1,6;predmet2,rok1,10;predmet1,rok2,9
Marko Markovic	predmet1,rok1,8;predmet2,rok1,6;predmet3,rok3,9

Na kolokvijumu su bile dostupne Students_V0.txt i Students_V1.txt datoteke za testiranje rešenja.