Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/inspectionProfiles/profiles_settings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions .idea/safebodarwanda.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Empty file added Backend/safe_boda/.github/.keep
Empty file.
2 changes: 2 additions & 0 deletions Backend/safe_boda/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[![Review Assignment Due Date](https://classroom.github.com/assets/deadline-readme-button-22041afd0340ce965d47ae6ef1cefeee28c7c493a6346c4f15d667ab976d596c.svg)](https://classroom.github.com/a/QaSr7QEi)
[![Open in Codespaces](https://classroom.github.com/assets/launch-codespace-2972f46106e565e64193e422d61a12cf1da4916b45550586e14ef0a7c637dd04.svg)](https://classroom.github.com/open-in-codespaces?assignment_repo_id=21159337)
Empty file.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
3 changes: 3 additions & 0 deletions Backend/safe_boda/api/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.contrib import admin

# Register your models here.
6 changes: 6 additions & 0 deletions Backend/safe_boda/api/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class ApiConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'api'
59 changes: 59 additions & 0 deletions Backend/safe_boda/api/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Generated by Django 5.2.7 on 2025-10-19 15:43

import django.contrib.auth.models
import django.contrib.auth.validators
import django.db.models.deletion
import django.utils.timezone
from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):

initial = True

dependencies = [
('auth', '0012_alter_user_first_name_max_length'),
]

operations = [
migrations.CreateModel(
name='CustomUser',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('password', models.CharField(max_length=128, verbose_name='password')),
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')),
('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')),
('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')),
('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')),
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
('user_type', models.CharField(choices=[('RIDER', 'Rider'), ('DRIVER', 'Driver')], max_length=10)),
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')),
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')),
],
options={
'verbose_name': 'user',
'verbose_name_plural': 'users',
'abstract': False,
},
managers=[
('objects', django.contrib.auth.models.UserManager()),
],
),
migrations.CreateModel(
name='Trip',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('pickup_location', models.CharField(max_length=255)),
('dropoff_location', models.CharField(max_length=255)),
('status', models.CharField(choices=[('REQUESTED', 'Requested'), ('IN_PROGRESS', 'In Progress'), ('COMPLETED', 'Completed')], default='REQUESTED', max_length=20)),
('created_at', models.DateTimeField(auto_now_add=True)),
('driver', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='driver_trips', to=settings.AUTH_USER_MODEL)),
('rider', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='rider_trips', to=settings.AUTH_USER_MODEL)),
],
),
]
Empty file.
Binary file not shown.
Binary file not shown.
194 changes: 194 additions & 0 deletions Backend/safe_boda/api/migrations/program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
using System;
using System.Collections.Generic;

