1. Static scope in python

Python 같은 경우 static scope(lexical scope)만을 지원하며, 변수가 어디서 선언되냐에 따라 범위가 결정된다.

함수가 중첩되어 있을 시에는, 내부 함수에서 호출 대상이 없을 경우 상위 스코프에서 찾는다.

#in Fighter File
def obtain_coins(self):
        global coins_to_obtain
        self.coins += coins_to_obtain
        coins_to_obtain = 20
        
  
  
# in Tournament File 
def update_fighter_properties_and_award_coins(self, fighter, flag_defeat=False, flag_rest=False):
        if flag_rest == True:
            AdvancedFighterFile.coins_to_obtain /= 2
            AdvancedFighterFile.delta_attack = 1
            AdvancedFighterFile.delta_defense = 1
            AdvancedFighterFile.delta_speed = 1

과제를 했을 때 두 파일을 오고 가며 coins_to_obtain이라는 변수를 지속적으로 업데이트해야했는데 이때 global이라는 전역변수로 사용하여 함수 밖에서 사용가능하도록 만들어 줄 수 있다. 이때 Tournament file에서는 AdvancedFighterFile에서 coins_to_obtain 변수를 갖고왔으므로 AdvancedFighterFile.coins_to_obtain이라고 선언하여 변수를 활용 할 수 있다. 파이썬에서는 한 변수를 다른 범위내에서 사용하고 싶을 경우 global이라는 전역변수를 사용 할 수 있고 다른 파일에서 사용될 경우 반드시 그 변수 앞에 그 변수가 선언된 파일을 명시 해줘야한다.

 

2. 장점

변수를 정확히 어디서 가져오는지 명시하므로 가독성이 높다.

 

3. 단점

프로그램 실행 전의 컴파일할때 영역이 정해지므로 프로그램을 설계할때 변수의 scope도 항상 고려해서 설계해야하므로 프로그램 구조를 설계하기 어려울 수 있다.

 

 

4. My Review

확실히 파이썬의 경우 static scoping이라 변수를 어디서 선언하는지에 대해따라 값이 바뀔 수 있다. 그렇기에 어떤 함수 내에서 변수를 변환하고 또 다른 함수를 호출 할 경우, 만약 이 변수가 global이 선언 되있을 시 값이 원하는 대로 변하지 않을 수 있다. 따라서 항상 변수의 scope를 고려하는 것이 중요한 것 같다.

'Language' 카테고리의 다른 글

[Perl] What is dynamic scoping in Perl ?  (3) 2023.02.14
[Python] What is Duck typing?  (1) 2023.02.06
[Python] What is Dynamic typing?  (2) 2023.01.30
[C 언어] How to read file in C  (2) 2023.01.18
[COBOL] What is COBOL ?  (0) 2023.01.10

1. Dynamic scoping in Perl

    Perl에서는 Dynmaic scoping 변수를 선언하기 위해서는 local 이라는 키워드를 사용해야한다. 

#in Fighter file

our $coins_to_obtain = 20;
sub obtain_coins{
    my ($self) = @_;

    if ($AdvancedFighter::coins_to_obtain eq $coins_to_obtain ){
        $self->{coins} = sum $self->{coins}, $coins_to_obtain;
    }else{
        $self->{coins} = sum $self->{coins}, $AdvancedFighter::coins_to_obtain;
    }
    
}
# in tournament file

sub update_fighter_properties_and_award_coins{
	local $AdvancedFighter::coins_to_obtain = 20;
    local $AdvancedFighter::delta_attack = -1;
    local $AdvancedFighter::delta_defense = -1;
    local $AdvancedFighter::delta_speed = -1;

}

과제 때 활용한 코드에서는 coins_to_obtain에 local 키워드를 사용하여 이 변수를 다른 파일에서도 사용 할 수 있게 해주었다. 이때 이 변수 데이터가 fighter file의 coins_to_obtain가 구분하기 위하여 앞에 $AdvancedFighter::라는 대응표로 구분 시켜 주었다. 따라서 local 키워드를 사용한 변수들은 다른 파일이든 아니면 다른 함수에서 사용해도 어디에서든 변화 될 수 있고 사용할 수 있다. 즉, dynamic scoping이 적용된 변수는 다른 영역에서도 아무 선언 없이 자유롭게 사용 될 수 있다.

 

