글

라벨이 업무 자동화인 게시물 표시

파이썬 argparse 입력 검증: 필수 옵션, 허용 값, 처리 건수 제한하기

자동화 실행 인자는 argparse에서 필수 여부·허용 값·범위를 검사하고, 실제 반영은 별도 명시 옵션으로 분리하세요. 확인일: 2026-10-24. Python 3.14 표준 라이브러리 예제입니다. Windows Python 3.14.4에서 합성 입력으로 로컬 실행과 assert 검사를 통과했습니다. 왜 실행 인자를 먼저 검사해야 하나요? 스케줄러에서 같은 프로그램을 반복 실행할 때 옵션을 빠뜨리거나 대상을 오타로 입력하면, 잘못된 자료를 처리할 수 있습니다. 이 예제는 데이터 조회나 변경보다 앞에 두는 명령줄 입력 검증 계층입니다. source는 sales 또는 support, limit는 1~1000 정수로 제한합니다. 이 숫자는 서비스 한도가 아니라 합성 예제의 입력 계약입니다. 기본 동작을 어떻게 정하나요? --source는 반드시 입력해야 하고 --limit를 생략하면 100입니다. --apply는 존재할 때만 True가 되는 플래그로 기본 False입니다. allow_abbrev=False로 --sou 같은 긴 옵션의 축약을 허용하지 않습니다. 옵션을 정확히 적도록 하는 선택이며 모든 CLI의 보편적인 필수 설정은 아닙니다. 최소 예제와 실패 조건 아래 코드는 인자 분석기와 자체 테스트입니다. 실제 파일이나 API를 처리하는 함수는 없습니다. 따라서 --apply를 넣어도 이 코드 자체가 운영 자료를 변경하지 않습니다. 실제 프로그램에는 분석 결과를 확인한 뒤 미리보기와 반영 함수를 분기하는 호출부를 별도로 작성해야 합니다. import argparse from contextlib import redirect_stderr from io import StringIO def bounded_limit(text): try: value = int(text) except ValueError: raise argparse.ArgumentTypeError("정수가 필요합니다") from None ...

파이썬 최신 보고서 파일 선택: 수정 시간 대신 파일명 날짜와 중복 검사

파일명에서 업무 날짜를 검증해 기준일 이하의 최신 날짜를 찾고, 같은 날짜 후보가 여러 개면 자동 선택을 중단하세요. 적용 환경: Python 3.14 표준 라이브러리. 2026-10-22 확인. Windows Python 3.14.4에서 아래 예제를 임시 작업 폴더에서 실행하고 assert 및 예상 예외 검사를 통과했습니다. 실제 회사 자료·외부 서비스는 사용하지 않았습니다. 업무 날짜와 파일 수정 시간은 다릅니다 수정 시간은 파일 시스템 메타데이터이고 보고서가 집계한 날짜 자체가 아닙니다. 오래된 보고서를 다시 저장하거나 전송 도구가 시간을 바꾸면 수정 시간 순서와 업무 날짜 순서가 달라질 수 있습니다. 복사 도구가 시간을 보존하는 경우도 있으므로 복사하면 항상 수정 시간이 바뀐다고 가정하지 마세요. 파일명 날짜를 신뢰하려면 생성 측과 명명 규칙을 먼저 합의해야 합니다. 선택할 이름 규칙과 기준일을 명시합니다 예제는 폴더 바로 아래의 report_YYYY-MM-DD.csv 또는 report_YYYY-MM-DD_rev2.csv 같은 이름만 후보로 받습니다. rev 뒤에는 1 이상의 정수를 허용합니다. 확장자는 소문자 .csv로 고정하고 임시 파일·다른 접두사·하위 폴더는 처리하지 않습니다. 기준일은 date(2026, 10, 22)로 주입해 테스트가 실행 날짜에 따라 달라지지 않게 했습니다. 직접 실행하는 최소 예제 from pathlib import Path from datetime import date from tempfile import TemporaryDirectory import os import re NAME = re.compile(r"report_([0-9]{4}-[0-9]{2}-[0-9]{2})(?:_rev[1-9][0-9]*)?\.csv") def select_report(folder, as_of): candidates = [] for path in Path(folder).iterdir(): ...

파이썬 UTC 로그를 한국 날짜로 집계하기: 자정 경계와 시간대 누락 검사

