Skip to content

Instantly share code, notes, and snippets.

@znarfm
Last active November 29, 2025 06:40
Show Gist options
  • Select an option

  • Save znarfm/d365898b752b3b59046440d46b46009b to your computer and use it in GitHub Desktop.

Select an option

Save znarfm/d365898b752b3b59046440d46b46009b to your computer and use it in GitHub Desktop.
pup-sis-helper

PUP SIS Helper

This script helps PUP students automate faculty evaluations by setting survey ratings to achieve a desired average score. It dynamically adjusts responses, ensures accuracy, and works for any number of questions, saving time and simplifying the feedback process.

Instructions

Browser Developer Console

  1. Open your web browser (e.g., Chrome, Firefox).
  2. Navigate to the faculty evaluation page on the PUP SIS portal.
  3. Open the Developer Console:
    • For Chrome: Press Ctrl + Shift + J (Windows/Linux) or Cmd + Option + J (Mac).
    • For Firefox: Press Ctrl + Shift + K (Windows/Linux) or Cmd + Option + K (Mac).
  4. Copy and paste the entire script below into the console.
window.se = (a = prompt("Avg?")) => {
  q = document.querySelectorAll('input[name^="q"]').length / 5;
  h = Math.ceil(a);
  l = Math.floor(a);
  n = Math.round(a * q) - l * q;
  for (i = 1; i <= q; i++)
    document.getElementById("q" + i + (i <= n ? h : l)).checked = 1;
};
  1. Press Enter to execute the script.

Note

If the console blocks pasting, type allow pasting and press Enter.

Userscript Manager (Recommended)

For a better experience, install the script permanently using a userscript manager. This way, the script will automatically run every time you visit the faculty evaluation page.

Installing

  1. Choose and install a userscript manager extension for your browser (e.g., Tampermonkey, Violentmonkey, or Greasemonkey).
  2. Click on the raw userscript.js file link in this gist (your userscript manager should automatically detect it and prompt you to install).
  3. Click Install or Confirm Installation

Usage

  • Navigate to the faculty evaluation page on the PUP SIS portal:
  • The script will automatically load and display a floating helper panel in the top-right corner
  • Use the panel features:
    • Preset buttons (2.0, 2.5, 3.0, 3.5, 4.0, 5.0): Click any preset to instantly fill the survey with that average
    • Apply button: Enter a custom average rating (1.0-5.0)
    • Auto Comment button: Automatically fill all empty comment boxes with a default message
    • Keyboard shortcut: Press Ctrl+Shift+E to quickly apply your last used rating
  • The script uses organic randomization to make responses look natural
