[카테고리:] 컴퓨터

  • DB숙제 – 완전 OTL

    DB 숙제를 하다가 1주일을 날려먹었다.

    처음은 쉽다.

    A테이블에서 칼럼 a와 b를 출력해라

    SELECT a, b FROM A

    두번째도 쉽다. B테이블에서 a, b, c를 출력하는데 c가 ‘abc’인 것만 출력해라

    SELECT a, b, c FROM B WHERE c=’abc’

    세번째가 1주일을 말아먹은 그 문제다. C는 A와 B의 관계 테이블인데, C에 관계가 있는 것들만 A와 B에서 찾아서 A의 a칼럼과 B의 a칼럼을 출력해라.

    이걸 1개의 Select로 처리하려고 하니 안된다. Join질의는 한번에 2개까지만 받아주고 3개는 못받더라. 그래서 View를 하나 만들었다.

    CREATE VIEW D AS SELECT A.a, A.b, C.c FROM A JOIN C ON A.b=C.c

    그리고

    SELECT A.a, B.b FROM B JOIN D ON B.b=D.b

    이렇게 처리했다.

    그렇게 했더니 네번째는 좀 쉬웠다. C테이블에 관계가 있는 것들중에 A테이블의 PK별로 B에 있는 c칼럼 항목의 합을 출력해라. 위의 View를 B.c를 포함하도록 조금 고쳐주고

    SELECT sum(B.c) FROM A JOIN D ON A.a=C.c GROUP BY A.a

    이렇게 했다.

    그리고 마지막 문제…완전 막장이다.

    C테이블에 관계가 있는 E테이블의 a칼럼이 ‘abc’이면서 B테이블의 b칼럼이 ‘def’인 A테이블의 a, b 칼럼과 B테이블의 d칼럼과 E테이블의 b칼럼을 출력해라.

    어떻게 해야 하나 고민중이다. View를 하나 더 만들어야 하나…

    *숙제라서 표절시비에 휘말리면 안되므로 내용을 전혀 알수 없게 처리했다.

    *추가. Instance를 7개 이상(각 테이블에 7건 이상) 입력해야 한다는 조건을 이제 발견했다. 처음부터 다시 해야 한다. -_-;;; 제출에 화면 캡쳐까지 포함이기 때문에 화면 캡쳐를 하려면 처음부터 다시 해야 한다는 뜻. 근데 SQL Plus에선 붙여넣기가 안된다. 교수가 이걸 알고 오라클은 SQL Plus를 쓰라고 시킨 걸까?

    *또 추가. 교재에 오타가 너무 많다. 그것도 설명문이 아니라 예제로 나온 명령문에 오타가 많다. 예제 그대로 입력했는데 실행되질 않아서 인터넷을 찾아보니 책이 틀렸더라. 제발…ㅜ_ㅜ

    초보자들은 교재 내용, 특히 그중에서도 예제만 믿고 가는데 컴퓨터 교재는 제발 예제에는 오류가 없었으면 좋겠다.

  • DB숙제

    방통대 숙제하다가…

    1. ER-win을 써서…

    ER-win이라는 것을 써서 뭔가 그림을 그려서 제출해야 한다. 근데 뭔가 공부한건 많은데 정작 써야 하는 기능은 몇개 없고, 결과적으로는 겉보기에 이쁜 그림이면 OK라서 그냥 써보다가 말았다.

    2. 오라클

    숙제하기 전, 오라클에게 Neo가 누구냐고 물어보고 싶었지만…

    설치할 때 지정한 관리자 계정의 암호를 잊어먹었다. 다시 설치해야 하나보다.

    3. 오라클 캐무시

    이 숙제는 MS-SQL이나 오라클을 써서 수행해야 하는 과제이다. 그런데 MS-SQL은 쿼리분석기(GUI툴)를 써서 하고 오라클은 SQL*Plus(CUI툴)를 써서 하라고 한다. 오라클에도 SQL Developer라는 GUI툴이 있던데.

    오라클은 왜 도스창 띄워서 해야 하는지 모르겠다. 숙제 지정사항이라 뭐라 할수도 없고…

    4. Neo를 찾아라

    SELECT location FROM persons WHERE name=’Neo’

    이러면 되나요?

    5. 테이블 별명

    숙제에서는 테이블 별명을 사용하라고 하는데…

    교재는 아무리 뒤져봐도 테이블 별명이 없다. 설마 강의에서만 나온 내용인가?

  • 정규표현식

    정규표현식(Regular Expressions, Regex)은 문자열의 패턴을 정하는 방법이다. 예를들어, 이런걸 할 수 있다.

    “로또 번호는 00부터 45사이에 있는 6개의 두자리수인데, 각 수는 쉼표로 구분된다”

    이건

    (([0-3]{1}[0-9]{1})[,]{1}|([4]{1}[0-5]{1}[,]{1})){5}([0-3]{1}[0-9]{1}|[4]{1}[0-5]{1}){1}

    이렇게 나타내면 된다. (다만 이 표현식으로는 중복된건 못 걸러낸다.)

    정규표현식을 테스트 해보고 싶으면 아래 웹 사이트에서 간단히 해볼 수 있다.


    http://regexpal.com/

    이 얘기를 왜 하냐면, 만화를 하나 소개하려고…

    이 만화는 CCL에 의해서 사용된다.


    Creative Commons License


    This work is licensed under a

    Creative Commons Attribution-NonCommercial 2.5 License

    .


    This means you’re free to copy and share these comics (but not to sell them).

    More details

    .

    원본 :

    http://xkcd.com/208/

    알면 재밌다.

  • 방통대 숙제하기

    이번에 데이터베이스의 설계 및 구현 과목을 듣는데 중간고사 대체 과제가 DB를 실제로 설계하는 것이다.

    문제는, 오라클 또는 MS-SQL을 써서 뭘 해야 한다는 건데, 중간에 ER-Win이라는 프로그램을 이용한 것을 캡쳐해서 제출해야 한다.

    ER-win은 또 무엇인가…하면 Entity-Relation 그림을 쉽게 그릴 수 있게 해주는 툴이라고 한다.

    오라클이든 MS-SQL이든 ER-win이든 다 좋은데, 왜 비싼 프로그램만 쓰게 하는지 모르겠다. 물론 세계적으로 가장 많이 사용되는 프로그램이고 이런걸 배워야 나중에 실무에서 금방 적용할 수 있겠지만, 학교면 학교답게 돈 없는 개발자들을 위한 오픈소스 솔루션도 지원하면 안될까?

    SQL은 MySQL이나 postgreSQL이라는 걸출한 SQL프로그램이 있다.


    http://www.mysql.com/



    http://www.postgresql.org/


    물론 여기에 빼먹을 수 없는 오픈소스 프로그램인 우리나라에서 만든 큐브리드도 있다.




    http://www.cubrid.com/zbxe/home

    ER그림 그리는 프로그램도 알아봤더니


    http://www.fabforce.net/dbdesigner4/



    http://gnuwin.epfl.ch/apps/DDT/en/


    이런 그럭저럭 쓸만한 프로그램이 있다. 물론 둘 다 윈도우/리눅스 등에서 쓸 수 있다.

    만약, NHN과 방통대 컴퓨터과학과가 제휴하여 학과 차원에서 큐브리드를 밀어준다면 어떨까? 국익에도 도움이 되고 NHN에도 도움이 되고, 오픈소스니까 가난한 개발자들에게도 도움이 되지 않을까.

    혹시 NHN쪽에서 관련되어 일하시는 분 있으면 이 소식을 좀 전달해 주었으면 좋겠다. 그리 어려운 일은 아닐 것이다. 교재 개발을 새로 해야 할 뿐…

    추가 : 오라클 설치했더니 백그라운드 서비스 때문에 느려졌다. 젠장. 숙제 끝나면 바로 지워야겠다.

  • 예외상황때문에 나오는 오류 처리하기

    VB에서는 예외상황을 다음과 같이 처리하면 된다.

    try

    해봐야할것들()

    catch 붙잡아올예외상황 as type [when 이럴때만]

    예외처리를위해할것들()

    fianally

    어쨌든할것들()

    end try

    try 밑에 있는 것들은 일단 실행된다. 예외가 안나오면 그냥 가고, 예외가 나온다면 그 예외를 catch에 던져준다.

    catch는 여러개가 있을 수 있는데, 그중 자기가 처리할 예외를 받은 catch 안에 있는 것들이 실행된다. when은 조건인데, 어떤 경우에는 그 예외를 처리해주고 어떤 경우에는 처리하지 않을지 결정한다. 물론 when의 조건이 참일 때 처리하고 거짓일때 처리하지 않는다.

    fianally는 try하고나서 예외가 발생하든 말든 무조건 실행되는 부분이다.

    사용설명서에 보면 catch가 하나도 없으면 fianally는 반드시 있어야 한댄다. 물론 catch가 하나라도 있으면 fianally는 필요없다.

    나는 이 구문을 유용하게 쓰고 있는데, 예외가 발생하면 무조건 try-catch에 넣어버리고, 예외가 발생하면 그 부분을 그냥 건너뛰어 버린다. 그래도 괜찮은 프로그램을 만들고 있기 때문이다.

  • VB의 조건문

    비주얼 베이직(이하 VB)은 꽤 잘 만든 것 같은 언어지만 의외로 대단히 허접한 구석이 있다. 조건절을 평가할 때, 가령 다음과 같은 경우가 있다.

    if P and Q then

    something()

    end if

    위와 같은 경우 P가 참이고 Q가 참이면, 즉 둘 다 참이어야만 그 안의 구문이 실행되고 그 외에는 실행되지 않는다. 따라서 P가 거짓인 경우 Q를 평가할 필요 없이 그냥 실행을 안해도 된다. 하지만 VB에서는 굳이 Q까지 평가한다. 이래서 난감한 경우가 있는데…

    P에는 “A라는 변수가 메모리에 자리를 잡고 있는가? (malloc같은걸로 잘 잡혀 있느냐는 질문)”가 들어가 있고, Q에는 “A가 10보다 큰 수인가?”라는 질문이 들어가 있다고 하자. 그럼 P가 안되면 Q는 평가할 필요가 없으므로 그냥 잘 넘어가면 되지만 VB에서는 실행하다가 오류가 난다(Q에서 평가해야 할 A가 메모리에 어디에 있는지 알 수가 없으므로). 따라서 이런 경우에는 if구문을 2중으로 써야 한다.

    if P then

    if Q then

    something()

    end if

    end if

    이게 VB에서만 그런건지 VC++에서도 그런건지 모르겠다. 난 VC++는 배워본적이 없다. (윈도우즈 프로그래밍이라는 과목에서 구경은 했지만…)

    어쨌든 내가 아는 C에서는 위와 같은 경우 2중으로 쓰지 않아도 되지만 VB에서는 2중으로 써야 한다.

    이것때문에 하루동안 삽질한 날이 많아서 기록해 둔다.

    *추가 : and 대신에 andAlso를 쓰면 중지연산이 된다. 즉, 앞에 있는게 false면 뒤쪽을 판정하지 않고 곧바로 전체를 false로 해 준다. 하지만 이미 늦은… 중지 연산 써야 할 부분은 대부분 잘 구현되었다.

  • 인체의 신비와 자료구조

    여러가지 자료구조가 있다.

    큐, 스택, 그래프, 트리, 배열, 연결 리스트 등이 유명한 자료구조이다.

    큐와 스택은 자료를 쌓아놓는 방법을 말하는데, 먼저 들어간 놈이 먼저 나오면 큐, 나중에 들어간 놈이 먼저 나오면 스택이다.

    우리 몸에서 음식을 처리하는 과정은 큐를 통해서 이루어 지는데, 그것은 먹은 순서대로 싼다는 사실을 보면 알 수 있다. 반면, 가끔은 스택처럼 처리하기도 한다. 너무 많이 먹으면 나중에 들어간 놈이 먼저 입으로 나와 버리는 사고가 터진다.

    인체의 구조는 그래프이다. 혈관을 보면 점과 점을 잇는 선으로 구성된 것을 알 수 있다. 그래프는 점과 선으로 이루어진 것을 말한다. 그중에서, 고리가 하나도 없는 것을 트리라고 한다. 고리는 어떤 점에서 출발하여 한번 갔던 길을 되돌아오지 않고도 원래의 점으로 되돌아올 수 있는 경로를 말한다. 트리 중에서 가장 중요한 1개의 점을 정할 수 있다면 뿌리가 있는 트리가 된다.

    배열은 정보를 늘어놓고서 인덱스를 통해서 접근할 수 있는 것을 말한다. 가령, “몇번째 정보”라고 말하면 어떤 정보인지 알 수 있는 것을 배열이라고 한다. 우리 몸에서는, 가령 치아의 위치가 배열처럼 되어 있다. (실제로 배열이다.) 연결 리스트는 배열이랑 비슷하긴 한데, “다음번의 다음번의 다음번 정보”라는 식으로 상대적인 위치만을 알 수 있는 자료이다. 이것은 신경망과 비슷한 자료구조이다. 신경세포들은 자신이 몇번째 신경세포인지는 알지 못하고, 단지 받은 신호를 적당히 처리해서 다음번 신경세포로 넘겨줄 뿐이다.

  • 자동 눈금자 알고리즘

    그래프 그리는 프로그램을 보면 눈금자가 적당히 그려진다.

    가령, 그래프가 출력되는 범위가 13부터 30까지라면, 눈금자가 15, 20, 25, 30의 위치에 그려져 있는 뭐 그런거. 격자(grid)를 그린다고도 한다.

    이런건 어떻게 구현 할 수 있을까?

    Gnuplot같은 오픈소스 프로그램을 보면 알 수 있겠지만, 난 다른 사람이 만든 프로그램을 뜯어볼 정도로 고수도 아니고 의지도 없으므로 직접 만들어 보기로 했다.

    아래의 소스는 구간의 길이를 적당히 판단해서, 1단위, 2단위, 5단위로 눈금의 위치를 출력하는 알고리즘이다.

    비주얼 베이직으로 소스를 만들어 보았다. 물론 이 소스는 아마 제대로 작동하지 않을 것이며 (보안상 그렇다. 난 당연히 작동하는 소스를 이용하고 있다.) 공부한 후 직접 작동하도록 고쳐서 쓰는 것은 숙제이다.

    Function determineTics(min, max) As Double()

    d = max – min 일단 양쪽 끝 값의 차이를 알아서, 얼마나 긴 구간을 그려야 하는지 조사한다.

    tics(0) = 0 첫 값은 그냥 0이라고 해 두자. 아무 의미 없다.

    If d < 0 Then
    Return tics 만약 구간 길이가 음수라면, 최대값이 최소값보다 작은 경우이므로 아무 의미 없는 값을 돌려준다.

    End If

    digit = CInt(System.Math.Floor(System.Math.Log10(d))) 자리수가 몇자리인지 세야 한다. 자리수는 상용로그에서 지표값이 된다. 따라서 상용로그를 계산한 후 올린다. 가령, 10은 상용로그값이 1인데 2자리수이며, 0.1은 상용로그값이 -1인데 이런건 0자리수라고 치자.

    이제, 가수를 계산하자.

    added = System.Math.Log10(d) – CDbl(digit) 이건 가수를 뜻한다. 가수는 상용로그 값의 소수부분을 말한다. 잘 모르겠으면 고등학교 수학 교과서에서 로그함수 부분을 찾아보도록 하자. 어떤 수의 소수부분은 당연히 그 수에서 정수부분을 빼면 된다.

    If added >= 0 And added < System.Math.Log10(2) Then 만약 가수가 0보다 크고 2의 상용로그값보다 크면 눈금의 크기는 2눈금이 된다.
    s = System.Math.Log10(2)

    ElseIf added > System.Math.Log10(2) And added < System.Math.Log10(5) Then 마찬가지로 2의 상용로그값보다 크고 5의 상용로그값보다 작으면 5눈금이 된다.
    s = System.Math.Log10(5)

    Else

    s = 1 나머지는 1눈금으로 가자.

    End If

    diff = System.Math.Pow(10, s + CDbl(digit – 1)) 이것은 눈금자 사이의 간격을 말한다.

    beginning = System.Math.Floor(min / System.Math.Pow(10, digit)) * System.Math.Pow(10, digit) 이것은 최초 시작하는 값이다. 전체 구간의 시작부분보다는 큰 값이면서 눈금에 해당하는 곳을 찾아낸다.

    If beginning < min Then
    beginning += diff 만약을 위해, 혹시 눈금의 시작값이 구간의 시작부분보다 작다면 한칸 더해준다. 아마 한칸만 더하면 될 것이다. 두칸이나 틀릴수는 없다고 생각한다.

    End If

    tics(0) = beginning 이제 되돌려줄 배열의 최초값을 설정한다.

    Dim i As Integer = 1 원래는 for문을 쓰고 싶었지만 구간이 도대체 얼마나 될지 알수가 없으니까 무한반복문을 쓰고 중간에 빠져나오도록 했다.

    Do

    ReDim Preserve tics(i) 한칸 늘려주고

    tics(i) = tics(i – 1) + diff 그 다음칸의 값은 앞에 있던 칸에다가 눈금의 간격만큼을 더한 값이다

    If tics(i) + diff >= max Then 만약 그 다음값이 구간의 끝값을 넘어갈 것 같으면

    Exit Do 끝낸다

    End If

    i += 1 아니면 한단계 더 올리고 다시 반복하자.

    Loop

    Return tics 이제 배열을 되돌려 주면 된다.

    End Function

    문제 : 그럼, 로그 눈금으로 그리고 싶으면 어떻게 하면 될까?

    답 :

    newtic = determineTics(System.Math.Floor(System.Math.Log10(min)), System.Math.Ceiling(System.Math.Log10(max)))

  • Visual Basic에서 파일 읽고 쓰기 삽질

    삽질 기록.

    내가 갖고 있는 것

    labels() : 몇가지 이름이 들어있는 배열

    config.txt : labels()가 저장되는 파일

    원하는 것

    config.txt에 labels()의 내용을 쓰고 싶은데, 이미 있는 내용이라면 그냥 놔두고 없으면 끝에다 추가한다

    현재 구현된 상태

    readline(config.txt)으로 불러오고

    적당한 비교 구문으로 찾아본 후

    없는 애들만 골라서

    writeline(config.txt)으로 저장

    그런데 오류 발생. IOexception 에러. 분명히 readline 후에 dispose하고 close했는데도 다른 프로세스가 그 파일을 붙들고 있다면서…

    소스 코드

    ‘이 코드는 snowall이 직접 작성한 코드이다.

    ‘이 코드는 Public Domain License를 적용받는다.

    Private Sub saveConfig()

    Dim j As Integer

    Dim i As Integer

    Dim tmp As System.IO.FileStream

    If Not (System.IO.File.Exists(“C:\TOFconfig.txt”)) Then

    tmp = System.IO.File.Create(“C:\TOFconfig.txt”)

    tmp.Close()

    tmp.Dispose()

    End If

    MsgBox(System.IO.File.ReadAllLines(“C:\TOFconfig.txt”).Length)

    Dim labels(0) As String

    If System.IO.File.ReadAllLines(“C:\TOFconfig.txt”).Length Then

    ReDim Preserve labels(System.IO.File.ReadAllLines(“C:\TOFconfig.txt”).Length)

    For i = 0 To labels.Length – 1

    labels(i) = System.IO.File.ReadAllLines(“C:\TOFconfig.txt”)(i)

    Next

    End If

    Dim flag As Boolean = False

    MsgBox(labels(labels.Length – 1))

    For j = 0 To frmMainWindow.numberOfData – 1

    For i = 0 To labels.Length – 1

    If Not (labels(i) Is Nothing) Then

    If labels(i).StartsWith(frmMainWindow.clsSignalData(j).label) Then

    labels(i) = frmMainWindow.clsSignalData(j).label & frmMainWindow.clsSignalData(j).intChannel

    flag = True

    End If

    End If

    Next

    If Not (flag) Then

    ReDim Preserve labels(labels.Length)

    labels(labels.Length – 1) = frmMainWindow.clsSignalData(j).label & frmMainWindow.clsSignalData(j).intChannel

    End If

    flag = False

    Next


    Dim objfilew As New System.IO.StreamWriter(“C:\TOFconfig.txt”)


    For i = 0 To labels.Length – 1

    objfilew.WriteLine(labels(i))

    Next

    objfilew.Close()

    objfilew.Dispose()

    End Sub

    위에서 파랗게 칠해둔 부분이 오류임.


    해결된줄 알았는데 아직 해결이 안됐다. 어디의 무엇이 문제일까. -_-;

    해결 방법


    C:\를 E:\로 바꾸었음


    Writeline을 WriteAllLine 으로 바꾸었음

    원인


    윈도 Vista에서 C:\는 보안상 접근을 허락하지 않는고로, 이래저래 괴로운 일이 발생함.


    모름. 도대체…

    결론


    윈도 Vista가 쓰레기.


    어쨌든 윈도 Vista는 쓰레기.

    잠재적 문제점


    E:\가 없는 컴퓨터에서 작동시킬 때 100% 확률로 오류 발생.




    이 프로그램을 작동시킬 컴퓨터는 윈도 XP가 설치되어 있으므로 C:\로 하더라도 문제가 없을 것임.




    개발은 E:\로 해놓고 배포는 C:\로 해야 하는 딜레마 상황.



    잠재적이라서 모름.

    디버깅하는데 걸린 시간

    2 업무일 + 야근 8시간

    잠재적 결론

    빌어먹을.






  • 비주얼 베이직의 단점

    비주얼 베이직으로 프로그램 개발하는데…

    매우 난감한 상황이 발생한다.

    비주엘 베이직에서는, 대부분의 프로그래밍 언어가 그렇듯, 값을 전달할 때 참조에 의해 전달하는 것과 값 자체로 전달하는 두가지 방법을 사용할 수 있다.

    문제는, 그럼에도 불구하고 “포인터”라는 개념이 없다는 것이다.

    그 결과, = 연산자를 사용할 때, 이게 도대체 값으로 넘어가는건지 주소로 넘어가는건지 알 수 없게 되어 버리는 경우가 많다.

    그리고 당연히 메모리 참조 오류가 발생하게 된다.

    답답하다. -_-

    그 다음으로 답답한건 배열의 선언과 사용이다.

    배열은 다음과 같이 선언한다.

    dim arr(10) as integer

    자, 질문이다. 위와 같이 선언하면 사용할 수 있는 배열의 크기는 모두 몇칸일까?

    정답은 “11”칸이다. 인덱스가 0부터 10까지 갈 수 있다. 내가 C에 익숙해서 그런건지는 모르겠지만, 저 사소한 차이가 개발에 아주 큰 어려움을 주고 있다. 대체 0부터 어디까지 세야 하는건지 쓸 때마다 헷갈린다.

    딱 10개만 쓰고 싶으면 그냥 1부터 시작해서 쓰라고 “책”에는 나와 있지만, 숫자는 0부터 시작하는 것이 정석이다. -_-

    생각해보니, 내가 만든 배열이야 0부터 쓰든 1부터 쓰든 문제가 없지만, 남이 쓴거 가져다 쓸 때는 골치아파지는 문제가 생길 수도 있다. 그 사람이 1부터 시작했는데 내가 0부터 시작하기로 한다거나, 그 사람이 9까지 쓰기로 했는데 내가 10까지 쓰기로 한다거나 하면 엉뚱한 값이 들어와 버릴 수도 있다. 즉, 애초에 0부터 10까지 11칸을 쓰기로 하는 것이 가장 정확하다는 뜻이다.

    MS에서…C랑 다른 무언가를 만들려고 하다가 좀 삽질한 듯 싶다.

    셋째로…

    조건절 평가할 때 전부 다 계산해보고 한다. 이건 단점인지 장점인지 모르겠지만 불편하다. 예를들어

    if Not (objData is nothing) and objData.someFlag then

    someFunction(objData)

    end if

    이렇게 쓰면 objData가 nothing(이라고 쓰고 Null이라고 읽는다) 인 경우에는 오류가 발생한다. 왜냐하면 objData.someFlag는 아직 정의되지도 않은 객체의 속성이기 때문에 객체 참조 오류가 나오는 것이다. 하지만 이미 objData가 nothing이라는 조건이 만족되었기 때문에 그냥 넘어가면 안되는 걸까? 끝까지 평가를 다 해봐야 아나…그것도 and로 이어진 조건들인데. 똑똑하지 못한 것 같다.

    *추가 : and 대신에 andAlso 연산자를 쓰면 앞에서 조건이 만족되면 뒤쪽은 계산하지 않는다.