Cafeteria Management System

Introduction

A cafeteria management system is a program designed to control and monitor students’ access to meals in the university cafeteria.
This project uses R programming to simulate a cafeteria system.

The system is designed to:

  • generate student IDs,
  • classify students as cafeteria or non-cafeteria,
  • check meal access based on time,
  • prevent repeated meal access,
  • and record attendance.

Step 1: Define Allowed Digits

The first step is to define the digits that can be used to create student IDs.

In this project, only the digits:

are allowed.

Code

# Define the allowed digits
digits <- 0:3

# Display the digits
digits
## [1] 0 1 2 3

Explanation

This code creates a vector called digits containing:

0 1 2 3

These digits will be used to generate all possible student IDs.


Step 2: Generate All Possible 4-Digit Student IDs

Now we generate all possible student IDs using the four allowed digits.

Since each ID has 4 digits, and each position can take 0, 1, 2, or 3, we generate all combinations.

Code

# Generate all possible 4-digit combinations
combinations <- expand.grid(
  d1 = digits,
  d2 = digits,
  d3 = digits,
  d4 = digits
)

# Display first few combinations
head(combinations)
##   d1 d2 d3 d4
## 1  0  0  0  0
## 2  1  0  0  0
## 3  2  0  0  0
## 4  3  0  0  0
## 5  0  1  0  0
## 6  1  1  0  0

Explanation

The function expand.grid() creates every possible combination of the four digits.

For example:

  • 0000
  • 0001
  • 0002
  • 0003
  • 0010
  • 0011

and so on.


Step 3: Combine the Digits into Student IDs

The combinations created above are still stored in separate columns.
Now we combine each row into a single 4-digit student ID.

Code

# Combine each row into one student ID
student_ids <- apply(combinations, 1, function(x) paste0(x, collapse = ""))

# Display first few student IDs
head(student_ids)
## [1] "0000" "1000" "2000" "3000" "0100" "1100"

Explanation

The apply() function works row by row.

For each row, paste0(..., collapse = "") joins the four digits into one string.

Example:

  • 0 0 0 0 becomes "0000"
  • 0 0 0 1 becomes "0001"

Step 4: Sort the Student IDs

Now we sort the IDs so that they appear in a neat order.

Code

# Sort student IDs
student_ids <- sort(student_ids)

# Display first few sorted IDs
head(student_ids)
## [1] "0000" "0001" "0002" "0003" "0010" "0011"
# Display last few sorted IDs
tail(student_ids)
## [1] "3322" "3323" "3330" "3331" "3332" "3333"

Explanation

This arranges the student IDs in ascending order, from:

  • 0000
  • 0001
  • 0002

up to:

  • 3333

Step 5: Count Total Number of Student IDs

Now we count how many student IDs were generated.

Code

# Count total number of student IDs
length(student_ids)
## [1] 256

Explanation

Because:

  • 4 choices for digit 1
  • 4 choices for digit 2
  • 4 choices for digit 3
  • 4 choices for digit 4

Total number of IDs is:

\[ 4 \times 4 \times 4 \times 4 = 256 \]

So the system generates 256 student IDs.


Step 6: Create the Main Student Database

Now we create the student database.

Each student will have:

The status will determine whether the student is allowed to eat in the cafeteria.

Rule:

  • If the ID starts with 0 or 2 → student is a cafeteria student
  • If the ID starts with 1 or 3 → student is a non-cafeteria student

Code

# Create the student database
students_db <- data.frame(
  id = student_ids,
  status = ifelse(grepl("^[02]", student_ids), "cafe", "non-cafe"),
  stringsAsFactors = FALSE
)

# Display first few rows
head(students_db)
##     id status
## 1 0000   cafe
## 2 0001   cafe
## 3 0002   cafe
## 4 0003   cafe
## 5 0010   cafe
## 6 0011   cafe

Explanation

data.frame()

This creates a table with two columns:

  • id
  • status

grepl("^[02]", student_ids)

This checks whether the student ID starts with:

  • 0
  • or 2

If yes → "cafe"
If no → "non-cafe"


Step 7: View Some Records from the Student Database

Now we inspect some records to make sure the classification works correctly.

Code

# Display first 20 student records
head(students_db, 20)
##      id status
## 1  0000   cafe
## 2  0001   cafe
## 3  0002   cafe
## 4  0003   cafe
## 5  0010   cafe
## 6  0011   cafe
## 7  0012   cafe
## 8  0013   cafe
## 9  0020   cafe
## 10 0021   cafe
## 11 0022   cafe
## 12 0023   cafe
## 13 0030   cafe
## 14 0031   cafe
## 15 0032   cafe
## 16 0033   cafe
## 17 0100   cafe
## 18 0101   cafe
## 19 0102   cafe
## 20 0103   cafe

Explanation

This helps us verify that the IDs are correctly classified.

For example:

  • 0000 → cafe
  • 0001 → cafe
  • 1000 → non-cafe
  • 2000 → cafe
  • 3000 → non-cafe