한국 시간의 당일 자정과 다음 날 자정을 UTC로 변환한 뒤, 시작은 포함하고 끝은 제외하는 구간으로 로그를 고르세요. API나 서버 로그는 UTC로 저장하고, 보고서는 한국 날짜로 요청받는 경우가 있습니다. UTC 문자열에서 날짜 부분만 잘라 고르면 한국 시간으로 전날 밤이나 다음 날 새벽의 기록을 잘못 포함할 수 있습니다. 이 글은 예약 프로그램을 만드는 방법이 아니라 이미 기록된 시각을 날짜 구간으로 선별하는 방법 을 다룹니다. 한국의 10월 20일은 UTC에서 어느 구간인가요? 예제의 업무 시간대는 Asia/Seoul, 기준 날짜는 2026-10-20입니다. 코드로 계산한 구간은 UTC 2026-10-19 15:00:00 이상부터 2026-10-20 15:00:00 미만입니다. 아래 네 시각은 직접 만든 경계 시험 자료이며 실제 접속 로그가 아닙니다. 표식 UTC 입력 한국 시간의 위치 선택 before 10-19 14:59:59 전날 23:59:59 제외 start 10-19 15:00:00 당일 00:00:00 포함 last 10-20 14:59:59 당일 23:59:59 포함 next 10-20 15:00:00 다음 날 00:00:00 제외 시간대가 없는 입력을 거부하는 최소 예제 Windows Python 3.14.4에서 다음 코드를 실행했습니다. zoneinfo는 Python 3.9 이상에 포함되지만 IANA 시간대 데이터는 별도로 필요할 수 있습니다. 특히 Windows에서 ZoneInfoNotFoundError가 나면 사용하는 가상환경에 python -m pip install tzdata 로 데이터를 준비하고 다시 확인하세요. 예제에는 외부 API 호출이나 실제 로그 읽기가 없습니다. from datetime import datetime, date, time, timedelta, timezone from zoneinfo import ZoneInfo SEOUL = ZoneInfo("Asia/Seoul")...

파이썬 subprocess.run 오류 처리: 타임아웃, 종료 코드, stderr를 구분하는 예제

subprocess.run에 check와 timeout을 지정하고, 비정상 종료와 시간 초과를 별도로 처리하세요. 표준 출력과 표준 오류도 구분해 기록합니다. 자동화 도구가 다른 프로그램을 실행할 때, 화면에 문구가 출력됐다는 사실만으로 성공이라고 처리하면 안 됩니다. 반대로 stderr에 경고가 있다고 무조건 실패인 것도 아닙니다. 이 글은 현재 Python으로 작은 자식 프로세스를 만들어 성공·비정상 종료·시간 초과 를 나눠 확인합니다. 무엇을 실행하는 예제인가요? 별도 도구 설치 없이 Python 3 표준 라이브러리만 사용합니다. Windows의 Python 3.14.4에서 아래 예제를 실행했습니다. sys.executable 로 현재 인터프리터를 선택하고, -c 뒤에는 개발자가 직접 적은 고정된 연습 코드만 전달합니다. 사용자가 입력한 문장을 실행 코드로 바꾸는 구조가 아닙니다. 명령과 인자는 리스트로 분리합니다. 예제의 report draft.csv 는 공백을 포함해도 하나의 인자로 전달되며 파일을 열거나 수정하지 않습니다. 실제 외부 프로그램에 연결한 결과는 검증 범위에 포함하지 않습니다. 성공·종료 코드·타임아웃을 분리하는 최소 코드 import subprocess import sys def run_demo(source, *arguments, timeout=3): # source는 개발자가 작성한 고정된 연습 코드입니다. command = [sys.executable, "-X", "utf8", "-c", source, *arguments] try: result = subprocess.run( command, capture_output=True, text=True, encoding="utf-8", check=True, timeout=timeout, shell=False, )...

파이썬 파일 이름 일괄 변경 전 dry-run: 기존 파일 충돌을 먼저 검사하는 방법

파일 이름을 바로 바꾸지 말고 원본 이름과 새 이름의 계획표를 만든 뒤, 기존 파일 및 다른 변경 대상과의 충돌을 먼저 검사하세요. 보고서 폴더의 sales 01.csv 를 sales_01.csv 로 통일하려는 상황을 생각해 보겠습니다. 이미 같은 이름의 파일이 있거나 두 원본이 같은 새 이름을 만들면, 실행 도중 멈추거나 파일을 잃을 수 있습니다. 이 글은 이름 변경 실행이 아니라 실행 전 계획 검증 만 다룹니다. dry-run 계획표에는 무엇을 넣어야 하나요? 원본 이름과 바꿀 이름을 한 쌍으로 기록하고, 변경하지 않을 파일까지 포함한 현재 폴더의 이름 목록과 대조합니다. 여기서는 파일 이름의 ASCII 공백만 밑줄로 바꾸며, 하위 폴더를 재귀 탐색하지 않습니다. 폴더와 심볼릭 링크는 변경 대상에서 제외하지만, 그 이름은 충돌 검사 목록에 포함합니다. 비교 키는 NFC 정규화 후 casefold한 문자열입니다. 이는 서로 다른 표기나 대소문자를 보수적으로 충돌 처리하는 예제의 정책이며, 모든 파일시스템의 이름 비교 규칙을 그대로 재현하는 것은 아닙니다. 원본을 바꾸지 않는 실행 예제 Python 3 표준 라이브러리만 사용합니다. 이 예제는 Windows의 Python 3.14.4에서 실행했습니다. 샘플 파일은 임시 폴더에만 생성되며 rename 이나 replace 는 호출하지 않습니다. 업무 폴더 경로를 넣기 전에 예제 그대로 실행해 보세요. from pathlib import Path from tempfile import TemporaryDirectory import unicodedata def name_key(name): # 대소문자와 유니코드 표기 차이도 보수적으로 충돌로 취급합니다. return unicodedata.normalize("NFC", name).casefold() def build_plan(folder): entries = sorted(Path(folder).iterdir(), ke...

