ИЕП/К2 Септембар 2021 — разлика између измена

Извор: SI Wiki
Пређи на навигацију Пређи на претрагу
м (Sada zapravo radi)
м (Ispravke nakon današnjeg K2)
Ред 17: Ред 17:


import java.io.File;
import java.io.File;
import java.io.IOException;


import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FileUtils;
Ред 34: Ред 33:
public static class Map extends Mapper<LongWritable, Text, Text, Text> {
public static class Map extends Mapper<LongWritable, Text, Text, Text> {
@Override
@Override
public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
public void map(LongWritable key, Text value, Context context) {
for (String exam : value.toString().split("\t")[1].split(";")) {
try {
String[] examSplit = exam.split(",");
String[] split = value.toString().split("\t");
String examCode = examSplit[0];
if (split.length <= 1) {
String examName = examSplit[1];
// Студент нема ниједан испит.
int grade = Integer.parseInt(examSplit[2]);
return;
int[] gradeSplit = new int[5];
}
gradeSplit[grade - 6] = 1;
for (String exam : split[1].split(";")) {
StringBuilder sb = new StringBuilder();
String[] examSplit = exam.split(",");
sb.append(1);
String examCode = examSplit[0];
for (int i = 0; i < 5; ++i) {
String examName = examSplit[1];
sb.append("\t");
int grade = Integer.parseInt(examSplit[2]);
sb.append(gradeSplit[i]);
int[] gradeSplit = new int[5];
gradeSplit[grade - 6] = 1;
StringBuilder sb = new StringBuilder();
sb.append(1);
for (int i = 0; i < 5; ++i) {
sb.append("\t");
sb.append(gradeSplit[i]);
}
context.write(new Text(examCode + "\t" + examName), new Text(sb.toString()));
}
}
context.write(new Text(examCode + "\t" + examName), new Text(sb.toString()));
} catch (Exception e) {
// Хватају се све грешке јер Hadoop понекад може да их не испише.
e.printStackTrace();
}
}
}
}
Ред 55: Ред 64:
public static class Reduce extends Reducer<Text, Text, Text, Text> {
public static class Reduce extends Reducer<Text, Text, Text, Text> {
@Override
@Override
public void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
public void reduce(Text key, Iterable<Text> values, Context context) {
int studentCount = 0;
try {
int[] grades = new int[5];
int studentCount = 0;
for (Text value : values) {
int[] grades = new int[5];
String[] valueSplit = value.toString().split("\t");
for (Text value : values) {
studentCount += Integer.parseInt(valueSplit[0]);
String[] valueSplit = value.toString().split("\t");
studentCount += Integer.parseInt(valueSplit[0]);
for (int i = 0; i < 5; ++i) {
grades[i] += Integer.parseInt(valueSplit[i + 1]);
}
}
StringBuilder sb = new StringBuilder();
sb.append(studentCount);
for (int i = 0; i < 5; ++i) {
for (int i = 0; i < 5; ++i) {
grades[i] += Integer.parseInt(valueSplit[i + 1]);
sb.append("\t");
sb.append(grades[i]);
}
}
context.write(key, new Text(sb.toString()));
} catch (Exception e) {
// Хватају се све грешке јер Hadoop понекад може да их не испише.
e.printStackTrace();
}
}
StringBuilder sb = new StringBuilder();
sb.append(studentCount);
for (int i = 0; i < 5; ++i) {
sb.append("\t");
sb.append(grades[i]);
}
context.write(key, new Text(sb.toString()));
}
}
}
}
Ред 77: Ред 91:
public static void main(String[] args) throws Exception {
public static void main(String[] args) throws Exception {
FileUtils.deleteDirectory(new File(args[1]));
FileUtils.deleteDirectory(new File(args[1]));
Job job = Job.getInstance();
Job job = Job.getInstance();
job.setJarByClass(Ocene1.class);
job.setJarByClass(Ocene1.class);
Ред 104: Ред 119:


import java.io.File;
import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import java.util.LinkedList;
import java.util.List;
import java.util.List;
Ред 126: Ред 140:
public static class Map1 extends Mapper<LongWritable, Text, Text, Text> {
public static class Map1 extends Mapper<LongWritable, Text, Text, Text> {
@Override
@Override
public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
public void map(LongWritable key, Text value, Context context) {
for (String exam : value.toString().split("\t")[1].split(";")) {
try {
String[] examSplit = exam.split(",");
String[] split = value.toString().split("\t");
context.write(new Text(examSplit[0]), new Text(examSplit[2] + "\t1"));
if (split.length <= 1) {
// Студент нема ниједан испит.
return;
}
for (String exam : split[1].split(";")) {
String[] examSplit = exam.split(",");
context.write(new Text(examSplit[0]), new Text(examSplit[2] + "\t1"));
}
} catch (Exception e) {
// Хватају се све грешке јер Hadoop понекад може да их не испише.
e.printStackTrace();
}
}
}
}
Ред 136: Ред 160:
public static class Reduce1 extends Reducer<Text, Text, Text, Text> {
public static class Reduce1 extends Reducer<Text, Text, Text, Text> {
@Override
@Override
public void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
public void reduce(Text key, Iterable<Text> values, Context context) {
int sum = 0;
try {
int count = 0;
int sum = 0;
for (Text value : values) {
int count = 0;
String[] valueSplit = value.toString().split("\t");
for (Text value : values) {
sum += Integer.parseInt(valueSplit[0]);
String[] valueSplit = value.toString().split("\t");
count += Integer.parseInt(valueSplit[1]);
sum += Integer.parseInt(valueSplit[0]);
count += Integer.parseInt(valueSplit[1]);
}
context.write(key, new Text(sum + "\t" + count));
} catch (Exception e) {
// Хватају се све грешке јер Hadoop понекад може да их не испише.
e.printStackTrace();
}
}
context.write(key, new Text(sum + "\t" + count));
}
}
}
}
Ред 170: Ред 199:
public static class Map2 extends Mapper<LongWritable, Text, Text, Text> {
public static class Map2 extends Mapper<LongWritable, Text, Text, Text> {
private static Text text = new Text("ocene2-text");
private static final Text text = new Text("ocene2-text");
private int N;
 
@Override
@Override
public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
public void setup(Context context) {
String[] splitValue = value.toString().split("\t");
N = context.getConfiguration().getInt("N", DEFAULT_N);
int N = context.getConfiguration().getInt("N", DEFAULT_N);
}
double sum = Double.parseDouble(splitValue[1]);
 
double count = Double.parseDouble(splitValue[2]);
@Override
if (count >= N) {
public void map(LongWritable key, Text value, Context context) {
context.write(text, new Text(splitValue[0] + "\t" + (sum / count)));
try {
String[] splitValue = value.toString().split("\t");
double sum = Double.parseDouble(splitValue[1]);
double count = Double.parseDouble(splitValue[2]);
if (count >= N) {
context.write(text, new Text(splitValue[0] + "\t" + (sum / count)));
}
} catch (Exception e) {
// Хватају се све грешке јер Hadoop понекад може да их не испише.
e.printStackTrace();
}
}
}
}
Ред 185: Ред 225:
public static class Reduce2 extends Reducer<Text, Text, Text, Text> {
public static class Reduce2 extends Reducer<Text, Text, Text, Text> {
@Override
@Override
public void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
public void reduce(Text key, Iterable<Text> values, Context context) {
double maxAvg = 0;
try {
List<String> list = new LinkedList<>();
double maxAvg = 0;
for (Text value : values) {
List<String> list = new LinkedList<>();
String[] valueSplit = value.toString().split("\t");
for (Text value : values) {
double avg = Double.parseDouble(valueSplit[1]);
String[] valueSplit = value.toString().split("\t");
if (avg > maxAvg) {
double avg = Double.parseDouble(valueSplit[1]);
list.clear();
if (avg > maxAvg) {
maxAvg = avg;
list.clear();
maxAvg = avg;
}
if (avg == maxAvg) {
list.add(value.toString());
}
}
}
if (avg == maxAvg) {
for (String value : list) {
list.add(value.toString());
context.write(key, new Text(value));
}
}
}
} catch (Exception e) {
for (String value : list) {
// Хватају се све грешке јер Hadoop понекад може да их не испише.
context.write(key, new Text(value));
e.printStackTrace();
}
}
}
}
Ред 220: Ред 265:
job.setMapperClass(Map2.class);
job.setMapperClass(Map2.class);
job.setReducerClass(Reduce2.class);
job.setReducerClass(Reduce2.class);
job.setCombinerClass(Reduce2.class);


FileInputFormat.setInputPaths(job, new Path("ocene2-temp"));
FileInputFormat.setInputPaths(job, new Path("ocene2-temp"));

Верзија на датум 5. мај 2022. у 21:45

Други колоквијум у септембарском року 2021. године одржан је 17. септембра.

Поставка

Посматра се евиденција о положеним испитима. У једном реду се налазе идентификатор студента и листа испитима[sic] које је положио дати студент. Сваки рад[sic] садржи информације о положеном испиту као што су шифра предмета, шифра рока, и оцена коју је студент добио. За потребе наведене евиденције подаци се чувају у текстуалној датотеци на Hadoop систему. Подаци су дати у облику:

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

Где поље <Student> представља идентификатор студента, а поље <Exam> садржи шифру предмета, након кога долази знак ,, па шифра рока, након кога долази знак , и на крају оцена.

  1. У програмском језику Јава саставити Map/Reduce посао који враћа статистичке податке о испитима у испитним роковима: шифру предмета, шифру рока, број студената који су полагали дати испит, број студената који су добили оцену 6, број студената који су добили оцену 7, број студената који су добили оцену 8, број студената који су добили оцену 9, број студената који су добили оцену 10. Водити рачуна о конкурентности.
  2. У програмском језику Јава саставити ланац од два Map/Reduce посла који враћа списак предмета са највишим просеком (MAX) (просек није по року него од свих који су га икада полагали), при чему је сваки од предмета положило барем студената (, параметар који се прослеђује рачунарима који раде обраду). Водити рачуна о конкурентности.

Одговор[sic] се предају у виду два[sic] јава датотека (Ocene1.java и Ocene2.java).

Ocene1.java

package rs.etf.iep.mapreduce;

import java.io.File;

import org.apache.commons.io.FileUtils;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;

public class Ocene1 {
	public static class Map extends Mapper<LongWritable, Text, Text, Text> {
		@Override
		public void map(LongWritable key, Text value, Context context) {
			try {
				String[] split = value.toString().split("\t");
				if (split.length <= 1) {
					// Студент нема ниједан испит.
					return;
				}
				for (String exam : split[1].split(";")) {
					String[] examSplit = exam.split(",");
					String examCode = examSplit[0];
					String examName = examSplit[1];
					int grade = Integer.parseInt(examSplit[2]);
					int[] gradeSplit = new int[5];
					gradeSplit[grade - 6] = 1;
					StringBuilder sb = new StringBuilder();
					sb.append(1);
					for (int i = 0; i < 5; ++i) {
						sb.append("\t");
						sb.append(gradeSplit[i]);
					}
					context.write(new Text(examCode + "\t" + examName), new Text(sb.toString()));
				}
			} catch (Exception e) {
				// Хватају се све грешке јер Hadoop понекад може да их не испише.
				e.printStackTrace();
			}
		}
	}

	public static class Reduce extends Reducer<Text, Text, Text, Text> {
		@Override
		public void reduce(Text key, Iterable<Text> values, Context context) {
			try {
				int studentCount = 0;
				int[] grades = new int[5];
				for (Text value : values) {
					String[] valueSplit = value.toString().split("\t");
					studentCount += Integer.parseInt(valueSplit[0]);
					for (int i = 0; i < 5; ++i) {
						grades[i] += Integer.parseInt(valueSplit[i + 1]);
					}
				}
				StringBuilder sb = new StringBuilder();
				sb.append(studentCount);
				for (int i = 0; i < 5; ++i) {
					sb.append("\t");
					sb.append(grades[i]);
				}
				context.write(key, new Text(sb.toString()));
			} catch (Exception e) {
				// Хватају се све грешке јер Hadoop понекад може да их не испише.
				e.printStackTrace();
			}
		}
	}

	public static void main(String[] args) throws Exception {
		FileUtils.deleteDirectory(new File(args[1]));

		Job job = Job.getInstance();
		job.setJarByClass(Ocene1.class);
		job.setJobName("ocene1");

		job.setInputFormatClass(TextInputFormat.class);
		job.setOutputFormatClass(TextOutputFormat.class);

		job.setOutputKeyClass(Text.class);
		job.setOutputValueClass(Text.class);

		job.setMapperClass(Map.class);
		job.setReducerClass(Reduce.class);
		job.setCombinerClass(Reduce.class);

		FileInputFormat.setInputPaths(job, new Path(args[0]));
		FileOutputFormat.setOutputPath(job, new Path(args[1]));

		job.waitForCompletion(true);
	}
}

Ocene2.java

package rs.etf.iep.mapreduce;

import java.io.File;
import java.util.LinkedList;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;

public class Ocene2 {
	public static final int DEFAULT_N = 1;
	
	public static class Map1 extends Mapper<LongWritable, Text, Text, Text> {
		@Override
		public void map(LongWritable key, Text value, Context context) {
			try {
				String[] split = value.toString().split("\t");
				if (split.length <= 1) {
					// Студент нема ниједан испит.
					return;
				}
				for (String exam : split[1].split(";")) {
					String[] examSplit = exam.split(",");
					context.write(new Text(examSplit[0]), new Text(examSplit[2] + "\t1"));
				}
			} catch (Exception e) {
				// Хватају се све грешке јер Hadoop понекад може да их не испише.
				e.printStackTrace();
			}
		}
	}

	public static class Reduce1 extends Reducer<Text, Text, Text, Text> {
		@Override
		public void reduce(Text key, Iterable<Text> values, Context context) {
			try {
				int sum = 0;
				int count = 0;
				for (Text value : values) {
					String[] valueSplit = value.toString().split("\t");
					sum += Integer.parseInt(valueSplit[0]);
					count += Integer.parseInt(valueSplit[1]);
				}
				context.write(key, new Text(sum + "\t" + count));
			} catch (Exception e) {
				// Хватају се све грешке јер Hadoop понекад може да их не испише.
				e.printStackTrace();
			}
		}
	}

	public static void job1(String[] args) throws Exception {
		Job job = Job.getInstance();
		job.setJarByClass(Ocene2.class);
		job.setJobName("ocene2-1");

		job.setInputFormatClass(TextInputFormat.class);
		job.setOutputFormatClass(TextOutputFormat.class);

		job.setOutputKeyClass(Text.class);
		job.setOutputValueClass(Text.class);

		job.setMapperClass(Map1.class);
		job.setReducerClass(Reduce1.class);
		job.setCombinerClass(Reduce1.class);

		FileInputFormat.setInputPaths(job, new Path(args[0]));
		FileOutputFormat.setOutputPath(job, new Path("ocene2-temp"));

		job.waitForCompletion(true);
	}
	
	public static class Map2 extends Mapper<LongWritable, Text, Text, Text> {
		private static final Text text = new Text("ocene2-text");
		private int N;

		@Override
		public void setup(Context context) {
			N = context.getConfiguration().getInt("N", DEFAULT_N);
		}

		@Override
		public void map(LongWritable key, Text value, Context context) {
			try {
				String[] splitValue = value.toString().split("\t");
				double sum = Double.parseDouble(splitValue[1]);
				double count = Double.parseDouble(splitValue[2]);
				if (count >= N) {
					context.write(text, new Text(splitValue[0] + "\t" + (sum / count)));
				}
			} catch (Exception e) {
				// Хватају се све грешке јер Hadoop понекад може да их не испише.
				e.printStackTrace();
			}
		}
	}

	public static class Reduce2 extends Reducer<Text, Text, Text, Text> {
		@Override
		public void reduce(Text key, Iterable<Text> values, Context context) {
			try {
				double maxAvg = 0;
				List<String> list = new LinkedList<>();
				for (Text value : values) {
					String[] valueSplit = value.toString().split("\t");
					double avg = Double.parseDouble(valueSplit[1]);
					if (avg > maxAvg) {
						list.clear();
						maxAvg = avg;
					}
					if (avg == maxAvg) {
						list.add(value.toString());
					}
				}
				for (String value : list) {
					context.write(key, new Text(value));
				}
			} catch (Exception e) {
				// Хватају се све грешке јер Hadoop понекад може да их не испише.
				e.printStackTrace();
			}
		}
	}

	public static void job2(String[] args) throws Exception {
		Configuration conf = new Configuration();
		conf.setInt("N", Integer.parseInt(args[2]));

		Job job = Job.getInstance(conf, "ocene2-2");
		job.setJarByClass(Ocene2.class);

		job.setInputFormatClass(TextInputFormat.class);
		job.setOutputFormatClass(TextOutputFormat.class);

		job.setOutputKeyClass(Text.class);
		job.setOutputValueClass(Text.class);

		job.setMapperClass(Map2.class);
		job.setReducerClass(Reduce2.class);

		FileInputFormat.setInputPaths(job, new Path("ocene2-temp"));
		FileOutputFormat.setOutputPath(job, new Path(args[1]));

		job.waitForCompletion(true);
	}
	
	public static void main(String[] args) throws Exception {
		FileUtils.deleteDirectory(new File(args[1]));
		FileUtils.deleteDirectory(new File("ocene2-temp"));
		job1(args);
		job2(args);
	}
}

Провера

Следећи садржај датотеке која се прослеђује као први аргумент оба програма може се користити за тестирање:

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