# =============================================================================
# NAME: [Your Name]
# TITLE: ACCA7022 - Advanced Statistical Programming - Component 1
# FILE: Data Manipulation - Smart City Utilities Operations Simulation
# DATE: May 2026
# PURPOSE: Simulate, manipulate, and summarise operational output data for
#          six utility services across 30 days using loops only (no aggregation
#          functions like apply(), aggregate(), rowSums(), colSums(), etc.)
# =============================================================================

# ------------------------- A. Generate Production Data -------------------------
# Create an empty dataframe with the required columns
production_data <- data.frame(Day = integer(),
                              Utility = integer(),
                              Team = integer(),
                              Output = numeric(),
                              stringsAsFactors = FALSE)

# Nested loops: Day (1-30), Utility (1-6), Team (1-5)
# Using sample() for random integer generation between -5 and +5
for (day in 1:30) {
  for (util in 1:6) {
    for (team in 1:5) {
      # Random integer between -5 and +5
      RandomNoise <- sample(-5:5, 1)
      BaseOutput <- 40
      Output <- BaseOutput + RandomNoise
      
      # Add row to dataframe using rbind
      new_row <- data.frame(Day = day,
                            Utility = util,
                            Team = team,
                            Output = Output)
      production_data <- rbind(production_data, new_row)
    }
  }
}

# Display first 10 rows
cat("First 10 rows of production_data:\n")
print(head(production_data, 10))

# ------------------------- B. Total Production per Utility -------------------------
# Create empty dataframe for utility totals
Utility_totals <- data.frame(Utility = integer(),
                             TotalOutput = numeric(),
                             stringsAsFactors = FALSE)

# Loop over each Utility (1 to 6)
for (util in 1:6) {
  total <- 0
  # Sum outputs for this utility across all days and teams
  for (day in 1:30) {
    for (team in 1:5) {
      # Find matching row using nested loops only
      for (row_idx in 1:nrow(production_data)) {
        if (production_data[row_idx, "Day"] == day &&
            production_data[row_idx, "Utility"] == util &&
            production_data[row_idx, "Team"] == team) {
          total <- total + production_data[row_idx, "Output"]
        }
      }
    }
  }
  Utility_totals <- rbind(Utility_totals, data.frame(Utility = util, TotalOutput = total))
}

cat("\nUtility_totals:\n")
print(Utility_totals)

# ------------------------- C. Detect Production Anomalies -------------------------
# Create empty dataframe for anomalies
anomalies <- data.frame(Day = integer(),
                        Utility = integer(),
                        Team = integer(),
                        Output = numeric(),
                        Anomaly = logical(),
                        stringsAsFactors = FALSE)

# Loop over each day and utility to calculate daily average per utility
for (day in 1:30) {
  for (util in 1:6) {
    # Sum outputs for this utility on this day across all 5 teams
    daily_sum <- 0
    for (team in 1:5) {
      for (row_idx in 1:nrow(production_data)) {
        if (production_data[row_idx, "Day"] == day &&
            production_data[row_idx, "Utility"] == util &&
            production_data[row_idx, "Team"] == team) {
          daily_sum <- daily_sum + production_data[row_idx, "Output"]
        }
      }
    }
    # Calculate daily average as sum of all teams divided by 4 (per specification)
    daily_avg <- daily_sum / 4
    
    # Check each team's output for anomaly
    for (team in 1:5) {
      team_output <- NA
      for (row_idx in 1:nrow(production_data)) {
        if (production_data[row_idx, "Day"] == day &&
            production_data[row_idx, "Utility"] == util &&
            production_data[row_idx, "Team"] == team) {
          team_output <- production_data[row_idx, "Output"]
        }
      }
      # Calculate absolute percentage deviation from daily utility average
      deviation <- abs(team_output - daily_avg) / daily_avg
      # Mark anomaly if deviation exceeds 10% (0.10)
      anomaly_flag <- (deviation > 0.10)
      
      anomalies <- rbind(anomalies, data.frame(Day = day,
                                               Utility = util,
                                               Team = team,
                                               Output = team_output,
                                               Anomaly = anomaly_flag))
    }
  }
}

cat("\nFirst 10 anomalies detected:\n")
print(head(anomalies, 10))

# ------------------------- D. Identify Peak Productivity Days -------------------------
# Create empty dataframe for peak days
peak_days <- data.frame(Utility = integer(),
                        Day = integer(),
                        TotalOutput = numeric(),
                        stringsAsFactors = FALSE)

# For each utility, find the day with maximum total output across all teams
for (util in 1:6) {
  max_total <- -Inf
  peak_day <- NA
  for (day in 1:30) {
    # Sum total output for this utility on this day across all 5 teams
    daily_total <- 0
    for (team in 1:5) {
      for (row_idx in 1:nrow(production_data)) {
        if (production_data[row_idx, "Day"] == day &&
            production_data[row_idx, "Utility"] == util &&
            production_data[row_idx, "Team"] == team) {
          daily_total <- daily_total + production_data[row_idx, "Output"]
        }
      }
    }
    # Update maximum if current day's total is higher
    if (daily_total > max_total) {
      max_total <- daily_total
      peak_day <- day
    }
  }
  peak_days <- rbind(peak_days, data.frame(Utility = util, Day = peak_day, TotalOutput = max_total))
}

cat("\nPeak productivity days:\n")
print(peak_days)

# ------------------------- E. Calculate Efficiency Score -------------------------
# Add new column EfficiencyScore to production_data
# Formula: (Output - 40) / 40
# This represents the proportional deviation from the base output of 40
production_data$EfficiencyScore <- NA

for (row_idx in 1:nrow(production_data)) {
  output_val <- production_data[row_idx, "Output"]
  efficiency <- (output_val - 40) / 40
  production_data[row_idx, "EfficiencyScore"] <- efficiency
}

cat("\nFirst 10 rows of updated production_data with EfficiencyScore:\n")
print(head(production_data, 10))

# =============================================================================
# END OF CODE
# =============================================================================