수집·변환·저장 코드를 나누는 파이썬 파이프라인

자동화 코드는 입력 수집, 형식 변환, 저장을 나누고 각 단계의 입출력 형태를 고정하면 테스트하기 쉽습니다. 어떤 상황에서 적용하나요? 네트워크 호출을 하지 않는 작은 파이프라인으로 구조부터 확인합니다. 수집 함수가 반환하는 원문과 저장 함수가 받는 정제 결과를 분리하면 외부 API가 바뀌었을 때 변환 단계만 시험할 수 있습니다. 검증 범위: 아래 코드는 외부 서비스에 요청하지 않는 로컬 예제입니다. 실제 서비스 연결은 별도로 검증해야 합니다. 최소 예제로 동작 확인하기 def collect(): return [{"title": " 보고서 ", "id": "A1"}] def transform(raw_rows): return [{"id": row["id"], "title": row["title"].strip()} for row in raw_rows if row.get("id")] def store(rows, destination): destination.extend(rows) return len(rows) saved = [] count = store(transform(collect()), saved) assert saved == [{"id": "A1", "title": "보고서"}] assert count == 1 print(saved) 결과는 어떻게 확인하나요? 앞뒤 공백이 제거된 한 행이 저장용 리스트에 들어갑니다. 이 예제에서 store는 메모리 저장소를 사용합니다. 실제 파일이나 DB 저장으로 바꾸더라도 transform 테스트에는 외부 연결이 필요 없습니다. 실제 업무에 적용할 때 확인할 점 단계를 클래스로 나누는 것만으로 재시도나 중복 방지가 생기지는 않습...

파이썬 태그 목록 만들기: 공백과 중복을 정리하는 규칙

태그 생성은 단어 수를 늘리는 작업보다, 글의 실제 주제를 나타내는 짧고 중복 없는 목록을 만드는 작업입니다. 어떤 상황에서 적용하나요? 아래 예제는 사람이 고른 후보 단어를 정리합니다. 단순 빈도만으로 글의 의미를 이해한다고 주장하지 않으며 외부 플랫폼에 태그를 전송하지 않습니다. 검증 범위: 아래 코드는 외부 서비스에 요청하지 않는 로컬 예제입니다. 실제 서비스 연결은 별도로 검증해야 합니다. 최소 예제로 동작 확인하기 import unicodedata def normalize_tags(candidates, limit=5): result = [] seen = set() for raw in candidates: tag = unicodedata.normalize("NFKC", raw).strip().lstrip("#") key = tag.casefold() if tag and key not in seen: result.append(tag) seen.add(key) if len(result) == limit: break return result tags = normalize_tags([" Python ", "python", "#업무자동화", "", "CSV"]) assert tags == ["Python", "업무자동화", "CSV"] print(tags) 결과는 어떻게 확인하나요? Python의 대소문자 중복과 빈 후보가 사라집니다. NFKC 정규화는 호환 문자를 통합하므로 원문 표기가 중요한 고유명사에서는 정규화 전후를 비교해야 합니다. 실제 업무에 적용할 때 확인할 점 limit=5는 이 예제의 출력 정책입니다. 플랫폼이...

외부 채널용 글 요약 검토: 중복 링크와 자동 게시 점검

