{"nbformat":4,"nbformat_minor":0,"metadata":{"colab":{"provenance":[],"authorship_tag":"ABX9TyO8q2D+/JTDEpEU215YwzAt"},"kernelspec":{"name":"ir","display_name":"R"},"language_info":{"name":"R"}},"cells":[{"cell_type":"code","source":["# ============================================================\n","# Name:    Vivek\n","# Title:   Smart City Utilities Operations Simulation\n","# Purpose: Data Manipulation Assignment - Task 1 (ACCA7022)\n","# Date:    June 2026\n","# ============================================================\n","\n","# Set seed for reproducibility\n","set.seed(42)\n","\n","# ============================================================\n","# PART A: Generate Production Data\n","# ============================================================\n","\n","# Define simulation parameters\n","n_days      <- 30   # 30 days of operation\n","n_utilities <- 6    # 6 utility services\n","n_teams     <- 5    # 5 operational teams per utility\n","base_output <- 40   # Base output value for all teams\n","\n","# Calculate total number of rows: 30 days x 6 utilities x 5 teams\n","total_rows <- n_days * n_utilities * n_teams  # = 900\n","\n","# Pre-allocate vectors to hold each column of the data frame\n","day_col     <- integer(total_rows)\n","utility_col <- integer(total_rows)\n","team_col    <- integer(total_rows)\n","output_col  <- numeric(total_rows)\n","\n","# Use a single index counter to fill each row position\n","row_index <- 1\n","\n","# Nested loops: iterate over every combination of Day, Utility, and Team\n","for (day in 1:n_days) {\n","  for (utility in 1:n_utilities) {\n","    for (team in 1:n_teams) {\n","\n","      # Generate random noise: integer between -5 and +5 (inclusive)\n","      random_noise <- sample(-5:5, size = 1)\n","\n","      # Calculate output using the formula:\n","      # Output = BaseOutput + (UtilityID * 3) + (TeamID * 2) + RandomNoise\n","      output_value <- base_output + (utility * 3) + (team * 2) + random_noise\n","\n","      # Store values into the pre-allocated vectors at the current row position\n","      day_col[row_index]     <- day\n","      utility_col[row_index] <- utility\n","      team_col[row_index]    <- team\n","      output_col[row_index]  <- output_value\n","\n","      # Move to the next row\n","      row_index <- row_index + 1\n","    }\n","  }\n","}\n","\n","# Assemble the data frame from the populated vectors\n","production_data <- data.frame(\n","  Day     = day_col,\n","  Utility = utility_col,\n","  Team    = team_col,\n","  Output  = output_col\n",")\n","\n","# Display the first 10 rows to verify the structure\n","cat(\"=== Part A: First 10 rows of production_data ===\\n\")\n","print(production_data[1:10, ])\n","cat(\"\\n\")\n","\n","\n","# ============================================================\n","# PART B: Total Production per Utility\n","# ============================================================\n","\n","# Pre-allocate vectors for Utility_totals data frame\n","utility_ids   <- integer(n_utilities)\n","total_outputs <- numeric(n_utilities)\n","\n","# Loop over each utility and accumulate output across all days and teams\n","for (utility in 1:n_utilities) {\n","  utility_ids[utility] <- utility\n","  running_total <- 0\n","\n","  # Loop over every row in production_data\n","  for (row in 1:nrow(production_data)) {\n","\n","    # Add this row's output only if it belongs to the current utility\n","    if (production_data$Utility[row] == utility) {\n","      running_total <- running_total + production_data$Output[row]\n","    }\n","  }\n","\n","  # Store the accumulated total for this utility\n","  total_outputs[utility] <- running_total\n","}\n","\n","# Build the Utility_totals data frame\n","Utility_totals <- data.frame(\n","  Utility     = utility_ids,\n","  TotalOutput = total_outputs\n",")\n","\n","# Display the result\n","cat(\"=== Part B: Total Production per Utility ===\\n\")\n","print(Utility_totals)\n","cat(\"\\n\")\n","\n","\n","# ============================================================\n","# PART C: Detect Production Anomalies\n","# ============================================================\n","\n","# Pre-allocate vectors for the anomalies data frame\n","# (same length as production_data; we will flag each row)\n","anom_day     <- integer(total_rows)\n","anom_utility <- integer(total_rows)\n","anom_team    <- integer(total_rows)\n","anom_output  <- numeric(total_rows)\n","anom_flag    <- logical(total_rows)\n","\n","# Outer loop: iterate over each unique Day\n","for (day in 1:n_days) {\n","\n","  # Inner loop: iterate over each unique Utility\n","  for (utility in 1:n_utilities) {\n","\n","    # Step 1 – sum the outputs for this (day, utility) combination\n","    day_utility_sum <- 0\n","    count           <- 0\n","\n","    for (row in 1:total_rows) {\n","      if (production_data$Day[row] == day &&\n","          production_data$Utility[row] == utility) {\n","        day_utility_sum <- day_utility_sum + production_data$Output[row]\n","        count           <- count + 1\n","      }\n","    }\n","\n","    # Step 2 – calculate the daily average for this utility\n","    # The specification states: sum of all teams divided by 4\n","    daily_avg <- day_utility_sum / 4\n","\n","    # Step 3 – check each team's output against the daily average\n","    for (row in 1:total_rows) {\n","      if (production_data$Day[row] == day &&\n","          production_data$Utility[row] == utility) {\n","\n","        team_output    <- production_data$Output[row]\n","\n","        # Deviation as an absolute percentage from daily average\n","        deviation_pct  <- abs(team_output - daily_avg) / daily_avg\n","\n","        # Mark TRUE if deviation exceeds 10%\n","        is_anomaly     <- deviation_pct > 0.10\n","\n","        # Store results in the anomaly vectors\n","        anom_day[row]     <- day\n","        anom_utility[row] <- utility\n","        anom_team[row]    <- production_data$Team[row]\n","        anom_output[row]  <- team_output\n","        anom_flag[row]    <- is_anomaly\n","      }\n","    }\n","  }\n","}\n","\n","# Assemble the anomalies data frame\n","anomalies <- data.frame(\n","  Day     = anom_day,\n","  Utility = anom_utility,\n","  Team    = anom_team,\n","  Output  = anom_output,\n","  Anomaly = anom_flag\n",")\n","\n","# Display the first 10 detected anomalies (rows where Anomaly == TRUE)\n","cat(\"=== Part C: First 10 Anomalies Detected ===\\n\")\n","anomaly_rows <- integer(0)    # will collect row indices of anomalies\n","for (row in 1:nrow(anomalies)) {\n","  if (anomalies$Anomaly[row] == TRUE) {\n","    anomaly_rows <- c(anomaly_rows, row)\n","  }\n","}\n","print(anomalies[anomaly_rows[1:10], ])\n","cat(\"\\n\")\n","\n","\n","# ============================================================\n","# PART D: Identify Peak Productivity Days\n","# ============================================================\n","\n","# Pre-allocate vectors for the peak_days data frame\n","peak_utility <- integer(n_utilities)\n","peak_day     <- integer(n_utilities)\n","peak_output  <- numeric(n_utilities)\n","\n","# Loop over each utility to find the day with the maximum total output\n","for (utility in 1:n_utilities) {\n","\n","  best_day        <- NA\n","  best_day_output <- -Inf   # initialise to negative infinity\n","\n","  # Loop over each day\n","  for (day in 1:n_days) {\n","\n","    # Accumulate total output for (utility, day) across all teams\n","    day_total <- 0\n","    for (row in 1:total_rows) {\n","      if (production_data$Utility[row] == utility &&\n","          production_data$Day[row] == day) {\n","        day_total <- day_total + production_data$Output[row]\n","      }\n","    }\n","\n","    # Update best day if this day's total exceeds the current maximum\n","    if (day_total > best_day_output) {\n","      best_day_output <- day_total\n","      best_day        <- day\n","    }\n","  }\n","\n","  # Store results for this utility\n","  peak_utility[utility] <- utility\n","  peak_day[utility]     <- best_day\n","  peak_output[utility]  <- best_day_output\n","}\n","\n","# Build the peak_days data frame\n","peak_days <- data.frame(\n","  Utility     = peak_utility,\n","  Day         = peak_day,\n","  TotalOutput = peak_output\n",")\n","\n","# Display peak_days\n","cat(\"=== Part D: Peak Productivity Days per Utility ===\\n\")\n","print(peak_days)\n","cat(\"\\n\")\n","\n","\n","# ============================================================\n","# PART E: Calculate Efficiency Score\n","# ============================================================\n","\n","# Add EfficiencyScore column to production_data\n","# Formula: EfficiencyScore = (Output / utility + team)\n","# We use a loop to calculate and assign one row at a time\n","\n","efficiency_scores <- numeric(total_rows)\n","\n","for (row in 1:total_rows) {\n","  efficiency_scores[row] <- (production_data$Output[row] / utility + team)\n","}\n","\n","# Append the new column to the existing data frame\n","production_data$EfficiencyScore <- efficiency_scores\n","\n","# Display the first 10 rows showing the new column\n","cat(\"=== Part E: First 10 rows of production_data with EfficiencyScore ===\\n\")\n","print(production_data[1:10, ])\n","cat(\"\\n\")\n","\n","\n"],"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"cHMrKaz7Eo0g","executionInfo":{"status":"ok","timestamp":1782467061241,"user_tz":-60,"elapsed":765,"user":{"displayName":"Vivek nelapati","userId":"11760536282152039558"}},"outputId":"90c150d6-4252-442e-c92c-90e24714aa7c"},"execution_count":5,"outputs":[{"output_type":"stream","name":"stdout","text":["=== Part A: First 10 rows of production_data ===\n","   Day Utility Team Output\n","1    1       1    1     40\n","2    1       1    2     46\n","3    1       1    3     44\n","4    1       1    4     54\n","5    1       1    5     57\n","6    1       2    1     46\n","7    1       2    2     46\n","8    1       2    3     56\n","9    1       2    4     49\n","10   1       2    5     58\n","\n","=== Part B: Total Production per Utility ===\n","  Utility TotalOutput\n","1       1        7394\n","2       2        7729\n","3       3        8284\n","4       4        8722\n","5       5        9148\n","6       6        9566\n","\n","=== Part C: First 10 Anomalies Detected ===\n","   Day Utility Team Output Anomaly\n","1    1       1    1     40    TRUE\n","2    1       1    2     46    TRUE\n","3    1       1    3     44    TRUE\n","4    1       1    4     54    TRUE\n","6    1       2    1     46    TRUE\n","7    1       2    2     46    TRUE\n","8    1       2    3     56    TRUE\n","9    1       2    4     49    TRUE\n","11   1       3    1     52    TRUE\n","12   1       3    2     51    TRUE\n","\n","=== Part D: Peak Productivity Days per Utility ===\n","  Utility Day TotalOutput\n","1       1   2         260\n","2       2  27         271\n","3       3  17         296\n","4       4  24         308\n","5       5   9         317\n","6       6   4         339\n","\n","=== Part E: First 10 rows of production_data with EfficiencyScore ===\n","   Day Utility Team Output EfficiencyScore\n","1    1       1    1     40        11.66667\n","2    1       1    2     46        12.66667\n","3    1       1    3     44        12.33333\n","4    1       1    4     54        14.00000\n","5    1       1    5     57        14.50000\n","6    1       2    1     46        12.66667\n","7    1       2    2     46        12.66667\n","8    1       2    3     56        14.33333\n","9    1       2    4     49        13.16667\n","10   1       2    5     58        14.66667\n","\n"]}]},{"cell_type":"code","source":["# =====================================================\n","# Simulate Utility Team Output Data\n","# =====================================================\n","\n","# Set parameters\n","BaseOutput <- 40\n","n_days <- 30\n","n_utilities <- 6\n","n_teams <- 5\n","\n","# Calculate total number of observations\n","n_rows <- n_days * n_utilities * n_teams\n","\n","# Pre-allocate vectors\n","Day <- integer(n_rows)\n","Utility <- integer(n_rows)\n","Team <- integer(n_rows)\n","Output <- numeric(n_rows)\n","\n","# Initialize row counter\n","row_index <- 1\n","\n","# Generate data\n","for (day in 1:n_days) {\n","\n","  for (utility in 1:n_utilities) {\n","\n","    for (team in 1:n_teams) {\n","\n","      # Random noise between -5 and 5\n","      noise <- sample(-5:5, 1)\n","\n","      # Calculate output\n","      output_value <- BaseOutput + (utility * team) + noise\n","\n","      # Store values\n","      Day[row_index] <- day\n","      Utility[row_index] <- utility\n","      Team[row_index] <- team\n","      Output[row_index] <- output_value\n","\n","      # Move to next row\n","      row_index <- row_index + 1\n","    }\n","  }\n","}\n","\n","# Create data frame\n","production_data <- data.frame(\n","  Day,\n","  Utility,\n","  Team,\n","  Output\n",")\n","\n","# Display first 10 rows\n","print(head(production_data, 10))\n","\n","# Display dataset dimensions\n","cat(\"\\nDataset Dimensions:\", dim(production_data)[1],\n","    \"rows and\", dim(production_data)[2], \"columns\\n\")\n","\n","# Summary statistics\n","summary(production_data)"],"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":364},"id":"qF7643z5E2Zh","executionInfo":{"status":"ok","timestamp":1782467080256,"user_tz":-60,"elapsed":70,"user":{"displayName":"Vivek nelapati","userId":"11760536282152039558"}},"outputId":"a88bbe78-98f1-4724-ba34-80276b746e1e"},"execution_count":6,"outputs":[{"output_type":"stream","name":"stdout","text":["   Day Utility Team Output\n","1    1       1    1     36\n","2    1       1    2     39\n","3    1       1    3     45\n","4    1       1    4     49\n","5    1       1    5     41\n","6    1       2    1     38\n","7    1       2    2     45\n","8    1       2    3     50\n","9    1       2    4     48\n","10   1       2    5     49\n","\n","Dataset Dimensions: 900 rows and 4 columns\n"]},{"output_type":"display_data","data":{"text/plain":["      Day          Utility         Team       Output     \n"," Min.   : 1.0   Min.   :1.0   Min.   :1   Min.   :36.00  \n"," 1st Qu.: 8.0   1st Qu.:2.0   1st Qu.:2   1st Qu.:45.00  \n"," Median :15.5   Median :3.5   Median :3   Median :49.00  \n"," Mean   :15.5   Mean   :3.5   Mean   :3   Mean   :50.54  \n"," 3rd Qu.:23.0   3rd Qu.:5.0   3rd Qu.:4   3rd Qu.:56.00  \n"," Max.   :30.0   Max.   :6.0   Max.   :5   Max.   :75.00  "]},"metadata":{}}]}]}