Step 8: Create an Attendance Log

Now we create an empty attendance log.

This log will record students who have successfully eaten.

The attendance log contains:

Code

# Initialize attendance log
attendance_log <- data.frame(
  id = character(),
  meal = character(),
  timestamp = character(),
  stringsAsFactors = FALSE
)

# Display attendance log
attendance_log
## [1] id        meal      timestamp
## <0 rows> (or 0-length row.names)

Explanation

At the beginning, the attendance log is empty because no student has eaten yet.


Step 9: Define Meal Time Rules

Now we define the cafeteria meal schedule.

Meal schedule:

  • Breakfast → 06:30 to 08:30
  • Lunch → 11:00 to 13:00
  • Dinner → 16:00 to 18:30

We create a function to check the time and return the correct meal.

Code

# Function to determine meal based on time
case_when_custom <- function(tm) {
  if (tm >= "06:30" && tm <= "08:30") return("Breakfast")
  if (tm >= "11:00" && tm <= "13:00") return("Lunch")
  if (tm >= "16:00" && tm <= "18:30") return("Dinner")
  return("none")
}

Explanation

This function takes a time (for example "07:00") and returns:

  • "Breakfast"
  • "Lunch"
  • "Dinner"
  • or "none" if the cafeteria is closed.

Step 10: Test the Meal Time Function

Before building the full cafeteria system, we test whether the meal-time function works correctly.

Code

# Test meal-time function
case_when_custom("07:00")
## [1] "Breakfast"
case_when_custom("12:00")
## [1] "Lunch"
case_when_custom("17:00")
## [1] "Dinner"
case_when_custom("14:00")
## [1] "none"

Explanation

Expected results:

  • "07:00" → Breakfast
  • "12:00" → Lunch
  • "17:00" → Dinner
  • "14:00" → none

Step 11: Build the Main Cafeteria Function

Now we create the main function called check_cafeteria().

This function performs all important checks.

It checks:

  1. Is the cafeteria open?
  2. Is the student ID registered?
  3. Is the student a cafeteria student?
  4. Has the student already eaten this meal?
  5. If all checks pass, grant access and record attendance.

Code

check_cafeteria <- function(input_id, test_time = NULL) {
  
  # Convert input into a 4-character ID
  input_id <- sprintf("%04d", as.integer(input_id))
  
  # Use current time or test time
  current_time <- if (is.null(test_time)) format(Sys.time(), "%H:%M") else test_time
  
  # Determine meal type
  meal_type <- case_when_custom(current_time)
  
  # 1. Check if cafeteria is open
  if (meal_type == "none") {
    return(sprintf("CLOSED: Current time is %s. Please return during meal hours.", current_time))
  }
  
  # 2. Check if student ID is registered
  if (!(input_id %in% students_db$id)) {
    return(sprintf("INVALID: ID %s is not registered.", input_id))
  }
  
  # 3. Check student status
  student_status <- students_db$status[students_db$id == input_id]
  
  if (student_status == "non-cafe") {
    return(sprintf("DENIED: ID %s is a Non-cafe student.", input_id))
  }
  
  # 4. Check repeated meal access
  already_eaten <- any(attendance_log$id == input_id & attendance_log$meal == meal_type)
  
  if (already_eaten) {
    return(sprintf("DENIED: ID %s already you have eaten %s today.", input_id, meal_type))
  }
  
  # 5. Record successful meal access
  new_entry <- data.frame(
    id = input_id,
    meal = meal_type,
    timestamp = current_time,
    stringsAsFactors = FALSE
  )
  
  attendance_log <<- rbind(attendance_log, new_entry)
  
  return(sprintf("SUCCESS: Welcome ID %s! Enjoy your %s.", input_id, meal_type))
}

Step 12: Explanation of the Main Function

Now let us explain the logic of the main cafeteria function step by step.


12.1 Standardizing the Student ID

sprintf("%04s", as.character("12"))
## [1] "  12"

Explanation

This ensures the ID is always treated as a 4-digit string.

For example:

  • 12 becomes " 12" in %04s, so for numeric-like IDs it’s better to pass them already as "0012" or use a stronger fix later if needed.

In our testing, we use full 4-digit IDs like:

  • "0000"
  • "2201"

So it works correctly.


12.2 Time Checking

The function checks whether the given time falls under:

  • Breakfast
  • Lunch
  • Dinner
  • Closed hours

If the cafeteria is closed, access is denied.


12.3 Registration Check

The function checks whether the ID exists in the student database.

If the ID is not found, the system returns:

"INVALID"

12.4 Eligibility Check

Even if the ID exists, the student may still be a non-cafeteria student.

If the student is classified as "non-cafe", access is denied.


12.5 Double Entry Check

A student is allowed to eat only once per meal.

So if a student already ate breakfast, they cannot eat breakfast again.

This is checked using:

any(attendance_log$id == input_id & attendance_log$meal == meal_type)

12.6 Successful Entry

If all checks pass:

  • the student is allowed to eat,
  • the student is recorded in the attendance log,
  • and a success message is returned.

Step 13: Test the Cafeteria System

Now we test the program using different situations.


Test 1: Valid Breakfast Access

print(check_cafeteria("0000", "07:00"))
## [1] "SUCCESS: Welcome ID 0000! Enjoy your Breakfast."

Explanation

  • ID "0000" exists
  • starts with 0 → cafeteria student
  • time "07:00" → Breakfast
  • student has not eaten yet

Expected Result

SUCCESS: Welcome ID 0000! Enjoy your Breakfast.

Test 2: Double Entry Attempt

print(check_cafeteria("0000", "07:30"))
## [1] "DENIED: ID 0000 already you have eaten Breakfast today."

Explanation

The same student "0000" tries to eat Breakfast again.

Expected Result

DENIED: ID 0000 already you have eaten Breakfast today.

Test 3: Non-Cafeteria Student

print(check_cafeteria("1000", "12:00"))
## [1] "DENIED: ID 1000 is a Non-cafe student."

Explanation

  • ID "1000" exists
  • starts with 1 → non-cafe student

Expected Result

DENIED: ID 1000 is a Non-cafe student.

Test 4: Invalid Student ID

print(check_cafeteria("9999", "12:00"))
## [1] "INVALID: ID 9999 is not registered."

Explanation

ID "9999" does not exist in the generated database.

Expected Result

INVALID: ID 9999 is not registered.

Test 5: Closed Hours Attempt

print(check_cafeteria("0112", "14:35"))
## [1] "CLOSED: Current time is 14:35. Please return during meal hours."

Explanation

  • "14:35" is outside:
    • Breakfast
    • Lunch
    • Dinner

Expected Result

CLOSED: Current time is 14:35. Please return during meal hours.

Test 6: Valid Dinner Access

print(check_cafeteria("2201", "17:35"))
## [1] "SUCCESS: Welcome ID 2201! Enjoy your Dinner."

Explanation

  • ID "2201" exists
  • starts with 2 → cafeteria student
  • time "17:35" → Dinner

Expected Result

SUCCESS: Welcome ID 2201! Enjoy your Dinner.

Test 7: Double Dinner Attempt

print(check_cafeteria("2201", "17:59"))
## [1] "DENIED: ID 2201 already you have eaten Dinner today."

Explanation

The same student tries to eat Dinner again.

Expected Result

DENIED: ID 2201 already you have eaten Dinner today.

Step 14: Run All Tests Together

Now we run all test cases together.

Code

print(check_cafeteria("0000", "07:00"))   # Valid Breakfast Access
## [1] "DENIED: ID 0000 already you have eaten Breakfast today."
print(check_cafeteria("0000", "07:30"))   # Double Entry Attempt
## [1] "DENIED: ID 0000 already you have eaten Breakfast today."
print(check_cafeteria("1000", "12:00"))   # Non-cafe Student
## [1] "DENIED: ID 1000 is a Non-cafe student."
print(check_cafeteria("9999", "12:00"))   # Invalid ID
## [1] "INVALID: ID 9999 is not registered."
print(check_cafeteria("0112", "14:35"))   # Closed Hours Attempt
## [1] "CLOSED: Current time is 14:35. Please return during meal hours."
print(check_cafeteria("2201", "17:35"))   # Dinner Access
## [1] "DENIED: ID 2201 already you have eaten Dinner today."
print(check_cafeteria("2201", "17:59"))   # Double Dinner Attempt
## [1] "DENIED: ID 2201 already you have eaten Dinner today."

Step 15: View Final Attendance Log

Now we display the attendance log after all successful entries.

Code

attendance_log
##     id      meal timestamp
## 1 0000 Breakfast     07:00
## 2 2201    Dinner     17:35

Explanation

This log should contain only students who were successfully allowed to eat.

For example:

  • "0000" at Breakfast
  • "2201" at Dinner

Only successful entries are stored.


Step 16: Summary of Program Logic

This program works in the following order:

  1. Generate all 4-digit student IDs
  2. Create student database
  3. Classify students as cafe or non-cafe
  4. Create attendance log
  5. Define meal-time schedule
  6. Check cafeteria access
  7. Prevent repeated access
  8. Record successful attendance

Step 17: Advantages of the System

This system helps in:


Step 18: Limitations of the Current System

This version still has some limitations:


Step 19: Recommendations for Improvement

This project can be improved in the future by adding:


Step 20: Conclusion

In conclusion, this Cafeteria Management System is a useful simulation program written in R.

The system successfully performs:

This makes the system suitable as a beginner-level university cafeteria management project.


R Markdown

This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more details on using R Markdown see http://rmarkdown.rstudio.com.

When you click the Knit button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:

Note that the echo = FALSE parameter was added to the code chunk to prevent printing of the R code that generated the plot.