학습 목표
- 웹 실행 환경에서 코드를 넣고 결과를 확인하는 흐름을 이해한다.
- 변수와 자료형의 역할을 정확히 구분한다.
int(),float(),str()를 이용한 기본 형변환을 직접 수행할 수 있다.=대입과+,-,*,/같은 기본 연산을 식 순서대로 읽을 수 있다.- 괄호와 중간 변수를 사용해 계산 의도를 분명하게 표현한다.
- 단위 변환을 안전하게 수행하는 기본 패턴을 익힌다.
- C와 Python의 변수/연산자 차이 중 처음 배우는 학생이 많이 헷갈리는 지점을 비교할 수 있다.
1) 변수: 값을 담는 이름표이자 계산의 기준점
변수는 단순한 상자가 아니라 값의 의미를 고정하는 이름표입니다.
distance_m: 거리(m)time_s: 시간(s)speed_mps: 속도(m/s)
왜 변수명이 중요한가?
- 공학 계산은 값 자체보다 무엇의 값인지가 더 중요합니다.
- 단위가 빠진 이름은 나중에 다시 볼 때 큰 함정을 만듭니다.
- 변수명 자체가 짧은 설명문 역할을 해 디버깅 시간을 줄여 줍니다.
좋은 변수명 기준
- 물리적 의미가 드러난다.
- 단위를 포함한다.
- 다시 읽어도 혼동이 없다.
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) 자료형: 값의 성격이 다르면 가능한 연산도 달라진다
자주 쓰는 자료형:
int: 정수 (예: 샘플 개수)float: 실수 (예: 주파수, 전압)str: 문자열 (예: 장비 이름)bool: 참/거짓 (예: 측정 성공 여부)
sample_count = 128 # intvoltage_v = 3.3 # floatsensor_name = "RX-A1" # stris_valid = True # bool핵심 이해: 자료형이 다르면 할 수 있는 연산도 달라진다
- 숫자형(
int,float)은 더하기, 빼기, 곱하기, 나누기 같은 계산이 중심입니다. - 문자열(
str)은 이어 붙이기, 길이 확인, 일부 잘라내기가 중심입니다. - 불리언(
bool)은 조건 판단이 중심입니다.
즉, 값과 자료형은 항상 함께 생각해야 합니다.
형변환(type conversion)이란?
형변환은 값의 자료형을 계산 목적에 맞게 바꾸는 것입니다.
"12"→12: 문자열을 정수로"3.14"→3.14: 문자열을 실수로24→"24": 숫자를 문자열로
처음 배우는 학생 입장에서 가장 중요한 상황은 입력값은 문자열인데 계산은 숫자로 해야 할 때입니다.
자주 쓰는 형변환 함수
| 함수 | 용도 | 예시 | 결과 |
|---|---|---|---|
int() | 정수로 변환 | int("12") | 12 |
float() | 실수로 변환 | float("3.14") | 3.14 |
str() | 문자열로 변환 | str(24) | "24" |
형변환 예시 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: 계산 결과를 사람이 읽는 문자열로 바꾸기
frequency_ghz = 24label = "Radar frequency = " + str(frequency_ghz) + " GHz"print(label)설명: 숫자는 계산에 편하지만, 화면에 설명문과 함께 붙일 때는 str()로 문자열로 바꾸면 연결하기 쉽습니다. 실무에서는 f-string도 많이 쓰지만, 지금은 str()가 하는 일을 먼저 이해하는 것이 중요합니다.
형변환에서 특히 주의할 점
int(3.9)의 결과는3입니다. 소수점 아래가 사라집니다."12.0"은int("12.0")로 바로 바꿀 수 없습니다. 먼저float("12.0")처럼 해석해야 합니다.- 입력이 숫자처럼 보여도 따옴표가 있으면 문자열입니다.
3) 대입과 연산자: 식을 차례대로 읽는 법
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) + : 값을 더한다
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를 뺀다
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) * : 값을 곱한다
power_w = 2.5time_s = 8.0energy_j = power_w * time_sprint(energy_j)*는 두 값을 곱합니다.- 위 코드는 전력 × 시간으로 에너지
20.0 J를 계산합니다. - 비율 확대, 면적 계산, 전력·에너지 계산에서 기본적으로 사용합니다.
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) ** : 거듭제곱을 계산한다
voltage_v = 3.0power_like_value = voltage_v ** 2print(power_like_value)**는 거듭제곱입니다.- 위 코드는
3.0 × 3.0과 같은 값인9.0을 계산합니다. - 제곱거리, 분산, 에너지식처럼 같은 값을 여러 번 곱할 때 사용합니다.
3-7) % : 나머지를 구한다
total_samples = 10group_size = 4remain_samples = total_samples % group_sizeprint(remain_samples)%는 나머지를 구합니다.- 위 코드는 10개를 4개씩 묶었을 때 2개가 남는다는 뜻입니다.
- 짝수/홀수 판정, 블록 처리, 남은 데이터 수 확인에 유용합니다.
3-8) == : 같은지 비교한다 (=와 다름)
score = 90print(score == 90)==는 “왼쪽 값과 오른쪽 값이 같은가?”를 묻는 비교 연산자입니다.- 결과는
True또는False입니다. =는 저장,==는 비교입니다. 둘은 역할이 완전히 다릅니다.
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) 비트 연산자
비트 연산자는 정수를 비트(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)
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과 완전히 같지 않습니다.
안전한 비교 방법
두 실수가 “충분히 같은지” 비교할 때는 == 대신 오차 허용 범위를 사용합니다.
a = 0.1 + 0.2b = 0.3print(abs(a - b) < 1e-9) # True4) 연산자 우선순위: 괄호로 의도를 드러내기
기본적으로 *, /가 +, -보다 먼저 계산됩니다.
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) 단위 변환: 계산 전에 표준 단위로 먼저 통일
단위 실수는 결과를 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 · 주파수에서 파장 구하기
예제 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 점검 포인트
frequency_hz = frequency_ghz * 1e9줄을 지우면 결과가 얼마나 이상해지는지 확인해 보세요.print(type(frequency_ghz), type(frequency_hz), type(wavelength_m))로 자료형도 직접 확인해 보세요.
예제 2 · 옴의 법칙으로 전류와 전력 구하기
예제 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가지: 표 내용을 코드로 보기
실수 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) 단위 변환을 빼먹고 계산
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) =와 ==를 혼동
Bad
score = 90print(score = 90)Good
score = 90print(score == 90)설명: =는 값을 저장하는 기호이고, ==는 두 값이 같은지 비교하는 기호입니다. 저장과 비교는 완전히 다른 동작입니다.
실수 4) 괄호 없이 긴 식을 한 줄에 몰아 쓰기
Bad
value = 10 + 2 * 3 - 4 / 2Good
value = (10 + (2 * 3)) - (4 / 2)설명: 파이썬은 규칙대로 계산하지만, 사람은 긴 식을 읽다가 쉽게 실수합니다. 괄호를 쓰면 계산 순서와 의도가 바로 드러납니다.
실수 5) 의미 없는 축약 변수명을 쓰기
Bad
a = 120.0b = 4.0c = a / bGood
distance_m = 120.0time_s = 4.0speed_mps = distance_m / time_s설명: a, b, c는 지금은 알아도 나중에는 거의 기억나지 않습니다. 변수명에 물리량과 단위를 넣으면 코드가 곧 설명문이 됩니다.
실수/오류 빠른 정리표
| 실수 | 증상 | 원인 | 해결 |
|---|---|---|---|
| 문자열로 입력받고 바로 계산 | TypeError/문자열 결합 | 형변환 누락 | float() 또는 int()로 즉시 변환 |
| 단위 변환 누락 | 물리적으로 비정상 값 | GHz→Hz 등 변환 생략 | 입력 직후 표준 단위 변수 생성 |
=와 == 혼동 | 조건식 문법 오류/오동작 | 대입/비교 개념 혼동 | 대입은 =, 비교는 ==로 구분 |
| 괄호 없이 긴 식 작성 | 예상과 다른 결과 | 우선순위 착각 | 괄호 + 중간 변수로 분리 |
변수명 축약(a,b,c) | 디버깅 시간 증가 | 의미/단위 정보 부재 | quantity_unit 패턴 사용 |
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) 변수 선언 방식
C
int sample_count = 128;float voltage_v = 3.3f;Python
sample_count = 128voltage_v = 3.3설명: C는 자료형을 먼저 선언하고 세미콜론으로 문장을 끝냅니다. Python은 값이 들어가면서 자료형이 정해집니다. 대신 Python에서도 변수명은 더 명확하게 써야 합니다.
차이 2) 같은 이름의 자료형이 바뀔 수 있다
C
int value = 10;/* value = "ten"; // 오류 */Python
value = 10value = "ten"print(value)설명: Python에서는 문법상 가능하지만, 학습 초기 코드에서는 한 변수에 숫자 역할과 문자열 역할을 섞지 않는 것이 좋습니다. 이름은 같아도 의미가 바뀌면 디버깅이 훨씬 어려워집니다.
차이 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) 거듭제곱 표기가 다르다
C
/* pow(x, 2) 사용 또는 x * x */Python
x = 3print(x ** 2) # 9설명: ^는 C와 Python 모두 거듭제곱이 아니라 비트 XOR입니다. “제곱”을 쓰고 싶을 때 ^를 쓰지 않도록 주의하세요.
차이 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() 같은 형변환이 여전히 필요합니다.
학생 실습 · 직접 코딩
문제: 24 GHz 전파의 파장을 계산하세요.
문제: 옴의 법칙을 사용해 전류와 전력을 계산하세요.
문제: 섭씨를 화씨로 변환하고, 3개 측정값의 평균을 구하세요.
문제 (응용): 10진수 값을 2진수와 16진수로 변환하고, 반대로 2진수/16진수 리터럴을 10진수로 출력해 보세요.
문제 (도전): 8비트 상태 레지스터에서 비트 마스킹으로 각 필드를 추출하세요.
레지스터 0b10110101에서 bit[3:2](팬 속도)와 bit[0](전원 상태)를 각각 추출하세요.