2. 장점

local이라는 키워드를 변수에 선언하면 어디서든 자유롭게 사용 가능하다.

 

 

3. 단점

해당 변수를 여기저기서 사용할 경우 어떻게 그 변수가 변화되는지 추적하기 어려워 질 것이다.

 

 

4. My Review

내가 한 과제에서는 local이라는 키워드를 사용한 이유는 해당 로직에서 라운드 승리시 코인의 변화를 준 후에 라운드 종료시 다시 획득 코인의 수를 기본값인 20으로 초기화 해줘야 하기때문에 이것을 dynamic scoping으로 만들어야 했다. 처음에는 같은 이름의 변수가 어떻게 다르게 적용 될 수가 있는 지 이해가 되지 않았지만 과제를 통해 어떻게 활용 할 수 있을지 조금 더 깨닫을 수 있었다.

'Language' 카테고리의 다른 글

[Python] What is static scoping in python?  (2) 2023.02.28
[Python] What is Duck typing?  (1) 2023.02.06
[Python] What is Dynamic typing?  (2) 2023.01.30
[C 언어] How to read file in C  (2) 2023.01.18
[COBOL] What is COBOL ?  (0) 2023.01.10

1. Duck typing

파이썬에는 덕타이핑이라는 특이한 특징이 있다. 이것은 타입을 미리 정하는게 아니라 실행이 되었을 때 해당 method들을 확인하여 타입을 정한다.

def interact_with(self, comer): #python version
        if comer._name == "Goblin":
            print(comer._active)
            print('\033[1;31;46mPlayer meets a Goblin! Player\'s HP - %d.\033[0m' %(comer._damage))
            
            self._hp -= comer.get_damage()
            comer.set_active(False)
            return False
            
 
 public boolean interactWith(Object comer) { #java version
		if (comer instanceof Goblin) {
			System.out.printf("\033[1;31;46mPlayer meets a Goblin! Player\'s HP - %d.\033[0m%n", ((Goblin)comer).getDamage());
			this.hp -= ((Goblin)comer).getDamage();
			((Goblin)comer).setActive(false);
			return false;
		}
		return false;
	}

첫번째 interact_with function은 파이썬에서 쓰이는 함수인데 보는 것과 같이 comer의 type을 일일히 적을 필요 없어 complie할때 타입을 정해준다. 반면에 자바같은 경우 코드를 적을때 comer의 type을 instanceof 를 이용하요 Goblin으로 명시하여야 해당 method 들을 사용 할 수 있다.

 

2. 장점

타입을 일일히 명시 할 필요가 없어서 편리하고 유용하다.

 

 

3. 단점

컴파일시 런타임 자료형 오류가 발생할 수 있다.

이런 오류가 발생시 정확히 어디서 잘못되었는지 오류를 찾기 어려워 할 수 있다.

 

 

4. My Review

나는 Moving in planet 프로젝트를 통해 이 duck typing의 효율성을 확실히 느낄 수 있었다. 이 프로젝트에서는 Map 이라는 object에 3가지 종류의 cell들이 있었는데 각각 다른 method 들을 가지고 있었다. 그래서 자바에서는 이것을 일일히 구분하여 적고 신경쓰면서 적었어야 했지만 파이썬에서는 그냥 해당 Map의 method 들을 다른 명시 없이 바로 사용해도 문제가 없어서 굉장히 편리했다. 하지만 나중에 컴파일 에러가 생기면 정확히 어디서 에러가 나는지 찾기 힘들 수 도 있다는 것은 확실히 어떤 느낌인지 알 것 같을 수 있었다.

'Language' 카테고리의 다른 글

[Python] What is static scoping in python?  (2) 2023.02.28
[Perl] What is dynamic scoping in Perl ?  (3) 2023.02.14
[Python] What is Dynamic typing?  (2) 2023.01.30
[C 언어] How to read file in C  (2) 2023.01.18
[COBOL] What is COBOL ?  (0) 2023.01.10

1. Dynamic Typing