외부 블로그에 원문을 소개할 때는 원문 URL과 핵심 요약을 준비한 뒤, 채널 목적에 맞는 설명을 추가해 검토하고 발행합니다. 원문을 그대로 여러 곳에 복제하는 방식으로 검색 노출을 보장할 수는 없습니다. 원문과 공유문을 다르게 설계하기 자기 사이트에는 전체 문제 해결 과정과 코드를 보관하고, 외부 채널에는 그 독자가 이해할 수 있는 배경과 핵심 요약을 제공합니다. 외부 게시물의 목적과 출처를 명확히 해야 독자가 링크를 누를 이유도 이해할 수 있습니다. 요약문을 검토하는 작은 함수 다음은 Python 3에서 빈 요약과 중복 링크를 찾는 로컬 예제입니다. 외부 플랫폼에 요청을 전송하지 않습니다. def review_draft(summary, links): if not summary.strip(): raise ValueError("요약을 작성하세요") unique_links = list(dict.fromkeys(links)) return {"summary": summary.strip(), "links": unique_links, "ready_for_review": True} draft = review_draft( "CSV 병합에서 식별번호의 앞자리 0을 보존하는 방법입니다.", ["https://www.goodkyoungs.com/2026/05/csv-pandas.html"] * 2, ) assert len(draft["links"]) == 1 print(draft) 중복 URL을 지운 것이 곧 발행 승인이라는 의미는 아닙니다. 실제 게시문은 원문과의 일치, 독자에게 제공하는 가치, 저작권과 플랫폼 정책을 사람이 확인해야 합니다. 자동 게시 API를 연결하기 전 계정 소유권과 권한, 토큰 보관, 중복 게시 방지, 실패 시 처리 방식을 설계하세요. API ...

작업 대상 선택과 진행률 계산: GUI 상태 모델 분리

진행률은 실제 완료한 작업 수를 기준으로 계산하고, 대상 선택과 실행 상태를 별도 데이터로 관리해야 합니다. 어떤 상황에서 적용하나요? 색인 완료를 알 수 없는 HTTP 요청을 처리했다고 표시하더라도 그것은 알림 작업의 진행률입니다. 아래는 네트워크와 GUI 없이 선택된 대상의 작업 완료율만 계산합니다. 검증 범위: 아래 코드는 외부 서비스에 요청하지 않는 로컬 예제입니다. 실제 서비스 연결은 별도로 검증해야 합니다. 최소 예제로 동작 확인하기 targets = {"site-a": True, "site-b": False, "site-c": True} selected = [name for name, checked in targets.items() if checked] def progress(completed, total): if total <= 0 or not 0 <= completed <= total: raise ValueError("작업 수를 확인하세요") return round(completed / total * 100) assert selected == ["site-a", "site-c"] assert progress(1, len(selected)) == 50 print(f"알림 작업 진행률: {progress(1, len(selected))}%") 결과는 어떻게 확인하나요? 두 대상 중 한 작업이 끝나면 50%입니다. 여기서 완료는 로컬 작업의 정의이며 실제 검색엔진 색인 상태를 뜻하지 않습니다. UI에도 “요청 처리”처럼 관찰한 작업을 정확히 표시하세요. 실제 업무에 적용할 때 확인할 점 작업 시작 후 대상 목록이 바뀌면 분모가 달라집니다. 실행 시점의 목록을 복사해 고정하고, 취소·실패 항목을 어떻게 집계할지 정해야 합니다. GUI 스레드에서 오래 걸리는 요청을 직접 실...

일일 배치 작업 설계: 실행 날짜와 중복 처리 방지

정기 배치는 시작 시각뿐 아니라 처리한 날짜와 실패 후 재실행 정책까지 정해서 구현해야 합니다. 어떤 상황에서 적용하나요? 일정 간격으로 sleep하는 상주 프로그램은 PC가 꺼진 동안의 실행을 보장하지 않습니다. 아래는 같은 날짜에 두 번 호출되어도 한 번만 처리하는 개념을 외부 통신 없이 확인하는 예제입니다. 검증 범위: 아래 코드는 외부 서비스에 요청하지 않는 로컬 예제입니다. 실제 서비스 연결은 별도로 검증해야 합니다. 최소 예제로 동작 확인하기 completed = set() def run_daily(day): if day in completed: return "skipped" # 실제 작업이 성공한 뒤 완료를 기록합니다. completed.add(day) return "done" assert run_daily("2026-10-17") == "done" assert run_daily("2026-10-17") == "skipped" print(sorted(completed)) 결과는 어떻게 확인하나요? 같은 날짜의 두 번째 호출은 skipped가 됩니다. 다만 set은 메모리에 있어 재시작하면 사라집니다. 운영에서는 DB 등에 상태를 보관하고 실제 처리 결과와 완료 기록이 일치하도록 설계해야 합니다. 실제 업무에 적용할 때 확인할 점 시간대, 절전 후 놓친 작업 처리, 실행 시간이 다음 예약 시각을 넘는 경우를 확인하세요. 일반 블로그에 Google Indexing API 요청을 반복하는 용도로 사용하지 말고, CSV 집계처럼 허용된 정형 업무에 적용합니다. 공식 자료와 다음 단계 관련 공식 문서 에서 사용하는 버전의 기능과 제한을 확인하세요. 학습 경로: 업무 자동화 가이드 · 입력 오류 처리 작성: 로그 · 2026-10-17 수정: 확인되지 않은 경험담과 성능 보장 표현을 제거하고...