namespace RidehailingApp
{

//1. Create the Driver Class
public class Driver
{
public string Name { get; set; }
public string MotoPlateNumber { get; set; }
public bool IsAvailable { get; set; }

public Driver(string name, string motoPlateNumber, bool isAvailable)
{
Name = name;
MotoPlateNumber = motoPlateNumber;
IsAvailable = isAvailable;
}

public override string ToString()
{
return $"Driver Name: {Name}, Moto Plate Number: {MotoPlateNumber}, Availability: {(IsAvailable ? "Available" : "Not Available")}";
}
}
// 2. Create the Passenger
public class Passenger
{
public string Name { get; set; }
public Passenger(string name)
{
Name = name;
}
}

public class RideService
{
private List<Driver> drivers;
private List<Passenger> passengers;

//3. Create the RideService Class
public RideService()
{
drivers = new List<Driver>();
passengers = new List<Passenger>();
}

public void RegisterDriver(Driver driver)
{
if (driver == null) throw new ArgumentNullException(nameof(driver));
drivers.Add(driver);
}

public void RegisterPassenger(Passenger passenger)
{
if (passenger == null) throw new ArgumentNullException(nameof(passenger));
passengers.Add(passenger);
}

public IReadOnlyList<Driver> GetAvailableDrivers() => drivers.AsReadOnly();
public IReadOnlyList<Passenger> GetRegisteredPassengers() => passengers.AsReadOnly();
}
//4. Implement the Main Application Logic
class Program
{
static void Main(string[] args)
{
var rideService = new RideService();
bool exitRequested = false;

while (!exitRequested)
{
Console.WriteLine("\n=== Ride Hailing Service Menu ===");
Console.WriteLine("1. Register Driver");
Console.WriteLine("2. Register Passenger");
Console.WriteLine("3. List Drivers");
Console.WriteLine("4. List Passengers");
Console.WriteLine("5. Exit");
Console.Write("Choose an option (1-5): ");

string choice = Console.ReadLine()?.Trim();

switch (choice)
{
case "1":
RegisterDriverFlow(rideService);
break;
case "2":
RegisterPassengerFlow(rideService);
break;
case "3":
ListDrivers(rideService);
break;
case "4":
ListPassengers(rideService);
break;
case "5":
exitRequested = true;
Console.WriteLine("Exiting the application. Goodbye!");
break;
default:
Console.WriteLine("Invalid choice. Please enter a number between 1 and 5.");
break;
}
}

Console.WriteLine("Thank you for using the Ride Hailing Service. Goodbye!");
}
//5. Implement User Interaction
static void RegisterDriverFlow(RideService rideService)
{
Console.WriteLine("\n--- Register Driver ---");
Console.Write("Enter Driver Name: ");
string name = Console.ReadLine()?.Trim();
Console.Write("Moto Plate Number: ");
string plate = Console.ReadLine()?.Trim();

bool isAvailable = AskBoolean("Is the driver available? (yes/no): ");
var driver = new Driver(name, plate, isAvailable);
rideService.RegisterDriver(driver);

Console.WriteLine("Driver registered successfully!");
}
//6. Implement Passenger Registration

static void RegisterPassengerFlow(RideService rideService)
{
Console.WriteLine("\n--- Register Passenger ---");
Console.Write("Enter Passenger Name: ");
string name = Console.ReadLine()?.Trim();

var passenger = new Passenger(name);
rideService.RegisterPassenger(passenger);

Console.WriteLine("Passenger registered successfully!");
}
//7. Implement Driver Listing
static void ListDrivers(RideService rideService)
{
Console.WriteLine("\n--- List of Registered Drivers ---");
var drivers = rideService.GetAvailableDrivers();
if (drivers.Count == 0)
{
Console.WriteLine("No drivers registered yet.");
return;
}

for (int i = 0; i < drivers.Count; i++)
{
Console.WriteLine($"{i + 1}. {drivers[i]}");
}
}
//8. Implement Passenger Listing
static void ListPassengers(RideService rideService)
{
Console.WriteLine("\n--- List of Registered Passengers ---");
var passengers = rideService.GetRegisteredPassengers();
if (passengers.Count == 0)
{
Console.WriteLine("No passengers registered yet.");
return;
}

for (int i = 0; i < passengers.Count; i++)
{
Console.WriteLine($"{i + 1}. {passengers[i].Name}");
}
}
//9. Implement Boolean Input Helper
static bool AskBoolean(string prompt)
{
while (true)
{
Console.Write(prompt);
string input = Console.ReadLine()?.Trim().ToLower();

if (string.IsNullOrEmpty(input))
{
Console.WriteLine("Please enter yes or no.");
continue;
}

if (input == "yes" || input == "y" || input == "true" || input == "t")
return true;
if (input == "no" || input == "n" || input == "false" || input == "f")
return false;

Console.WriteLine("Invalid input. Please enter yes or no.");
}
}
}
}


43 changes: 43 additions & 0 deletions Backend/safe_boda/api/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from django.db import models
from django.contrib.auth.models import AbstractUser


class CustomUser(AbstractUser):
USER_TYPE_CHOICES = (
('RIDER', 'Rider'),
('DRIVER', 'Driver'),
)
user_type = models.CharField(max_length=10, choices=USER_TYPE_CHOICES)

def __str__(self):
return f"{self.username} ({self.user_type})"


class Trip(models.Model):
rider = models.ForeignKey(
CustomUser,
on_delete=models.CASCADE,
related_name='rider_trips'
)
driver = models.ForeignKey(
CustomUser,
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name='driver_trips'
)
pickup_location = models.CharField(max_length=255)
dropoff_location = models.CharField(max_length=255)
status = models.CharField(
max_length=20,
choices=[
('REQUESTED', 'Requested'),
('IN_PROGRESS', 'In Progress'),
('COMPLETED', 'Completed'),
],
default='REQUESTED'
)
created_at = models.DateTimeField(auto_now_add=True)

def __str__(self):
return f"Trip {self.id} - {self.status}"
14 changes: 14 additions & 0 deletions Backend/safe_boda/api/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from rest_framework import serializers
from .models import CustomUser, Trip


class UserSerializer(serializers.ModelSerializer):
class Meta:
model = CustomUser
fields = "__all__"


class TripSerializer(serializers.ModelSerializer):
class Meta:
model = Trip
fields = "__all__"
3 changes: 3 additions & 0 deletions Backend/safe_boda/api/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.test import TestCase

# Create your tests here.
11 changes: 11 additions & 0 deletions Backend/safe_boda/api/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import UserViewSet, TripViewSet

router = DefaultRouter()
router.register(r'users', UserViewSet)
router.register(r'trips', TripViewSet)

urlpatterns = [
path('', include(router.urls)),
]
Loading