어제
UDP를 이용해 데이터를 주고받는 프로그램을 만들었고

그 데이터를 덤프시킬 프로그램도 만들었었다.

이제 그 데이터를 분석해보겠다.


(어제 했던 Hello 데이터를 전달하는 UDP 패킷내용)


Hello 앞에 나오는 헤더부분을 살펴보자.
b'E\x00\x00!\x11\xf6\x00\x00\x80\x11\x9f\xf1\xc0\xa8\x03\xa5\xc0\xa8\x03\xef\xce\x89\xea`\x00\r\x9a2
(이건 오늘 실행시켜서 복사한 패킷헤더이다.)

\ (역슬래쉬)
\x 로 표시는 16진수 표시이다.

왜 어떤건 문자로 나오고 16진수로 나올까?
-> 문자로 나올수 있는 것은 문자로 나온다.
16진수 중에 문자로 표시할수 있는건 문자로 표시한다. (이것도 16진수)
(아스키 코드에 따라)

앞에 b라고 붙어있다. -> 실제 네트워크 스트림에 사용하는 데이터가 파이썬에서 맞지 않는다.
       -> 그래서 C에서 API를 가져온다.
       -> C언어가 쓰는 바이트타입을 가져온것이다.
       -> 그래서 다시 파이썬에 맞게 바꾸는 함수가 있는데,
           그건 - pack()
                  - unpack()
             함수이다.

이 함수들은 struct 모듈 안에 들어있다.


(unpack의 사용 모습 (파이썬공식홈페이지 출처))


hhl 표시  -> 각각 2바이트 2바이트 4바이트로 묶어서 출력하라는 뜻이다.

우리는 앞에부터 20바이트는 뺄것이다. 이 패킷은 IP헤더이기 때문에
20바이트 뒤부터 분석을 해볼 것이다.


(slice로 앞 20바이트는 잘라내는 모습)



(IP헤더는 떨어지고 UDP 패킷내용만 남은 모습)



여기서 unpack을 사용하지않고
list를 사용해 전부 hex 표시로 바꾸겠다.

* map() 함수 - 두번째 인자를 첫번째인자(함수)에모두 입력한다.
hex 또한 함수이기 때문에 지금 쓰는것은 두번째 인자를 모두 16진수의 수로 바꿔주는 것이다.

(hex 표시로 바꿔주는 코드)



(16진수로 표시되는 모습)



전부 16진수로 나오는 모습이다.

뒤에 다섯자리 '0x48', '0x65', '0x6c', '0x6c', '0x6f' 를 아스키코드에 대입하면
Hello 라고 우리가 보내는 데이터임을 알 수 있다.

그리고 데이터 앞자리 우리가 구한 UDP헤더의 내용이다.
['0xcc', '0xe8', '0xea', '0x60', '0x0', '0xd', '0x9b', '0xd3']

헤더에는 총 4개의 내용이 들어있다. (첫번째 부터)

1. Sorce Port Number (출발지의 포트번호) 
     ->2바이트 (출발지 포트)

2. Destination Port Number (출발지의 포트번호) 
     -> 2바이트 (도착지 포트)  '0xea', '0x60'  = ea60  = 60000
3. Length (길이) 
     -> 2바이트  = '0x0', '0xd  = 0d   =13  = 13바이트 
(헤더 8바이트, UDP데이터 5바이트) 13바이트가 맞다.

4. Checksum
     ->2바이트   검사용

-> 이런게 Protocol 프로토콜이다.
처음에는 데이터 Hello가 보내지는걸  봤는데 이제 Hello가 패키징 되면서 붙는 내용들을 확인한다.
그 과정중 하나가 UDP를 본것이다.

UDP 헤더의 내용은 4개 밖에 없다. -> 에러정정, Flow Control 등 기능은 없다.

* 바이트
1 바이트로 숫자 하나를 표현할 수 있다. 16진수 2자리를 표현할수 있는 것이 1 바이트 (0x00 ~ 0xFF)

이제 unpack을 이용해 좀더 정확하게 데이터를 출력해보겠다.

H -> 2바이트를 묶어서 하나로 만들어준다.
! -> network stream 데이터를 읽어들일때는 !를 붙여준다.
 붙이는 이유 네트워크에서 돌아다니는 데이터랑 컴퓨터에서 다루는 데이터랑 다르다.
 그래서 ! 느낌표를 붙여서 네트워크 데이터라라는것을 알려줘야한다.

이제는 조금 구분 할 수 있게 됬다.


(UDP 헤더 패킷 분석 코드)


-> 목적지 주소가 60000 포트인 경우에만 출력한다. (내가 60000번 포트로 패킷을 전송할거기 때문에
       내가 보내는 패킷의 정보가 궁금한 것.)


(UDP 헤더 분석)



지금까지 Hello라는 데이터를 UDP로 보낼때의 패킷 내용들을 분석해 보았다.

윈도우 소켓으로 볼수있는 것은 L3 까지 볼 수 있다.

- Layer 4 ( Transport Layer ) 의 프로토콜(UDP, TCP)
- L4에서는 데이터가 어디서 어떻게 전달되는지 해당 계층에서는 상관이 없다.
- 에러 정정(UDP에는 없다.), 흐름제어(UDP에는 없다.), 이런 내용만 포함하고 있다.

- L4에서는 관련된 정보만을 포함한다.
-> UDP의 checksum에서는 오류가 났는지 안났는지만 판별 오류났으면 버린다. 그 외의 행동은 하지 않는다. 그래서 에러정정의 기능이 없다고 말한다.


* UDP인지, TCP인지 어떻게 판별할까?
: 더 하위계층에서 그 내용을 가지고 있다. -> IP 패킷

우리가 잘라냈던 IP헤더를 보면 UDP인지 TCP인지 확인할 수 있다.
socket 생성시 PROTOCOL 부분을  IPPROTO_UDP 를 IPPROTO_IP로 바꾸었다.



(socket 타입 변경)


UDP = User Datagram Protocol

IP 헤더 ( Internet Protocol Header )
-> L3 ( Network Layer (네트워크 계층) )
-> IP는 해당 계층의 대표적인 프로토콜이다.
-> 데이터를 송신지에서 수신지로 향하게 하는 데이터의 전달과 밀접한 관련이 있다.
-> 주요목적은 전송경로 설정 등이 있다.
-> 경로에대한 담당은 라우터가 하는것이다. 즉 IP헤더에는 IP주소만 적혀있고 라우터가 IP주소를 보고 경로를 설정한다.
-> 사이즈는 기본 20바이트이다. (추가로 옵션이 있긴하다.)
현재 우리가 보는 것은 IPv4의 IP헤더 이다. IPv6는 또 조금 다르다.

Layer2, Layer1의 내용들은 현재 윈도우즈 환경에서는 지원하지 않는다.
윈도우즈 소켓은 Layer3 까지 밖에 지원이 안된다.

이제 IP헤더를 분석해 본다.