Dynamic Typing 이란 프로그램이 런타임하는 동안 변수의 data type을 결정하는 것을 말한다.

그래서 파이썬에서는 따로 변수에 대한 정보를 선언할 필요없이 바로 사용가능하다. 

class Cell: #Python version
	def __init__(self, row = 0 , col = 0):
    		self._row = row
            self._col = col
            self._occupant = None
            self._color = None
            self._hours = 0
            
            
 pubilc class Cell { #Java version
 	public Cell(int row, int col) {
    	this.row = row;
        this.col = col;
        this.occupant = null;
        this.color = null;
        this.hours = 0;
    }
 
 
 }

파이썬 같은 경우 함수의 매개변수 row, col에 따로 변수 선언 을 할 필요 없지만, 자바같은 경우, row와 col에 int라는 data type을 확실히 선언해줘야한다.

def set_occupant(self, obj): #Python version
        if self.occupant == None or self.occupant.interact_with(obj):
            self._occupant = obj
            return True
        else:
            return False
            
            
public boolean set_occupant(GameCharacter obj) { #Java version
		if (this.getOccupant() == null || this.occupant.interactWith(obj)) {
			this.occupant = obj;
			return true;
		} else {
			return false;
		}
	}

이 경우는 function에도 똑같이 적용되는데, set_occupant라는 함수를 선언할때도 파이썬은 따로 변수를 선언할 필요없지만 자바같은 경우 boolean같이 data type을 반드시 명시해줘야한다.

 

2. 장점

코드를 작성하기 편하고 빠름

처음 프로그래밍을 접하기에는 편함

 

3. 단점

컴파일 시 데이터타입을 결정하기 때문에 속도 측면에선 안 좋음

아무래도 데이터 타입이 명시되있지 않기 때문에 이해하기 수정할때 이해하기 힘든 요소도 있음

 

My Review

이렇게 Dynamic typing 과 Static typing을 구분하여 보고나서 이러한 점들을 고려할 수 있게 되었다.

만약 Static typing을 쓴다면 에러를 빠르게 식별하기 편하고 프로그램의 실행속도를 확실히 올려 줄 수 있는 것은 확실하다. 하지만 불필요한 타이핑(반복된 변수 선언, 명시)을 반복해야하고 구조체를 변수로 사용할 때 불편한 점도 있을 것 같다.

반면 Dynamic typing은 구조체나 클래스의 method도 간단하게 쓸 수 있고 코드를 작성할 때도 훨씬 편하지만 코드가 복잡해질수록 에러가 발생시 이 에러를 찾아내는데 그만큼 많은 시간을 필요로 할 수 있는 위험이 있는 것 같다.

'Language' 카테고리의 다른 글

[Perl] What is dynamic scoping in Perl ?  (3) 2023.02.14
[Python] What is Duck typing?  (1) 2023.02.06
[C 언어] How to read file in C  (2) 2023.01.18
[COBOL] What is COBOL ?  (0) 2023.01.10
[Java] Why use Prepared Statement  (0) 2023.01.02

1. 파일 스트림을 파일 포인터를 이용하여 생성하기

FILE* fp;

 

2. fopen() 함수를 사용하여 파일 열기

fp = fopen("master.txt", "r"); //for read
if (fp == NULL){
	printf("fail read"\n);
}

fp = fopen("master.txt", "w"); //for write
if (fp == NULL){
	printf("fail write"\n);
}

fopen() 함수를 활용하여 파일을 열때 우리는 3가지 파일 모드중 하나를 선택할 수 있다.

r : read 파일 존재한다면 오픈/ 파일 없다면 실패 있다면 데이터 보존

w : write 없다면 파일 생성, 있으면 새로 수정

a : append 없다면 파일 생성, 있으면 기존 내용 보존

 

 

3. 파일 입출력 수행하기

파일에서 문자열 읽기

while(1){
	if (feof(fp) != 0) break;
    fgets(acc_name, sizeof(acc_name), fp);
    fgets(acc_num, sizeof(acc_num), fp);
}

char* fgets(char* str, int num, FILE* stream)

str : 문자열을 저장할 공간

num : 읽을 문자열의 길이

