AUTOMATA

머리말

글을 쓰기 앞서, 본 게시글의 목적을 언급하고 가겠습니다.

글을 쓰게 된 이유는, 3학년 1학기에 들었던 오토마타 수업 내용을 나중에 다시 봐야할 때, 내가 기록해둔
글을 보면 좀더 좋지 않을까 싶어 작성합니다. 그러다보니, 생략된 부분이 있을 수도 있고, 또는 오개념이 있을 수도 있습니다.

잘못된 부분은 댓글로 달아주시면 수정하도록 하겠습니다.

이 글이 오토마타를 처음 공부하는, 또 복습하는 사람들에게 도움이 됐으면 좋겠습니다.

오토마타

오토마타란 무엇일까?
#0 글에서 얘기했지만 한번 더 알아보자.

위키피디아에서 정의하고 있는 오토마타는 다음과 같다.

오토마타는 이산 시간 동안 주어진 입력에 의존해 작동하는 수학적인 기계이다. 

출처 - https://ko.wikipedia.org/wiki/오토마타_이론

처음 배워 저 내용만 듣고는 정확히 오토마타에 대해서 이해하기 힘들었다.

주어진 입력에 따라 원하는 결과가 나오도록 설계하는 과정, 혹은 그러한 기계이다.

컴퓨터에 관심있는 사람이라면, 알고리즘에 대해서 들어봤거나, 직접 짜본적이 있을거다.

짧은 시간적은 공간으로 문제를 해결하는 코드가 좋은 알고리즘이라고 한다.

하지만 알고리즘이라는 것을 작업할 때마다 사용해야 한다면, 아무리 좋은 알고리즘이라도 비효율적일 것이다.
그래서 입력에 대한 모든 처리가 되어있다면, 입력받은 값과 현재 상태를 안다면, 훨씬 더 빠른 작업을 할 수 있다.
사실상 state, transition으로 구성된 알고리즘이라고 생각하면 된다.

 

오토마타 수업에서는...

  • Notation
  • Non Deterministic & Deterministic
  • language
  • Regular Expression

에 대해 다루고, 개념을 응용한 Turing Machine까지 약간 다룰 것이다.(튜링머신은 아주 조금 배웠다.)

우선, 예를 들어보자.

 

배고픔에 관한 그래프


현재 State는 {hungry, not ungry} 2개, hungry와 not hungry 사이의 4개의 Edge가 존재한다.
하나의 State 마다 Transition에 대한 Edge가 있는 것도 확인 할 수 있다.

다음은 테니스 경기를 통해 예를 들어보겠다.

테니스 경기에 관한 그래프



테니스 점수 방식에 대해 모를수 있어 설명하자면, 한게임당 15점이며, 30점에서는 이기면 10점오른다.
먼저 40점에 도달했다면, 매치포인트 상황이고, 두 팀의 점수가 40점으로 동일하다면 듀스이다.
듀스에서는 연속으로 두경기를 이겨야 승리할 수 있다.

 

두 개의 예시를 통해 오토마타의 특징을 얘기해보자.

  • 둘다 유한한 갯수의 state가 존재한다. (Finite States)
  • Input을 받고, Output을 만들어 낸다.
  • 현 상태를 저장하는 아주 작은 임시저장공간만 있으면 된다.
  • Input에서 Output으로 변환하는 과정에서는 Output은 그래프의 Edge를 따라 결정된다.

마무리

좀더 자세한 수업이 듣고 싶다면 아래 링크에 들어가서 수업을 듣기를 권장합니다.
아래 링크는 KOCW에 올라와 있는 한양대학교 박희진 교수님의 오토마타 강의이며, 명강의로 알려져있다.

 

Youtube Link - https://www.youtube.com/watch?v=9RGYOBNh-iM&list=PLSN_PltQeOygPrInjCFdQM992AotARlFa&index=1

예고

다음 게시글에서는 오토마타 이해를 위한 집합 에 대해 다룰 예정입니다.

'학교 공부 > automata' 카테고리의 다른 글

#1 오토마타 첫걸음  (0) 2020.07.06
#0 오토마타  (0) 2020.07.05

AUTOMATA

개요

2020년 3학년 1학기 과목으로 오토마타 수업을 들었다. 수업은 이론이 100%인 수업이였다.

처음 들었던 오토마타는 생소한 단어였다. 인터넷에 검색을 해봐도 이해하기 힘들었다.

오토마타는 이산 시간 동안 주어진 입력에 의존해 작동하는 수학적인 기계이다. 
[출처 - https://ko.wikipedia.org/wiki/오토마타_이론]

수업을 다 듣고 정리하는 지금, 오토마타를 쉽게 설명하자면 다음과 같다.

주어진 입력에 따라 원하는 결과가 나오도록 설계하는 과정, 혹은 그러한 기계이다.

물론 기계적인 부분은 배우지 않아 전혀 다룰 계획은 없다.

지금부터 어떤 컨텐츠로 글을 작성할지 소개하고자 한다.

참고서로는 Formal Languages And AUTOMATA 6th edition written by _Peter Linz_를 사용했다.

혼자공부하거나 오토마타 수업을 듣다가 참고하기 좋은 강의가 있다.

[Youtube Link - [https://www.youtube.com/watch?v=9RGYOBNh-iM&list=PLSN\_PltQeOygPrInjCFdQM992AotARlFa&index=1]]

위 링크는 KOCW에 올라와 있는 강의이다. 한양대학교 박희진 교수님의 강의이며, 매우 좋은 강의로 불린다.

목차

블로그 글은 참고서의 목차와 같은 순서로 진행될 예정이다.

  • 오토마타 이해를 위한 도입부분
  • language 와 grammars
  • dfa와 nfa 그리고 regular language
  • dfa, nfa, grammar 그리고 regular expression
  • 비둘기집 원리와 펌핑레마(Pumping lemma)
  • context-free language(grammar) 와 normal-form grammar
  • npda
  • two Puming lemma
  • Turing machine

오토마타에 대한 내 생각은 다음과 같다.

수학을 좋아하는 사람이라면 흥미를 느낄 수 있는 과목이다.

게시글부터는 오토마타에 대해 제대로 얘기해보자.

'학교 공부 > automata' 카테고리의 다른 글

#1 오토마타 첫걸음  (0) 2020.07.06
#0 오토마타  (0) 2020.07.05

2020/06/11 수요일

문제


  1. 2016/06/10 3번 문제해결 코드의 문제점이 있다.

    1. 코드의 문제

      • 일대 다수관계의 있기 때문에, 유저관련 데이터를 삭제하는데 있어 3가지의 경우의 수가 있다.
      1. Tag가 있다면 태그를 지우고 Memo를 지우고, User마저 지운다.

        return res.status(200).json({message: "Tag, Memo, User delete success"});
      2. Tag가 없다면 넘어간다.

        1. Memo가 있다면, Memo를 지우고, User를 지운다.

          1. User가 있다면 다음과 같은 코드를 리턴해준다.

            return res.status(200).json({message: "Memo, User delete success"});
          2. User가 없다면 다음과 같은 코드를 리턴해준다.

            return res.status(400).json({message: "no such user"});
        2. Memo가 없다면, User로 넘어다.

          1. User가 있다면 다음과 같은 코드를 리턴해준다.

            return res.status(200).json({message: "User delete success"});
          2. User가 없다면 다음과 같은 코드를 리턴해준다.

            return res.status(400).json({message: "no such user"});
  1. Memolight 마지막 페이지인경우 처리 필요

    1. 현재 코드

      let hasNextPage = page <= (filteredMemos.length / LIMIT);
    2. 해결 방법

      • ~ <= 를 < 로 변경해주면 된다. ~ 6월 12일에 다른 해결방법 찾음

궁금증

  • ORM
  • DB설계

'매일매일' 카테고리의 다른 글

매일매일 코딩하기 #2  (0) 2020.06.15
매일매일 코딩하기 #1  (0) 2020.06.11

Software studio 1 수업 중 server environment 셋팅에 관련해서 정리해보고자 한다.

ERD 만들기

Models

User

  1. pk
  2. id
  3. pw
  4. Name
  5. createdAt ( sequelize 자동생성 )
  6. updatedAt ( sequelize 자동생성 )

Memo

  1. pk
  2. UserPk ( sequelize 자동생성 )
  3. memo # ERD 만들기
  4. title
  5. description
  6. book (Naver API 이용하는 부분이라 2차기능)
  7. createdAt ( sequelize 자동생성 )
  8. updatedAt ( sequelize 자동생성 )

Tag

  1. pk
  2. MemoPk ( sequelize 자동생성 )
  3. tag
  4. createdAt ( sequelize 자동생성 )
  5. updatedAt ( sequelize 자동생성 )

Relations

  • 한 유저가 여러 개의 메모를 가질 수 있다. hasMany
  • 메모 하나는 한 유저에 속한다. belongsTo
  • 하나의 메모는 여러 개의 태그를 가질 수 있다. hasMany
  • 하나의 태그는 하나의 메모에 속한다. belongsTo

서버를 클라우드 환경으로 올리기 ( 서버, 데이터베이스 )

Aws.amazon.com 에서 RDS, ec2 프리티어 12개월로 생성함

RDS

  1. 데이터베이스
  2. Mysql 5.7.21 버젼으로 함 ( 최신이라고 좋은게 아니라고 함 )
  3. DB 인스턴스 식별자 - memolight-db
  4. 퍼블릭 액세스 가능성 - 예
  5. 보안그룹 - ec2 관리하는 곳에서 보안그룹 생성해서 기존의 보안그룹 지우고 새로 만든 보안그룹 추가해주기
    a. 인바운드 규칙에 MYSQL/Aurora 위치무관 을 추가하기

ec2

  1. 인스턴스 시작누르고 Amazon Linux 2 AMI (HVM), SSD Volume Type - ami-01288945bd24ed49a 제일 위에 있는 것 선택하기
  2. 2번째꺼 체크 되어 있는 것 확인하고 검토 및 시작 버튼 누름
  3. 이후 별다른 설정 없이 넘기다가 보안 그룹에서 설정해줌
  • 보안그룹 - SSH, HTTP, HTTPS 위치 무관으로 추가해줌
  1. 새 키 페어 생성 누른후, 원하는 키 페어 이름 설정 - memolight
  2. 키 페어 다운로드 버튼 누르면 memolight.pem 파일 다운로드
  3. 해당 파일을 자주 사용하는 폴더로 옮겨둔 후, 인스턴스 시작 누름
  4. 터미널을 켜서 해당 폴더로 들어감

In terminal

$ chmod 400 memolight.pem

$ ssh -i "memolight.pem" ec2-user@ec2-15-164-165-241.ap-northeast-2.compute.amazonaws.com

$ sudo yum install git

$ git clone https://github.com/ProjectInTheClass/MemoLight.git

$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash

$ . ~/.nvm/nvm.sh

$ nvm install node

$ cd Memolight/backend

$ node app.js

mysql workbench

  1. MySQL Connections 옆에 + 버튼 눌러서 추가하기
  2. Connection name 은 Memolight으로 설정하기
  3. 엔드포인트(memolight-db.cve2tudmkydi.ap-northeast-2.rds.amazonaws.com)를 Hostname에 넣어주기
  4. Username은 memo로 password는 store in Keychain에 하고 로그인하기
  5. Schemas에서 innodb 와 sys는 건들면 안됨. 따라서 Query1 파일에서 CREATE DATABASE 'memoligh' 해주고 번개 버튼 누르면 새로운 데이터베이스가 생김.

Sequelize를 기존 서버에 import 시킨 후 MySQL과 연동하기

Sequelize 설치

$ npm i sequelize mysql2

$ npm i -g sequelize-cli

$ sequelize init

config

  • 기존의 config.json 파일은 database-development, database-test, database-production 으로 나뉘어져 있다. 이를 하나만 사용해도 무방하다고 한다 (대규모 개발이 아닌경우에는)

  • config.json 코드를 config.js에 옮기면 에러가 난다. Module.exports =를 해주면 해결된다.

  • Database-production 대신 db로 바꿔주고, username은 memo, password는 알맞게 입력해주고, database는 (확인요망)host는 memolight-db의 엔드포인트이고 나머지는 그대로 해주면 된다.

  • Index.js 코드를 보면 윗부분에 const config = ~~와 그 윗줄을 지워준다.

  • 그리고 나서 const config = require('../config/config'); 를 추가해준다.

  • sequelize 변수를 초기화 해주는 부분도 바꿔준다.

.gitignore

config.js 추가

models 폴더에 테이블 추가

js코드랑 mySQL을 연결해주는 코드는

const models = require('./models');

models.sequelize.sync();

ERD를 바탕으로 Sequelize에 테이블들 만들어 놓기

PrimaryKey

attribute중 primaryKey : true, autoIncrement : true 설정해주기

Relation

table명.asscociate = function(폴더명) {...}

ex)

  • belongsTo
  • hasMany

'학교 공부 > software studio' 카테고리의 다른 글

AWS Server Environment setting  (0) 2020.06.11

2020/06/10 수요일

문제


  1. get 방식에서는 body를 사용하지 못한다.

    1. 해결방법
      1. query나 params를 통해서만 보내는 방법으로 해결함.
    2. 궁금증
      1. POST 이외에 PUT, DELETE 방식도 body를 사용하지 못하는가?
  2. 계정 탈퇴시, 해당 계정으로 로그인 하고 있는 다른 디바이스들의 세션도 삭제해줘야한다.

    1. 해결방법

      1. Middleware를 사용해서 각 디바이스의 세션에 저장된 유저정보가 실제로 DB의 User Table에 존재하는지 체크하도록 했다.
      2. Middleware 같은 경우 모든 API요청마다 실행되기 때문에 최적화를 위해 필요한 상황에만 코드를 읽을 수 있도록 예외처리했다.
      • 필요한 상황 - 그림으로 설명 하겠다.
    2. 코드

      app.use(function(req, res, next) {
      if(!req.session.isLogin)
      return next();  //return 을 붙이지 않으면 에러 발생 
      
      const id = req.session.user.id;
      
      models.User
      .findOne({where: { id }})
      .then((result)=> {
         if(result) {
             console.log('next');
             return next();  
         } 
         else {
             console.log('here');
             req.session.destroy(err => {
                 if (err)
                     return res.status(500).json({ message: "server error"});
                 else
                     return res.status(200).json({ message: "session destroy cause of delete user"});
             });
         }
      })
      });
    3. 새로 알게된 점

      • 미들웨어를 사용하는 중, 예외처리를 하고 나서, 예외조건에 걸리지 않은 경우에만, 처리하도록 했다. 이때 예외처리에서 next( )를 사용했는데 다음과 같은 에러가 발생했다.
        TypeError: Cannot read property 'id' of undefined
        next( ) 앞에 return을 붙여주니 해결되었다. 원인은 아직 찾지 못함
  1. User DELETE API 기능을 분리하고 싶다.

    1. 현재 User, Memo, Tag 데이터가 있다.

    2. 각 데이터 간의 관계

      • 유저와 메모는 1대 다 관계이다.
      • 유저와 태그는 1대 다 관계이다.
      • 메모와 테그는 1대 다 관계이다.
    3. 현재진행 상황

      1. 1대 다 관계중 1인 데이터를 지울 경우, 해당 API 요청 메소드에서 먼저 다 관계에 있는 데이터를 지운 후, 1인 데이터를 지워주고 있다.

      2. 코드

        router.delete('/delete', function (req, res) {
        //deactivate user account
        let UserPk = req.session.user.pk;
        
        if(!req.session.isLogin)
           return res.status(400).json({message: "login first"});
        
        let id = req.session.user.id;
        
        models.Tag
           .destroy({where: { UserPk }})
           .then(result => {
               if(result) {
                   models.Memo
                       .destroy({where: { UserPk }})
                       .then(result => {
                           if (result) {
                               models.User
                                   .destroy({where: { id }})
                                   .then(result => {
                                       if (result) {
                                           req.session
                                               .destroy(err => {
                                                   if (err)
                                                       console.log("delete session fail");
                                                   else
                                                       console.log("delete session ok");
                                               });
                                           return res.status(200).json({message: 'deactivate account ok'});
                                       } else
                                           return res.status(400).json({message: 'bad request deleting user'});
                                   })
                                   .catch(err => {
                                       console.log(err);
                                       return res.status(500).json({message: 'user server error'});
                                   })
                           } else {
                               return res.status(400).json({message: 'bad request deleting memo'});
                           }
                       })
                       .catch(err => {
                           console.log(err);
                           return res.status(500).json({message: 'memo server error'});
                       })
               } else {
                   return res.status(400).json({message: 'bad request deleting tag'});
               }
           })
           .catch(err => {
               console.log(err);
               return res.status(500).json({message: 'tag server error'});
           })
        });
    4. 원하는 해결방안

    • 각 데이터별 지우는 API가 따로 존재하기 떄문에, 그 것을 이용하는 방법으로 가고 싶다.

'매일매일' 카테고리의 다른 글

매일매일 코딩하기 #2  (0) 2020.06.15
매일매일 코딩하기 #1  (0) 2020.06.11

2020.05.28 새벽 3시 30분

지금 블로그의 첫 글을 쓰기 시작한 순간이자, 제목 그대로의 경험을 했다.

'첫 단추를 잘 꿰어야 한다'라는 속담에서 볼 수 있듯이, 첫 게시글부터 좋은 글을 쓰고 싶었다.

그러던 중, 지금 이 감정을 고스란히 잘 녹여내 글로 남긴다면,

훗날 이 글을 보는 나에게도, 또 개발의 길에 이제 막 들어섰거나, 그 위에서 힘들어하고 있을 개발자들에게

도움이 되지 않을까라는 생각을 하게 되었다.

 

독자들이 좀 더 감정이입을 하기 위해 필자에 대한 간략한 소개와 이어질 내용에서 ''라는 표현을 사용하고자 한다.

 

나는 서울 모 대학교 컴퓨터 소프트웨어학부에 재학 중이다. 군대 복학 후, 군 버프 덕분에 좋은 학점을 받을 수 있을 거라는 생각에 

학기 중에 감당하기 힘든 과목들을 선택했다. 그중 하나가 바로 iOS 앱 개발에 관한 수업이다.

수업내용은 원래 앱 개발에 관심이 있던 터라, 배우는 과정은 나름 괜찮았다. 이 수업은 중간고사와 팀 프로젝트로 성적을 매긴다.

전역 후부터 개강 전까지 실제 창업을 준비하는 지인분 밑에서 배우면서 코딩을 할 수 있는 기회가 생겼다.

이후 나는 database부터 Dao, Service, API, back, front까지 한 번씩 해본 것을 back-end를 잘 다룰 줄 안다고 생각했다.

이 생각은 2020.05.26시 오후 3시에 처참히 깨졌다.

iOS 앱 개발 수업에서 참여한 팀에서 back-end를 담당하기로 했다. 개발을 시작하면서, 나의 생각이 자만이었고,

나의 무지함을 느낄 수 있었다. 짧으면 30분, 길면 몇 시간을 투자했는데 알고 보니, 더 쉬운 방법이 있거나, 에러가 생기는 이유가 단지

세미콜론(;)이나, 오탈자 때문임을 느꼈을 때... 나는 노트북을 부수고 싶었다. 

***(비속어 주의)***

그리고 한 시간 정도를 계속 '나는 병신이다', '군인이나 할걸... 삽질 전문인가...'를 되뇌었다.

 

하지만, 과 선배(같은 프로젝트 팀원) 랑 카톡 하면서 누구나 다 겪는 일임을 깨달았다.

 

그리고 곧장 나의 이 감정과 앞으로도 계속 반복될 나의 삽질, 그리고 그 삽질들이 모여 만들어진 무언가를 기록하고 남기기 위해

블로그를 만들러 왔다. 아니.. 사실 코딩하다가 쉴 겸 온 거다

 

갑자기 이 노래 가사가 떠올랐다. 

 

[길-god 가사 중 일부]

내가 가는 이 길이 어디로 가는지

어디로 날 데려가는지 그곳은 어딘지

알 수 없지만 알 수 없지만

알 수 없지만 오늘도 난 걸어가고 있네

 

...

 

나는 왜 이 길에 서있나

이게 정말 나의 길인가

이 길에 끝에서 내 꿈은 이뤄질까

 

[출처 : https://music.bugs.co.kr/track/104788?wl_ref=list_tr_08_mab]

 

'모두 단 한 번의 삶을 살 수 있다. 또 대부분이 처음 가는 길일 거다.

그러니 두려워말자. 남들보다 뒤처진다고,

내가 지금 힘들어한걸 남들도 똑같이 경험했을 거다

그러니 오늘도 열심히 삽질하자

코딩 시발'

 

+ Recent posts