int autograderGraphicalMain(int argc, char** argv) { GWindow gui(500, 300, /* visible */ false); gui.setTitle(STATIC_VARIABLE(FLAGS).assignmentName + " Autograder"); gui.setCanvasSize(0, 0); gui.setExitOnClose(true); GLabel startLabel(""); if (!STATIC_VARIABLE(FLAGS).startMessage.empty()) { std::string startMessage = STATIC_VARIABLE(FLAGS).startMessage; if (!stringContains(startMessage, "<html>")) { startMessage = stringReplace(startMessage, "Note:", "<b>Note:</b>"); startMessage = stringReplace(startMessage, "NOTE:", "<b>NOTE:</b>"); startMessage = "<html><body style='width: 500px; max-width: 500px;'>" + startMessage + "</body></html>"; } startLabel.setLabel(startMessage); gui.addToRegion(&startLabel, "NORTH"); } std::string autogradeText = addAutograderButton(gui, "Automated\ntests", "check.gif"); std::string manualText = addAutograderButton(gui, "Run\nmanually", "play.gif"); std::string styleCheckText = addAutograderButton(gui, "Style\nchecker", "magnifier.gif"); for (int i = 0; i < STATIC_VARIABLE(FLAGS).callbackButtons.size(); i++) { STATIC_VARIABLE(FLAGS).callbackButtons[i].text = addAutograderButton(gui, STATIC_VARIABLE(FLAGS).callbackButtons[i].text, STATIC_VARIABLE(FLAGS).callbackButtons[i].icon); } std::string lateDayText = addAutograderButton(gui, "Late days\ninfo", "calendar.gif"); std::string aboutText = addAutograderButton(gui, "About\nGrader", "help.gif"); std::string exitText = addAutograderButton(gui, "Exit\nGrader", "stop.gif"); gui.pack(); gui.setVisible(true); int result = 0; while (true) { GEvent event = waitForEvent(ACTION_EVENT); if (event.getEventClass() == ACTION_EVENT) { GActionEvent actionEvent(event); std::string cmd = actionEvent.getActionCommand(); if (cmd == autogradeText) { if (STATIC_VARIABLE(FLAGS).callbackStart) { STATIC_VARIABLE(FLAGS).callbackStart(); } // stanfordcpplib::getPlatform()->autograderunittest_clearTests(); stanfordcpplib::getPlatform()->autograderunittest_clearTestResults(); stanfordcpplib::getPlatform()->autograderunittest_setTestingCompleted(false); stanfordcpplib::getPlatform()->autograderunittest_setVisible(true); result = mainRunAutograderTestCases(argc, argv); stanfordcpplib::getPlatform()->autograderunittest_setTestingCompleted(true); // if style checker is merged, also run it now if (stylecheck::isStyleCheckMergedWithUnitTests()) { mainRunStyleChecker(); } if (STATIC_VARIABLE(FLAGS).callbackEnd) { STATIC_VARIABLE(FLAGS).callbackEnd(); } } else if (cmd == manualText) { // set up buttons to automatically enter user input if (STATIC_VARIABLE(FLAGS).showInputPanel) { inputpanel::load(STATIC_VARIABLE(FLAGS).inputPanelFilename); } // actually run the student's program // (While program is running, if we close console, exit entire // autograder program because we might be blocked on console I/O. // But after it's done running, set behavior to just hide the // console, since the grader will probably try to close it and then // proceed with more grading and tests afterward. // A little wonky, but it avoids most of the surprise cases of // "I closed the student's console and it killed the autograder". stanfordcpplib::getPlatform()->jbeconsole_clear(); stanfordcpplib::getPlatform()->jbeconsole_setVisible(true); stanfordcpplib::getPlatform()->jbeconsole_toFront(); // setConsoleCloseOperation(ConsoleCloseOperation::CONSOLE_EXIT_ON_CLOSE); autograder::setExitEnabled(false); // block exit() call setConsoleCloseOperation(ConsoleCloseOperation::CONSOLE_HIDE_ON_CLOSE); studentMain(); // gwindowSetExitGraphicsEnabled(true); } else if (cmd == styleCheckText) { mainRunStyleChecker(); } else if (cmd == lateDayText) { showLateDays(); } else if (cmd == aboutText) { GOptionPane::showMessageDialog(STATIC_VARIABLE(FLAGS).aboutText, "About Autograder", GOptionPane::MessageType::INFORMATION); } else if (cmd == exitText) { autograder::setExitEnabled(true); // don't block exit() call // free up memory used by graphical interactors for (GButton* button : STATIC_VARIABLE(AUTOGRADER_BUTTONS)) { delete button; } STATIC_VARIABLE(AUTOGRADER_BUTTONS).clear(); gui.close(); // exits program; will not return break; } else { for (CallbackButtonInfo buttonInfo : STATIC_VARIABLE(FLAGS).callbackButtons) { if (cmd == buttonInfo.text) { buttonInfo.func(); break; } } } } } // free up memory used by graphical interactors for (GButton* button : STATIC_VARIABLE(AUTOGRADER_BUTTONS)) { delete button; } STATIC_VARIABLE(AUTOGRADER_BUTTONS).clear(); return result; }
int main(int argc, char *argv[]) { initPython(); studentMain(); deInitPython(); }
int autograderTextMain(int argc, char** argv) { std::cout << STATIC_VARIABLE(FLAGS).assignmentName << " Autograder" << std::endl << AUTOGRADER_OUTPUT_SEPARATOR << std::endl; // set up buttons to automatically enter user input if (STATIC_VARIABLE(FLAGS).showInputPanel) { inputpanel::load(STATIC_VARIABLE(FLAGS).inputPanelFilename); } std::string autogradeYesNoMessage = STATIC_VARIABLE(FLAGS).startMessage; if (!autogradeYesNoMessage.empty()) { autogradeYesNoMessage += "\n\n"; } autogradeYesNoMessage += "Attempt auto-grading (Y/n)? "; int result = 0; bool autograde = autograderYesOrNo(autogradeYesNoMessage, "", "y"); if (autograde) { if (STATIC_VARIABLE(FLAGS).callbackStart) { STATIC_VARIABLE(FLAGS).callbackStart(); } result = mainRunAutograderTestCases(argc, argv); // a hook to allow per-assignment code to run at the start if (STATIC_VARIABLE(FLAGS).callbackEnd) { STATIC_VARIABLE(FLAGS).callbackEnd(); } } // manual testing bool manualGrade = autograderYesOrNo("Run program for manual testing (y/N)? ", "", "n"); if (manualGrade) { gwindowSetExitGraphicsEnabled(false); while (manualGrade) { studentMain(); std::cout << AUTOGRADER_OUTPUT_SEPARATOR << std::endl; manualGrade = autograderYesOrNo("Run program again (y/N)? ", "", "n"); } gwindowSetExitGraphicsEnabled(true); } std::cout << AUTOGRADER_OUTPUT_SEPARATOR << std::endl; // run any custom callbacks that the assignment's autograder added for (int i = 0; i < STATIC_VARIABLE(FLAGS).callbackButtons.size(); i++) { std::string buttonText = STATIC_VARIABLE(FLAGS).callbackButtons[i].text; buttonText = stringReplace(buttonText, "\n", " "); // GUI often uses multi-line button text strings; strip if (autograderYesOrNo(buttonText + " (Y/n)? ", "", "y")) { STATIC_VARIABLE(FLAGS).callbackButtons[i].func(); } } // run Style Checker to point out common possible style issues if (!STATIC_VARIABLE(FLAGS).styleCheckFiles.isEmpty()) { if (autograderYesOrNo("Run style checker (Y/n)? ", "", "y")) { mainRunStyleChecker(); } } // display turnin time information to decide late days used if (STATIC_VARIABLE(FLAGS).showLateDays) { showLateDays(); } std::cout << "COMPLETE: Autograder terminated successfully. Exiting." << std::endl; return result; }