stream : 읽을 파일포인터

 

int feof(FILE* stream)

파일의 끝에 도달했는지 여부를 확인할 때 사용

파일에 끝에 도달할 경우 0이 아닌 값을 반환

 

파일 전체 읽기

#define MAX 1000
char buffer[MAX] {0, }; //1000바이트의 문자를 담을 수 있는 buffer를 변수 0으로 초기화
fread(buffer, 1, MAX, fp);  //1바이트를 1000번, fp내용을 buffer에 저장한 후 내용을 읽는다
pritnf("%s", buffer); //buffer의 내용을 출력한다

한줄씩 읽거나 한 글자씩 읽는 함수보다 파일 전체를 읽는 fread함수의 효율이 가장 좋다.

 

 

파일 쓰기

fp = fopen("trans711.txt", "w");
fprintf(fp, acc_num);
fpinrtf(fp, acc_oper);
fprintf(fp, "%07d", amount);
fputs("\n", fp);

fprtinf(FILE* stream, const char* format, ...)

stream이 가르키는 파일에 format에 맞게 문자열 쓰기

fprintf(FILE* stream, ...)

stream이 가르키는 파일에 문자열 쓰기

리턴 값 : 파일에 성공적으로 write한 문자의 개수

fputs(text, FILE* stream)

stream이 가르키는 파일에 text 쓰기

 

[fprintf, fputs는 버퍼에다가 값을 쓴다] => 즉 파일에 바로 쓰는것이 아니라 버퍼에 write 한 이후 추후에 버퍼를 파일에 내보내는 형식이다.

fflush(FILE* stream) => fflush를 통해 버퍼에 있던 값을 파일로 내보내 버퍼를 비워주면 바로 파일에 쓰기 가능!

 

 

4. fclose() 함수를 사용하여 파일 닫기

fclose(fp);

'Language' 카테고리의 다른 글

[Python] What is Duck typing?  (1) 2023.02.06
[Python] What is Dynamic typing?  (2) 2023.01.30
[COBOL] What is COBOL ?  (0) 2023.01.10
[Java] Why use Prepared Statement  (0) 2023.01.02
[Java] How to connect SQL with JAVA  (0) 2023.01.01

코볼이란 ?

코볼은 사무용으로 설계된, 영어와 같은 컴퓨터 프로그래밍 언어이다. 절차적, 명령형 언어이므로 객체지향 언어가 아니다.

코볼은 주로 비즈니스, 금융, 회사/정부 관리 시스템에서 주로 사용되었었다. 현재는 객체 지향도 지원한다고 한다.

 

코볼은 총 4가지 구역으로 나눌 수 있다.

1. IDENTIFICATION DIVISION : 소스 요소의 이름과 종류를 정의하는 곳

2. ENVIRONMENT DIVISION : 파일과 문자 집합을 정의하는 곳

ENVIRONMENT DIVISION.
           INPUT-OUTPUT SECTION.
           FILE-CONTROL.
               SELECT OPTIONAL MASTER ASSIGN TO "master.txt"
               ORGANIZATION IS LINE SEQUENTIAL.

ex) MASTER라는 변수에 master.txt 파일을 설정 할 수 있는 곳

 

3. DATA DIVISION : 변수와 매개변수 선언하는 곳

FD MASTER.
           01 WIZARD-INFO.
               03 ACC-NAME PIC A(20).
               03 ACC-NUM PIC X(16).
               03 ACC-PWD PIC 9(6).
               03 ACC-BLC PIC 9(16).

WIZARD-INFO 구조체를 만들어 불러온 MASTER 파일을 구조체에 맞게 구성 가능하게 할 수 있다.

 

4. PROCEDURE DIVISION : 프로그램을 동작하는 곳