(list를 이용해 출력하는 코드)



(IP 헤더 출력 모습)



출력한 IP 헤더
['0x45', '0x0', '0x0', '0x21', '0x35', '0xd3', '0x0', '0x0',
'0x80', '0x11', '0x7c', '0x14', '0xc0', '0xa8', '0x3', '0xa5',
'0xc0', '0xa8', '0x3', '0xef']

ip 헤더 분석
총 20바이트로 되어있다. 

첫번째 바이트 숫자 하나가 2개의 값을 의미한다.
   0x45  -> 4랑 5로 읽을 수 있다.
1. Version -> 맨 앞 4 = IPv4
2. Header length -> 그 뒤 숫자 5 = 헤더의 길이 : 4를 곱해준다. 5x4 = 20 바이트  헤더의 길이다.
3. Service  -> 현대 IPv4에서는 사용하지 않는다. 거의 항상 0으로 초기화된 값이 들어간다.  : 0x0'
4. Total length (전체길이) : 그다음 숫자 2바이트 '0x0', '0x21' = 0x021  = 33바이트
    ( Ip헤더 20바이트, udp패킷 13바이트 )
5. Identification (식별자) : 그다음 숫자 2바이트 '0x35', '0xd3'
6. Flag ->  '0x0'
7. Fragment OFFSET ->  '0x0'
* IP패킷은 여러개로 분할 될 수도있다. 그래서 5,6,7 정보가 필요하다.
    자세한 내용은 다음에 확인하겠다.
8. TTL (Time to live) -> '0x80'  = 128.  ( 윈도우즈에서 만들어진 패킷은 기본적으로 128로 나간다.)
 TTL은 네트워크를 방황하는 패킷들을 예방하기 위해서 있다.
 TTL은 라우터를 한 Hop이라고 지날수 있는 Hop의 수이다.
9. Protocol 타입 -> '0x11' = 17 :  (udp :17번) (tcp:6번) (ICMP: 1번)
10. Header checksum -> '0x7c', '0x14'  checksum은 각 헤더마다 들어있다.
11. 출발지 IP (4글자) : '0xc0', '0xa8', '0x3', '0xa5'  -> 192  168  3  165  
12. 도착지 IP (4글자) : '0xc0', '0xa8', '0x3', '0xef


-> 전송에 관련된 내용들을 가지고 있다.
1,1,2,2,1,1,1,1,2,4,4 개씩 unpack하면 된다. 위 데이터를 끊는 개수이다.



(IP 헤더 내용을 쪼개어 출력하는 코드)



(IP 헤더 분석)


IP 헤더에 무슨 내용들이 있는지
어떤 역할을 하는지
확인하였다.

또, UDP 패킷도 함께 분석하였다.

-> 나중에 이걸 이용해 패킷 스니퍼를 만들것이다.
(비슷한 원리로 만들것이므로 기억해둬야한다.)













어제 하던 통신프로그램을 보완해서

그럴싸한 통신을 하는 프로그램으로 업그레이드 했다.



(while 문을 이용해 메세지를 종료할 때 까지 통신하는 코드)


(메세지를 주고받는 모습)


(맨 아래줄에 보면 외부 IP주소와 포트번호가 나와있다.)



위 화면에서 외부주소 맨 아래를 보면 상대 IP주소와 포트번호가 나와있다.

코드에 적힌 대로 IP주소와 포트번호로 연결된것을 확인할 수 있다.

현재, 이 프로그램은 동기식 통신이다. 즉 한번 보내고 한번 받고 해야하는 방식이다.

여기서,

상대와 보통 채팅처럼 비동기식으로도 만들 수 있다.
내가 보내지않아도 상대가 마음껏 보낼 수 있는 상태로.

그러려면
Thread를 이용해야한다.

하나는 send만 하고 하나는 recv만 하도록 쓰레드를 열어서 실행해야한다.

하지만 현재 우리는 네트워크를 이해하는 차원에서
여기 까지 하겠다.

우리가 패킷을 분석하기 위해 만드는 프로그램이기 때문이다.

우리가 위에서 보낸 메세지나
네트워크에서 주고받는 데이터는
전달하기위해 여러가지가 붙어서 패킷을 만들어 전달된다.

이런 규칙들이 프로토콜인데
4계층의 TCP, UDP를 알아보겠다.

먼저 파이썬 코드로 어떻게 동작되는지 두 프로토콜의 차이점을 봐야한다.

동작 과정

* TCP server
 1. socket()
 2. bind()
 3. listen()
 4. accept()
 5., send(), recv()

* TCP Client
 1. socket()
 2. connect()    -> server의 accept와 연결된다.
 3. send(), recv()

* UDP server
 1. socket()
 2. bind()
 3. sendto() ,recvfrom()

* UDP server
 1. socket()
 2. sendto(), recvfrom()
-> send()를 못쓰는 이유는 send는 연결되어있는 곳으로 보내는건데
UDP는 연결된게 없으므로 sendto()로 그때그때 어디로 보내는지 적어줘야한다.

UDP의 특징
-> 연결과정 없이 바로 보내고 받는다.
-> 데이터가 갈수도있고 안갈 수도 있다. 그래서 TCP는 신회성이 있는 통신이다. 왜냐하면 안갔는지 갔는지 체크하기 때문이다. TCP는 체크하지만 UDP는 체크하지 않는다.
-> UDP는 신뢰할 수 없는 통신이다. ( 이말은 상대가 받았는지 체크할 수 없다는 뜻)
-> 인증 절차도 없다. 그냥 보내고 그냥 받는다.
보통 UDP를 사용하는 프로그램은 보통 인증과정이 없다.
UDP자체로는 인증을 할 수 없다.

그렇다면 왜 쓸까?
  위 말만 들으면 왜쓰는 걸까 싶지만 UDP의 큰 장점은 복잡하지않고 빨리빨리 보낼 수 있다는 것이다. 보내는 데이터가 크지 않다면 UDP가 적절하다. UDP는 에러체크등이 없고 그냥 보내기만 하는 것이다. 그래서 사실 예전에는 많이 쓰이지 않았다. 하지만 요즘 많이 쓰이고 있는것이 실시간 통신이 필요할 때 특히 UDP를 많이 쓴다. 빨리보낼 수 있고 에러 났다고 다시 보낼 필요가 없는 실시간 통신에 적합하다. 혹은 짧은 데이터 같은 경우가 적합하다.

- netstat -anp UDP
입력하면 UDP 포트 정보를 볼 수 있다. 여기에 상태 정보가 없다. 연결과정이 없기 때문이다.


(상태 부분이 없다.)


파이썬에서 UDP에 사용되는
recvfrom() 함수.
-> 받아온 내용보면 클라이언트 정보도 같이 출력된다.


(맨 아래 데이터와 데이터가 날라온 IP주소와 포트정보)


-> 튜블정보이므로 ip주소와 포트번호를 따로 입력받아서 출력해 봤다.


(튜플정보를 따로 받아와 출력한 모습)


