LG DX DATA SCHOOL

12/19

getfeelingsfrom 2025. 12. 19. 17:44

함수 = 1번의 선언 + 여러 번의 호출로 코드를 재사용한다

1) 멀티프로세스(Multi-process)란?

하나의 프로그램을 여러 개의 “프로세스”로 나눠 동시에(또는 병렬로) 실행하는 방식

  • 프로세스: 실행 중인 프로그램 1개(각각 독립된 메모리 공간을 가짐)
  • 멀티프로세스는 보통
    • 동시에 여러 작업 처리(성능/응답성 향상)
    • 장애 격리(한 프로세스가 죽어도 다른 프로세스는 영향 적음)
      를 위해 씁니다.

예시:

  • 웹서버가 여러 요청을 동시에 처리하려고 요청마다 프로세스를 분리
  • 데이터 처리 파이프라인에서 “수집 / 전처리 / 분석 / 저장”을 프로세스로 쪼개 병렬 처리

2) “개발 비용”은 왜 커질까?

개발 비용은 단순히 코딩 시간만이 아니라 보통 이런 것들이 합쳐져요.

  • 요구사항 변경 대응 비용
  • 디버깅/테스트/품질 보증 비용
  • 유지보수 비용(운영 중 장애, 기능 추가)
  • 인수인계/문서화 비용
  • 일정 지연으로 인한 기회비용

그래서 소프트웨어 공학은 “코드 잘 짜기”를 넘어서
비용이 커지는 구조를 미리 설계로 막는 학문


3) 개발 비용 절감 → 재사용 → 모듈화가 필요한 이유

재사용을 하려면 코드가 떼어서 다시 붙일 수 있는 형태여야 합니다.
그걸 가능하게 만드는 게 모듈화예요.

모듈화 정의

  • 독립적으로 쪼개서 다룰 수 있도록 분리하는 것
  • 각 모듈은 “자기 책임”이 명확하고
  • 밖에서는 “정해진 인터페이스(사용법)”로만 접근하게 만들기

 

 


 

소프트웨어 공학 = 전체적인 생명 주기 ( 발생 개발~ 폐기) 발생 하는 비용 줄이기 위한 방안 

비용절감을 위한 효율적인 프로그래밍 방법론 

개발 비용 

개발 비용 절감 -> 코드를 재사용 ( 기간 압축 ) = 모듈화 필요

모듈화? 독립적으로 쪼개서 다룰 수 있게 해야 됨 

어떻게 쪼갤까? 하나의 단위를 '함수'를 통해 기능(하나의 입력 -> 출력)  단위로 분리 

 


 

함수 = 1번의 선언 + 여러 번의 호출로 코드를 재사용한다

연산 = 기능 

x(입력)-> 기능(function) -> y(결과)

 

max = 0

 

#메모리 초기화 

# 대입연산자 왜 필요? 값을 저장하기 위한 메모리 공간 확보하기 위해서 

 
 if x> y : 
     max = x
 else: 
     max = y



else 문 없이 구현할 수 있는 방법
임의의 변수 하나를 max로 지정하고 시작 

 max = x
 if x<y: 
     max = y 
 print(max)

 

def get_max(x,y): // c언어 계열 

def_getMax(x,y) // Java 계열 -> 카멜 방법 

 

#함수 정의 = 정의문 
def getMax(a,b): #c계열 함수 정의 
    max = a
    if b>max: 
        max = b 
    return max

##---main
x=10
y=20
##call
result = getMax(x,y) #함수호출
print("1.더 큰 값은: ", result)

x=30
y=15
#호출문
result = getMax(x,y)
print("2.더 큰 값은: ", result)

 

 


1. 파일의 종류와 형태

컴퓨터에서 다루는 파일은 크게 내용과 목적에 따라 구분할 수 있다.

① 코드 파일 / 실행 파일 (데이터 + 코드)

  • 프로그램 코드와 실행에 필요한 정보가 함께 포함된 파일
  • 대표적인 예:
    • *.exe (Windows 실행 파일)

② 데이터 파일 – 텍스트 데이터

  • 사람이 읽을 수 있는 문자 기반 데이터
  • 예:
    • *.txt
    • *.csv
    • *.log

 


