Archives
Trending
Support
Login
clear text
XML
Django
JavaScript
MATLAB
C
C++
C#
Python
SQL
Shell
Bash
Markdown
YAML
JSON
HTML
CSS
PHP
Java
Ruby
Go
Rust
Swift
Kotlin
Arduino
TypeScript
Perl
Autohotkey
Lua
SQF
R
Scala
Haskell
Groovy
Dart
Clojure
VB.NET
Objective-C
PowerShell
Bash
CoffeeScript
Verilog
# club_assignment_stv_hours_auto_v8_final_output.R library(dplyr) library(readr) library(tidyr) library(stringr) # --- Ρυθμίσεις --- required_hours <- 10L responses_file <- "responses.csv" clubs_file <- "clubs.csv" output_prefix_assignments <- "club_assignments" auto_select_count <- 15L min_pool_size <- 15L set.seed(42) # --- Διαβάζουμε δεδομένα --- responses <- read_csv(responses_file, show_col_types = FALSE) clubs <- read_csv(clubs_file, show_col_types = FALSE) # --- Καθαρισμός και εναρμόνιση Clubs --- colnames(clubs) <- tolower(trimws(colnames(clubs))) club_name_source <- if("club_name" %in% colnames(clubs)) "club_name" else "club_id" if("clubname" %in% colnames(clubs) & !("club_name" %in% colnames(clubs))) { club_name_source <- "clubname" } if("hours_per_week" %in% colnames(clubs)) { clubs <- clubs |> rename(hours = hours_per_week) } else if(!("hours" %in% colnames(clubs))) { hours_col_name <- setdiff(colnames(clubs), c("club_id", "club_name", "clubname"))[1] if (!is.na(hours_col_name)) { clubs <- clubs |> rename(hours = hours_col_name) } } clubs <- clubs |> mutate( club_id = trimws(tolower(club_id)), club_name = .data[[club_name_source]], club_name = trimws(club_name), hours = as.integer(hours), hours = if_else(is.na(hours), 2L, hours) ) |> select(club_id, club_name, hours) # --- Καθαρισμός και εναρμόνιση Responses --- student_col <- colnames(responses)[1] responses <- responses |> mutate(across(all_of(student_col), as.character)) initial_club_cols <- trimws(tolower(colnames(responses)[-1])) colnames(responses) <- c(student_col, initial_club_cols) responses_long_master <- responses |> pivot_longer(cols = -all_of(student_col), names_to = "ClubID", values_to = "Rank") |> mutate( ClubID = trimws(tolower(ClubID)), Rank = as.integer(Rank) ) |> filter(!is.na(Rank)) # --- Ενεργές Καταστάσεις --- active_clubs <- initial_club_cols student_hours <- data.frame(StudentID = unique(responses[[student_col]]), HoursAssigned = 0L, stringsAsFactors = FALSE) colnames(student_hours)[1] <- student_col club_assignments <- data.frame(StudentID = character(), ClubID = character(), ClubName = character(), stringsAsFactors = FALSE) colnames(club_assignments)[1] <- student_col round <- 1L cat(sprintf("--- Έναρξη Διαδικασίας Κατανομής Ομίλων (Στόχος: %d Ώρες/Μαθητή, Min Pool: %d) ---\n", required_hours, min_pool_size)) repeat { # --- 1. Υπολογισμός Πρώτων Προτιμήσεων (Τρέχουσα κατάσταση) --- active_students <- student_hours |> filter(HoursAssigned < required_hours) |> pull(all_of(student_col)) current_prefs <- responses_long_master |> filter(ClubID %in% active_clubs) |> filter(get(student_col) %in% active_students) |> group_by(across(all_of(student_col))) |> filter(Rank == min(Rank, na.rm = TRUE)) |> ungroup() counts <- current_prefs |> count(ClubID, name = "FirstPrefCount") |> right_join(data.frame(ClubID = active_clubs), by = "ClubID") |> replace_na(list(FirstPrefCount = 0)) cat(sprintf("\n*** Γύρος %d ***\n", round)) # Έλεγχος Τερματισμού if(length(active_clubs) == 0 || length(active_students) == 0) { students_not_reached_target <- student_hours |> filter(HoursAssigned < required_hours) if(length(active_clubs) == 0 && nrow(students_not_reached_target) > 0) { cat(sprintf("\nΤΕΡΜΑΤΙΣΜΟΣ ΛΟΓΩ ΕΞΑΝΤΛΗΣΗΣ ΟΜΙΛΩΝ: %d μαθητές δεν συμπλήρωσαν τις %d ώρες.\n", nrow(students_not_reached_target), required_hours)) } else { cat("\nΤερματισμός: Όλοι οι μαθητές έχουν συμπληρώσει τις ώρες τους.\n") } break } # --- 2. Εντοπισμός Δημοφιλέστερου Ομίλου --- max_count <- max(counts$FirstPrefCount) if (max_count == 0) { cat("Δεν υπάρχουν πλέον πρώτες προτιμήσεις για ενεργούς Ομίλους. Τερματισμός.\n") break } pop_candidates <- counts |> filter(FirstPrefCount == max_count) club_to_select <- sort(pop_candidates$ClubID)[1] match_idx <- match(club_to_select, clubs$club_id) club_name <- clubs$club_name[match_idx] club_hours <- clubs$hours[match_idx] cat(sprintf("-> Δημοφιλέστερος Όμιλος: %s (%s) με %d **πρώτες** προτιμήσεις (Ώρες: %d).\n", club_to_select, club_name, max_count, club_hours)) # --- 3. Διεύρυνση Pool Υποψηφίων (ΛΟΓΙΚΗ ΕΛΑΧΙΣΤΟΥ 15) --- students_for_club_pool <- current_prefs |> filter(ClubID == club_to_select) |> pull(all_of(student_col)) if(length(students_for_club_pool) < min_pool_size) { cat(sprintf("-> Οι πρώτες προτιμήσεις (%d) είναι < %d. Αναζήτηση σε χαμηλότερα ranks...\n", length(students_for_club_pool), min_pool_size)) club_rankings <- responses_long_master |> filter(ClubID == club_to_select) |> filter(get(student_col) %in% active_students) |> arrange(Rank) |> select(all_of(student_col), Rank) max_rank_to_include <- club_rankings$Rank[min(nrow(club_rankings), min_pool_size)] students_for_club_pool <- club_rankings |> filter(Rank <= max_rank_to_include) |> pull(all_of(student_col)) cat(sprintf("-> Το pool διευρύνθηκε για να συμπεριλάβει μαθητές μέχρι την %dη προτίμηση (Συνολικά: %d υποψήφιοι).\n", max_rank_to_include, length(students_for_club_pool))) } # --- 4. Αυτόματη Επιλογή 15 Μαθητών (Προσομοίωση) --- if (length(students_for_club_pool) > 0) { num_to_select <- min(auto_select_count, length(students_for_club_pool)) final_selected_students <- sample(students_for_club_pool, size = num_to_select, replace = FALSE) cat(sprintf("-> Επιλέγονται τυχαία %d μαθητές από το pool.\n", num_to_select)) } else { final_selected_students <- character(0) } # --- 5. Καταχώρηση και Μεταφορά Ψήφων --- if(length(final_selected_students) > 0) { new_assignments <- data.frame(StudentID = final_selected_students, ClubID = club_to_select, ClubName = club_name, stringsAsFactors = FALSE) colnames(new_assignments)[1] <- student_col club_assignments <- bind_rows(club_assignments, new_assignments) for (sid in final_selected_students) { student_hours[student_hours[[student_col]] == sid, "HoursAssigned"] <- student_hours[student_hours[[student_col]] == sid, "HoursAssigned"] + club_hours } cat(sprintf("-> Καταχωρήθηκαν %d μαθητές στον Όμιλο %s.\n", length(final_selected_students), club_name)) assignment_file <- sprintf("%s_%s.csv", output_prefix_assignments, club_to_select) write_csv(new_assignments, assignment_file) } # Αφαίρεση του Ομίλου από τη λίστα των ενεργών (Βάσει του Κανόνα του Χρήστη) active_clubs <- setdiff(active_clubs, club_to_select) # --- 6. Ενημέρωση Ranks (Μεταφορά Ψήφων) --- responses_long_master <- responses_long_master |> mutate(Rank = ifelse(ClubID == club_to_select, NA_integer_, Rank)) |> filter(!is.na(Rank)) responses_long_master <- responses_long_master |> group_by(across(all_of(student_col))) |> mutate(Rank = rank(Rank, ties.method = "min")) |> ungroup() # --- 7. Αποθήκευση Ενδιάμεσων Αρχείων --- write_csv(student_hours, "student_hours_log.csv") round <- round + 1L } # --- Τελική Καταγραφή & Νέο Αρχείο (Student Club List) --- cat("\nΟλοκληρώθηκε η διαδικασία κατανομής.\n") write_csv(club_assignments, "club_assignments_final.csv") # --- ΒΗΜΑ 8: ΔΗΜΙΟΥΡΓΙΑ ΑΡΧΕΙΟΥ ΜΕ ΛΙΣΤΑ ΟΜΙΛΩΝ ΑΝΑ ΜΑΘΗΤΗ --- student_club_list <- club_assignments |> # Ομαδοποίηση ανά μαθητή group_by(across(all_of(student_col))) |> # Συνένωση των ClubName σε μία συμβολοσειρά, χωρισμένη με κόμμα summarise( Clubs_Assigned = paste(ClubName, collapse = ", "), .groups = 'drop' ) # Ενσωμάτωση των συνολικών ωρών για πληρέστερη εικόνα student_club_list <- student_club_list |> left_join(student_hours, by = student_col) |> select(all_of(student_col), Clubs_Assigned, HoursAssigned) # Αποθήκευση του νέου αρχείου write_csv(student_club_list, "student_club_list.csv") cat("Δημιουργήθηκε το αρχείο: student_club_list.csv (Λίστα Ομίλων ανά Μαθητή)\n") # --- ΒΗΜΑ 9: ΕΥΡΕΣΗ ΟΜΙΛΩΝ ΜΕ ΛΙΓΟΤΕΡΟΥΣ ΑΠΟ 10 ΜΑΘΗΤΕΣ --- # Υπολογίζουμε τους μαθητές ανά Όμιλο clubs_less_than_10 <- club_assignments |> # Ομαδοποίηση ανά όνομα Ομίλου group_by(ClubName) |> # Καταμέτρηση των αναθέσεων (μαθητών) summarise( Students_Count = n(), .groups = 'drop' ) |> # Φιλτράρισμα μόνο για όσους έχουν λιγότερους από 10 μαθητές filter(Students_Count < 10) |> # Ταξινόμηση για ευκολότερη επισκόπηση arrange(Students_Count, ClubName) # Εκτύπωση αποτελεσμάτων στην κονσόλα cat("\n\n--- ΟΜΙΛΟΙ ΜΕ ΛΙΓΟΤΕΡΟΥΣ ΑΠΟ 10 ΜΑΘΗΤΕΣ ---\n") print(clubs_less_than_10) # Αποθήκευση του αποτελέσματος σε αρχείο CSV write_csv(clubs_less_than_10, "clubs_less_than_10_students.csv") cat("\nΑποθηκεύτηκαν τα αποτελέσματα στο: clubs_less_than_10_students.csv\n")
Mark as private (unlisted)
for 30 minutes
for 6 hours
for 1 day
for 1 week
for 1 month
for 1 year
everlasting (like CCCP)