친환경 이동수단 탄소 배출량 계산 CLI 프로그램
EBS Python 객체지향 프로그래밍 과제용 프로젝트입니다.
사용자가 출발지, 도착지, 이동 거리, 이동수단을 입력하면 탄소 배출량과 환경 등급을 계산하고, 상황에 맞는 안내 문구를 출력합니다.
외부 라이브러리는 사용하지 않으며, Python 표준 기능만으로 동작합니다.
- 프로젝트 목적
- 실행 방법
- 폴더 구조
- 프로그램 실행 흐름
- 핵심 계산 규칙
- 추천 로직
- 클래스 설계
- 파일별 상세 설명
- 모듈 호출 관계
- 수업 내용과의 연결
- 잘못된 입력 처리 예시
- 실행 시나리오 예시
- 같은 거리에서 수단별 비교
- 설계 포인트 요약
- 이동수단별 탄소 배출량을 계산한다.
- 내연기관차 대비 절감률을 보여준다.
- 환경 등급(A ~ F)을 판정한다.
- 거리와 선택 수단을 고려해 더 나은 이동수단을 안내하거나, 이미 좋은 선택이면 격려한다.
- 단순 계산기가 아니라 클래스 분리, 상속, 오버라이딩, 딕셔너리를 활용한 OOP 프로그램으로 구현한다.
프로젝트 루트에서 아래 명령으로 실행합니다.
python3 main.py또는
python3 src/main.py실행하면 터미널에 환영 문구가 나오고, 출발지부터 순서대로 입력을 받습니다.
py/
├── README.md # 이 설명서
├── main.py # 프로그램 실행 진입점
└── src/
├── main.py # src 기준 실행 진입점
├── data.py # 배출계수, 등급 기준 등 데이터
├── models.py # Vehicle 계층, Route, 객체 생성
├── calculator.py # 탄소/절감률/등급 계산
├── report.py # 결과 출력 및 추천 문구
└── app.py # 입력, 메뉴, 전체 실행 흐름
| 파일 | 역할 |
|---|---|
main.py |
EcoMoveApp 객체를 만들어 프로그램을 시작한다. |
data.py |
이동수단 정보와 등급 문구를 딕셔너리로 관리한다. |
models.py |
이동수단/경로 클래스를 정의하고 상속 구조를 구현한다. |
calculator.py |
배출량, 절감률, 환경 등급을 계산한다. |
report.py |
결과를 출력하고 추천/격려 문구를 만든다. |
app.py |
사용자 입력과 프로그램 전체 흐름을 제어한다. |
프로그램 시작
↓
환영 문구 출력
↓
출발지 입력
↓
도착지 입력
↓
이동 거리(km) 입력
↓
이동수단 선택
↓
탄소 배출량 계산
↓
내연기관차 대비 절감률 계산
↓
환경 등급 판정
↓
추천/격려 안내 출력
↓
다시 계산 여부 확인 (y/n)
↓
종료 또는 재실행
- 내연기관차
- 하이브리드차
- 전기차
- 버스
- 지하철
- 오토바이
- 자전거
- 도보
| 입력 | 규칙 | 실패 시 메시지 |
|---|---|---|
| 출발지 / 도착지 | 빈 문자열이면 안 됨 | 출발지를 입력해 주세요. / 도착지를 입력해 주세요. |
| 이동 거리 | 숫자이고 0보다 커야 함 | 숫자로 입력해 주세요. / 0보다 큰 값을 입력해 주세요. |
| 이동수단 번호 | 1 ~ 8 사이 정수 | 숫자로 입력해 주세요. / 1부터 8 사이의 번호를 입력해 주세요. |
| 다시 계산 | y/yes/ㅇ 또는 n/no/ㄴ |
y 또는 n을 입력해 주세요. |
배출량(kg) = 거리(km) × 배출계수(kg/km)
| 이동수단 | 배출계수 (kg/km) | 기본 계산 예시 (10km) |
|---|---|---|
| 내연기관차 | 0.192 | 1.92kg |
| 하이브리드차 | 0.121 | 1.21kg (실제는 오버라이딩 적용) |
| 전기차 | 0.053 | 0.53kg (실제는 오버라이딩 적용) |
| 버스 | 0.105 | 1.05kg |
| 지하철 | 0.041 | 0.41kg |
| 오토바이 | 0.103 | 1.03kg |
| 자전거 | 0.0 | 0.00kg |
| 도보 | 0.0 | 0.00kg |
일부 클래스는 기본 공식을 그대로 쓰지 않고 계산식을 재정의합니다.
| 클래스 | 계산식 | 10km 실제 배출량 |
|---|---|---|
HybridCar |
거리 × 계수 × 0.85 |
10 × 0.121 × 0.85 = 1.0285kg |
ElectricCar |
거리 × 계수 × 0.45 |
10 × 0.053 × 0.45 = 0.2385kg |
| 그 외 | 거리 × 계수 |
위 표의 기본값 |
같은 calculate_emission()을 호출해도 객체 종류에 따라 결과가 달라집니다.
이것이 다형성(Polymorphism) 입니다.
코드 예시:
# Vehicle (기본)
def calculate_emission(self, distance: float) -> float:
return distance * self.emission_factor
# HybridCar (오버라이딩)
def calculate_emission(self, distance: float) -> float:
return distance * self.emission_factor * 0.85
# ElectricCar (오버라이딩)
def calculate_emission(self, distance: float) -> float:
return distance * self.emission_factor * self.GRID_INTENSITY # 0.45절감률(%) = (내연기관차 배출량 - 선택 수단 배출량) / 내연기관차 배출량 × 100
- 비교 기준 이동수단은
내연기관차입니다. - 기준 배출량은
거리 × 0.192로 계산합니다. - 양수면
약 N% 감소, 음수면약 N% 증가로 표시합니다. - 내연기관차 본인을 선택하면
비교 기준: 내연기관차라고 출력합니다.
| 배출량 | 등급 | 기본 안내 문구 |
|---|---|---|
| 0kg | A | 탄소 배출이 거의 없습니다. |
| 0 초과 ~ 1kg 이하 | B | 탄소 배출이 낮은 편입니다. |
| 1 초과 ~ 2kg 이하 | C | 탄소 배출이 보통 수준입니다. |
| 2 초과 ~ 3kg 이하 | D | 탄소 배출이 다소 높습니다. |
| 3kg 초과 | F | 탄소 배출이 높은 편입니다. |
더 나은 추천 수단이 없으면, 등급 기본 문구 대신 아래 문구를 사용합니다.
이 거리에서는 이미 좋은 선택입니다.
report.py에서 현재 선택보다 배출량이 낮은 친환경 수단을 찾아 안내합니다.
- 도보
- 자전거
- 지하철
- 버스
| 조건 | 동작 |
|---|---|
| 이동 거리 5km 초과 | 도보를 추천하지 않음 |
| 이동 거리 10km 초과 | 자전거를 추천하지 않음 |
1. 추천 후보(도보/자전거/지하철/버스)인가?
2. 거리 제한에 걸리지 않는가?
3. 현재 선택보다 배출량이 낮은가?
→ 세 조건을 모두 만족하면 추천 목록에 추가
| 상황 | 안내 문구 |
|---|---|
| 더 나은 추천 수단이 있음 | OO보다 XX를 이용하면 탄소 배출을 더 줄일 수 있습니다. |
| 추천 없음 + 배출계수 0 | OO는 탄소를 배출하지 않습니다. 좋은 선택입니다. |
| 추천 없음 + 그 외 | OO 이용은 이 거리에서 적절한 선택입니다. 현재 잘하고 계십니다. |
Vehicle
├─ Car
│ ├─ GasolineCar # 내연기관차
│ ├─ HybridCar # 하이브리드차 (계산식 오버라이딩)
│ └─ ElectricCar # 전기차 (계산식 오버라이딩)
├─ Bus
├─ Subway
├─ Motorcycle
├─ Bicycle
└─ Walk
Route
CarbonCalculator
Report
EcoMoveApp
- 이동수단 이름과 배출계수를 저장한다.
calculate_emission(distance)로 배출량을 계산한다.is_eco_friendly()로 배출계수 0 여부를 판정한다.HybridCar,ElectricCar는 계산식을 오버라이딩한다.
- 출발지, 도착지, 이동 거리를 저장한다.
describe()로집 → 학교 (42km)형태의 문자열을 만든다.
- 배출량 계산
- 내연기관차 대비 절감률 계산
- 환경 등급 판정
- 결과 화면 출력
- 거리 조건을 반영한 추천 수단 탐색
- 추천/격려 안내 문구 생성
- 사용자 입력 처리
- 이동수단 메뉴 출력
- 한 번의 계산 흐름 실행
- 재실행 여부 확인
data.py의 카탈로그와 models.py의 매핑을 연결합니다.
KIND_TO_CLASS = {
"gasoline": GasolineCar,
"hybrid": HybridCar,
"electric": ElectricCar,
"bus": Bus,
"subway": Subway,
"motorcycle": Motorcycle,
"bicycle": Bicycle,
"walk": Walk,
}
def create_vehicle(name: str, info: dict) -> Vehicle:
vehicle_class = KIND_TO_CLASS[info["kind"]]
return vehicle_class(name=name, emission_factor=info["factor"])예: "지하철": {"factor": 0.041, "kind": "subway"}
→ Subway(name="지하철", emission_factor=0.041) 객체가 만들어집니다.
딕셔너리로 데이터를 관리합니다.
| 이름 | 내용 |
|---|---|
VEHICLE_CATALOG |
이동수단 이름 → {factor, kind} |
VEHICLE_ORDER |
메뉴에 표시할 순서 |
GRADE_THRESHOLDS |
등급 기준값 (A=0, B=1, C=2, D=3) |
GRADE_MESSAGES |
등급별 안내 문구 |
BASELINE_CAR_NAME |
절감률 비교 기준 (내연기관차) |
딕셔너리는 키로 값을 바로 찾을 수 있어 데이터 관리에 적합합니다.
Vehicle기본 클래스와 하위 클래스 정의KIND_TO_CLASS딕셔너리로kind→ 클래스 매핑create_vehicle()으로 카탈로그 데이터에서 객체 생성Route로 출발지·도착지·거리 보관
계산만 담당합니다. 출력이나 입력은 하지 않습니다.
def calculate_emission(self, vehicle: Vehicle, distance: float) -> float:
return vehicle.calculate_emission(distance) # 다형성
def calculate_reduction_rate(self, emission: float, distance: float) -> float:
car_emission = distance * self.car_factor # 0.192
return (car_emission - emission) / car_emission * 100
def get_grade(self, emission: float) -> str:
# A / B / C / D / F 판정계산 결과를 사람이 읽기 쉬운 형태로 출력합니다.
추천 가능 여부와 거리 제한도 여기서 판단합니다.
주요 메서드:
| 메서드 | 역할 |
|---|---|
is_recommendable() |
후보 + 거리 제한 검사 |
find_better_options() |
현재보다 배출 낮은 수단 목록 |
get_recommendation() |
안내 문구 생성 |
get_grade_message() |
등급 옆 한 줄 문구 |
print_result() |
최종 화면 출력 |
프로그램의 컨트롤러 역할을 합니다.
- 차량 목록 생성
- 경로 입력
- 이동수단 선택
- 계산 요청
- 결과 출력 요청
- 재실행 여부 확인
app = EcoMoveApp()
app.run()객체를 생성한 뒤 프로그램을 시작합니다.
main.py
└─ EcoMoveApp.run()
├─ show_welcome()
└─ while True:
├─ run_once()
│ ├─ input_route() → Route 생성
│ ├─ select_vehicle() → Vehicle 선택
│ ├─ calculator.calculate_emission()
│ ├─ calculator.calculate_reduction_rate()
│ ├─ calculator.get_grade()
│ └─ report.print_result()
│ ├─ find_better_options()
│ ├─ get_grade_message()
│ └─ get_recommendation()
└─ ask_continue() → False면 종료
역할이 나뉘어 있어, 계산 방식을 바꿔도 calculator.py만, 문구를 바꿔도 report.py/data.py만 수정하면 됩니다.
| 학습 내용 | 프로젝트 적용 |
|---|---|
| 불변 객체 | 문자열, 숫자 등 기본 값 사용 |
| 가변 객체 | 리스트, 딕셔너리로 데이터/목록 관리 |
| 제어문 | if/elif/else, 입력 검증, 등급 판정 |
| 반복문 | while(재입력/재실행), for(메뉴/비교) |
| 함수 | 기능별 메서드 분리 |
| 알고리즘 | 배출량, 절감률, 추천 수단 탐색 |
| 클래스 | 5개 이상 클래스 역할 분리 |
| 상속/오버라이딩 | Car 계열, Hybrid/Electric 계산식 |
| 딕셔너리 | 배출계수, 등급, 클래스 매핑 |
| 다형성 | 같은 메서드 호출, 객체별 다른 계산 결과 |
프로그램은 잘못된 입력을 받으면 다시 물어봅니다.
출발지:
출발지를 입력해 주세요.
출발지: 집
도착지:
도착지를 입력해 주세요.
도착지: 학교
이동 거리(km): abc
숫자로 입력해 주세요. (예: 15)
이동 거리(km): 0
0보다 큰 값을 입력해 주세요.
이동 거리(km): 5
이동수단을 선택해 주세요.
1. 내연기관차
...
8. 도보
번호: 9
1부터 8 사이의 번호를 입력해 주세요.
번호: 버스
숫자로 입력해 주세요.
번호: 4
(...결과 출력...)
다시 계산하시겠습니까? (y/n): maybe
y 또는 n을 입력해 주세요.
다시 계산하시겠습니까? (y/n): n
이용해 주셔서 감사합니다.
아래 예시는 실제 계산 규칙으로 나온 결과입니다.
CLI에 같은 값을 입력하면 동일한 결과를 확인할 수 있습니다.
상황: 집이 학교에서 멀어 대중교통을 이용한다.
입력
출발지: 집
도착지: 학교
이동 거리(km): 42
번호: 5 (지하철)
다시 계산하시겠습니까? (y/n): n
계산 과정
배출량 = 42 × 0.041 = 1.722 → 화면에는 1.72kg
내연차 = 42 × 0.192 = 8.064
절감률 = (8.064 - 1.722) / 8.064 × 100 ≈ 78.65% → 약 79% 감소
등급 = 1kg 초과 ~ 2kg 이하 → C
추천 = 도보(5km 초과 제외), 자전거(10km 초과 제외)
버스는 지하철보다 배출량이 커서 제외
→ 추천 없음
전체 CLI 출력
========================================
EcoMove
========================================
이동 정보를 입력하면 탄소 배출량을 계산합니다.
출발지: 집
도착지: 학교
이동 거리(km): 42
이동수단을 선택해 주세요.
1. 내연기관차
2. 하이브리드차
3. 전기차
4. 버스
5. 지하철
6. 오토바이
7. 자전거
8. 도보
번호: 5
====================
출발지 : 집
도착지 : 학교
이동거리 : 42.0km
선택한 이동수단 : 지하철
탄소배출량 : 1.72kg CO₂
내연기관차 대비 약 79% 감소
환경등급 : C
→ 이 거리에서는 이미 좋은 선택입니다.
안내 :
지하철 이용은 이 거리에서 적절한 선택입니다. 현재 잘하고 계십니다.
====================
다시 계산하시겠습니까? (y/n): n
이용해 주셔서 감사합니다.
포인트
- 장거리라 도보/자전거는 추천하지 않는다.
- 이미 지하철을 골랐으므로 격려 문구가 나온다.
상황: 가까운 거리인데 차를 탄다.
입력
출발지: 집
도착지: 학교
이동 거리(km): 3
번호: 1 (내연기관차)
계산 과정
배출량 = 3 × 0.192 = 0.576 → 0.58kg
절감률 = 기준 수단 본인 → "비교 기준: 내연기관차"
등급 = 0 초과 ~ 1kg 이하 → B
추천 후보 검토
- 도보: 3km ≤ 5, 배출 0 < 0.576 → 포함
- 자전거: 3km ≤ 10, 배출 0 < 0.576 → 포함
- 지하철: 3 × 0.041 = 0.123 < 0.576 → 포함
- 버스: 3 × 0.105 = 0.315 < 0.576 → 포함
→ 버스, 지하철, 자전거, 도보
출력
출발지 : 집
도착지 : 학교
이동거리 : 3.0km
선택한 이동수단 : 내연기관차
탄소배출량 : 0.58kg CO₂
비교 기준: 내연기관차
환경등급 : B
→ 탄소 배출이 낮은 편입니다.
안내 :
내연기관차보다 버스, 지하철, 자전거, 도보를 이용하면 탄소 배출을 더 줄일 수 있습니다.
포인트
- 단거리에서는 도보·자전거까지 추천 후보에 들어간다.
- 내연기관차는 절감률 대신 비교 기준 문구가 나온다.
- 추천이 있으므로 등급 기본 문구(
탄소 배출이 낮은 편입니다.)가 그대로 나온다.
상황: 가까운 카페까지 걸어간다.
입력
출발지: 회사
도착지: 카페
이동 거리(km): 2
번호: 8 (도보)
계산 과정
배출량 = 2 × 0.0 = 0.00kg
내연차 = 2 × 0.192 = 0.384
절감률 = (0.384 - 0) / 0.384 × 100 = 100% 감소
등급 = 정확히 0kg → A
추천 = 더 낮은 배출 수단 없음
출력
출발지 : 회사
도착지 : 카페
이동거리 : 2.0km
선택한 이동수단 : 도보
탄소배출량 : 0.00kg CO₂
내연기관차 대비 약 100% 감소
환경등급 : A
→ 이 거리에서는 이미 좋은 선택입니다.
안내 :
도보는 탄소를 배출하지 않습니다. 좋은 선택입니다.
포인트
- 배출량 0이면 등급 A다.
is_eco_friendly()가 True라 탄소 미배출 격려 문구가 나온다.
상황: 마트까지 하이브리드차를 이용한다.
입력
출발지: 집
도착지: 마트
이동 거리(km): 8
번호: 2 (하이브리드차)
계산 과정
배출량 = 8 × 0.121 × 0.85 = 0.8228 → 0.82kg
(HybridCar 오버라이딩: × 0.85)
내연차 = 8 × 0.192 = 1.536
절감률 ≈ 46.43% → 약 46% 감소
등급 = B
추천 후보 검토
- 도보: 8km > 5 → 제외
- 자전거: 8km ≤ 10 → 가능, 배출 0 < 0.82 → 포함
- 지하철: 8 × 0.041 = 0.328 < 0.82 → 포함
- 버스: 8 × 0.105 = 0.84 > 0.82 → 제외
→ 지하철, 자전거
출력
출발지 : 집
도착지 : 마트
이동거리 : 8.0km
선택한 이동수단 : 하이브리드차
탄소배출량 : 0.82kg CO₂
내연기관차 대비 약 46% 감소
환경등급 : B
→ 탄소 배출이 낮은 편입니다.
안내 :
하이브리드차보다 지하철, 자전거를 이용하면 탄소 배출을 더 줄일 수 있습니다.
포인트
- 하이브리드는 기본식에
× 0.85가 붙는다. - 거리 제한과 배출량 비교가 함께 적용된다.
- 버스는 추천 후보지만, 이 거리에서는 하이브리드보다 배출이 커서 빠진다.
상황: 공항에서 호텔까지 전기차를 이용한다.
입력
출발지: 공항
도착지: 호텔
이동 거리(km): 12
번호: 3 (전기차)
계산 과정
배출량 = 12 × 0.053 × 0.45 = 0.2862 → 0.29kg
(ElectricCar 오버라이딩: × 0.45)
내연차 = 12 × 0.192 = 2.304
절감률 ≈ 87.58% → 약 88% 감소
등급 = B
추천 후보 검토
- 도보: 12km > 5 → 제외
- 자전거: 12km > 10 → 제외
- 지하철: 12 × 0.041 = 0.492 > 0.286 → 제외
- 버스: 12 × 0.105 = 1.26 > 0.286 → 제외
→ 추천 없음
출력
출발지 : 공항
도착지 : 호텔
이동거리 : 12.0km
선택한 이동수단 : 전기차
탄소배출량 : 0.29kg CO₂
내연기관차 대비 약 88% 감소
환경등급 : B
→ 이 거리에서는 이미 좋은 선택입니다.
안내 :
전기차 이용은 이 거리에서 적절한 선택입니다. 현재 잘하고 계십니다.
포인트
- 전기차는 전력망 계수
0.45가 곱해진다. - 장거리 + 낮은 배출량이라 추천 후보가 비고, 격려 문구가 나온다.
| 시나리오 | 거리 | 수단 | 배출량 | 절감률 | 등급 | 추천 |
|---|---|---|---|---|---|---|
| 1 | 42km | 지하철 | 1.72kg | 약 79% 감소 | C | 없음 (격려) |
| 2 | 3km | 내연기관차 | 0.58kg | 비교 기준 | B | 버스, 지하철, 자전거, 도보 |
| 3 | 2km | 도보 | 0.00kg | 약 100% 감소 | A | 없음 (탄소 미배출 격려) |
| 4 | 8km | 하이브리드차 | 0.82kg | 약 46% 감소 | B | 지하철, 자전거 |
| 5 | 12km | 전기차 | 0.29kg | 약 88% 감소 | B | 없음 (격려) |
거리 10km를 기준으로, 모든 이동수단의 실제 배출량·절감률·등급을 비교하면 다음과 같습니다.
| 이동수단 | 계산식 | 배출량 | 절감률 | 등급 |
|---|---|---|---|---|
| 내연기관차 | 10 × 0.192 |
1.92kg | 비교 기준 | C |
| 하이브리드차 | 10 × 0.121 × 0.85 |
1.03kg | 약 46% 감소 | C |
| 전기차 | 10 × 0.053 × 0.45 |
0.24kg | 약 88% 감소 | B |
| 버스 | 10 × 0.105 |
1.05kg | 약 45% 감소 | C |
| 지하철 | 10 × 0.041 |
0.41kg | 약 79% 감소 | B |
| 오토바이 | 10 × 0.103 |
1.03kg | 약 46% 감소 | C |
| 자전거 | 10 × 0.0 |
0.00kg | 약 100% 감소 | A |
| 도보 | 10 × 0.0 |
0.00kg | 약 100% 감소 | A |
10km일 때 추천 거리 제한:
- 도보: 10km > 5 → 추천 대상에서 제외
- 자전거: 10km ≤ 10 → 추천 가능
예: 10km에서 내연기관차를 고르면, 추천은 버스, 지하철, 자전거가 됩니다.
(도보는 거리 제한으로 빠지고, 하이브리드·전기차·오토바이는 추천 후보 자체가 아님)
- 역할 분리
데이터 / 모델 / 계산 / 출력 / 흐름 제어를 파일과 클래스로 나눔 - 확장성
새 이동수단은data.py의 카탈로그와models.py의 클래스·매핑에 추가하면 됨 - 상속과 다형성
공통 로직은Vehicle에, 특수 계산은 하위 클래스에서 오버라이딩 - 실사용 규칙 반영
장거리에서는 도보/자전거를 추천하지 않음 - 완성된 CLI
잘못된 입력 재요청, 반복 실행, 종료 안내까지 포함
현재 버전은 과제 제출과 OOP 개념 설명에 초점을 맞춘 CLI 완성본입니다.