File size: 6,235 Bytes
6e6e8e8 bd5a999 6e6e8e8 d51b6cd 6e6e8e8 d51b6cd 16495d2 1ea0fc8 6e6e8e8 16495d2 d51b6cd 16495d2 d51b6cd 16495d2 d51b6cd 6e6e8e8 d51b6cd 6e6e8e8 16495d2 d51b6cd 6e6e8e8 d51b6cd 6e6e8e8 d51b6cd 6e6e8e8 bd4642a 6e6e8e8 d51b6cd 6e6e8e8 d51b6cd 27a356c 6e6e8e8 27a356c 6e6e8e8 d51b6cd 6e6e8e8 d51b6cd 6e6e8e8 bd5a999 d51b6cd 6e6e8e8 bd5a999 d51b6cd 6e6e8e8 bd5a999 6e6e8e8 d51b6cd 6e6e8e8 d51b6cd 6e6e8e8 d51b6cd 6e6e8e8 d51b6cd 6e6e8e8 d51b6cd 6e6e8e8 d51b6cd 16495d2 d51b6cd 6e6e8e8 d51b6cd bd5a999 6e6e8e8 bd5a999 d51b6cd 6e6e8e8 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 | # 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)
|