Download app.R from stat-utas/marksarg: direct link, hf CLI and curl.
- Browser
- Download file 6.24 kB
-
https://huggingface.co/spaces/stat-utas/marksarg/resolve/main/app.R
- Command line
-
hf download hf://spaces/stat-utas/marksarg/app.R
-
curl -L -o app.R https://huggingface.co/spaces/stat-utas/marksarg/resolve/main/app.R
6.24 kB
| # Load required libraries | |
| library(shiny) | |
| library(readxl) | |
| library(tidyverse) | |
| library(stringr) | |
| library(openxlsx) | |
| # Define the timeout period in seconds | |
| timeoutSeconds <- 1200 | |
| # Create the JavaScript code to handle user inactivity | |
| inactivity <- sprintf(" | |
| function idleTimer() { | |
| var t; | |
| var timeout = %s * 1000; // Convert seconds to milliseconds | |
| // Events that reset the timer | |
| var events = ['mousemove', 'mousedown', 'click', 'scroll', 'keypress']; | |
| // Function to log out and notify the user | |
| function logout() { | |
| alert('You have been disconnected due to inactivity. Refresh your browser to use the webapp again. - Dr. Eduardo'); | |
| Shiny.setInputValue('timeOut', '%s'); | |
| } | |
| // Function to reset the timer | |
| function resetTimer() { | |
| clearTimeout(t); | |
| t = setTimeout(logout, timeout); | |
| } | |
| // Attach resetTimer to each event | |
| events.forEach(function(event) { | |
| window.addEventListener(event, resetTimer); | |
| }); | |
| // Initialize the timer | |
| t = setTimeout(logout, timeout); | |
| } | |
| // Initialize the idle timer when the document is ready | |
| document.addEventListener('DOMContentLoaded', function() { | |
| idleTimer(); | |
| }); | |
| ", timeoutSeconds, timeoutSeconds) | |
| ##### | |
| read_and_preprocess <- function(path, filename) { | |
| df <- read_excel(path) | |
| # Remove columns with entirely NA entries | |
| df <- df[, colSums(is.na(df)) != nrow(df), drop = FALSE] | |
| columns_selected <- c("ID number", "Last name", "Time taken", "State", "Grade/5.00") | |
| new_column_names <- c("ID_Number", "Last_Name", "Time_Taken", "State", "Grade") | |
| # Select and rename columns | |
| df <- df[, columns_selected, drop = FALSE] | |
| colnames(df) <- new_column_names | |
| # Convert Grade to numeric and Last_Name to title case | |
| df$Grade <- as.numeric(df$Grade) | |
| df$Last_Name <- str_to_title(df$Last_Name) | |
| # Remove rows with missing values | |
| df <- df[complete.cases(df), ] | |
| return(df) | |
| } | |
| # Function to calculate additional columns | |
| calculate_additional_columns <- function(df, attempted, filename) { | |
| avg_col_name <- paste("Average", filename, sep = "_") | |
| df <- df %>% | |
| group_by(ID_Number) %>% | |
| mutate(nAttempt = n(), | |
| !!avg_col_name := ifelse(nAttempt >= attempted, | |
| round(mean(sort(Grade, decreasing = TRUE)[1:attempted]),0), | |
| round(sum(Grade) / attempted))) %>% | |
| distinct(ID_Number, .keep_all = TRUE) | |
| return(df) | |
| } | |
| ##### | |
| # Define UI | |
| ui <- fluidPage( | |
| #tags$script(HTML(inactivity)), | |
| titlePanel( | |
| h4("UTAS - Online Marks Aggregator"), | |
| windowTitle = "Marks Aggregator" | |
| ), | |
| sidebarLayout( | |
| sidebarPanel( | |
| numericInput( | |
| "attempt", | |
| "Min Number of Attempts", | |
| value = 1, min = 1, max = 10, step = 1 | |
| ), | |
| fileInput( | |
| "files", | |
| "Upload Excel file(s)", | |
| accept = c(".xlsx"), | |
| multiple = TRUE, | |
| placeholder = "Please select excel file/s" | |
| ), | |
| helpText("Upload only Excel files with .XLSX extension to ensure consistency."), | |
| br(), | |
| downloadButton("downloadData", "Download"), | |
| hr(), | |
| div( | |
| class = "fluent-footer", | |
| div( | |
| class = "fluent-footer-legal", | |
| div( | |
| class = "fluent-footer-legal-left", | |
| a("Privacy Policy", href = "#"), | |
| " | ", | |
| a("Terms of Use", href = "#") | |
| ), | |
| div( | |
| class = "fluent-footer-legal-right", | |
| "© 2023 College of Computing and Information Sciences" | |
| ) | |
| ) | |
| ), | |
| tags$footer( | |
| style = "text-align: left; padding-top: 10px; font-size: 12px;", | |
| "Built by ", | |
| tags$a(href = "https://www.google.com/search?q=dr.+eduardo+lacap+jr&sca_esv=4136c3af1df3852c&sca_upv=1&sxsrf=ADLYWIIeq7fb1cWKSiyieFVwGRe7qJ40NA%3A1716361100562&ei=jJdNZqHvIZbeseMPj4O8sAs&oq=dr.+eduardo+lacap&gs_lp=Egxnd3Mtd2l6LXNlcnAiEWRyLiBlZHVhcmRvIGxhY2FwKgIIATIHECMYsAMYJzIHECMYsAMYJzILEAAYgAQYsAMYogQyCxAAGIAEGLADGKIEMgsQABiwAxiiBBiJBTILEAAYgAQYsAMYogRIuA1QAFgAcAF4AJABAJgBAKABAKoBALgBAcgBAJgCAaACBJgDAIgGAZAGBpIHATGgBwA&sclient=gws-wiz-serp", "Dr. Eduardo M. Lacap, Jr.") | |
| ) | |
| ), | |
| mainPanel( | |
| tableOutput("table") | |
| ) | |
| ) | |
| ) | |
| # Define server logic | |
| server <- function(input, output, session) { | |
| # Reactive expression for the number of attempts | |
| attempted <- reactive({ input$attempt }) | |
| # Reactive expression for the nature of the files uploaded | |
| independnt <- reactive({input$independent}) | |
| # Reactive expression to read and combine uploaded Excel files | |
| combined_df <- reactive({ | |
| req(input$files$datapath) # Ensure files are uploaded | |
| df_list <- mapply(function(path, name) { | |
| df <- read_and_preprocess(path, tools::file_path_sans_ext(basename(name))) | |
| df <- calculate_additional_columns(df, attempted(), tools::file_path_sans_ext(basename(name))) | |
| return(df) | |
| }, input$files$datapath, input$files$name, SIMPLIFY = FALSE) | |
| combined_df <- bind_rows(df_list) | |
| combined_df <- if (length(df_list) == 1) { | |
| df_list[[1]] %>% | |
| select(ID_Number, Last_Name, starts_with("Average")) | |
| } else { | |
| as.data.frame(combined_df) %>% | |
| select(ID_Number, Last_Name, starts_with("Average")) %>% | |
| pivot_longer(cols = starts_with("Average_"), names_to = "Average_Type", values_to = "Average_Value") %>% | |
| filter(!is.na(Average_Value)) %>% | |
| pivot_wider(names_from = "Average_Type", values_from = "Average_Value") %>% | |
| mutate_at(., vars(starts_with("Average_")), ~replace(., is.na(.), 0), values_fn = list) %>% | |
| mutate(Marks = round(rowMeans(select(., starts_with("Average_")), na.rm = TRUE)+0.1,0)) | |
| } | |
| return(combined_df) | |
| }) | |
| # Display combined data as a table | |
| output$table <- renderTable({ | |
| combined_df() | |
| }) | |
| # Download combined data | |
| output$downloadData <- downloadHandler( | |
| filename = function() { | |
| paste("MarksAggregated_", attempted(), "_MinAttempt.xlsx", sep = "") | |
| }, | |
| content = function(file) { | |
| write.xlsx(combined_df(), file) | |
| } | |
| ) | |
| } | |
| # Run the application | |
| shinyApp(ui = ui, server = server) | |