업무 자동화 도구 완성 점검: 입력부터 배포까지

자동화 도구의 완성 여부는 버튼이 작동하는지만이 아니라 입력 검증, 결과 확인, 실패 기록과 재실행 안전성으로 판단합니다. 어떤 상황에서 적용하나요? 검증되지 않은 개인 성공담 대신 재현할 수 있는 점검 과정을 정리했습니다. 콘솔 처리 로직을 먼저 시험하고 GUI와 실행 파일 배포를 뒤에 붙이면 오류가 생긴 단계를 찾기 쉽습니다. 검증 범위: 아래 코드는 외부 서비스에 요청하지 않는 로컬 예제입니다. 실제 서비스 연결은 별도로 검증해야 합니다. 최소 예제로 동작 확인하기 def summarize(amounts): if not amounts or any(not isinstance(x, int) or x < 0 for x in amounts): raise ValueError("0 이상의 정수 목록이 필요합니다") return {"count": len(amounts), "total": sum(amounts)} assert summarize([10, 20, 0]) == {"count": 3, "total": 30} try: summarize([-1]) except ValueError: print("잘못된 입력 차단 확인") else: raise AssertionError("입력 오류가 차단되지 않았습니다") 결과는 어떻게 확인하나요? 정상 입력과 잘못된 입력을 모두 확인합니다. 같은 함수를 CLI와 GUI에서 함께 쓰면 화면 구현이 바뀌어도 핵심 처리의 테스트를 유지할 수 있습니다. 실제 업무에 적용할 때 확인할 점 배포 전에는 빈 파일, 권한 없는 폴더, 같은 작업 재실행, 네트워크 중단과 취소를 시험하세요. 로그에 무엇이 남는지와 원본 파일이 보존되는지도 확인합니다. 실행 파일 생성은 이 검증을 대신하지 않습니다. 공식 자료와 다음 단계 관련 공식 문서 에서 사용하는 버전의...

윈도우 작업 스케줄러: 파이썬 경로와 작업 폴더 확인

작업 스케줄러에서는 파이썬 실행 파일, 스크립트 인자, 시작 폴더를 각각 지정해야 상대 경로 오류를 줄일 수 있습니다. 어떤 상황에서 적용하나요? 같은 코드가 터미널에서는 실행되는데 예약 실행에서 실패한다면 먼저 실행 계정과 현재 폴더를 확인하세요. 아래는 외부 연결 없이 진단 정보를 출력하는 스크립트입니다. 검증 범위: 아래 코드는 외부 서비스에 요청하지 않는 로컬 예제입니다. 실제 서비스 연결은 별도로 검증해야 합니다. 최소 예제로 동작 확인하기 from pathlib import Path import sys script_dir = Path(__file__).resolve().parent if "__file__" in globals() else Path.cwd() print("python:", sys.executable) print("cwd:", Path.cwd()) print("script_dir:", script_dir) assert Path(sys.executable).is_absolute() 결과는 어떻게 확인하나요? python에는 실제 실행 중인 인터프리터 경로가, cwd에는 현재 작업 폴더가 표시됩니다. 시작 폴더가 스크립트 폴더와 다를 수 있다는 점을 로그로 확인하세요. 실제 업무에 적용할 때 확인할 점 프로그램에는 가상환경의 python.exe 절대 경로, 인자에는 스크립트 절대 경로, 시작 위치에는 자료를 읽는 기준 폴더를 설정합니다. 네트워크 드라이브 문자는 예약 계정에서 없을 수 있으므로 승인된 UNC 경로와 권한을 확인하세요. 중복 실행 정책과 절전 후 놓친 작업 처리도 점검합니다. 공식 자료와 다음 단계 관련 공식 문서 에서 사용하는 버전의 기능과 제한을 확인하세요. 학습 경로: 업무 자동화 가이드 · 입력 오류 처리 작성: 로그 · 2026-10-17 수정: 확인되지 않은 경험담과 성능 보장 표현을 제거하고 예제·적용 조건·공식 근거를 보완했...

파이썬 가상환경으로 배포 의존성 정리하기