③ 데이터 파일 – 멀티미디어(색상/이미지)

  • 픽셀, 색상 정보 등 이진 데이터로 구성
  • 예:
    • *.bmp
    • *.png
    • *.jpg

2. 왜 파일 처리가 필요한가?

프로그램이 실행되면 모든 작업은 메모리(RAM) 위에서 이루어진다.
하지만 메모리는 휘발성이 있기 때문에 프로그램 종료 시 데이터가 사라진다.

그래서 프로그램은 다음과 같은 작업이 필요하다.

  • 분석할 데이터 준비
  • 이전 실행 결과 불러오기
  • 대용량 데이터 관리

이때 사용하는 것이 파일이다.


3. 입력(Input)과 출력(Output)의 개념

입력(Input)

외부에 따로 관리되던 파일로부터 데이터를 메모리로 불러오는 작업

  • 예:
    • 파일 읽기
    • 키보드 입력
    • 센서 데이터 수신
 
파일(외부) → 메모리

출력(Output)

메모리에 있는 데이터를 장치나 파일로 내보내는 작업

  • 예:
    • 화면 출력
    • 파일 저장
    • 프린터 출력
 
메모리 → 파일 / 장치

CPU의 역할

CPU는 직접 데이터를 옮기지 않는다.
대신 **제어 신호(control signal)**를 보내 입출력 장치가 동작하도록 한다.

 
print(result)

이 한 줄도 내부적으로는:

  • CPU가 출력 장치에 “출력하라”는 제어 신호를 전달
  • 장치가 메모리에 있는 데이터를 읽어 화면에 표시

라는 과정을 거친다.


4. I/O와 네트워크의 차이

I/O (입출력)

  • 로컬 시스템 내부에서의 데이터 이동
  • 예:
    • 파일 읽기/쓰기
    • 키보드, 모니터, 디스크

네트워크

  • 로컬 시스템 밖에서 일어나는 데이터 이동
  • 예:
    • 서버 ↔ 클라이언트 통신
    • 인터넷 데이터 송수신

5. 스트림(Stream)의 개념

스트림은 입출력을 이해하는 데 매우 중요한 개념이다.

스트림이란?

데이터가 한 방향으로만 흐르는 통로

  • 단방향이다.
    • 입력 스트림(Input Stream)
    • 출력 스트림(Output Stream)

 

 

#stream 생성하는 함수 ( 경로를 필요로 함 ) 
f= open("text.txt", "r") #독점권 제공 => 다른 프로세스가 사용 불가 
line = f.readline()
print (line)

f.close()

 

 

 

  • open() : 파일과 프로그램 사이에 입력 스트림 생성
  • readline() : 한 줄만 읽음 (개행 문자 \n 포함)
  • close() : 파일 사용 종료 (자원 반환)

 

#while
f= open("text.txt", "r")  
while True: 
    line = f.readline()
    if not line:#파이썬에는 EOF가 없다 -> not line으로 
        break
    print(line)
f.close()

 

 

  • Python에는 EOF 상수/키워드가 없음
  • 파일 끝에 도달하면
    👉 readline() → "" (빈 문자열) 반환

 

if not line:

 

 

 

 

#For문
f= open("text.txt", "r") 
for line in f:
    print (line)

f.close()
  • open() → 파일 객체(스트림) 생성
  • 파일 객체 f는 이터러블(iterable)
  • for line in f:
    → 내부적으로 다음과 같은 동작을 반복
    • 한 줄 읽기
    • EOF 도달 시 자동 종료
  • EOF 판단을 직접 하지 않아도 됨

➡ readline() + EOF 검사를 파이썬이 대신 처리

 

 

줄바꿈 뒤에 자동으로 들어가는 엔터 없애는 방법 

print(line, end="")

 

  • line 끝에 이미 \n 포함되었기 때문에 print()도 \n 추가됨 -> 줄 간격이 한 줄씩 더 벌어질 수 있음

    -> end ="" 로 줄바꿈 방지 

 

 


 

1️⃣ * 하나 (*args) — 위치 인자 (positional arguments)

 
def print_args(*args): 
	print(args)

의미

  • 여러 개의 위치 인자를 받음
  • 전달된 값들은 튜플(tuple) 로 묶임

호출 예시

 
print_args(1, 2, 3)
#출력 : (1, 2, 3)

핵심 요약

  • *args → 값만 받는다
  • 키워드 이름 없음
  • 결과 타입: tuple