TCP, UDP  -> Layer 4 (4계층)에 속한다.
-> 전송계층 (Transport Layer)

* PDU : Protocol Data Unit


-> packet : 패킷, 3계층에서 사용되는 단위
    근데 그냥 보내는 데이터 덩어리를 패킷이라고도 한다.


L4에서는 pdu가 segment 다.

-> 주소 체계 : Port번호

-> 각 계층별 사용하는 단위와 주소가 다르다.


패키징
-> Hello 데이터를 패키지화한다. 포장하듯이.
-> UDP 헤더를 붙인다. 데이터 앞에

헤더에 어떤 정보들이 들어가있는지 정해논다 -> 규약 Protocol

프로토콜에 맞게 데이터를 패키징해서 다음 계층으로 보낸다.



UDP 헤더에는 어떤 정보가 들어있을가?


UDP Header

 - dst Port 번호, src Port 번호
 - data length, checksum



-> 직접 확인해본다.

(먼저 패킷 데이터를 덤프받을 프로그램을 만들었다.)


socket.gethostname() 을 이용하면 컴퓨터의 이름을 얻어올 수 있다.

gethostbyname() 을 이용하면 이름을 가지고 호스트 정보를 가져올 수 있다. (IP정보)


-> 여기서 포트번호에 0을 쓴이유는 특정포트를 보기위해 하는게 아니라 특정 IP에 모든 포트들을 확인하는 것이다.


(여러번 실행한 경우)


뭔지 모를 데이터들이 오고가는 모습이다.


그러면 우리가 오늘 바로 작성한 UDP로 패킷을 보내고 이 패킷의 내용을 확인해보자.


(코드)


위 코드를 보면 info[0]에는 IP정보가 들어가므로 IP주소가 내꺼인 주소만 보겠다는 것이다.

이걸 안하면 이것저것 위에서 본거 처럼 구별하기가 힘들어서 그렇다.


이제 내가 UDP로 패킷을 보내고 이 프로그램으로 확인 해 볼 것이다.

보낼 데이터 : Hello


(출력 화면)


그림은 클릭하면 크게 보인다.


출력화면을 보면 끝에 Hello라고 적혀있는것이 보인다.

그리고 그 앞부분은 헤더의 내용이다.

UDP는 헤더에 많은 내용이 들어간다고 안햇는데 왜이렇게 길지???..


그건 UDP헤더만 붙는게 아니기 때문이다.


아래 계층으로 내려가면서 패키징되는데 점점 헤더가 붙어서 늘어나기 때문이다.


이제 앞으로 이 헤더 정보, 데이터 정보를 구별하여 읽는 법을 공부할 것이다.


다른 패킷을 분석하여 어떤 정보가 오고가는지 확인할 수 있게 될 것이다.







네트워크란


- 떨어져 있는 Host들간의 연결 혹은 연결되어있는 집단을 말한다.


네트워크의 기원


ALPANET -> 정부, 학교, 기업들간에 서로 데이터공유를 원활하게 하고자 해서 시작된 프로젝트이다.
              ->  이 때, router등 네트워크 장비들이 개발되었다.


그렇다면
네트워크에서 어떻게 데이터를 주고받을까?


-> 여러가지 프로토콜(규칙들)을 통해서 주고받는다.


네트워크에서 통신하는 모습을 오늘 확인해 볼 것이다.


네트워크의 구조부터 봐야한다.


* 네트워크 구조는 OSI 7 Layer (표준)로 이루어져있다.


크게 보면 아래와 같다.


1~4 계층
 - 하위 4계층이라고 한다.
 - 물리적인 전송 방법에 관해 역할을 담당한다.
 - 통신규약(프로토콜)
     -> TCP, UDP, IP, ARP, ETHERNET, ...  (데이터를 전달하는 방법들)


5~7 계층
 - 상위 3계층이라고 한다.
 - 논리적인 규칙에 따라 전송된다.
 - HTTP, FTP, Mail,... (프로토콜)
 - kakao talk, game.. (비표준프로토콜) -> 외부에 공개되지 않는 규약들

먼저, 하위 4계층을 이용해 문자를 전송해보자.
파이썬을 이용해 1~4계층으로 메세지를 직접 주고받는 통신을 해볼 것이다.
파이썬에서 통신을 하기 위해 필요한 내용들이다.


* 파이썬 소켓 프로그래밍

-> 우리가 하려는 것이 네트워크 상에서 데이터를 주고받는 모습을 확인하려는 것이다.
    그러기 위해서는 네트워크 프로그래밍을 해야한다. 네트워크 프로그래밍을 소켓 프로그래밍이라고도한다.
-> 네트워크 프로그래밍? : 통신을 위한 프로그래밍으로 소켓을 이용한다. 그래서 소켓프로그래밍이라고 하는 것이다.

 - socket? 소켓을 이해하기 위해 다음것들을 먼저 보는 것이 도움이 된다. 


* 입/출력 방식

 - 표준 입/출력 : input(), print()   (키보드, 모니터) (키보드, 모니터로 이루어지기 때문에 다른 식별자가 없다.)
 
- 파일 입/출력 : 파일 식별자가 필요하다. (어떤 파일을 열었는지 알아야하기 때문에 식별자가 필요하다.)

  - open ( 파일을 가져온다 )
   a, w, r    (추가, 쓰기 읽기전용)
   a -> 있으면 거기다 쓰고 없으면 새로 만든다.



(open() 을 이용해 파일입력해보는 코드)


(이렇게 바탕화면에 text 파일이 생긴다.)



핸들러 -> 파일 변수. 파일을 다룰수있는 변수


(핸들러 내용)


open 되있으면 파일이 열려있는것이다. 이 때 삭제를 누르면 열려있다고 삭제가 안된다. (열려있다는거 확인할 수 있다.)
close로 닫을 수 있다.


(Python 에서 close()를 하지 않은 경우)


(close() 를 해야 열려있던 파일이 종료된다.)


write -> 화면에는 입력한 문자의 길이가 표시된다.

* 파일을 다룰 때는 식별자를 주의해야한다.


(파일에 문자를 입력해본 결과(11이라고 적힌건 입력된 문자수를 출력한다.)


파일 접근 방법
ex) fd = open("파일 경로", "모드")

네트워크 입/출력도 파일 입/출력과 비슷하다고 생각하면 된다.
파일은 open으로 접근했다면 네트워크는 socket으로 접근한다고 생각하면 된다.

 - 네트워크 입/출력 : socket (파일의 디스크립터와 같은 맥락) 소켓은 식별자이다.
  ex) 서버는 여러개의 소켓꽂을 자리를 준비하고있다. 우리는 소켓을 들고가서 콕 꼽는다.
 -> 네트워크 프로그래밍을 소켓프로그래밍이라고도 한다.
 먼저 소켓을 생성해줘야한다. (파일입출력할때 파일을 생성한것처럼.)

1. socket 생성
 - socket module
 - 소켓 인자 : (1. 인터넷 타입, 2 통신 타입,  3. 프로토콜)

*인터넷 타입
 - AF_INET  (IPv4)
 - AF_INET6
 ...
 - AF_PACKET

* 통신 타입
 - 통신하는 타입
 - SOCKET_STREAM  (TCP)
 - SOCK_DGRAM     (UDP)
 - SOCK_RAW

* 프로토콜 -> defalt 값은 0이다. (안적어도 된다.)

출력해보면 볼수 있는데 fd가 중요하다. 소켓마다 번호가 다르다.
하나 더 만들면 번호가 다르게 생성된다.


(소켓 생성 모습)


* 네트워크 타입

 1. 서버-클라이언트 ( 1: N )
 2. Peer To Peer ( 1 : 1 )  (카톡, 채팅)
    -> 알고보면 이것도 서버-클라이언트다
    -> 누군가는 서버가 되야하고 클라이언트되야한다.
     -> 누군가는 반드시 전화를 먼저 걸어야한다. (전화를 예로)

윈도우즈 위에 여러개의 프로그램이 있다. 그래서 포트라는 개념이 필요하다.
Port 번호를 가지고 프로그램을 식별한다.
포트 번호는 ( 1~ 65535번 ) 까지 사용한다.
1~1024번 포트는 well-known 포트번호라고 한다. 조금 공식적인 포트 번호
1~10000번 까지는 비우는게 좋다. (요새는 통신하는게 많아져서)

* IPv4, IPv6 
 - IP Address : 네트워크상에서 호스트를 식별할 수 있는 식별자(식별번호)

ipv4
 - 4자리의 정수를 '.' 으로 구분해서 표시한다.
 - 각 정수의 범위는 (0~255) 이다.

ipv6
 - 6자리의 16진수 정수를 가지고 주소를 표현한다.
 - 0x00 ~ 0xff (255개)

커맨드창에 아래와 같이 입력하면
netstat -anp tcp
-> 현재 열려있는 포트들을 보여준다.



(netstat -anp tcp 명령어)


(포트 번호 50000번을 열어둔 상태)



(포트번호 50000번이 열려있는 것을 확인할 수 있다.)


이제 간단한 통신을 하는 프로그램을 만들어 볼것이다.

동작 방식은

* 서버 프로그램의 동작방식
1. 소켓을 생성한다.  -> socket()
2. 포트를 오픈한다.  ->bind()   : 튜플 형태로 하나의 인자. 튜플안에 뒤는 포트번호
3. 네트워크의 상태를 Listen 상태로 변경한다.  -> listen()  괄호 안에 연결 개수를 적기도한다.
4. 클라이언트의 연결 요청을 기다린다.     -> accept()  : 클라이언트 소켓을 리턴해준다.

* 클라이언트 프로그램의 동작방식
1. 소켓을 생성한다.   -> socket()
2. 서버에 연결한다.   -> connect()  : IP주소와 포트번호를 튜플형태로 적어준다.



(통신 프로그램 코드, connect()는 빠져있다.)


(서버 측 출력)


위 코드를 보면 서버 모드일 때 연결이 되면 연결되어있는 정보가 출력되는 것을 확인 할 수 있다.
리턴되는 값은 클라이언트 소켓 정보이다.

연결된 이후에는 send, recv 함수를 통해서 데이터를 송/수신 할 수 있다.

그러면 이제 메세지를 주고받겠다.



(문자열 abcde를 보내는 클라이언트 모드)



(에러가 났다.)

문자열을 그대로 보내면 파이썬은 처리를 못한다.
그래서 .encode()를 하면 파이썬이 적절하게 인코딩을 해서 보내주게 된다.


(서버에 입력이 들어온 모습)


내가 클라이언트 모드일때 abcde를 보냈고
내가 서버모드로 하고 옆사람이 클라이언트모드로 내게 Hello를 보낸 것을 확인 할 수있다.

출력 결과를보면 첫번째 꺼는
b' Hello라고 적혀있고
아래꺼는
Hello 라고 적혀있다.

첫번째꺼는 데이터 받은 것을 디코딩하지 않고 바로 출력한것이다.
보면 바이트 표시가 되있는 것을 볼 수 있다.

두번째 꺼는 .decode()를 한 모습이다.










함수를 정의하고 내용을 입력하지 않으면 에러가 난다.

돌아가는지 확인해보고싶으면 pass를 쓰면 넘어간다.


(함수 내용이 없는 경우 에러)


(pass를 적으면 에러없이 넘어간다.)


* 파이썬에서의 함수
1. 입력된 문자열이 실수로 이루어져있는지를 판단하는 함수

def isfloat( data ):

입력 : 임의의 문자열
출력 : True of False
           - 실수로 변경가능한 문자열이라면 True
           - 그렇지 않으면 False

2. 입력된 문자열이 음수로 이루어져있는지를 판단하는 함수

def isneg( data ):

입력 : 임의의 문자열
출력 : True of False
         - 음수로 변경가능한 문자열이라면 True
         - 그렇지 않으면 False


(함수 코드)


(결과)


*라이브러리 : 이미 만들어져있는 함수이다.

* 파이썬 모듈
 - 파이썬 코드로 이루어진 파이썬 파일
 - 사용하고싶은 함수들을 하나의 파일에 만들어 두는 것이다.
   그 후 사용하고 싶으면 import한다.


 - 어디서나 import 하고 싶으면
 -> 파이썬3의 라이브러리 파일들의 경로가 따로 있다. 이 곳에 넣어둬야한다.


(내가 만든 모듈을 라이브러리에 추가한 모습)


import 방법
import 파일
from 파일 import *      -> 이렇게 적으면 모듈 이름을 안적어도 된다.
from 파일 import 특정함수    -> 특정 함수만 import할 수 있다.

왠만하면 import 파일   형식으로 하는게 좋다.
왜냐하면 두세번째로 하다가 함수 이름이 겹칠 가능성이 있을 수 있어서 그렇다.
두세번째는 편하기는 하지만 충동할 수 있다는걸 주의하고 해야한다.
보통 모듈파일에는 실행코드는 적지 않는다.
실행코드가 있다면 import 되는 순간 파일이 실행된다.

만약 모듈을 만들고
이 모듈이 잘 돌아가는지 테스트코드를 넣어볼 수 있다.

만약 실행코드를 안삭제하고 import하고 실행시키면
import 될때 모듈파일의 테스트코드가 실행된다.
만약 지우지않고 쓰고싶다면
if __name_- == "__main__":
    main()
이코드를 넣으면 이 해당파일이 단독으로 실행되면 실행되지만
import되는 경우에는 코드가 실행되지 않는다.
-> 단독으로 실행하는 경우 실행코드들이 실행되고
   import되는 경우에는 실행되지 않는다.



(모듈 파일에 테스트코드를 추가한 모습)



(모듈을 import 한 순간 테스트코드가 실행되는 모습)



(__name__ 을 모듈에 추가해서 실행시 테스트코드가 실행되지 않는 모습)



* 프로그램 작성

1) 안전한 제곱근을 구하는 함수

math 모듈에 sqrt() 함수로 제곱근을 구할 수 있다.
 - 숫자가 아니거나 음수가 입력되면 에러가된다.
 
알고리즘
1. 사용자로부터 값을 입력받는다.
 
 - 입력값의 형태는 실수여야 한다.

2. safe_sqrt 함수 인자로 입력값 전달
 3. 입력된 값이 허용범위의 값인지 판별 허용범위라면 실수로 변환 후에
    sqrt 함수를 이용해서 제곱근을 구한 후 출력
 4. 허용된 입력값의 범위가 아니라면 다시 입력받을 수 있도록 한다. 
 5. 3번으로 돌아간다.


(만들어본 코드(좌), 실행화면(우))


2)  대출 상환금 계산 프로그램

- 입력 :
 대출 원금
 대출 기간
 대출 이율

- 출력 :
 연상환금
 월상환금
 총상환금

- 연상환금 계산 공식

                   (1 + 대출 이율)^대출 기간 + 대출 원금 + 대출 이율
연상환금 = ---------------------------------------------------------------
                                  (1 + 대출 이율)^대출기간 - 1

1) 대출 원금과 대출 기간, 대출 이율을 각각 입력 받는다.
 - 대출원금과 대출 기간은 자연수의 입력만 허용하며 대출 이율은 실수 입력만 허용할 수 있도록 한다.
2) 입력값에 맞춰서 연상환금을 계산한다.
3) 연상환금과 월상환금, 총상환금을 출력
4) 프로그램을 계속 진행할 것인지를 입력받는다.
 a-1) "yes"를 입력한 경우 1)번으로 돌아가서
       대출 원금과 대출 기간, 대출 이율을 새로 입력
 b-2) no 를 입력한 경우 프로그램 종료
 4-3) yes no 이외의 값이면 새로 입력을 받는다.
* 소수점이하를 버리고 싶으면 int 형으로 형변환 하면한다.
* 반올림 하고 싶으면 round 함수를 이용하여 형변환한다.



(소수점 그대로 출력)



(소수점까지 출력되는 모습)




(작성해본 코드, 결과를 int형으로 형변환 한 모습 : 소수점 자리 버리는 모습)




(소수점 자리 버림 모습)












오늘의 주제는

* 실수는 어떻게 구분할까?
 1.4, 10.2, .... 
* 음수는 어떻게 구분할까?
 -2, -4

에서 부터 시작된다.

성적처리프로그램을 만들 던 중
입력으로 들어오는 값 중
음수, 실수(소수점자리수)를 어떻게 구분할까? 라는 문제제기가 되었다.

먼저 음수와 실수의 특징들을보면

음수일 경우
 
 -10, -2, ......  ( 맨 앞에 대쉬(-)로 시작하고 이어서 숫자가 나오는 경우 )
  
실수일 경우
 23.2    ( 숫자나오고 .(점) 문자 후 바로 숫자 )

이러한 문자열들을 구분할 수 없을까?

먼저, str.isdigit() 함수에서는 정수인지만 판별 할 수 있다.

먼저 자료 타입을 더 공부해본다.

파이썬에서 제공하는 자료 타입
 - list, tuple, set, dictionary

리스트
 - 데이터들의 순서열(sequence)
 - 리스트내의 원소들의 값을 변경 할 수 있다. *
 - 인덱스 : 0부터 시작한다.
-  표현 : [ ] 이 기호 안에 입력한다.


(리스트 예시, 값을 변경하는 모습)


튜플
 - 리스트와 거의 동일 (차이점 : 투플내 원소들을 변경할 수 없다.)
 - 문자열은 튜플이다. (문자열은 변경되지 않는다.) *
 - () 소괄호로 표시한다.
 - 문자열도 튜플이기 때문에 변경할 수 없다.


(튜플을 정의하고 출력하는 모습, 값을 변경하는 경우 에러가 발생한다.)


* 리스트나 튜플의 특징을 이용하면 음수나 실수를 구분 할 수 있다.

이러한 특징 중 내장함수들을 잘 이용해야한다.
https://docs.python.org/3/library/index.html


위의 홈페이지에 들어가보면
파이썬에 관련된 문서들을 찾아볼 수 있다.


(파이썬 공식홈페이지 참조)


순서열에서 사용가능한 연산자들
순서열 -> 문자열, 리스트, 튜플 등등
x in s  -> 순서열 검색  s 문자열 내에 x순서열이 존재하는지 체크하는 연산자
s * n   -> s 순서열을 n번 반복 (n은 숫자)
s[i]    -> s 순서열 내 i번째 원소 가리키는 표시.

s[i:j]   -> i번째에서 j번까지 잘라냄  j번을 포함하지 않는다. j번전까지 해서 잘라짐.
len(s)   -> s의 길이를 표현 
s.index   -> 순서열이 시작하는 위치
s.count   -> 얼마나 있는지 카운팅함   (안되는 경우도 있다.)


(연산자 사용 예시)


- 슬라이스 가능 -> 슬라이스는 원 자료를 변형시키는 것이 아니라
                              잘라진 새로운 자료을 만드는 것이다.

* sample = [1, 2, 3, 4, 5]
sample은 위 리스트의 주소를 가지고 있는 참조 변수이다.
그런데 슬라이스는 새로운 자료를 만드는 것이므로
슬라이스해서 입력하면 기존 자료가 변하지 않는다.  -> 그래서 튜플도 슬라이스가능한 것이다.


(참조변수로 사용되는 리스트 변수이름)


* partition을 이용해 실수를 체크해보겠다.
  -> 파티션은 기준으로 부터 3개의 튜플로 반환한다.


(str.partition(x) 사용 예시)


* 동시지정문 이용
(n, x, m) = '1.4'.partition('.')


(동시지정문으로 .partition 된 결과를 입력받는 모습)


* partition 은 문자열에서만 제공하는 메소드이다.
   다른 리스트나 이런데서 사용할 수 없다.

모듈 -> 함수를 모아둔 파일을 모듈이라고 한다.
* 파이썬에서의 함수 작성
입력에 대해 출력이 없으면 프로시져라고 부르고
            있으면 함수라고 부른다.

1. 함수(function)
 - 출력을 나타내면 함수라고한다.

2. 프로시져(procedure)
 - 입력에 대해 출력이 없으면 프로시져라고한다.

3. 메서드(method)
 - class 내에 선언된 함수를 정의하면 메서드라고 한다.

-> 결국 세개가 다 같은 맥락이다. 만드는 방법도 같다.

파이썬에서의 함수 정의
ex)
 f(x) = 2x + 10      정의
 이 함수를 파이썬에서 그대로 표현한다면
 def f(x):
  return 2* x + 10


(함수 표현)


여러개의 값을 동시에 return도 가능하다. -> 파이썬에서는 동시지정이 가능하기 때문이다.


(동시지정문으로 하나의 함수에서 여러값을 return받는 모습)


위의 기능들을가지고
isneg()  -> 음수판별
isfloat()  -> 실수판별
함수를 만들 수 있을 것이다.

다음시간에 만들어 보겠다 :)









오늘 상속을 이용해
전화번호 관리 프로그램을 4번째 단계로 업그레이드 하였다.

업그레이드 내용은.

전화번호 내용 데이터를
대학, 회사, 일반 정보로 나누는 것이다.

쉽게 말하면 대학, 회사의 클래스 두개를 추가하는 것이다.

만약 상속을 이용하지 않았더라면
좀 더 복잡하게 바꿨어야했을 텐데

상속을 이용했기에 기존에 몇개만 바꾸어서 업그레이드 가능했다.

먼저
기본 상위 클래스인 일반친구들의 정보 클래스를 만들었다.


(상위 클래스)


이 정보를 상속받아 대학, 회사의 정보도 만들었다.


(상속을 이용해 추가한 두개 클래스)


상속을 이용해 PhoneInfo 의 클래스로 규정화 시켜 다룰 것이다.

먼저 입력을 다루기위해 manager 클래스(controller)에서 일반, 대학, 회사의 입력을
나누었다.


(입력을 추가해 놓은 코드)


이렇게 되면 inputData 메소드로 입력을 간단히 완성시킬 수 있다.
보면 들어오는 정보는 PhoneInfo 클래스로 다루어진다.


(입력 코드)


PhoneInfo 클래스인 info 로 한번에 다루어서 저장한다.

그리고

최종 출력화면


(정상적으로 돌아가는 화면)


이로써 상속을 이용하여 4번째 단계로 전화번호 관리 프로그램을 업그레이드 하였다.

:)

(*참조 - 난 정말 JAVA를 공부한 적이 없다구요, 윤성우)


@ 상속의 조건
 
아래 조건과 필요가 충족되지 않으면 상속을 안하는 것이 좋다.
 
* IS-A관계
: IS-A 관계란 하위 클래스를 상위 클래스로 부를 수 있어야한다.
 
예를 들면,
핸드폰 -> 스마트폰
여기서 핸드폰은 상위클래스이고, 스마트폰은 하위클래스이다.
 
이 때, 우리는 스마트폰을 핸드폰이라고 말할 수 있다.
스마트폰 IS A 핸드폰
 
이 관계를 IS-A 관계라고 부른다. 이 조건을 만족하지 않는다면 상속을 하지 않는 것이 더 좋다.
 
* HAS-A 관계
: HAS-A 관계란 하위클래스가 상위클래스를 가지고 있다는 의미이다. 이 경우 상속을 사용할 수 있지만, 왠만하면 쓰지 않는 것이 좋다.
이유는 가지는 게 추가해야될 때 고치기 힘들다. 자바에서는 중복상속이 안되기 때문이다.
그렇기 때문에 HAS-A 관계에서는 복합관계로 대신하는 것이 좋다.
 
@ 메소드 오버라이딩
: 메소드 오버라이딩이란 상위클래스에서 정의한 메소드를 다시 정의한 것이다. 메소드의 이름과 반환형, 매개변수의 선언이 완전이 일치할 때 메소드 오버라이딩이된다.
 
참조 변수를 이용해서, 인스턴스의 오버라이딩 된 메소드를 호출하면, 상위클래스가 아닌 하위 클래스의 메소드가 호출된다.
하위 클래스에서 오버라이딩 된 상위 클래스의 메소드를 호출하려면 키워드 super를 사용한다.
 
쉽게 말하면 오버라이딩이 되면 하위 클래스에서 재정의 된 메소드로 호출이 되고, 그 전의 메소드들은 가려지게 된다. 그 전의 메소드는 호출이 불가능하다.
 
 
 
 
여기서 조금 복잡한 내용인데,
상속에 있어서 인스턴스 참조관계를 일반화 해서 정리하면
 
AAA -> BBB -> CCC ( 상속 관계)
 
AAA ref1 = new BBB();
AAA ref2 = new CCC();
BBB ref3 = new CCC();
 
위를 보면 ref1, ref2는 클래스 AAA로 바라봐진다. ref3는 클래스 BBB로 바라봐진다.
 
ref1BBB로 인스턴스가 생성되지만 AAA 취급을 받는다.
ref1AAA의 메소드만 이용할 수 있다.
 
* XXX 클래스의 참조변수는 XXX 클래스의 이느턴스, 또는 XXX를 상속받는 하위 클래스의 인스턴스를 참조할 수 있다.
* 참조변수의 자료형에 상관없이 마지막으로 오버라이딩을 한 메소드만 호출된다.
(가려지기 때문이다.)

문제 15-1
오버라이딩을 이용해 같은 메소드로 다른 메소드로 연결시킨다.


(코드)


(동작화면)


-> 오버라이딩으로 자료형에 상관없이 같은 메소드로 다른 메소드처럼 동작하였다.

@ 상속의 목적
상속을 통해 연관된 일련의 클래스에 대한 공통적인 규약을 정의할 수 있다.”
 
이 뜻은 상속이 된 클래스들에 대해 일괄적으로 다룰 수 있게 된다는 이야기 이다.
상속을 계획하여 설계하고 이러한 이득을 얻을 수 있다.
 
* Object 클래스
: java.lang 패키지에 묶여있는 클래스이다. 보통 다른 어떤 클래스도 상속하지 않으면 Object 클래스를 상속하게 된다.
Object클래스 안에는
public String toString() 메소드가 정의되어있다.
그렇기 때문에 이 toString을 오버라이딩하여 사용할 수 있다.
 
* final 클래스와 final 메소드
: final 선언이 된 클래스는 상속되지 않는다.
final로 선언된 메소드는 오버라이딩을 허용하지 않겠다는 의미이다.

(*참조 - 난 정말 JAVA를 공부한 적이 없다구요, 윤성우)



* 비교연산자
-> 비교를 하는 연산자이다. 종류로는
==       :  같다
!=        : 같지 않다.
왼쪽이 크다는 기준으로
>        : 크다.
<        : 작다
>=      : 크거나같다.
<=      : 작거나 같다

- 문자열도 비교연산자를 쓸 수 있다.  크기 비교도 한다 
: 크기 비교할 때 의미는 크지 않는데 문자마다 숫자값을 가지고 있어서 크기비교연산이 되기는한다.
   하지만 이걸 사용해서 문자 정렬을 하기도 한다.

* 수학식에서는 =  기호가 같다라는 뜻이다.
하지만 프로그래밍 언어에서 = 기호는 assignment 의미로 사용된다.

ex)
10 == 10
결과 -> True 
여기서 True는  문자열이 아니다. , 숫자 1과 같은 의미를 가지고있다. (반대로 False는 0을 의미한다.)
문자열에서는 '', "" 로 표현된다.

* bool's 논리식
 - AND(그리고) , OR(또는), NOT(아닌)

NOT 은 피연산자 하나만 온다.  (AND, OR 는 피연산자가 두개 와야한다.)

ex)
 A가 참이고 B가 참이면 결과는 참이다.
 A and B -> True   (A,B 에 보통 비교 연산자가 온다.) 

 A가 참이거나 B가 참이면 결과도 참이다. 
A or B  -> True   (A,B 둘 중 하나만 참이여도 결과는 참이다.)
 
A는 아니다.
 -> not A 
(만약 True면)  -> False


(비교연산자, bool's 연산자 예시)



* 표준 입/출력 함수
 
 - print() -> 표준 출력장치로 내용을 출력하는 함수

 - input() -> 표준 입력장치로 내용을 입력하는 함수
  - 한줄을 입력받는다.
  - 괄호 안에 문자열을 적으면 입력받기 전에 문자열을 출력해준다.
  - input된 값은 무조건 문자열이 된다. 
     (만약 숫자로 받고싶으면  정수형, 혹은 실수형으로 형변환을 해야한다.

분기문 -> 분기점을 만들어줄 수 있는 문장. (실행 흐름 제어)

* 파이썬에서의 분기문
 if 사용법
 
 if expression :   
 
 콜론을 써줘야한다. 
 if expression :
  <if block>
  ...
  ...
 -> if block의 구분 방법 : 들여쓰기로 구분한다.

if - else 사용법
 if expression:
  <if block>
 else:
  <else block>
 -> 둘중에 하나만 실행된다. else는 if문장이 참이 아니면 else blck을 실행한다.
 
다중 if 사용법
 다중 블록
 if expression:
  <if block>
 elif expression:
  <elif block>
 else:
  <else block>

* 반복문
 
 while expression :
  <while block>
 -> 조건이 참일 때 반복된다.

* 멤버 메서드
 
 해당 객체가 제공해주는 함수.
 문자열도 하나의 객체처럼 다뤄진다.

 -> isalnum()
 -> isdigit()  : 문자열에 숫자만 있는지 확인해주는 함수.

* 반복문 혹은  if문으로 block을 묶을 때 들여쓰기 간격이 일정해야한다.

* 프로그램 이란?
 - 저장된 명령어들을 일괄적으로 실행하는 것이다.

이제 지금까지 배운 내용들로 프로그램을 작성해 볼 것이다.

만들어볼 프로그램은
온도변환 프로그램이다.

특징
- 대화식 프로그램이다. 사용자가 입력하면 그에 따라 컴퓨터는 출력한다.
- 사용자가 섭씨 온도를 입력하면 화씨 온도로 변경해서 출력해주는 프로그램
- 혹은 화씨 온도를 입력하면 섭씨 온도로 출력하는 프로그램

* 알고리즘
: 문제를 해결하는 과정으로 프로그램의 동작 과정을 먼저 생각해야한다.


(프로그램 코드)


(정상적으로 출력되는 화면)


오늘 부터 상속을 공부하는데,
상속은 조금 나누어서 공부를 할 것이다.

완전한 이해가 필요하기 때문이다.

상속은 무엇일까?
-> 상속은 기존에 정의했던 클래스의 메소드, 변수들을 이어 받는 개념이다.

먼저 오늘은 상속의 문법, 사용법에 관해 공부했다.

상속
: 기존에 정의된 클래스에 메소드와 변수를 추가하여 새로운 클래스를 정의 하는 것.

표현으로는 상위 클래스, 하위 클래스가 있다.
* 상위클래스
: 기초 클래스라고도 한다. ( super class, base class )
: 원판이라고 생각하면 된다. 이제 이 클래스로 확장시켜 새로운 클래스를 만들 것이다.
: 상속할 대상의 클래스이다.

* 하위클래스
: 유도 클래스라고도 한다. ( sub class, derived class )
: 상속 받은 클래스이다. 상위 클래스의 메소드, 변수들을 이 하위클래스로 가져와 사용한다.

- 상위, 하위라고해서 헷갈린다면
  base class, derived class 라고 생각해도 된다.

사용법은
하위 클래스 선언시 상위 클래스를 언급해주면 된다.
예로 들면,
class sub extends super
{
...
}

이렇게 sub (하위클래스)를 선언할 때 extends super(상위클래스)를 적어주면된다.
여기서 sub, super는 클래스 이름이다.!!

그렇다면 상속을 할 때 초기화는 어떻게 될까?
초기화? 음 다시말하면 생성자는 어떻게 호출 될까?
-> 하위클래스의 생성자 속에 상위 클래스위 생성자를 부른다.
(그렇다고 생성자를 상속 받았다. 라는 의미는 아니다.)

부르는 방법은
super(전달 변수);
이렇게 전달한다.

예시로 문제를 적어보았다.
문제 14-1



(상속 예시)


문제를 풀고 작성한 코드인데,

여기서 Car -> HybridCar -> HybridWaterCar 이렇게 상속되었다.
보면 super() 를 통해 전달변수를 전달하여 각 상위클래스의 생성자를 호출하였다.



(실행 화면)


* 상위클래스의 생성자를 호출해야한다.
super를 이용해 상위클래스를 생성해야하는데 만약 super가 없다면
컴파일할때 자동으로 빈 super() 가 삽입된다.

* 상속과 접근제어 지시자
전에 접근제어 지시자 공부할 때 protected는 변수는 상속받은 클래스에서 까지 사용가능하다고 공부했었다. (다른 패키지에 존재할 지라도 상속관계에 놓이면 접근을 허용하는 접근제어 지시자 이다.)

* private 멤버는 간접적으로 접근해야한다.
-> 이 말의 뜻은 private 로 선언된 멤버는 직접 접근이 아니라 그 클래스의 호출을 통해 접근을 해야된다는 뜻이다. private으로 선언해 프로그램의 안전성을 높이는 것이 좋고 이 점을 생각하고 있어야한다.

(* 참조 - 난 정말 JAVA를 공부한 적이 없다구요, 윤성우)



네트워크 해킹 공부 전에

파이썬 공부를 시작한다.

* 파이썬은 인터프리터 언어이다.

+ 프로그램 실행 방법에 따라 프로그램언어를 크게 두가지로 나눌 수 있다.
1. 컴파일 언어
2. 인터프리터 언어

컴파일 언어
- 번역기가 필요한 언어이다. 컴파일(번역)을 하고 나서야 .exe 실행파일이 생기고 프로그램을 실행 시킬 수 있다. (ex. C, C++, Java, ASM, ...)

인터프리터 언어
- 컴파일 언어와는 다르게 컴파일이 필요없다. 다만 실행기가 필요하다. 실행을 하기 위해서는 실행기가 필요한다. 이 실행기는 코드를 한 줄 한 줄 읽으면서 해석하면서 실행한다. 보통 대형 프로그램에서는 적합하지 않은데 이유는 안전성이 떨어지기 때문이다. 한 줄 한 줄 해석하기 때문에 뒤에 어떤 영향이 있는지 고려가 잘 안되기 때문에 안전성이 떨어진다. 하지만 작은 프로그램들에서는 강력한 언어이다. 바로바로 코드를 실행시킬 수 있고 많은 API를 통해 다양한 일을 할 수 있기 때문이다.


(파이썬 IDLE 화면 )


>>>  표시는 프롬프트다. 이 프롬프트에 입력을 하면 바로바로 대답이 온다. 
        (대화식언어. 파이썬)

* 파이썬의 데이터 타입
- 정수형(음수, 0, 양수), 실수형, 문자
- 정수(10진수, 8진수, 16진수)

ex)
       10(10)  -> 1010(2)
                 -> 0o12(8)  (8진수는 앞에 0을씀. 앞에 0은 8진수를 나타내는 의미)
                 -> 0xA(16)  (16진수는 0x를 앞에씀, 앞에 0x는 16진수를 나타내는 의미)

네트워크에서는 보통 16진수의 데이터를 다룬다.
컴퓨터에서는 16진수가 다루기 쉽기 때문이다.


(다양한 데이터 타입 표현)


* 파이썬에서 사용가능한 수식.(연산자)

1. 사칙연산 
그 중에 나눗셈은 기본적으로 실수형으로 표현된다. (여기서 실수연산은 정확하지 않고 어느정도의 오차가 있게 나온다. 그 이유는 세밀한 연산이 불가능 해서 근사값을 이용해 계산하기 때문이다.)

2. 그 외 연산자
**(지수연산), %(나머지연산), //(몫연산), -(부호변경)
+  수식을 사용할 때 주의점. (우선순위)
    - 좌결합 우선순위 : 
    - 지수연산자는 우결합 우선순위
    - 연산자 우선순위.
                      지수연산 > 부호 > *,/,%, // > +,-
    - 우선순위를 변경할 때는 () 괄호 사용.
      ( 그렇기 때문에 () 괄호를 쓰는 습관을 들여야한다.)


(연산자 결과 모습)


* 파이썬에서의 문자
     - 문자열
     - ''  or ""    : 작은따옴표 혹은 큰따옴표를 사용한다. 그리고 이 둘의 차이는 없다.
ex)
  10    :  정수 십
 '10'  :  문자열 '일공'  (십이라고 읽을 수 없다.)
-> 똑같은 모양이지만 하나는 숫자 십 이고 하나는 문자 일공 이다.
 
 문자열 표시 예. 'hello, world'
출력에 작은 따옴표가 나오는데, 문자열이라는 뜻이다. (출력할 때 나오는 따옴표는 문자열이라는 뜻)
큰따옴표와 작은 따옴표는 섞어서 쓸 수 있다.

 hello, "world" 이렇게 출력하고 싶으면 섞어서 써야하는데
 예를 들면
 'hello, "world"'   이 런식으로 쓰면 된다.

* 파이썬에서의 문자 연산자: +, *
    -  문자를 더하거나, 곱할수는 없다.  (즉, 문자열에서의 +, * 는 의미가 다르다.)
    -     + : 문자와 문자를 연결한다.
    -     * : 문자를 반복한다.


(문자열 표현, 문자열 연산)


* 문자를 다룰때의 주의할 점
   - 빈문자와 공백문자를 구분해야한다.
   - 공백문자도 문자이기 때문이다.
ex)
 ''  <- 빈 문자
 ' ' <- 공백문자                       위 화면을 보면 맨 아래코드 예시를 보면 이해가 된다.


  -  피연산자의 타입은 하나로 통일되어야한다.
 : 만약 피연산자의 타입이 다를 경우에는 연산을 할 수 없다.
ex) 10 + '10'    <- 불가능  (통일해줘야한다.)


(다른 타입의 연산은 안된다.)


타입이 다르다면 데이터 타입을 통일 시켜주면 연산이 가능하다.
타입을 맞추는 방법은 타입 변환이다.

* 타입 변환 (형변환)
 - 내장 함수(built-in function)를 이용해서 타입 변환(형변환)을 한다.
  -int(), str(), float() 이런 함수들이 내장 함수이다.

주의할점 : int() 로 형변환 할 때 실수에서 손실이 있을 수 있다.
ex int(12.34) -> 12

(형변환을 하여 연산을 한 경우)


위 화면을 보면 형 변환을 하였고 또 그를 이용해 연산도 가능하였다.

* expression( 표현식 )
 - 지금까지 살펴본 내용들을 표현식이라고 한다. 표현식이란 연산이 가능한 문장이다.
비교하자면
 expression  -> (수식들) : 연산이 가능함을 뜻한다.
 value       -> (값)     : 연산이 가능하지 않음을 뜻한다.

* 파이썬의 변수
   사용 이유 : 값을 저장하는 용도로 사용된다. 

 - 필요할 때 꺼내서 사용한다.
 - 반복적으로 사용되는 값들은 변수를 사용하여 더 효율적으로 관리하기 위해서다.

* 지정문, 할당문, 배정문 ( assignment )
 -  사용 연산자 :  =(equal, assign)
 - 수학적 기호로는 같다라는 의미이지만 프로그래밍에서는 assignment의 의미로 사용된다.
 - 우결합을 사용한다. (오른쪽에서 왼쪽으로 연산이 이루어진다.)
 - 모든 연산자 중에 우선순위가 가장 낮다.

ex)  (지정문)
 var = 10
 var = 1 + 2 + 3      -> assign 연산자와 + 연산자가 같이 사용된다. (assign 연산자가 우선순위가 가장 낮음)
 var = 10  -> 10이라는 정수가 들어갔기 때문에 var가 int 형으로 설정된다.
 var = 'a'  -> 문자열로 설정된다.

* 재지정 : 다시 지정하는 것. 이전에 저장됬던 값은 사라진다.
 - 어떠한 값이 입력됨에 따라 type이 계속 바뀔 수 있다.



(변수 사용, 지정문 사용)


 * 동시 지정문
  - var1 = var2 = var3 = 10
  - var1, var2 = 10, 20  (파이썬에서만 볼 수 있는 문법이다.)
 
* 변수의 이름
 - 숫자로 시작할 수 없다.  (숫자 뒤에 오는건 가능하다.)
 - 특수문자는 사용할 수 없다. (예외 :  _ (언더바))
 - 파이썬3에서는 한글 변수 가능하다.
 - 예약된 문자도 사용할 수 없다. (ex.  if, while, list, ...)  -> 검은색으로 나오는 변수만 쓸수 있다. (보라색이나 다른 색으로 표시되는 단어는 쓸수없다.)
ex)
 numOfApple = 10
 num_of_apple = 10   (변수의 이름을 잘 정해야. 나중에 읽기 쉽다.)
 a = 10              (이런식으로 쓰면 나중에 뭔지 모르기 쉽다.)
 i, j, k, n  -> 반복하는 인덱스로 많이 사용된다.



(변수 지정문)



+ Recent posts