가상환경은 프로젝트의 패키지를 분리하는 도구이며, 만들기만 한다고 실행 파일 용량이 자동으로 줄어들지는 않습니다. 어떤 상황에서 적용하나요? 새 작업 폴더에서 필요한 패키지만 설치하고 동작을 확인한 뒤 의존성을 기록하세요. 아래 명령은 Windows 터미널에서 사용하는 예이며 이 글을 읽는 것만으로 실행되지는 않습니다. 검증 범위: 아래는 터미널 명령 예시입니다. 실제 설치·빌드·오프라인 배포를 실행한 결과가 아닙니다. 최소 예제로 동작 확인하기 python -m venv .venv .venv\Scripts\python.exe -m pip install requests .venv\Scripts\python.exe -m pip freeze .venv\Scripts\python.exe -m pip check 결과는 어떻게 확인하나요? freeze는 해당 환경에 설치된 패키지 버전을 보여 주고 check는 설치된 의존성 충돌을 점검합니다. 출력에는 직접 설치한 패키지의 하위 의존성도 포함될 수 있습니다. 실제 업무에 적용할 때 확인할 점 freeze 결과를 아무 환경에서나 재현 가능한 완전한 잠금 파일로 간주하지 마세요. Python 버전과 운영체제, 네이티브 라이브러리도 영향을 줍니다. 용량을 줄이려고 필요한 라이브러리를 임의로 삭제하기보다 사용하지 않는 의존성이 들어오는 경로를 조사하세요. 공식 자료와 다음 단계 관련 공식 문서 에서 사용하는 버전의 기능과 제한을 확인하세요. 학습 경로: 업무 자동화 가이드 · 입력 오류 처리 작성: 로그 · 2026-10-17 수정: 확인되지 않은 경험담과 성능 보장 표현을 제거하고 예제·적용 조건·공식 근거를 보완했습니다.

PyInstaller 리소스 누락: 파일 경로를 코드 기준으로 찾기

PyInstaller 배포에서 이미지나 설정 파일을 읽을 때는 현재 작업 폴더와 패키지 내부 파일 위치를 구분해야 합니다. 어떤 상황에서 적용하나요? 아래는 읽기 전용 리소스를 현재 모듈 파일의 위치를 기준으로 찾는 예제입니다. 실제 bundle에는 해당 파일이 데이터로 포함되어 있어야 합니다. 이 검사는 임시 폴더에서 경로 계산만 확인합니다. 검증 범위: 아래 코드는 외부 서비스에 요청하지 않는 로컬 예제입니다. 실제 서비스 연결은 별도로 검증해야 합니다. 최소 예제로 동작 확인하기 from pathlib import Path from tempfile import TemporaryDirectory def resource_path(module_file, name): return Path(module_file).resolve().parent / "assets" / name with TemporaryDirectory() as folder: module = Path(folder) / "app.py" asset = resource_path(module, "logo.txt") asset.parent.mkdir() asset.write_text("sample", encoding="utf-8") assert asset.read_text(encoding="utf-8") == "sample" print(asset.name) 결과는 어떻게 확인하나요? logo.txt가 출력됩니다. 배포할 때는 사용 중인 PyInstaller 버전의 add-data 또는 spec 설정으로 assets를 포함하고, 번들 안의 실제 상대 위치를 확인하세요. 실제 업무에 적용할 때 확인할 점 번들 내부 리소스와 사용자가 변경하는 설정은 다른 위치에 두어야 합니다. one-file 임시 해제 폴더에 수정 데이터를 저장...

PyInstaller exe 만들기: 먼저 onedir로 오류 확인하기

처음 실행 파일을 만들 때는 콘솔과 onedir 구성을 유지해 오류를 확인하고, 동작을 검증한 뒤 배포 옵션을 정하는 편이 좋습니다. 어떤 상황에서 적용하나요? 아래 명령은 main.py가 있는 프로젝트 폴더에서 사용할 예시입니다. Python과 패키지 버전, 대상 운영체제를 함께 기록하세요. 실제 빌드 결과는 의존성에 따라 달라집니다. 검증 범위: 아래는 터미널 명령 예시입니다. 실제 설치·빌드·오프라인 배포를 실행한 결과가 아닙니다. 최소 예제로 동작 확인하기 python -m pip install pyinstaller python -m PyInstaller --onedir --name WorkReport main.py 결과는 어떻게 확인하나요? 성공하면 dist 안에 앱과 필요한 파일이 생성됩니다. 배포 테스트에서는 Python이 설치되지 않은 별도 대상 환경에서도 실행되는지 확인해야 합니다. 빌드 명령 성공만으로 배포 검증이 끝나지는 않습니다. 실제 업무에 적용할 때 확인할 점 windowed 옵션은 콘솔 오류를 보이지 않게 하므로 개발 초기에 바로 사용하지 마세요. one-file은 시작 시 파일을 해제하는 방식이라 실행 특성이 달라질 수 있습니다. Windows 실행 파일은 대상 OS와 아키텍처에 맞는 환경에서 빌드하고 보안 경고를 임의로 끄도록 안내하지 않습니다. 공식 자료와 다음 단계 관련 공식 문서 에서 사용하는 버전의 기능과 제한을 확인하세요. 학습 경로: 업무 자동화 가이드 · 입력 오류 처리 작성: 로그 · 2026-10-17 수정: 확인되지 않은 경험담과 성능 보장 표현을 제거하고 예제·적용 조건·공식 근거를 보완했습니다.

