파이썬 조건문파이썬 반복문파이썬
전체 성과를 하나로 합치는 조건문·반복문·집계
그로스앤디 · 2026-08-27 발행· 11분 읽기
목차
코드 해부 1편에서는 광고 데이터가 JSON 파일에서 들어오고 결과로 저장되는 흐름을 살펴봤습니다. 2편에서는 그 데이터를 딕셔너리·리스트·집합에 담았고, 3편에서는 잘못된 값이 계산을 오염시키지 않도록 검증했습니다. 4편에서는 검증을 통과한 데이터로 CTR·CVR·CPC·CPA·ROAS를 안전하게 계산했어요.
이제 숫자를 만드는 단계에서 한 걸음 더 나아가, 그 숫자가 목표에 비해 어떤 상태인지 판단할 차례입니다. ROAS 350%와 CPA 8,824원이 나왔더라도 기준이 없다면 좋은 성과인지, 예산을 유지해야 하는지, 개선이 필요한지 결정할 수 없으니까요.
이번 글에서 다루는 조건문·반복문·집계를 이해하면 여러 캠페인에 같은 판단 기준을 적용할 수 있습니다. 캠페인마다 ROAS와 CPA를 눈으로 대조하는 대신 목표 달성, 부분 달성, 개선 필요, 판정 보류로 자동 분류하고, 오류가 없는 캠페인만 모아 전체 성과를 계산할 수 있어요.
광고 캠페인 성과 진단기는 계산값을 목표 ROAS·CPA와 비교해 네 가지 상태로 바꿉니다.
목표 달성
부분 달성
개선 필요
판정 보류
그리고 여러 캠페인 중 정상 데이터만 모아 전체 성과를 다시 계산합니다.
이제 계산식을 통한 숫자들이, 판정받을 순간입니다.
목표조건 만들기 : ROAS와 CPA
ROAS는 목표 이상이어야 하고, CPA는 목표 이하여야 합니다.
checks = [
metrics["roas"] >= goals["target_roas"],
metrics["cpa"] <= goals["target_cpa"],
]
예를 들어 실제 ROAS가 350%, CPA가 8,824원이고 목표가 300%·20,000원이라면 두 비교 결과는 모두 True입니다.
checks = [True, True]
반대로 ROAS만 목표를 달성했다면 다음과 같습니다.
checks = [True, False]
all()과 any()로 세 가지 상태를 판정하기
evaluate_performance()는 두 조건의 조합을 확인합니다.
def evaluate_performance(metrics, goals):
if metrics["roas"] is None or metrics["cpa"] is None:
return "판정 보류"
checks = [
metrics["roas"] >= goals["target_roas"],
metrics["cpa"] <= goals["target_cpa"],
]
if all(checks):
return "목표 달성"
if any(checks):
return "부분 달성"
return "개선 필요"
all(checks)는 모든 조건이 참일 때만 True이고, any(checks)는 하나라도 참이면 True입니다.
| ROAS | CPA | all |
any |
판정 |
|---|---|---|---|---|
| 달성 | 달성 | True | True | 목표 달성 |
| 달성 | 미달 | False | True | 부분 달성 |
| 미달 | 달성 | False | True | 부분 달성 |
| 미달 | 미달 | False | False | 개선 필요 |
첫 번째 if에서 all()을 먼저 확인했기 때문에 두 조건을 모두 만족한 경우가 부분 달성으로 내려가지 않습니다.
ROAS나 CPA가 None이면 숫자와 목표를 비교할 수 없으므로 먼저 판정 보류를 반환합니다. 이 조건이 없다면 None >= 300 같은 비교에서 오류가 발생합니다.
조건문의 순서는 어떤 상태를 먼저 판정할지 우선순위를 결정하게 됩니다.
모든 캠페인에 같은 규칙 적용하기_반복문
캠페인이 몇 개든 diagnose_campaigns()의 반복문은 같은 순서로 처리합니다.
for number, campaign in enumerate(campaigns, start=1):
errors = validate_campaign(campaign, seen_names)
enumerate(..., start=1)은 캠페인과 함께 사람이 읽기 쉬운 1번부터의 번호를 제공합니다.
각 캠페인은 다음 경로를 통과합니다.
캠페인 한 건
→ 검증
├─ 오류 → 오류 결과 저장 → 다음 캠페인
└─ 정상 → 지표 계산 → 목표 판정 → 정상 목록 저장
코드에서는 if와 continue가 경로를 나눕니다.
if errors:
results.append({
"number": number,
"campaign": campaign_name or f"캠페인 {number}",
"status": "입력 오류",
"errors": errors,
})
continue
metrics = calculate_metrics(campaign)
continue를 만나면 현재 반복의 아래 코드를 건너뛰고 다음 캠페인으로 이동합니다. 따라서 오류 캠페인은 계산되지 않아요.
결과 목록과 정상 목록 분리하기
함수는 두 개의 리스트를 함께 관리합니다.
results = []
valid_campaigns = []
results: 화면과 결과 파일에 보여줄 모든 캠페인 결과valid_campaigns: 전체 합계에 포함할 정상 캠페인 원자료
오류 캠페인도 사용자가 이유를 확인해야 하므로 results에는 남깁니다. 하지만 잘못된 수치가 전체 CPA와 ROAS를 왜곡하면 안 되므로 valid_campaigns에는 넣지 않습니다.
results.append({
"number": number,
"campaign": campaign["campaign"].strip(),
"status": evaluate_performance(metrics, goals),
"metrics": round_metrics(metrics),
})
valid_campaigns.append(campaign)
함수는 두 리스트를 튜플로 반환합니다.
return results, valid_campaigns
호출하는 쪽에서는 각 이름으로 나누어 받습니다.
results, valid_campaigns = diagnose_campaigns(campaigns, goals)
보여줄 결과와 계산에 사용할 데이터를 분리하면 오류를 숨기지 않으면서도 전체 집계의 신뢰도를 지킬 수 있습니다.
전체 ROAS ≠ 개별 ROAS의 평균
정상 캠페인이 여러 개라면 calculate_summary()가
원자료를 먼저 합치는 과정을 겪게 돼요.
totals = {
"spend": sum(campaign["spend"] for campaign in campaigns),
"impressions": sum(campaign["impressions"] for campaign in campaigns),
"clicks": sum(campaign["clicks"] for campaign in campaigns),
"conversions": sum(campaign["conversions"] for campaign in campaigns),
"revenue": sum(campaign["revenue"] for campaign in campaigns),
}
그다음 합계 데이터로 지표를 다시 계산합니다.
metrics = calculate_metrics(totals)
통합 ROAS는 다음 식으로 계산됩니다.
전체 매출 합계 ÷ 전체 광고비 합계 × 100
개별 ROAS를 단순 평균하면 캠페인 규모를 무시하게 됩니다. 광고비 1만원 캠페인과 100만원 캠페인이 같은 영향력을 갖기 때문이에요.
예를 들어 다음 두 캠페인을 생각해보겠습니다.
| 캠페인 | 광고비 | 매출 | ROAS |
|---|---|---|---|
| A | 10,000원 | 50,000원 | 500% |
| B | 1,000,000원 | 2,000,000원 | 200% |
개별 ROAS의 단순 평균은 350%입니다. 하지만 실제 전체 ROAS는 다음과 같아요.
(50,000 + 2,000,000) ÷ (10,000 + 1,000,000) × 100
≈ 202.97%
전체 사업 성과는 약 203%에 가깝습니다. 원자료를 합한 뒤 비율을 다시 계산해야 광고비 규모가 반영됩니다.
main()이 모든 단계를 순서대로 연결합니다
지금까지 살펴본 함수는 각자 하나의 역할을 맡았습니다.
main()은 이 함수들을 실행 순서에 맞게 호출합니다.
입력 경로 확인
→ JSON 읽기
→ 최상위 구조 확인
→ 목표 검증
→ 캠페인 목록 확인
→ 캠페인별 검증·계산·판정
→ 정상 캠페인 전체 집계
→ 터미널 출력
→ 결과 JSON 저장
→ 종료 코드 반환
data = load_json(input_path)
goals = data.get("goals")
campaigns = data.get("campaigns")
results, valid_campaigns = diagnose_campaigns(campaigns, goals)
summary = calculate_summary(valid_campaigns, goals)
print_report(results, summary, goals)
save_report(output_path, goals, results, summary)
main()이 모든 세부 계산을 직접 수행하지 않는다는 점이 중요합니다.
main()은 각 함수에 일을 맡기고 전체 순서만 조정합니다.
결과 예측, 미리 해보기
예제 캠페인의 ROAS는 350%, CPA는 약 8,824원입니다. 코드를 실행하기 전에 다음 목표에서 어떤 상태가 나올지 적어보세요.
| 목표 ROAS | 목표 CPA | 예상 판정 |
|---|---|---|
| 300% | 20,000원 | ? |
| 400% | 20,000원 | ? |
| 300% | 8,000원 | ? |
| 400% | 8,000원 | ? |
정답은 차례대로 목표 달성, 부분 달성, 부분 달성, 개선 필요입니다.
그다음 실제 JSON의 목표값을 바꾸어 실행해보세요. 예측과 결과가 같다면 축하드립니다.🎉
all()·any()와 조건문의 순서를 이해한 것입니다.
정리하자면,
이번 ‘광고 캠페인 성과 진단기’ 콘텐츠 시리즈에서는 파이썬에서 중요한 개념들을 5개로 나눠 살펴봤어요.
1편: JSON으로 데이터를 입력하고 결과를 저장하기
2편: 딕셔너리·리스트·집합으로 데이터를 표현하기
3편: 검증과 예외 처리로 잘못된 데이터를 막기
4편: CTR·CVR·CPC·CPA·ROAS를 안전하게 계산하기
5편: 목표 판정·반복 처리·전체 집계로 의사결정을 완성하기
처음에는 300줄이 넘는 하나의 코드로 보였지만,
- 실제로는 입력을 받고
- 데이터를 정리하고
- 오류를 막고
- 지표를 계산하고
- 판단을 내리는 그런 역할들의 연결이라는 걸 잘 확인할 수 있었을 거에요. 이 구조를 이해하면 새로운 지표나 판정 기준이 필요할 때도 전체 코드를 다시 만들지 않고 해당 규칙만 바꿀 수 있어요.
다섯 편을 모두 읽었다면 다시 전체 흐름 글로 돌아가 보세요. 처음에는 하나의 긴 흐름으로 보였던 프로그램이 이제는 역할이 다른 함수들 간의 협업으로 보일 거예요.
그리고 다음 글에서는 여기서 한 단계 더 나아갑니다. 지금까지 사람이 직접 만든 데이터 구조와 판단 규칙 위에 인공지능을 연결하면, 광고 성과를 단순히 분류하는 것을 넘어 어떤 해석과 다음 행동까지 제안할 수 있을까요?
다음 이야기는 그 가능성에서 시작해보겠습니다.
관련 키워드
파이썬 조건문파이썬 반복문all anyROAS 목표광고 성과 집계