파이썬 조건문파이썬 반복문파이썬

전체 성과를 하나로 합치는 조건문·반복문·집계

· 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번부터의 번호를 제공합니다.

각 캠페인은 다음 경로를 통과합니다.

캠페인 한 건
→ 검증
├─ 오류 → 오류 결과 저장 → 다음 캠페인
└─ 정상 → 지표 계산 → 목표 판정 → 정상 목록 저장

코드에서는 ifcontinue가 경로를 나눕니다.

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줄이 넘는 하나의 코드로 보였지만,

  • 실제로는 입력을 받고
  • 데이터를 정리하고
  • 오류를 막고
  • 지표를 계산하고
  • 판단을 내리는 그런 역할들의 연결이라는 걸 잘 확인할 수 있었을 거에요. 이 구조를 이해하면 새로운 지표나 판정 기준이 필요할 때도 전체 코드를 다시 만들지 않고 해당 규칙만 바꿀 수 있어요.

다섯 편을 모두 읽었다면 다시 전체 흐름 글로 돌아가 보세요. 처음에는 하나의 긴 흐름으로 보였던 프로그램이 이제는 역할이 다른 함수들 간의 협업으로 보일 거예요.

그리고 다음 글에서는 여기서 한 단계 더 나아갑니다. 지금까지 사람이 직접 만든 데이터 구조와 판단 규칙 위에 인공지능을 연결하면, 광고 성과를 단순히 분류하는 것을 넘어 어떤 해석과 다음 행동까지 제안할 수 있을까요?

다음 이야기는 그 가능성에서 시작해보겠습니다.

광고 캠페인 성과 진단기 사용하기 · 전체 Python 코드 보기

관련 키워드

파이썬 조건문파이썬 반복문all anyROAS 목표광고 성과 집계

앤디의 마케팅노트

마케팅을 시스템으로 만드는 과정을 매주 기록해요. 잘 된 것도, 안 된 것도 같이 봐요.

maily에서 구독하기