공유 폴더 백업 자동화: 복사 후 해시로 결과 확인

파일 백업은 복사 작업이 끝났다는 사실과 원본 내용이 보존됐는지를 구분해 확인해야 합니다. 어떤 상황에서 적용하나요? 아래는 임시 폴더 안에서 샘플 파일을 복사하고 SHA-256 값이 같은지 확인합니다. 실제 네트워크 공유 폴더에 쓰지 않습니다. 공유 경로에 적용할 때는 허용된 대상 경로와 계정 권한을 먼저 확인하세요. 검증 범위: 아래 코드는 외부 서비스에 요청하지 않는 로컬 예제입니다. 실제 서비스 연결은 별도로 검증해야 합니다. 최소 예제로 동작 확인하기 from pathlib import Path from tempfile import TemporaryDirectory import hashlib import shutil def digest(path): return hashlib.sha256(path.read_bytes()).hexdigest() with TemporaryDirectory() as folder: base = Path(folder) source = base / "source.txt" target = base / "backup.txt" source.write_text("report", encoding="utf-8") shutil.copy2(source, target) assert digest(source) == digest(target) print("내용 일치") 결과는 어떻게 확인하나요? 내용 일치가 출력됩니다. read_bytes는 파일 전체를 읽는 작은 예제이므로 큰 파일은 블록 단위로 해시를 계산하세요. 복사 중 원본이 바뀌는 상황은 별도 잠금이나 스냅샷 정책이 필요합니다. 실제 업무에 적용할 때 확인할 점 네트워크 단절, 같은 이름의 기존 백업, 심볼릭 링크와 접근 권한을 고려하세요. 원본을 지우는 동작을 백업과 묶지 말고 복구 시험도 수행해야 합니다. 예약 실행 계정에는 사용자...

오프라인 파이썬 패키지 설치: 대상 환경에 맞는 wheel 준비

오프라인 설치는 인터넷이 되는 환경에서 대상 Python·OS·아키텍처에 맞는 패키지와 의존성을 준비한 뒤 검증하는 과정입니다. 어떤 상황에서 적용하나요? 아래 명령은 온라인 준비 단계와 오프라인 설치 단계를 구분한 예시입니다. requirements.txt에는 실제 프로젝트에서 검증한 버전을 기록합니다. 다른 OS에서 받은 바이너리 wheel을 그대로 사용할 수 있다고 가정하지 마세요. 검증 범위: 아래는 터미널 명령 예시입니다. 실제 설치·빌드·오프라인 배포를 실행한 결과가 아닙니다. 최소 예제로 동작 확인하기 # 온라인 준비 환경 python -m pip download -r requirements.txt -d wheelhouse # 오프라인 대상 환경 python -m pip install --no-index --find-links=wheelhouse -r requirements.txt python -m pip check 결과는 어떻게 확인하나요? no-index는 패키지 인덱스에 접속하지 않고 준비한 위치에서 찾도록 합니다. 설치 성공 후에는 실제 프로그램의 import와 최소 작업까지 시험해야 합니다. 소스 배포만 받은 패키지는 추가 빌드 도구가 필요할 수 있습니다. 실제 업무에 적용할 때 확인할 점 온라인 준비 환경과 대상 환경이 다르면 pip download의 platform·python-version·implementation·abi 옵션을 검토하세요. 파일 전송 전에 출처와 해시를 확인하고 조직의 반입 절차를 따릅니다. 무조건 최신 패키지로 갱신하기보다 재현 가능한 버전 구성을 유지하세요. 공식 자료와 다음 단계 관련 공식 문서 에서 사용하는 버전의 기능과 제한을 확인하세요. 학습 경로: 업무 자동화 가이드 · 입력 오류 처리 작성: 로그 · 2026-10-17 수정: 확인되지 않은 경험담과 성능 보장 표현을 제거하고 예제·적용 조건·공식 근거를 보완했습니다.

파이썬 예외 처리: 예상한 입력 오류만 복구하기

