2주차 · 변수와 연산자
- 웹 실행 환경에서 코드를 넣고 결과를 확인하는 흐름을 이해한다.
- 변수와 자료형의 역할을 정확히 구분한다.
int(),float(),str()를 이용한 기본 형변환을 직접 수행할 수 있다.=대입과+,-,*,/같은 기본 연산을 식 순서대로 읽을 수 있다.- 괄호와 중간 변수를 사용해 계산 의도를 분명하게 표현한다.
- 단위 변환을 안전하게 수행하는 기본 패턴을 익힌다.
- C와 Python의 변수/연산자 차이 중 초보자가 많이 헷갈리는 지점을 비교할 수 있다.
1) 변수: 값을 담는 이름표이자 계산의 기준점
Section titled “1) 변수: 값을 담는 이름표이자 계산의 기준점”변수는 단순한 상자가 아니라 값의 의미를 고정하는 이름표입니다.
distance_m: 거리(m)time_s: 시간(s)speed_mps: 속도(m/s)
왜 변수명이 중요한가?
Section titled “왜 변수명이 중요한가?”- 공학 계산은 값 자체보다 무엇의 값인지가 더 중요합니다.
- 단위가 빠진 이름은 나중에 다시 볼 때 큰 함정을 만듭니다.
- 변수명 자체가 짧은 설명문 역할을 해 디버깅 시간을 줄여 줍니다.
좋은 변수명 기준
Section titled “좋은 변수명 기준”- 물리적 의미가 드러난다.
- 단위를 포함한다.
- 다시 읽어도 혼동이 없다.
Good
radar_frequency_ghz = 24.0c_m_per_s = 3.0e8wavelength_m = c_m_per_s / (radar_frequency_ghz * 1e9)Bad
x = 24.0y = 3.0e8z = y / (x * 1e9)설명: x, y, z는 처음 작성한 사람도 며칠 뒤에는 의미를 잊기 쉽습니다.
2) 자료형: 값의 성격이 다르면 가능한 연산도 달라진다
Section titled “2) 자료형: 값의 성격이 다르면 가능한 연산도 달라진다”자주 쓰는 자료형:
int: 정수 (예: 샘플 개수)float: 실수 (예: 주파수, 전압)str: 문자열 (예: 장비 이름)bool: 참/거짓 (예: 측정 성공 여부)
sample_count = 128 # intvoltage_v = 3.3 # floatsensor_name = "RX-A1" # stris_valid = True # bool핵심 이해: 자료형이 다르면 할 수 있는 연산도 달라진다
Section titled “핵심 이해: 자료형이 다르면 할 수 있는 연산도 달라진다”- 숫자형(
int,float)은 더하기, 빼기, 곱하기, 나누기 같은 계산이 중심입니다. - 문자열(
str)은 이어 붙이기, 길이 확인, 일부 잘라내기가 중심입니다. - 불리언(
bool)은 조건 판단이 중심입니다.
즉, 값과 자료형은 항상 함께 생각해야 합니다.
형변환(type conversion)이란?
Section titled “형변환(type conversion)이란?”형변환은 값의 자료형을 계산 목적에 맞게 바꾸는 것입니다.
"12"→12: 문자열을 정수로"3.14"→3.14: 문자열을 실수로24→"24": 숫자를 문자열로
초보자 관점에서 가장 중요한 상황은 입력값은 문자열인데 계산은 숫자로 해야 할 때입니다.
자주 쓰는 형변환 함수
Section titled “자주 쓰는 형변환 함수”| 함수 | 용도 | 예시 | 결과 |
|---|---|---|---|
int() | 정수로 변환 | int("12") | 12 |
float() | 실수로 변환 | float("3.14") | 3.14 |
str() | 문자열로 변환 | str(24) | "24" |
형변환 예시 1: 문자열 전압/전류를 계산용 숫자로 바꾸기
Section titled “형변환 예시 1: 문자열 전압/전류를 계산용 숫자로 바꾸기”Bad
voltage_v = "12.5"current_a = "0.8"power_w = voltage_v * current_aGood
voltage_v = float("12.5")current_a = float("0.8")power_w = voltage_v * current_aprint(power_w)설명: 문자열끼리는 공학 계산이 되지 않습니다. float()로 바꾼 뒤 곱해야 전력 계산이 가능합니다.
형변환 예시 2: 계산 결과를 사람이 읽는 문자열로 바꾸기
Section titled “형변환 예시 2: 계산 결과를 사람이 읽는 문자열로 바꾸기”frequency_ghz = 24label = "Radar frequency = " + str(frequency_ghz) + " GHz"print(label)설명: 숫자는 계산에 편하지만, 화면에 설명문과 함께 붙일 때는 str()로 문자열로 바꾸면 연결하기 쉽습니다. 실무에서는 f-string도 많이 쓰지만, 지금은 str()가 하는 일을 먼저 이해하는 것이 중요합니다.
형변환에서 특히 주의할 점
Section titled “형변환에서 특히 주의할 점”int(3.9)의 결과는3입니다. 소수점 아래가 사라집니다."12.0"은int("12.0")로 바로 바꿀 수 없습니다. 먼저float("12.0")처럼 해석해야 합니다.- 입력이 숫자처럼 보여도 따옴표가 있으면 문자열입니다.
3) 대입과 연산자: 식을 차례대로 읽는 법
Section titled “3) 대입과 연산자: 식을 차례대로 읽는 법”3-1) = : 오른쪽 값을 왼쪽 변수에 저장한다
Section titled “3-1) = : 오른쪽 값을 왼쪽 변수에 저장한다”초보자가 가장 먼저 정확히 이해해야 할 기호는 =입니다.
distance_m = 120.0time_s = 4.0speed_mps = distance_m / time_s이 코드는 아래 순서로 읽습니다.
distance_m = 120.0- 오른쪽의
120.0값을 왼쪽 변수distance_m에 저장합니다.
- 오른쪽의
time_s = 4.0- 오른쪽의
4.0값을 왼쪽 변수time_s에 저장합니다.
- 오른쪽의
speed_mps = distance_m / time_s- 먼저 오른쪽 식
distance_m / time_s를 계산합니다. - 계산 결과를 왼쪽 변수
speed_mps에 저장합니다.
- 먼저 오른쪽 식
핵심은 오른쪽에서 값이나 식을 준비하고, 왼쪽 변수에 넣는다는 점입니다.
3-2) + : 값을 더한다
Section titled “3-2) + : 값을 더한다”base_voltage_v = 5.0extra_voltage_v = 1.2total_voltage_v = base_voltage_v + extra_voltage_vprint(total_voltage_v)+는 두 값을 합칩니다.- 위 코드는
5.0 + 1.2를 계산한 뒤 결과6.2를total_voltage_v에 저장합니다. - 공학 계산에서는 여러 기여분을 합쳐 전체 값을 만들 때 자주 씁니다.
3-3) - : a - b는 a에서 b를 뺀다
Section titled “3-3) - : a - b는 a에서 b를 뺀다”target_temp_c = 80.0measured_temp_c = 74.5error_temp_c = target_temp_c - measured_temp_cprint(error_temp_c)-는 앞의 값에서 뒤의 값을 뺍니다.- 위 코드는 목표 온도
target_temp_c에서 실제 측정 온도measured_temp_c를 빼서 차이5.5를 계산합니다. - 제어 오차, 거리 차이, 손실량 계산에서 자주 등장합니다.
3-4) * : 값을 곱한다
Section titled “3-4) * : 값을 곱한다”power_w = 2.5time_s = 8.0energy_j = power_w * time_sprint(energy_j)*는 두 값을 곱합니다.- 위 코드는 전력 × 시간으로 에너지
20.0 J를 계산합니다. - 비율 확대, 면적 계산, 전력·에너지 계산에서 기본적으로 사용합니다.
3-5) / : 값을 나눈다
Section titled “3-5) / : 값을 나눈다”distance_m = 120.0time_s = 4.0speed_mps = distance_m / time_sprint(speed_mps)/는 나눗셈입니다.- 위 코드는 거리 120 m를 시간 4 s로 나누어 속도
30.0 m/s를 계산합니다. - 평균, 속도, 밀도, 비율 계산에 매우 자주 쓰입니다.
3-6) ** : 거듭제곱을 계산한다
Section titled “3-6) ** : 거듭제곱을 계산한다”voltage_v = 3.0power_like_value = voltage_v ** 2print(power_like_value)**는 거듭제곱입니다.- 위 코드는
3.0 × 3.0과 같은 값인9.0을 계산합니다. - 제곱거리, 분산, 에너지식처럼 같은 값을 여러 번 곱할 때 사용합니다.
3-7) % : 나머지를 구한다
Section titled “3-7) % : 나머지를 구한다”total_samples = 10group_size = 4remain_samples = total_samples % group_sizeprint(remain_samples)%는 나머지를 구합니다.- 위 코드는 10개를 4개씩 묶었을 때 2개가 남는다는 뜻입니다.
- 짝수/홀수 판정, 블록 처리, 남은 데이터 수 확인에 유용합니다.
3-8) == : 같은지 비교한다 (=와 다름)
Section titled “3-8) == : 같은지 비교한다 (=와 다름)”score = 90print(score == 90)==는 “왼쪽 값과 오른쪽 값이 같은가?”를 묻는 비교 연산자입니다.- 결과는
True또는False입니다. =는 저장,==는 비교입니다. 둘은 역할이 완전히 다릅니다.
3-9) 정수의 다른 표현: 2진수, 16진수
Section titled “3-9) 정수의 다른 표현: 2진수, 16진수”Python은 숫자 앞에 접두어를 붙여 2진수, 8진수, 16진수 리터럴을 바로 쓸 수 있습니다.
| 접두어 | 진법 | 예시 | 10진수 값 |
|---|---|---|---|
0b | 2진수 | 0b1010 | 10 |
0o | 8진수 | 0o17 | 15 |
0x | 16진수 | 0xFF | 255 |
변환 함수도 함께 알아 두세요.
| 함수 | 역할 | 예시 | 결과 |
|---|---|---|---|
bin(n) | 정수 → 2진수 문자열 | bin(10) | '0b1010' |
oct(n) | 정수 → 8진수 문자열 | oct(15) | '0o17' |
hex(n) | 정수 → 16진수 문자열 | hex(255) | '0xff' |
reg_value = 0b11010110 # 2진수 리터럴addr = 0x1F4 # 16진수 리터럴color = 0xFF8800 # 16진수 색상 코드
print(reg_value) # 214print(bin(reg_value)) # 0b11010110print(hex(addr)) # 0x1f43-10) 비트 연산자
Section titled “3-10) 비트 연산자”비트 연산자는 정수를 비트(0/1) 단위로 직접 다룹니다.
| 연산자 | 이름 | 예시 (4비트 기준) | 결과 |
|---|---|---|---|
& | AND | 0b1100 & 0b1010 | 0b1000 (8) |
| | OR | 0b1100 | 0b1010 | 0b1110 (14) |
^ | XOR | 0b1100 ^ 0b1010 | 0b0110 (6) |
~ | NOT | ~0b0000_1111 | 비트 전체 반전 |
<< | 왼쪽 시프트 | 0b0001 << 2 | 0b0100 (4) |
>> | 오른쪽 시프트 | 0b1000 >> 2 | 0b0010 (2) |
EE 응용: 레지스터의 특정 비트를 추출할 때 마스킹과 시프트를 조합합니다.
# 상태 레지스터에서 팬 비트(bit 2) 추출status_reg = 0b11010110fan_bit = (status_reg >> 2) & 1print("fan_bit:", fan_bit) # 1 또는 0status_reg >> 2: 오른쪽으로 2비트 밀어 bit 2를 최하위 자리로 가져옵니다.& 1: 최하위 비트만 남기고 나머지는 0으로 만듭니다.
3-11) 부동소수점 오차 (float precision)
Section titled “3-11) 부동소수점 오차 (float precision)”Python의 float는 IEEE 754 표준을 따르며, 10진수 소수를 2진수로 표현하는 과정에서 미세한 오차가 생깁니다.
print(0.1 + 0.2) # 0.30000000000000004print(0.1 + 0.2 == 0.3) # False0.1과 0.2는 2진수로 정확히 표현할 수 없어 내부적으로 아주 작은 오차를 가집니다. 두 값을 더하면 오차가 누적돼 0.3과 완전히 같지 않습니다.
안전한 비교 방법
Section titled “안전한 비교 방법”두 실수가 “충분히 같은지” 비교할 때는 == 대신 오차 허용 범위를 사용합니다.
a = 0.1 + 0.2b = 0.3print(abs(a - b) < 1e-9) # True4) 연산자 우선순위: 괄호로 의도를 드러내기
Section titled “4) 연산자 우선순위: 괄호로 의도를 드러내기”기본적으로 *, /가 +, -보다 먼저 계산됩니다.
result1 = 10 + 2 * 3 # 16result2 = (10 + 2) * 3 # 36핵심 규칙: 헷갈리면 괄호로 계산 순서를 고정하세요.
Good
import math
signal_power_w = 0.08noise_power_w = 0.002snr_linear = signal_power_w / noise_power_wsnr_db = 10 * math.log10(snr_linear)Bad
import math
signal_power_w = 0.08noise_power_w = 0.002snr_db = 10 * math.log10(signal_power_w / noise_power_w + 1)설명: Bad 코드는 + 1이 왜 필요한지 드러나지 않아 해석 오류를 부르기 쉽습니다.
5) 단위 변환: 계산 전에 표준 단위로 먼저 통일
Section titled “5) 단위 변환: 계산 전에 표준 단위로 먼저 통일”단위 실수는 결과를 10배에서 10억배까지 틀리게 만들 수 있습니다.
자주 쓰는 변환:
- GHz → Hz:
f_hz = f_ghz * 1e9 - ms → s:
t_s = t_ms / 1000 - cm → m:
d_m = d_cm / 100 - mW → W:
p_w = p_mw / 1000
예제 1 · 주파수에서 파장 구하기
Section titled “예제 1 · 주파수에서 파장 구하기” 예제 1 줄별 해설
Section titled “예제 1 줄별 해설”c_m_per_s = 3.0e8- 빛의 속도를 표준 단위(m/s)로 저장합니다.
frequency_ghz = 24.0- 입력 주파수를 GHz 단위로 저장합니다.
frequency_hz = frequency_ghz * 1e9- 계산 전에 GHz를 Hz로 바꿉니다.
wavelength_m = c_m_per_s / frequency_hz- \(\lambda = c / f\) 식으로 파장을 계산합니다.
print(...)- 입력값과 결과값을 각각 출력해 사람이 바로 검산할 수 있게 합니다.
예제 1 점검 포인트
Section titled “예제 1 점검 포인트”frequency_hz = frequency_ghz * 1e9줄을 지우면 결과가 얼마나 이상해지는지 확인해 보세요.print(type(frequency_ghz), type(frequency_hz), type(wavelength_m))로 자료형도 직접 확인해 보세요.
예제 2 · 옴의 법칙으로 전류와 전력 구하기
Section titled “예제 2 · 옴의 법칙으로 전류와 전력 구하기” 예제 2 줄별 해설
Section titled “예제 2 줄별 해설”voltage_v = 12.0- 전압 값을 V 단위로 저장합니다.
resistance_ohm = 6.0- 저항 값을 ohm 단위로 저장합니다.
current_a = voltage_v / resistance_ohm- 옴의 법칙
I = V / R을 그대로 코드로 적습니다.
- 옴의 법칙
power_w = voltage_v * current_a- 전력 식
P = V × I를 계산합니다.
- 전력 식
print(...)- 최종 결과를 값과 단위까지 붙여 출력합니다.
자주 하는 실수 5가지: 표 내용을 코드로 보기
Section titled “자주 하는 실수 5가지: 표 내용을 코드로 보기”실수 1) 문자열로 입력받고 바로 계산
Section titled “실수 1) 문자열로 입력받고 바로 계산”Bad
voltage_v = "12.0"resistance_ohm = "6"current_a = voltage_v / resistance_ohmGood
voltage_v = float("12.0")resistance_ohm = float("6")current_a = voltage_v / resistance_ohm설명: 문자열은 계산용 숫자가 아닙니다. 입력이 문자열이라면 float() 또는 int()로 먼저 바꿔야 합니다.
실수 2) 단위 변환을 빼먹고 계산
Section titled “실수 2) 단위 변환을 빼먹고 계산”Bad
c_m_per_s = 3.0e8frequency_ghz = 24.0wavelength_m = c_m_per_s / frequency_ghzGood
c_m_per_s = 3.0e8frequency_ghz = 24.0frequency_hz = frequency_ghz * 1e9wavelength_m = c_m_per_s / frequency_hz설명: 24.0 GHz를 24.0 Hz처럼 취급하면 결과가 완전히 틀어집니다. 계산에 들어가기 전에 표준 단위로 먼저 바꾸세요.
실수 3) =와 ==를 혼동
Section titled “실수 3) =와 ==를 혼동”Bad
score = 90print(score = 90)Good
score = 90print(score == 90)설명: =는 값을 저장하는 기호이고, ==는 두 값이 같은지 비교하는 기호입니다. 저장과 비교는 완전히 다른 동작입니다.
실수 4) 괄호 없이 긴 식을 한 줄에 몰아 쓰기
Section titled “실수 4) 괄호 없이 긴 식을 한 줄에 몰아 쓰기”Bad
value = 10 + 2 * 3 - 4 / 2Good
value = (10 + (2 * 3)) - (4 / 2)설명: 파이썬은 규칙대로 계산하지만, 사람은 긴 식을 읽다가 쉽게 실수합니다. 괄호를 쓰면 계산 순서와 의도가 바로 드러납니다.
실수 5) 의미 없는 축약 변수명을 쓰기
Section titled “실수 5) 의미 없는 축약 변수명을 쓰기”Bad
a = 120.0b = 4.0c = a / bGood
distance_m = 120.0time_s = 4.0speed_mps = distance_m / time_s설명: a, b, c는 지금은 알아도 나중에는 거의 기억나지 않습니다. 변수명에 물리량과 단위를 넣으면 코드가 곧 설명문이 됩니다.
실수/오류 빠른 정리표
Section titled “실수/오류 빠른 정리표”| 실수 | 증상 | 원인 | 해결 |
|---|---|---|---|
| 문자열로 입력받고 바로 계산 | TypeError/문자열 결합 | 형변환 누락 | float() 또는 int()로 즉시 변환 |
| 단위 변환 누락 | 물리적으로 비정상 값 | GHz→Hz 등 변환 생략 | 입력 직후 표준 단위 변수 생성 |
=와 == 혼동 | 조건식 문법 오류/오동작 | 대입/비교 개념 혼동 | 대입은 =, 비교는 ==로 구분 |
| 괄호 없이 긴 식 작성 | 예상과 다른 결과 | 우선순위 착각 | 괄호 + 중간 변수로 분리 |
변수명 축약(a,b,c) | 디버깅 시간 증가 | 의미/단위 정보 부재 | quantity_unit 패턴 사용 |
6) C와 Python의 변수·연산자 차이 정리
Section titled “6) C와 Python의 변수·연산자 차이 정리”학생들이 다른 수업에서 C를 배우면, 같은 “변수”와 “연산자”라도 쓰는 방식이 조금 다릅니다. 여기서는 2주차 기준으로 가장 자주 헷갈리는 차이만 정리합니다.
| 항목 | C | Python | 초보자 체크 포인트 |
|---|---|---|---|
| 변수 선언 | int count = 10;처럼 자료형을 먼저 씀 | count = 10처럼 값부터 넣음 | Python도 의미와 단위가 드러나는 이름을 써야 함 |
| 변수 타입 변경 | 같은 변수의 타입을 함부로 바꾸기 어려움 | x = 10 뒤 x = "ten"도 가능 | 가능하더라도 수업에서는 한 변수에 한 역할 유지 |
| 나눗셈 | 5 / 2가 정수 나눗셈이면 2 | 5 / 2는 2.5, 5 // 2는 2 | C 감각으로 /를 읽으면 실수함 |
| 거듭제곱 | pow(a, b) 또는 반복 곱셈 | a ** b | ^는 거듭제곱이 아님 |
| 조건 비교 | if (score == 90) | if score == 90: | =는 대입, ==는 비교 |
차이 1) 변수 선언 방식
Section titled “차이 1) 변수 선언 방식”C
int sample_count = 128;float voltage_v = 3.3f;Python
sample_count = 128voltage_v = 3.3설명: C는 자료형을 먼저 선언하고 세미콜론으로 문장을 끝냅니다. Python은 값이 들어가면서 자료형이 정해집니다. 대신 Python에서도 변수명은 더 명확하게 써야 합니다.
차이 2) 같은 이름의 자료형이 바뀔 수 있다
Section titled “차이 2) 같은 이름의 자료형이 바뀔 수 있다”C
int value = 10;/* value = "ten"; // 오류 */Python
value = 10value = "ten"print(value)설명: Python에서는 문법상 가능하지만, 초보자 코드에서는 한 변수에 숫자 역할과 문자열 역할을 섞지 않는 것이 좋습니다. 이름은 같아도 의미가 바뀌면 디버깅이 훨씬 어려워집니다.
차이 3) 나눗셈 결과 해석이 다르다
Section titled “차이 3) 나눗셈 결과 해석이 다르다”C
int a = 5;int b = 2;/* a / b 의 결과는 2 */Python
a = 5b = 2print(a / b) # 2.5print(a // b) # 2설명: Python의 /는 실수 결과를 주고, //는 몫만 남깁니다. C를 먼저 배운 학생은 이 차이를 특히 주의해야 합니다.
차이 4) 거듭제곱 표기가 다르다
Section titled “차이 4) 거듭제곱 표기가 다르다”C
/* pow(x, 2) 사용 또는 x * x */Python
x = 3print(x ** 2) # 9설명: ^는 C와 Python 모두 거듭제곱이 아니라 비트 XOR입니다. “제곱”을 쓰고 싶을 때 ^를 쓰지 않도록 주의하세요.
차이 5) 문자열과 숫자를 다루는 방식이 더 직접적이다
Section titled “차이 5) 문자열과 숫자를 다루는 방식이 더 직접적이다”C
/* printf("frequency = %d GHz\n", frequency_ghz); */Python
frequency_ghz = 24print("frequency =", frequency_ghz, "GHz")print("frequency = " + str(frequency_ghz) + " GHz")설명: Python은 출력이 훨씬 간단하지만, 문자열 연결을 할 때는 str() 같은 형변환이 여전히 필요합니다.
학생 실습 · 직접 코딩
Section titled “학생 실습 · 직접 코딩”문제: 24 GHz 전파의 파장을 계산하세요.
문제: 옴의 법칙을 사용해 전류와 전력을 계산하세요.
문제: 섭씨를 화씨로 변환하고, 3개 측정값의 평균을 구하세요.
문제 (응용): 10진수 값을 2진수와 16진수로 변환하고, 반대로 2진수/16진수 리터럴을 10진수로 출력해 보세요.
문제 (도전): 8비트 상태 레지스터에서 비트 마스킹으로 각 필드를 추출하세요.
레지스터 0b10110101에서 bit[3:2](팬 속도)와 bit[0](전원 상태)를 각각 추출하세요.