<commit_before>import java.io.*;
import java.util.*;
import org.json.simple.*;
import org.json.simple.parser.*;
import java.lang.annotation.*;
import java.lang.reflect.*;
import tester.annotations.*;
public class JUnitPointsMerger {
	private static final class SingleReport {
		boolean success;
		String description;
		String message;
	}


	private static final class SingleReportComparator implements Comparator<SingleReport> {
		public int compare(SingleReport r1, SingleReport r2) {
			if (r1 == null && r2 == null) return 0;
			if (r1 == null) return -1;
			if (r2 == null) return 1;
			boolean t1 = r1.success;
			boolean t2 = r2.success;
			if (t1 == t2) {
				if (r1.description.compareTo(r2.description) == 0) {
					return r1.message.compareTo(r2.message);
				}
				return r1.description.compareTo(r2.description);
			}
			if (t1) return +1;
			return -1;
		}
	}

	static {
		Locale.setDefault(Locale.US);
	}

	private static String summary = "";
	private static double points = 0;
	private static Class pub = null;
	private static Class secret = null;
	private static final HashMap<String, Ex> exerciseHashMap = new HashMap<>();
	private static final HashMap<String, Double> bonusPerExHashMap = new HashMap<>();


	private static double getPoints(double pts, double pointsDeclaredPerExercise, double bonusDeclaredPerExercise) {
		return pointsDeclaredPerExercise * Math.abs(pts) / bonusDeclaredPerExercise;
	}

	private static double getLocalPoint(Boolean success, String rawId){
		// get Bonus and malus from method
		String id = rawId;	
		// search in secret an in public
		
		Method method = null;
		Points points = null;
		try{
			method = pub.getMethod(id);
			points = (Points) method.getAnnotation(Points.class);
		} catch (NoSuchMethodException nsme){
			//throw new Error("WARNING - Method not found");
		}

		//try secret test class
		if(secret != null && method == null){
			try{
				method = secret.getMethod(id);
				points = (Points) method.getAnnotation(Points.class);
			} catch (NoSuchMethodException nsme){
				throw new Error("WARNING - Method "+ method.getName() +"not found");
			}
		}else if(secret == null && method == null){
			throw new Error("WARNING - Method not found");
		}

		double score = 0;
		if (points.bonus() != -1 && success){
			score = getPoints(points.bonus(), exerciseHashMap.get(points.exID()).points(), bonusPerExHashMap.get(points.exID()));
		}
		if (points.malus() != -1 && !success){
			score = -getPoints(points.malus(), exerciseHashMap.get(points.exID()).points(), bonusPerExHashMap.get(points.exID()));
		}
		return score;
	}


	private static void merge(ArrayList<JSONObject> rexs, JSONObject vex) { // merges two exercises
		ArrayList<SingleReport> reps = new ArrayList<>();
		double localpoints = 0;
		JSONArray vextests = (JSONArray) vex.get("tests");
		/* FIXME: this is not longer true, try to create a better check soon ;-)
		int cnt = 0;
		for (JSONObject rex : rexs) {
			cnt++;
			JSONArray rextests = (JSONArray) rex.get("tests");
			if (rextests.size() != vextests.size()) {
				throw new RuntimeException("vanilla and #" + cnt + " of replaced do have different number of tests (" + vextests.size() + " vs. " + rextests.size() + ") for exercise " + rex.get("name"));
			}
		}
		*/
		for (int i = 0; i < vextests.size(); i++) {
			JSONObject vextest = (JSONObject) vextests.get(i);
			JSONObject usedresult = vextest;
			for (JSONObject rexIt : rexs) {
				boolean found = false;
				JSONArray rextests = (JSONArray) rexIt.get("tests");
				for (int j = 0; !found && j < rextests.size(); j++) {
					JSONObject rextest = (JSONObject) rextests.get(j);
					if (rextest.get("id").equals(vextest.get("id"))) {
						if ((Boolean) rextest.get("success")) {
							usedresult = rextest;
						}
						found = true;
					}
				}
				/* FIXME: this is not longer true, see above
				   if (!found) {
				   throw new RuntimeException("could not find " + vextest.get("id") + " in replaced tests");
				   }
				   */
			}
			String localSummary = "";
			if ((Boolean) vextest.get("success")) {
				usedresult = vextest;
			}

			double localscore = getLocalPoint((Boolean) usedresult.get("success"), (String) usedresult.get("id"));
			localpoints += localscore;
			localSummary += ((Boolean) usedresult.get("success")) ? "✓" : "✗";

			localSummary += String.format(" %1$6.2f", localscore) + " | ";
			localSummary += (String) usedresult.get("desc");
			Object error = usedresult.get("error");
			if (error != null) {
				localSummary += " | " + (String) error;
			}
			localSummary += "\n";

			SingleReport r = new SingleReport();
			r.success = ((Boolean) usedresult.get("success"));
			r.message = localSummary;
			r.description = (String)usedresult.get("id");
			reps.add(r);
		}
		localpoints -= 0.00001; // XXX: subtract epsilon here
		localpoints = Math.max(0., localpoints);
		localpoints = Math.ceil(2. * localpoints) / 2; // round up to half points
		localpoints = Math.min(localpoints, exerciseHashMap.get(vex.get("name")).points());
		points += localpoints;
		summary += "\n" + (String) vex.get("name");
		summary += String.format(" (%1$.1f points):", localpoints) + "\n";
		Collections.sort(reps, new SingleReportComparator());
		for (SingleReport r : reps) {
			summary += r.message;<commit_msg>test methods are marked, extract either from public test or secrettest, #26<commit_after>import java.io.*;
import java.util.*;
import org.json.simple.*;
import org.json.simple.parser.*;
import java.lang.annotation.*;
import java.lang.reflect.*;
import tester.annotations.*;
public class JUnitPointsMerger {
	private static final class SingleReport {
		boolean success;
		String description;
		String message;
	}


	private static final class SingleReportComparator implements Comparator<SingleReport> {
		public int compare(SingleReport r1, SingleReport r2) {
			if (r1 == null && r2 == null) return 0;
			if (r1 == null) return -1;
			if (r2 == null) return 1;
			boolean t1 = r1.success;
			boolean t2 = r2.success;
			if (t1 == t2) {
				if (r1.description.compareTo(r2.description) == 0) {
					return r1.message.compareTo(r2.message);
				}
				return r1.description.compareTo(r2.description);
			}
			if (t1) return +1;
			return -1;
		}
	}

	static {
		Locale.setDefault(Locale.US);
	}

	private static String summary = "";
	private static double points = 0;
	private static Class pub = null;
	private static Class secret = null;
	private static final HashMap<String, Ex> exerciseHashMap = new HashMap<>();
	private static final HashMap<String, Double> bonusPerExHashMap = new HashMap<>();


	private static double getPoints(double pts, double pointsDeclaredPerExercise, double bonusDeclaredPerExercise) {
		return pointsDeclaredPerExercise * Math.abs(pts) / bonusDeclaredPerExercise;
	}

	// extract points annotation from either secret or public class and calculate the point
	private static double getLocalPoint(Boolean success, String id, Boolean fromSecret){

		Method method = null;
		Points points = null;

		if(fromSecret){
			// test method originated from a secret test
			try{
				method = secret.getMethod(id);
				points = (Points) method.getAnnotation(Points.class);
			} catch (NoSuchMethodException nsme){
				throw new Error("WARNING - Method " +method.getName()+ " was not found in secret test class " + pub.getName());
			}
		}else{
			try{
				method = pub.getMethod(id);
				points = (Points) method.getAnnotation(Points.class);
			} catch (NoSuchMethodException nsme){
				throw new Error("WARNING - Method " +method.getName()+ " was not found in public test class " + pub.getName());
			}
		}

		double score = 0;
		if (points.bonus() != -1 && success){
			score = getPoints(points.bonus(), exerciseHashMap.get(points.exID()).points(), bonusPerExHashMap.get(points.exID()));
		}
		if (points.malus() != -1 && !success){
			score = -getPoints(points.malus(), exerciseHashMap.get(points.exID()).points(), bonusPerExHashMap.get(points.exID()));
		}
		return score;
	}


	private static void merge(ArrayList<JSONObject> rexs, JSONObject vex) { // merges two exercises
		ArrayList<SingleReport> reps = new ArrayList<>();
		double localpoints = 0;
		JSONArray vextests = (JSONArray) vex.get("tests");
		/* FIXME: this is not longer true, try to create a better check soon ;-)
		int cnt = 0;
		for (JSONObject rex : rexs) {
			cnt++;
			JSONArray rextests = (JSONArray) rex.get("tests");
			if (rextests.size() != vextests.size()) {
				throw new RuntimeException("vanilla and #" + cnt + " of replaced do have different number of tests (" + vextests.size() + " vs. " + rextests.size() + ") for exercise " + rex.get("name"));
			}
		}
		*/
		for (int i = 0; i < vextests.size(); i++) {
			JSONObject vextest = (JSONObject) vextests.get(i);
			JSONObject usedresult = vextest;
			for (JSONObject rexIt : rexs) {
				boolean found = false;
				JSONArray rextests = (JSONArray) rexIt.get("tests");
				for (int j = 0; !found && j < rextests.size(); j++) {
					JSONObject rextest = (JSONObject) rextests.get(j);
					if (rextest.get("id").equals(vextest.get("id"))) {
						if ((Boolean) rextest.get("success")) {
							usedresult = rextest;
						}
						found = true;
					}
				}
				/* FIXME: this is not longer true, see above
				   if (!found) {
				   throw new RuntimeException("could not find " + vextest.get("id") + " in replaced tests");
				   }
				   */
			}
			String localSummary = "";
			if ((Boolean) vextest.get("success")) {
				usedresult = vextest;
			}

			double localscore = getLocalPoint((Boolean) usedresult.get("success"), (String) usedresult.get("id"), (Boolean) usedresult.get("fromSecret"));
			localpoints += localscore;
			localSummary += ((Boolean) usedresult.get("success")) ? "✓" : "✗";

			localSummary += String.format(" %1$6.2f", localscore) + " | ";
			localSummary += (String) usedresult.get("desc");
			Object error = usedresult.get("error");
			if (error != null) {
				localSummary += " | " + (String) error;
			}
			localSummary += "\n";

			SingleReport r = new SingleReport();
			r.success = ((Boolean) usedresult.get("success"));
			r.message = localSummary;
			r.description = (String)usedresult.get("id");
			reps.add(r);
		}
		localpoints -= 0.00001; // XXX: subtract epsilon here
		localpoints = Math.max(0., localpoints);
		localpoints = Math.ceil(2. * localpoints) / 2; // round up to half points
		localpoints = Math.min(localpoints, exerciseHashMap.get(vex.get("name")).points());
		points += localpoints;
		summary += "\n" + (String) vex.get("name");
		summary += String.format(" (%1$.1f points):", localpoints) + "\n";
		Collections.sort(reps, new SingleReportComparator());
		for (SingleReport r : reps) {
			summary += r.message;
{'fraction_non_alphanumeric': 0.14874099035851351, 'fraction_numerical': 0.008986239820275204, 'mean_word_length': 3.64723792953458, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '77979', 'n_tokens_mistral': 3868, 'n_tokens_neox': 3355, 'n_words': 923}