try-except는 모든 오류를 숨기는 장치가 아니라, 예상한 실패를 구분하고 복구하거나 원인을 전달하는 구조입니다. 어떤 상황에서 적용하나요? 빈 입력과 숫자 변환 실패를 처리하는 작은 예제입니다. 예외 범위를 좁히면 프로그래밍 오류까지 정상적인 빈 값으로 바꾸는 문제를 줄일 수 있습니다. 검증 범위: 아래 코드는 외부 서비스에 요청하지 않는 로컬 예제입니다. 실제 서비스 연결은 별도로 검증해야 합니다. 최소 예제로 동작 확인하기 def parse_count(raw): try: value = int(raw) except (TypeError, ValueError) as exc: raise ValueError("건수는 정수로 입력하세요") from exc if value < 0: raise ValueError("음수 건수는 허용하지 않습니다") return value assert parse_count("12") == 12 for bad in ["", "abc", None, "-1"]: try: parse_count(bad) except ValueError: pass else: raise AssertionError("잘못된 입력을 허용했습니다") print("입력 오류 검증 완료") 결과는 어떻게 확인하나요? 정상 입력은 정수로 변환되고 네 종류의 잘못된 입력은 ValueError가 됩니다. from exc는 원래 변환 오류의 원인을 보존합니다. 화면에는 간단한 메시지를 보여 주더라도 내부 로그에서는 원인을 추적할 수 있어야 합니다. 실제 업무에 적용할 때 확인할 점 except Exception: pass는 실패를 감추기 쉽습니다. 네트워크 시간 초과, 인증 오류, 데이...

GUI 설정 JSON 저장: 기본값과 원자적 교체

설정 파일은 읽은 값의 자료형을 검증하고, 새 파일을 완성한 뒤 같은 위치에서 교체하면 중간 쓰기 실패에 대응하기 쉽습니다. 어떤 상황에서 적용하나요? 아래는 임시 폴더에서 저장과 재읽기를 확인합니다. 비밀번호를 저장하지 않고 화면 너비 같은 비민감 설정만 다룹니다. 원자적 교체는 보통 같은 파일시스템 안에서 수행해야 합니다. 검증 범위: 아래 코드는 외부 서비스에 요청하지 않는 로컬 예제입니다. 실제 서비스 연결은 별도로 검증해야 합니다. 최소 예제로 동작 확인하기 from pathlib import Path from tempfile import TemporaryDirectory import json import os with TemporaryDirectory() as folder: path = Path(folder) / "settings.json" temporary = path.with_suffix(".tmp") settings = {"window_width": 800, "theme": "light"} temporary.write_text(json.dumps(settings), encoding="utf-8") os.replace(temporary, path) loaded = json.loads(path.read_text(encoding="utf-8")) if not isinstance(loaded.get("window_width"), int): raise ValueError("너비는 정수여야 합니다") assert loaded == settings print(loaded) 결과는 어떻게 확인하나요? 저장한 두 설정이 다시 출력됩니다. 실제 앱에서는 파일이 없을 때 기본값을 쓰고, 손상된 JSON일 때는 원본을 보...

자동화 실행 로그 만들기: 화면 출력과 파일 기록 분리

실행 로그는 발생 시각·단계·결과를 구조적으로 남기고, 화면 표시와 보관용 로그를 분리하는 편이 좋습니다. 어떤 상황에서 적용하나요? 아래 예제는 logging으로 메모리 스트림에 기록해 로그 문구를 검증합니다. 실제 GUI를 띄우지 않습니다. GUI에 표시할 때는 메인 스레드에서 스트림의 메시지나 큐 이벤트를 읽어 위젯에 추가하세요. 검증 범위: 아래 코드는 외부 서비스에 요청하지 않는 로컬 예제입니다. 실제 서비스 연결은 별도로 검증해야 합니다. 최소 예제로 동작 확인하기 import io import logging stream = io.StringIO() handler = logging.StreamHandler(stream) handler.setFormatter(logging.Formatter("%(levelname)s %(message)s")) logger = logging.getLogger("work-demo") logger.setLevel(logging.INFO) logger.addHandler(handler) logger.propagate = False try: logger.info("job=%s result=%s", "daily", "completed") text = stream.getvalue() assert "job=daily result=completed" in text print(text.strip()) finally: logger.removeHandler(handler) handler.close() 결과는 어떻게 확인하나요? INFO 수준의 작업 결과 한 줄이 출력됩니다. 같은 로거에 핸들러를 반복 추가하면 메시지가 여러 번 표시될 수 있으므로 생성과 종료 수명을 관리해야 합니다. 실제 업무에 적용할 때 확인할 점 긴 작업의 모든 행을 화면에 계속 쌓으면 UI가 느려질 수 있습니...