PROCEDURE DIVISION.
       START-PROCEDURE.
           OPEN OUTPUT ATM-711.
           OPEN OUTPUT ATM-713.
           DISPLAY "##############################################".
           DISPLAY "##         Gringotts Wizrding Bank          ##"
           DISPLAY "##                 Welcome                  ##"
           DISPLAY "##############################################".
           GO TO CHOOSE-ATM.

       CHOOSE-ATM.
           DISPLAY "=> PLEASE CHOOSE THE ATM".
           DISPLAY "=> PRESS 1 FOR ATM 711".
           DISPLAY "=> PRESS 2 FOR ATM 713".
           ACCEPT ATM_NUM FROM CONSOLE.
           IF ATM_NUM = 1 THEN GO TO INPUT-ACCOUNT.

           IF ATM_NUM = 2 THEN GO TO INPUT-ACCOUNT.

           IF ATM_NUM >= 3 OR ATM_NUM <= 0 THEN
               DISPLAY "=> INVALID INPUT",
               GO TO CHOOSE-ATM.

       INPUT-ACCOUNT.
           DISPLAY "=> ACCOUNT".
           ACCEPT ACC FROM CONSOLE.
           DISPLAY "=> PWD".
           ACCEPT PWD FROM CONSOLE.
           GO TO OPEN-MASTER.

       OPEN-MASTER.
           OPEN INPUT MASTER.
           GO TO READ-FILE.

       READ-FILE.
           READ MASTER INTO WZ-INFO
               AT END GO TO RE-INPUT.
           GO TO CHECK.

       CHECK.
           IF ACC NOT = WZ-NUM OR PWD NOT = WZ-PWD
              THEN GO TO READ-FILE.
           IF PWD = WZ-PWD AND ACC = WZ-NUM THEN GO TO CHOOSE-SERVICE.

GO TO function으로 여러 procedure을 넘나 들 수 있음.

READ MASTER INFO WZ-INFO => MASTER 파일을 WZ-INFO 구조체에 맞게 읽어 줌.

 

My Review

What is the difference between COBOL and C?

COBOL 같은 경우 아무래도 문법 구성이 영어와 매우 흡사하므로 C 언어 보단 readability가 뛰어난 거 같다. 그래서 비전공자인 사람도 코볼 코드를 보면 이해할 수 있을 정도의 쉬운 접근성이 있다. 

하지만 코볼의 format은 굉장히 제한적인 경우가 많다. 예를 들어, 12-72열까지만 명령문을 기입할 수 있는 굉장히 제한 적인 format이기 때문에 아무래도 C 언어 보단 불편한 점이 있는 거 같다.

 

Why COBOL is used in present? 

코볼은 초기 프로그램 언어이고 초반에 절차적. 명령형 언어로 설계되어 많은 비즈니스 관련 시스템에 녹아 들어있다. 그래서 많은 양의 코볼 프로그램을 다 갈아치우기는 힘들어 몇몇 곳은 여전히 코볼이 쓰인다고 한다. 하지만 많은 양의 코볼 프로그램을 현재 데이터베이스 프로그램으로 대체하는 중이라고 한다.

 

'Language' 카테고리의 다른 글

[Python] What is Duck typing?  (1) 2023.02.06
[Python] What is Dynamic typing?  (2) 2023.01.30
[C 언어] How to read file in C  (2) 2023.01.18
[Java] Why use Prepared Statement  (0) 2023.01.02
[Java] How to connect SQL with JAVA  (0) 2023.01.01

Why use Prepared Statement instead of Statement?

위에 구문을 Statement 객체를 사용하여 만들면 다음처럼 구현된다.

String sql = String sql = "SELECT * from car, car_category CC, copy, produce WHERE car.callnum =" + num;
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);

이렇게 구현할 경우 쿼리문을 수행할때마다 매번 컴파일을 하기 때문에 성능 저하

But 실행되는 SQL문을 확인가능

 

Prepared Statement 경우

 

컴파일이 미리 되어있기 때문에 Statement에 비해 좋은 성능

특수문자를 자동으로 파싱해주기 때문에 SQL injection 같은 공격을 막을 수 있음

"?" 부분에만 변화를 주어 쿼리문을 수행하므로 실행되는 SQL문 파악하기 어려울 수 있다.

 

Prepared Statement가 사용되면 좋은 경우

 

1. 사용자 입력하여 쿼리문을 실행할 경우 

=> 특수 문자가 들어와도 알아서 파싱하므로 에러 방지 가능

2. 쿼리 반복 수행 작업일 경우

Prepared Statement는 구문을 캐시에 담아 재사용 하기 때문에 반복적으로 동일한 쿼리를 사용한다면 DB에 훨씬 적은 부하를 주며 성능도 좋아진다.

 

'Language' 카테고리의 다른 글

[Python] What is Duck typing?  (1) 2023.02.06
[Python] What is Dynamic typing?  (2) 2023.01.30
[C 언어] How to read file in C  (2) 2023.01.18
[COBOL] What is COBOL ?  (0) 2023.01.10
[Java] How to connect SQL with JAVA  (0) 2023.01.01

JDBC API를 이용하여 데이터베이스에 연결하기

 

1. java.sql 모듈 import 하기

import java.sql.*;

 

2. 드라이버 Load하고 Connection하기

public static void main(String[] args) {

		String dbAddress = ""; 
		String dbUsername = "";
		String dbPassword = "";

		Connection conn = null;
		try {
			Class.forName("com.mysql.jdbc.Driver");
			conn = DriverManager.getConnection(dbAddress, dbUsername, dbPassword);
		} catch (ClassNotFoundException e) {
			System.out.println("[Error]: Java MySQL DB Driver not found!!");
			System.exit(0);
		} catch (SQLException ex) {
			System.out.println("SQLException: " + ex.getMessage());
			System.out.println("SQLState: " + ex.getSQLState());
			System.out.println("VendorError: " + ex.getErrorCode());
		}
  
  
  }

구현시 해당 경로에서 드라이버를 찾지 못하는 예외 발생을 대비해 try catch 구문 사용하기

Static은 프로그램이 시작되자마자 곧장 메모리에 올라가므로 Static 블록 안에 드라이브 클래스 로딩하기

DB에 접근하기 위해 getConnection 기능을 사용하는데 이때 3가지 정보가 필요

(1. 연결할 DB의 url, 2. 계정명, 3. 계정 비밀번호)

 

 

3. SQL문 실행하고 생성된 결과 반환하기

try{
	PreparedStatement pstm;
	String sql = "SELECT * from car, car_category CC, copy, produce  WHERE car.callnum = ?";
	pstm = conn.prepareStatement(sql);
	pstm.setString(1, callnumber);
	ResultSet rs = pstm.executeQuery();
	while (rs.next()){
                isresult = true;
                rs_call_num = rs.getString("callnum");
                rs_car_name = rs.getString("name");
                rs_name = rs.getString("ccname");
                rs_company = rs.getString("cname");
                rs_copy_num = rs.getInt("copynum");
                System.out.println("|" + rs_call_num + "|" + rs_car_name + "|" + rs_name + "|" + rs_company + "|" + rs_copy_num + "|");
            }
 }catch (SQLException e) {
 	System.out.println("Wrong SQL!");
 }

실행할 SQL문을 만들어  preparedStatement 메서드를 통해 실행하기

setString같은 메서드로 SQL구문에서 "?" 부분을 원하는 표현으로 대체 가능

SQL문이 SELECT문이면 executeQuery() 메서드 사용, INSERT, UPDATE, DELETE문이면 executeUpdate() 메서드 사용하기

ResultSet rs를 통해 SQL문 실행시 출력되는 데이터베이스 결과 값을 가져 올 수 있음

rs.getString, rs.getInt로 데이터베이스 값에서 원하는 항목을 불러 올 수 있음

 

Interested Concept

Why use preparedStatement ?

https://guswns00123.tistory.com/5

 

[Java] Why use Prepared Statement

Why use Prepared Statement instead of Statement? 위에 구문을 Statement 객체를 사용하여 만들면 다음처럼 구현된다. String sql = String sql = "SELECT * from car, car_category CC, copy, produce WHERE car.callnum =" + num; Statement stmt

guswns00123.tistory.com

 

 

 

'Language' 카테고리의 다른 글

[Python] What is Duck typing?  (1) 2023.02.06
[Python] What is Dynamic typing?  (2) 2023.01.30
[C 언어] How to read file in C  (2) 2023.01.18
[COBOL] What is COBOL ?  (0) 2023.01.10
[Java] Why use Prepared Statement  (0) 2023.01.02

+ Recent posts