// ==UserScript==
// @name PUP Survey Helper
// @namespace Violentmonkey Scripts
// @match https://survey.pup.edu.ph/apps/ofes/survey/*
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_registerMenuCommand
// @version 3.0
// @author intMeinVoid
// @icon https://www.pup.edu.ph/about/images/PUPLogo.png
// @description Adds a button to help fill out PUP faculty evaluation surveys with organic randomization
// @license MIT
// ==/UserScript==
(function () {
"use strict";
const CONFIG = {
DEFAULT_AVERAGE: 2.5,
PRESETS: [2.0, 2.5, 3.0, 3.5, 4.0, 5.0],
STORAGE_KEY: "pupSurveyLastUsedRating",
COMMENT_TEXT: "No further comments. satisfied with the performance.",
};
// --- State Management ---
const state = {
isMinimized: false,
lastRating: parseFloat(
GM_getValue(CONFIG.STORAGE_KEY, CONFIG.DEFAULT_AVERAGE),
),
};
// --- UI Construction ---
const container = document.createElement("div");
container.id = "pup-survey-helper";
container.style.cssText = `
position: fixed; top: 20px; right: 20px; z-index: 9999;
font-family: 'Segoe UI', Arial, sans-serif;
background: rgba(255, 255, 255, 0.98);
padding: 0; border-radius: 8px;
box-shadow: 0 4px 15px rgba(0,0,0,0.15);
border: 1px solid #e0e0e0;
overflow: hidden;
transition: height 0.3s ease;
`;
// Header with Minimize Button
const header = document.createElement("div");
header.style.cssText = `
padding: 10px; background: #880000; color: white;
display: flex; justify-content: space-between; align-items: center;
font-weight: bold; font-size: 13px; cursor: pointer;
`;
header.innerHTML = `<span>🎓 PUP Eval Helper</span> <span id="toggle-icon">▼</span>`;
const contentArea = document.createElement("div");
contentArea.style.cssText = `padding: 12px; display: flex; flex-direction: column; gap: 8px;`;
// Toggle Logic
header.onclick = () => {
state.isMinimized = !state.isMinimized;
contentArea.style.display = state.isMinimized ? "none" : "flex";
header.querySelector("#toggle-icon").textContent = state.isMinimized
? "▲"
: "▼";
};
const createButton = (text, onClick, isPrimary = false, title = "") => {
const btn = document.createElement("button");
btn.textContent = text;
btn.title = title;
btn.style.cssText = `
padding: 8px 12px;
background-color: ${isPrimary ? "#900000" : "#f8f9fa"};
color: ${isPrimary ? "white" : "#333"};
border: 1px solid ${isPrimary ? "#900000" : "#ddd"};
border-radius: 4px; cursor: pointer; font-size: 13px;
transition: all 0.2s; flex: 1;
`;
btn.onmouseenter = () => (btn.style.filter = "brightness(0.95)");
btn.onmouseleave = () => (btn.style.filter = "brightness(1)");
btn.onclick = onClick;
return btn;
};
// Preset Grid
const presetsContainer = document.createElement("div");
presetsContainer.style.cssText = `display: grid; grid-template-columns: repeat(3, 1fr); gap: 5px;`;
CONFIG.PRESETS.forEach((preset) => {
presetsContainer.appendChild(
createButton(preset, () => setEvaluation(preset)),
);
});
// Action Buttons
const mainButton = createButton(
`Apply (${state.lastRating})`,
() => setEvaluation(),
true,
);
const commentButton = createButton(
"✍️ Auto Comment",
() => {
const textAreas = document.querySelectorAll("textarea");
if (textAreas.length === 0)
return showToast("No comment boxes found", true);
textAreas.forEach((area) => {
if (!area.value) area.value = CONFIG.COMMENT_TEXT;
});
showToast(`Filled ${textAreas.length} comment boxes`);
},
false,
"Fill empty comment boxes",
);
contentArea.append(presetsContainer, mainButton, commentButton);
container.append(header, contentArea);
document.body.appendChild(container);
// --- Logic Utilities ---
// Fisher-Yates Shuffle Algorithm
const shuffleArray = (array) => {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
};
const showToast = (message, isError = false) => {
const toast = document.createElement("div");
toast.textContent = message;
toast.style.cssText = `
position: fixed; bottom: 20px; right: 20px;
background: ${isError ? "#dc3545" : "#28a745"};
color: white; padding: 10px 20px; border-radius: 4px;
z-index: 10001; font-size: 14px; box-shadow: 0 3px 6px rgba(0,0,0,0.2);
animation: fadeIn 0.3s ease-in-out;
`;
document.body.appendChild(toast);
setTimeout(() => {
toast.style.opacity = "0";
setTimeout(() => toast.remove(), 300);
}, 3000);
};
// --- Main Logic ---
const setEvaluation = async (targetAvg) => {
try {
if (targetAvg === undefined) {
const input = prompt(
"Enter target average (1.0 - 5.0):",
state.lastRating,
);
if (input === null) return;
targetAvg = parseFloat(input);
}
if (isNaN(targetAvg) || targetAvg < 1 || targetAvg > 5) {
throw new Error("Please enter a number between 1 and 5");
}
// Save preference
state.lastRating = targetAvg;
GM_setValue(CONFIG.STORAGE_KEY, targetAvg);
mainButton.textContent = `Apply (${targetAvg})`;
// Identify Questions
// Heuristic: Input names usually follow 'q1', 'q2' pattern in PUP SIS
// We count unique names starting with 'q' followed by a number
const allRadios = Array.from(
document.querySelectorAll('input[type="radio"]'),
);
const questionNames = [
...new Set(allRadios.map((r) => r.name).filter((n) => /^q\d+/.test(n))),
]; // Filter ensures we only get question inputs
const totalQuestions = questionNames.length;
if (totalQuestions === 0)
throw new Error("No evaluation questions detected.");
// Calculate Math
const exactTotal = targetAvg * totalQuestions;
const roundedTotal = Math.round(exactTotal);
const lowerValue = Math.floor(targetAvg);
const higherValue = Math.ceil(targetAvg);
const numberOfHigher = roundedTotal - lowerValue * totalQuestions;
// Create Score Distribution Array
let scoreDistribution = [];
for (let i = 0; i < numberOfHigher; i++)
scoreDistribution.push(higherValue);
for (let i = 0; i < totalQuestions - numberOfHigher; i++)
scoreDistribution.push(lowerValue);
// SHUFFLE the scores to make it look organic
scoreDistribution = shuffleArray(scoreDistribution);
// Execute
mainButton.textContent = "Processing...";
mainButton.disabled = true;
await new Promise((resolve) =>
requestAnimationFrame(() => {
let successCount = 0;
// Iterate through the identified question names (q1, q2, etc.)
questionNames.forEach((qName, index) => {
const scoreToSet = scoreDistribution[index];
// PUP Selector Logic: ID is usually q{questionNum}{score}
// Extract the question number from the name (e.g. "q15" -> "15")
const qNum = qName.replace("q", "");
// Try ID selector first (Fastest)
let targetRadio = document.getElementById(`q${qNum}${scoreToSet}`);
// Fallback: Query by name and value if ID fails
if (!targetRadio) {
targetRadio = document.querySelector(
`input[name="${qName}"][value="${scoreToSet}"]`,
);
}
if (targetRadio) {
targetRadio.checked = true;
successCount++;
}
});
showToast(
`Filled ${successCount}/${totalQuestions} items (Avg: ~${targetAvg})`,
);
mainButton.textContent = `Apply (${targetAvg})`;
mainButton.disabled = false;
resolve();
}),
);
} catch (error) {
showToast(error.message, true);
mainButton.disabled = false;
}
};
// Keyboard Shortcuts
document.addEventListener("keydown", (e) => {
if (e.ctrlKey && e.shiftKey && e.code === "KeyE") {
e.preventDefault();
setEvaluation();
}
});
// Style Injection
const style = document.createElement("style");
style.textContent = `@keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }`;
document.head.appendChild(style);
})();
@yam2-1111
Copy link

