기본 콘텐츠로 건너뛰기

추천 가젯

리액트 + 비트(Vite)로 모바일 청첩장 만들기 — 2편

모바일 청첩장 시리즈 2편 · R2 갤러리 & Firebase 방명록 Cloudflare R2 · Functions Firebase Firestore 클라우드플레어 R2로 갤러리 저장하고, Firebase로 방명록 달기 안녕하세요, 병민입니다 🙌 1편에서 전체 흐름을 잡았고, 이번엔 사진 업로드/보관 과 방명록 을 연결합니다. 서버는 따로 없고 Cloudflare Pages 를 쓰고 있으니, Pages Functions (= 워커)로 R2에 사전서명 URL을 만들어주고, 프론트에서 그 URL로 바로 업로드하는 구조예요. 방명록은 Firebase DB로 간단·안전하게! 전체 그림 프론트(React) → /api/r2/upload 로 업로드용 URL 요청 → R2에 파일 PUT 프론트(React) → /api/r2/list 로 목록 요청 → 갤러리 렌더 프론트(React) → Firebase SDK로 방명록 작성/조회 1) R2 버킷 & Pages Functions 준비 Cloudflare 대시보드 > R2 > Create bucket (예: wedding-gallery ) 버킷 > Settings > CORS 에서 사이트 도메인 허용(예: https://*.pages.dev , 커스텀 도메인) Pages 프로젝트 > Settings > Functions 에서 R2 바인딩 추가: ...

파이썬 fractions 모듈 완전 정복 ✖️➗ — 유리수로 정확 계산하기

파이썬 fractions 모듈 완전 정복 ✖️➗ — 유리수로 정확 계산하기 fractions(분수) 계산 아이콘

파이썬 fractions 모듈 완전 정복 ✖️➗

부동소수점(float)은 빠르지만 오차가 생길 수 있습니다. fractions.Fraction유리수(분수) 기반으로 정확한 연산을 제공합니다. 비율, 혼합비, 레시피, 확률 계산처럼 정확한 비가 중요한 상황에서 매우 유용합니다.

1) 기본: Fraction 생성과 사칙연산

from fractions import Fraction

# 정수/문자열/튜플로 생성
a = Fraction(1, 3)           # 1/3
b = Fraction("2/5")          # 2/5
c = Fraction(7, 10)          # 7/10

print(a + b)                 # 11/15
print(b * c)                 # 1/5
print(c - a)                 # 11/30
print(a / b)                 # 5/6

# 기약분수로 자동 정규화
print(Fraction(50, 100))     # 1/2

2) float → Fraction: limit_denominator() 활용

왜 복잡한 분모가 나오나요? float는 이진 근사라서 정확한 0.1을 표현하지 못합니다. 그 값을 Fraction으로 바꾸면 아주 큰 분모가 생길 수 있습니다.

from fractions import Fraction

x = 0.1
fx = Fraction(x)                 # Fraction(3602879701896397, 36028797018963968) 같은 큰 분모!
print(fx)

# 사람이 쓰기 좋은 근사분수로 제한
fx_simplified = fx.limit_denominator(1000)  # 분모 최대 1000으로 제한
print(fx_simplified)                        # 1/10
TIP: 센서 비율, 혼합비 등은 Fraction("3/20")처럼 처음부터 문자열/분자·분모로 생성하면 불필요한 오차를 피할 수 있습니다.

3) 실전 예제

3-1. 혼합비/레시피 스케일링

from fractions import Fraction

# 페인트 A:B = 3:7, 총 2.5L 만들기
ratio = Fraction(3, 10)  # A의 비율(3/10), B는 7/10
total = Fraction(5, 2)   # 2.5L = 5/2

a = ratio * total          # 3/10 * 5/2 = 15/20 = 3/4 L
b = (1 - ratio) * total    # 7/10 * 5/2 = 35/20 = 7/4 L
print(a, b)  # 3/4  7/4 (정확한 분수 결과)

3-2. 확률 계산(의사결정)

from fractions import Fraction

# 빨강 2개, 파랑 3개 공에서 하나 뽑기
p_red = Fraction(2, 5)
p_blue = Fraction(3, 5)

# 두 번 뽑아 둘 다 빨강일 확률(복원 추출 가정)
p_two_red = p_red * p_red
print(p_two_red)  # 4/25 (0.16 아님, '정확'히 4/25)

3-3. 평균도 정확하게 (가중 평균 포함)

from fractions import Fraction

scores = [Fraction(1, 3), Fraction(1, 2), Fraction(3, 4)]
avg = sum(scores, start=Fraction(0, 1)) / len(scores)
print(avg)  # 19/36

# 가중 평균: 가중치 2,3,5
weights = [2, 3, 5]
weighted = sum(s*w for s, w in zip(scores, weights)) / sum(weights)
print(weighted)  # 정확한 유리수

4) decimal vs fractions: 언제 무엇을?

  • fractions: 정확한 비율/조합/확률/개수(정수 비) — 분수 형태가 본질인 문제.
  • decimal: 소수 자릿수반올림 규칙이 중요한 금융/세금/회계.
# 두 접근의 의도 차이 예시
from fractions import Fraction
from decimal import Decimal, getcontext, ROUND_HALF_UP

# 비율 정확성(분수)
mix = Fraction(2, 3) + Fraction(1, 6)  # 5/6

# 금액 반올림(소수)
getcontext().rounding = ROUND_HALF_UP
price = Decimal("1.235").quantize(Decimal("0.01"))  # 1.24 (상업적 반올림)

5) 성능·주의사항 & TIP

  • 분자/분모가 커질수록 연산 비용이 증가합니다. 큰 데이터셋엔 limit_denominator로 관리하세요.
  • float → Fraction 변환은 가급적 피하고, 문자열·정수로 직접 생성하세요.
  • 출력 시엔 float()로 바꿔 보여줄 수 있지만, 내부 계산은 Fraction으로 유지하세요.

요약

  • fractions.Fraction유리수 기반의 정확 계산을 제공
  • limit_denominator()로 사람이 쓰기 좋은 근사 분수를 손쉽게 얻음
  • 혼합비/레시피, 확률, 정확 평균 등 비율이 핵심인 문제에 특히 적합
  • decimal은 소수 자릿수·반올림 규칙이 중요한 금융 문제에 추천

자주 묻는 질문(FAQ)

Q1. 이미 float로 계산했는데 정확하게 바꾸려면?
A. Fraction.from_float(x).limit_denominator(n)을 사용해 근사 분수를 구한 뒤 이후 연산은 분수로 진행하세요.

Q2. Fraction 결과를 소수로 보여주려면?
A. 표시할 때만 float()format을 쓰고, 내부 계산은 분수로 유지하는 것이 안전합니다.


더 보기: 정확한 소수 계산이 필요하면 decimal 모듈 글도 함께 참고하세요. (블로그 내 연관 글)

댓글

가장 많이 본 글

Icons by Flaticon