2️⃣ ** 두 개 (**args) — 키워드 인자 (keyword arguments)

 
def print_args(**args): 
	print(args)

의미

  • 여러 개의 키워드 인자를 받음
  • 전달된 이름=값 쌍이 딕셔너리(dict) 로 묶임

호출 예시

 
print_args(name="Alice", age=20)

#출력 {'name': 'Alice', 'age': 20}

핵심 요약

  • **args → 이름=값 쌍을 받는다
  • 결과 타입: dict

 


 

1️⃣ 함수 정의: 여러 값 반환의 실체

 
def add_and_mul(a, b): 
	return (a+b, a*b)
    
 # 출력 (a+b, a*b)

중요한 사실

  • Python 함수는 값을 하나만 반환
  • 여기서는 튜플(tuple) 하나를 반환
 
 

2️⃣ 튜플 언패킹으로 받기 (가장 권장)

 
(r1, r2) = add_and_mul(3, 4) 
print(r1) 
print(r2)

#출력 7 12

동작

  • 반환된 튜플 (7, 12)을
  • r1, r2에 순서대로 분해(언패킹)

 


3️⃣ 구조분해 할당 - 하나의 변수로 받기

 
result = add_and_mul(3, 4) 
result

#출력 (7,12)

결과

(7, 12)
  • result의 타입: tuple

4️⃣ 인덱스로 접근 (튜플 성질 사용)

 
result = add_and_mul(3, 4) 
rs1 = result[0] 
rs2 = result[1] 
print(rs1, rs2)

출력 : 7 12

출력

 
7 12
  • 튜플은 순서 있음
  • 인덱스 접근 가능

 


 

람다 함수 (익명 함수)

(lambda x, y: x + y)(10, 20)

구성

 
lambda 매개변수들 : 표현식
  • 이름이 없는 익명 함수
  • 반드시 하나의 표현식만 가능
  • return 키워드 사용 불가
  • 표현식의 결과가 자동으로 반환됨
  • 한줄짜리 함수 - > 쓰고 버릴 때 사용 

 

 


#문제 1

 

아~ 구조가 2차구낭 ! 

 

#1번 
students = [
    ["홍길동", 78, 79, 85, 88],
    ["김길동", 88, 67, 59, 90],
    ["이길동", 83, 77, 82, 81]
]

#총점 계산하는 함수 
def calc_total(students):
    return sum(students[1:])

# 학생 정보를 출력하는 함수
def print_student(name):
    for s in students:
        if s[0] == name:
            stuInfo = {
                "이름": s[0],
                "국어": s[1],
                "수학": s[2],
                "영어": s[3],
                "과학": s[4],
                "총점": calc_total(s)
            }
    return stuInfo

print_student("홍길동")

 

 

 

#문제2

#문제 2
customers=[
    {"고객명": "홍길동", "고객번호": 101, "상품A" : 79, "상품B": 85, "상품C" : 88},
    {"고객명": "김길동", "고객번호": 102, "상품A" : 67, "상품B": 59, "상품C" : 90},
    {"고객명": "이길동", "고객번호": 103, "상품A" : 77, "상품B": 82, "상품C" : 81},
    {"고객명": "박길동", "고객번호": 104, "상품A" : 90, "상품B": 88, "상품C" : 92}
]

#문제2-1 총구매 금액 계산 -> 딕셔너리에 추가 
def add_calc_total(customers):
    for cost in customers:
        total = cost["상품A"] + cost["상품B"] + cost["상품C"]
        cost["총구매금액"] = total


add_calc_total(customers)
print(customers)

#문제 2-2 총구매 금액의 평균
def avg_calc_total(customers):
    add_calc_total(customers)
    totalTotal = 0          
    for cost in customers: 
        totalTotal += cost["총구매금액"]
    avgCost = totalTotal / 4
    return avgCost

print(avg_calc_total(customers))

#문제3 총 구매 금액이 가장 높은 고객의 이름 반환

def high_total_cost(customers):
    highTotalCost = customers[0]["총구매금액"] 
    highTotalName = customers[0]["고객명"]
    for cost in customers:
        if cost["총구매금액"] > highTotalCost:
            highTotalCost = cost["총구매금액"]
            highTotalName = cost["고객명"]
    return highTotalName

high_total_cost(customers)