gagi balagbag

@syn-vita
Copy link

syn-vita commented Feb 7, 2025

wala po bang bisakol version ng instructions?

@yam2-1111
Copy link

wala po bang bisakol version ng instructions?

Faculty Evaluation Guide (Bisakol)

Paano Mag-Evaluate sang Faculty sa SIS

1. Mag-log in sa imo SIS account

Log in sa imo SIS account kag kadto sa faculty evaluation page para sa napili nga instructor.

2. Buksan ang Developer Console sang Browser

Para sa Chrome/Edge:

  • Pinduta ang Ctrl + Shift + J (Windows) o Cmd + Option + J (Mac).

Para sa Firefox:

  • Pinduta ang Ctrl + Shift + K (Windows) o Cmd + Option + K (Mac).

3. Paytuguti ang Pag-Paste (kung kinahanglan)

Kung indi ma-paste sa console, i-type ang allow pasting kag pinduta ang Enter.

4. I-copy kag i-paste ang script sa Developer Console

// I-paste ang script diri
const se = async (targetAvg) => { ... }; // (tan-awa ang script sa ibabaw)

5. Ipatakbo ang Script

Para manual nga magbutang sang desired average:

  • I-type ang se() kag pinduta ang Enter. Mag-prompt ini para sa target average (halimbawa: 3.5).

Para direkta nga i-type ang target average:

  • I-type ang se(3.5) kag pinduta ang Enter.

6. Pabayi ang Script nga Magtrabaho!

Awtomatiko nga magbutang sang ratings ang survey para maabot ang imo target average.

7. Suriha kag I-submit

  • Reviewha ang mga tubag, i-edit kung kinahanglan, kag i-submit ang imo evaluation.

Dali, sayon, kag wala hassle! 🎉

@EarlDinosaur
Copy link

thank you po sa bisakol translation <3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment