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

돌아가는지 확인해보고싶으면 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  -> 반복하는 인덱스로 많이 사용된다.



(변수 지정문)



3단계로 업그레이드 과정이다.

필요 조건은
그 전 단계버전까지는 데이터가 관리 되지 않았다.
이번 단계의 핵심은 배열로 전화번호 데이터들을 관리하는 것이다.

이렇게 관리되는 데이터들을 이름으로 검색할 수 있고,
또 필요에 따라 삭제 할 수 있는 기능을 추가해야한다.

점점 쓸만한 프로그램이 되가는 느낌이 들어서 좋다. :)

먼저,
main 코드를 중심으로 필요한 메소드와 클래스를 생각해보았다.

아무래도 전화번호들을 관리하는데 인스턴스가 필요해 보였다. 왜냐하면 데이터를 입력받고 검색하고 삭제하고 기능들의 메소드를 메인 클래스에 꾸겨 넣자니 모양새가 안좋았다.

manager라는 인스턴스(객체)를 생성하여 이 놈이 관리하도록
관리자를 만들어야겠다는 생각이 들었다.
또 이 클래스 안에
입력, 검색, 메뉴출력, 삭제 등의 메소드들을 포함시킬 생각이다.

코드를 작성하고 컴파일 도중 에러를 만났다..!


(마주친 에러)


1. reached end of file while parsing 에러

-> 처음에 이게 어떤 오류인지 이해가 안갔다.
내용은 파싱(구문해석)하는 동안에 파일의 끝에 닿았다.
코드를 보니 아직 끝날때가 안됐는데 이미 파일의 끝에 가버렸다는 말이다.
이게 무슨말인지.. 했더니

보통 { }를 잘 안닫아서 생기는 오류였다.
하나하나 검사해보니 } 하나 빠져있었다... ㅜ

수정 후 다시 컴파일을 하였다.


(마주친 에러2)


2. non-static variable registPhone cannot be referenced from a static context 에러
이 에러로 고민을 많이했다..
이유가.. 도통 뭔지 모르겠어서..

내용을 읽어보면 static으로 선언되지 않은 변수는 참조할 수 없다고 설명되있다.
!! ..
전에 내용을 내가 잊고있었다..
다시 책을 뒤져보니..!!!!!
static 메소드에서는 인스턴스 변수에 접근하지 못한다..
static 메소드 내에서는 static 변수나 static 메소드가 아닌 인스턴스 변수나 인스턴스 메소드의 접근이 불가능하다...
이유는 인스턴스는 여러개 생성될 수 있지만 static으로 선언하면 하나를 같이 공유하는 개념이기 때문이다.



(문제 코드.!)


static 메소드가 인스턴스 변수인 registPhone에 접근하려 했다..
-> 내가 static을 쓴 이유는 메뉴를 보이고 데이터 입력 등 이런 메소드를 manager 인스턴스를 안만들고 바로 쓰고 싶어서 static으로 선언했는데,
사실 생각해보면 manager 인스턴스를 한번만 만들고 그 인스턴스로 사용하기 때문에 상관없는 거였다.

registPhonestatic을 선언할 것인가 static을 메소드에서 제거할 것인가 고민 후 static 선언을 지웠다.

그 후 출력



(만족스러운 화면)


아주~ 잘됬다.!! :)

3단계까지 업그레이드에 성공하였다 :)

작성 풀 코드

----------------------------------------------------------------------------------------------

// 단계별 프로젝트 03
// 전화번호 관리 프로그램

import java.util.Scanner;

class PhoneInfo
{
 String name;
 String phoneNum;
 String birth;

 public PhoneInfo(String name, String phoneNum, String birth)
 {
    this.name = name;
    this.phoneNum = phoneNum;
    this.birth = birth;
 }
 public PhoneInfo(String name, String phoneNum)
 {
    this(name, phoneNum, null);
 }

 public void showPhoneInfo()
 {
    System.out.println("name : " + name);
    System.out.println("phone : " + phoneNum);
    if(birth == null)
  System.out.println("birthday :");
    else
  System.out.println("birthday : " + birth);
 }
}

class PhoneManager
{
 final int MAX = 100;
 PhoneInfo[] registPhone = new PhoneInfo[MAX];
 int cnt = 0;
 public static Scanner keyboard = new Scanner(System.in);

 public static void showMenu()
 {
    System.out.println("\n");  // 공백 띄우기.
    System.out.println("메뉴를 선택하세요.");
    System.out.println("1. 전화번호추가하기");
    System.out.println("2. 검색하기.");
    System.out.println("3. 삭제하기.");
    System.out.println("4. 사용종료.");
 }
 
 public void inputData()
 {
    System.out.print("이름을 입력해주세요 :");   // 개행하지 않기위해 그냥 print 메소드를 사용함.
    String name = keyboard.nextLine();           // 입력을 엔터로 종료하기 위해.
    System.out.print("전화번호를 입력해주세요 :");
    String phoneNum = keyboard.nextLine();
    System.out.print("생년월일을 입력해주세요(모른다면 그냥 넘어가도 좋습니다.) : ");
    String birth = keyboard.nextLine();
 
    registPhone[cnt] = new PhoneInfo(name, phoneNum, birth);

    System.out.println("\n\n입력된 정보를 확인해 주세요.");
    registPhone[cnt].showPhoneInfo();
    cnt++;
 }
 
 public void searchData()
 {
    System.out.println("검색을 시작합니다.");

    System.out.print("이름 : ");
    String name = keyboard.nextLine();

    int indx = search(name);    // 검색 메소드 이용.
    if(indx < 0)
    {
       System.out.println("해당 이름의 자료가 없습니다.\n");
    }
    else
    {
       registPhone[indx].showPhoneInfo();
       System.out.println("검색하였습니다.\n");
    }
 }

 public void delData()
 {
    System.out.print("삭제하실 분의 이름을 입력해 주세요 : ");
    String name = keyboard.nextLine();

    int indx = search(name);
    if(indx <0)
    {
       System.out.println("해당 이름의 자료가 없습니다.\n");
    }
    else
    {
       for(int idx = indx; idx<(cnt-1); idx++)
  registPhone[idx] = registPhone[idx+1];

       cnt--;
    }
 }

 private int search(String name)
 {
    for(int idx=0; idx<cnt; idx++)
    {
  PhoneInfo pointInfo = registPhone[idx];
  if(name.compareTo(pointInfo.name) == 0)
     return idx;
    }
    return -1;   // 못찾았을 경우
 }
}
 
class PhoneManage3
{
    
 public static void main(String[] args)
 {
    int sel;     // 선택 변수
    PhoneManager manager = new PhoneManager();   //인스턴스 생성 (번호 데이터 관리)


    while(true)            // 사용자의 종료 입력전까지 반복.
    {
  manager.showMenu();
  sel = manager.keyboard.nextInt();
  manager.keyboard.nextLine();  // 남아있는 Enter입력 버리기.

  switch(sel)
  {
     case 1 :
        manager.inputData();
        break;
     case 2:
        manager.searchData();
        break;
     case 3:
        manager.delData();
        break;
     case 4 :
        System.out.println("시스템 종료");
        return;    // 반복문 나가기
  }
    }
 }
}

----------------------------------------------------------------------------------------------


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





오늘 2단계, 3단계의 전화번호 관리 프로그램을 업그레이드 시켰다. !!

:)

먼저
2단계 업그레이드 조건은
오늘 공부한 콘솔입력을 통해
사용자로부터 데이터를 입력받아 전화번호 관리 데이터들을 만드는 것이다.

먼저 main 메소드를 중심으로 내용들을 설계해 보았고
필요한 메소드가 무엇인지 체크하면서 시작했다.

흐름은
크게 while(true)으로 진행 할 것이다.
사용자가 종료하기 전까지 반복문으로 돌릴 생각이다.

while 안에서
1. 메뉴출력을 한다.
2. 선택을 입력 받는다.
3. 입력에 따라 모드를 바꾼다. (switch 이용)
-> 즉 switch이용할 것이므로  flag용으로 선택변수가 필요하다. 나는 int sel로 설정하였다.
    그러면 sel에 입력받을것이다.
필요 메소드
-> 메뉴 출력,  데이터 입력.

(전화번호 정보 클래스는 1단계에서 만든 것을 사용할 것이다.)

메뉴 출력 메소드는 println으로 작성했다.

데이터 입력 메소드는 각각의 정보입력에 따라 문자열을 생성하여 그 곳으로 집어 넣고
이 정보들로 전화번호 정보 클래스로 인스턴스를 만든다.


(작성코드.)


윗부분에는 전에 작성했던 전화번호 정보 클래스가 있다.

실행 결과



(결과)


여기에 조금 추가한것은..
왠지 생년월일 입력해주세요에 강요가 묻어나는 것 같았다.
몰라도 입력이 가능하게 만들어 놨으니
생년월일을 안써도 된다는 문구만 더 추가했다.


(추가 수정 코드)


(만족 스러운 2단계 업그레이드 버전)


모를때 그냥 엔터로 입력을 넘겨도 정보가 저장되는 것을 확인 할 수 있다.

2단계까지 업그레이드를 성공시켰다.

작성 풀 코드

---------------------------------------------------------------------------------------------

// 단계별 프로젝트 02
// 전화번호 관리 프로그램

import java.util.Scanner;

class PhoneInfo
{
 String name;
 String phoneNum;
 String birth;

 public PhoneInfo(String name, String phoneNum, String birth)
 {
    this.name = name;
    this.phoneNum = phoneNum;
    this.birth = birth;
 }
 public PhoneInfo(String name, String phoneNum)
 {
    this(name, phoneNum, null);
 }

 public void showPhoneInfo()
 {
    System.out.println("name : " + name);
    System.out.println("phone : " + phoneNum);
    if(birth == null)
  System.out.println("birthday :");
    else
  System.out.println("birthday : " + birth);
 }
}

class PhoneManage2
{
 static Scanner keyboard = new Scanner(System.in);

 public static void showMenu()
 {
    System.out.println("\n");  // 공백 띄우기.
    System.out.println("메뉴를 선택하세요.");
    System.out.println("1. 전화번호추가하기");
    System.out.println("2. 사용종료.");
 }

 public static void inputData()
 {
    System.out.print("이름을 입력해주세요 :");   // 개행하지 않기위해 그냥 print 메소드를 사용함.
    String name = keyboard.nextLine();           // 입력을 엔터로 종료하기 위해.
    System.out.print("전화번호를 입력해주세요 :");
    String phoneNum = keyboard.nextLine();
    System.out.print("생년월일을 입력해주세요(모른다면 그냥 넘어가도 좋습니다.) : ");
    String birth = keyboard.nextLine();
 
    PhoneInfo newInfo = new PhoneInfo(name, phoneNum, birth);
    System.out.println("\n\n입력된 정보를 확인해 주세요.");
    newInfo.showPhoneInfo();
 }
   
 public static void main(String[] args)
 {
    int sel;     // 선택 변수

    while(true)            // 사용자의 종료 입력전까지 반복.
    {
  showMenu();
  sel = keyboard.nextInt();
  keyboard.nextLine();  // 남아있는 Enter입력 버리기.

  switch(sel)
  {
     case 1 :
        inputData();
        break;
     case 2 :
        System.out.println("시스템 종료");
        return;    // 반복문 나가기
  }
    }
 }
}

-----------------------------------------------------------------------------------------------


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



오늘 공부는 JAVA에서 입력과 출력이다.
오늘 공부로서
이제 프로그램 콘솔창에서 직접 입력을 넣을 수 있게 됬다.

먼저 콘솔 출력부터 살펴보면,
우리가 전까지 쓰던


System.out.println(" ");

으로 사용했는데 이 것과 .print 둘 다 가능하다.
println은 문자열을 출력하고 개행(다음행으로 넘어감)처리가 된다.
print는 문자열을 출력하고 개행되지 않는다.

+ 문자열 조합 출력

System.out.printf("%d", 12);

12가 출력되는 문장이다. 이 구성은 C와 같다. C에서의 printf의 기능과 같다.

콘솔의 입력!
입력은 자바에서 원래 복잡한 기능이었으나,
자바 버전 5.0 이후로 이에 대한 대안이 나왔다. :)

바로 Scanner 클래스를 이용한 것인데, 먼저 방법은

Scanner sc = new Scanner(System.in);
int num1 = sc.nextInt();

위 코드는 사용자에게 입력을 받은 정수를 num1 에 저장하는 문장이다.
먼저 sc는 참조 변수이다. scanner 인스턴스를 만들어 입력을 받고
인스턴스의 nextInt 메소드를 이용하여 num1로 넘긴다.

Scanner의 주요 메소드들이다.
- public boolean nextBoolean()
- public byte nextByte()
- public short nextShort()
- public int nextInt()
-public long nextLong()
- public float nextFloat()
- public double nextDouble()
- public String nextLine()
-> nextLine()은 문자열의 끝을 enter입력을 통해서 종료를 표시한다.
나머지는 자료형의 입력에 따라 나누어진다.

(콘솔 입력 코드)


(결과화면)


위 결과를 보면 콘솔 입력이 구분되는 기준을 이해할 수 있다.
보면 처음에 1 엔터 2 엔터 3 입력하였을 때, 1, 2, 3 이 입력되었고
엔터도, 스페이스바도 치지 않았을 때 123 이 입력,
엔터후 2 입력했을 때 2, 스페이스바 후 3입력했을 때 3...

입력 콘솔에서 모든 공백이 데이터를 구분하는 기준이 된다.

그 다음으로서는 배열을 공부했다. 전에 학교 자료구조수업때 배열을 공부했었는데
내용은 그와 같다. C에서의 배열과 같다는 이야기다.
자바에서 배열의 특징은
배열도 인스턴스라는 것이다.
즉,!
배열을 생성할 때
다른 인스턴스를 생성하던 것처럼 new 를 포함해 생성해야된다는 점이다.
(하지만 꼭 new를 안써도 { } 중괄호를 이용해 생성할 수 도 잇다.)
선언은


int[] ref = new int[5];


이렇게 선언된 배열은 정수형 크기는 5인 배열을 선언한 것이다. 그렇게 되면 메모리 상에 정수형 크기 5인 배열의 공간이 확보된다. 그리고 ref에는 그 주소값이 들어가게 되는것이다. 즉 ref는 여기서 참조 변수이다.

문제 13-1
사용자로부터 입력 받은 수 중에 최대값과 최소값을 구하는 프로그램을 작성하세요.


------------------------------------------------------------------------------------------------

import java.util.Scanner;

class Problem131
{
 public static int[] insertData()
 {
    Scanner keyboard = new Scanner(System.in);
 
    int[] arr = new int[10];     // 들어올 변수 선언

    for(int i=0; i<arr.length; i++)
    {
  System.out.printf("정수를 입력해 주세요.(%d개)", arr.length-i);
  arr[i] = keyboard.nextInt();
    }
    return arr;
 }


 public static int minValue(int[] arr)
 {
    int min = arr[0];

    for(int i = 1; i<arr.length; i++)
    {
  if(min>arr[i])
     min = arr[i];
    }
    return min;
 }

 public static int maxValue(int[] arr)
 {
    int max = arr[0];

    for(int i =1; i<arr.length; i++)
    {
  if(max<arr[i])
     max = arr[i];
    }
    return max;
 }

 public static void main(String[] args)
 {
    int[] arr = new int[10];

    System.out.println("10개의 정수 중 최대,최소값 구하기 프로그램 시작");
    arr = insertData();
   
    System.out.println("최대값은 : " + maxValue(arr));
    System.out.println("최소값은 : " + minValue(arr));
 }
}

------------------------------------------------------------------------------------------------


작성한 코드이다.

클래스를 하나로 만들었고, main 메소드로 실행을 한다.
그리고 동작에 필요한 3개의 메소드들을 작성하였다.
(입력, 최대값구하기, 최소값구하기)

동작 확인

(문제13-1 결과)


배열은 10개로 지정했으므로 10개의 정수를 입력 받게 시작했다. 그리고 출력에서 몇개 남았는지 헷갈릴것 같아서 () 안에 몇개를 더 입력해야하는지 출력하였다.

최대 , 최소값 나온 것을 확인 할 수 있다. :)

for-each문
-> 자바 버전 5.0 이후부터 추가된것이다.

배열의 모든 값들에 대해 반복할 때 사용된다.
예를 들면 어떤 배열의 값들에 모두 1을 더한다든지 이런 데 사용된다.

예)


for(int e : arr)

        e++;


위와 같이 작성하면 모든 배열에 1을 더할 수 있다.

여기서 arr은 배열 이름이다. e는 모든 요소들을 지칭하는 변수로 나타내어진다.
(*그러나 이 구문이 끝나고 나면 변경 결과는 적용되지 않는다. 다시말하면 저 문장이 끝나고 다른 곳에서 저 배열을 확인하면 1이 증가되있지 않다.)

그러므로 배열의 내용을 바꾸지 못하지만  탐색같은 것을 할 때 더 유용하게 활용 될 수 있다.


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







+ Recent posts