[카테고리:] Programming

  • Linux Ubuntu22.04 Go 언어 설치하다

    Linux Ubuntu22.04 Go 언어 설치하다

    Go 언어와 Rust 언어가 그렇게 핫하다길래…

    파이썬과 함께 go나 rust도 한 번 배워보라고 하셔서 둘 중 고민하다가 그나마 가장 쉽다는 Go부터 파고들려고 한다.

    저 귀여운 동물은 무엇인가

    우선 Go 웹사이트에 가서 다운로드 받기 링크는 하단에

    https://go.dev/learn/

    여기에서 download하면 리눅스용 tar 파일을 받을 수 있었다.

    윈도우용이랑 맥용, 리눅스용, source 파일도 있었다. 맥용이 친절하게 인텔 맥용이랑 m1맥용을 따로 만든 게 인상 깊었다.

    여기에서 리눅스용을 받고 저기 맨 에 installation instructions.부분을 클릭했다.

    installation 방법이 적혀 있었다. 이대로 치면 에러나더라. 호…

    1. 해당 tar파일을 받은 폴더로 이동해서

    cd Downloads/

    보통 다운로드 파일이니 다운로드 폴더로 이동하고

    2 저기 rm -rf는 관리자 권한으로 실행해야 한다.

    sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.19.2.linux-amd64.tar.gz

    비밀번호 입력하는 란이 있으니 비밀번호 입력

    3 .profile 을 열어서 경로 설정해주기

    nano 열어서 했었는데, 그냥 vim으로 해도 된다.

    홈디렉토리로 이동한 후,

    4 vim .profile해서

    하단에 저 코드를 입력하고

    5 source .profile

    6 그 다음에 go version으로 확인하니 설치되었단 걸 확인했다.

    그리고 돌아가는 걸 확인하기 위해서

    여기 샘플 코드가 있어서 원하는 폴더로 이동 후

    touch hello.go

    만들고

    vim hello.go

    로 들어가서

    그대로 입력해주고 저장했다.

    그 다음으로 터미널에서

    go run hello.go를 쳐주면 되었다.

    그냥 python3 생각해서 python hello.py 처럼 go hello.go 로 쳤다가 에러가 났다.

    go run hello.go 

    였고,

    실행 파일로 빌드하는 건

    go mod init example/hello
    go build
    만들어진 (초록색) 실행 파일

    로 치면 실행파일이 바로 만들어져서

    ./hello

    등으로 치면 실행 되었다.

    설치 끝.

  • ValueError) Input 0 of layer “inception_resnet_v2” is incompatible with the layer: expected shape=(None, 299, 299, 3), found shape=(32, 256, 3)

    ValueError) Input 0 of layer “inception_resnet_v2” is incompatible with the layer: expected shape=(None, 299, 299, 3), found shape=(32, 256, 3)

    2022.10월 말 기준

    여전히 레이어 개념이 헷갈린다. (256, 256, 3) 이렇게 있는데 한 개의 층을 왜 도대체 더해주어야 하는 걸까 (1, 256, 256, 3) 이런 식으로

    하나를 더해주는데 졸면서 코드 따라서 치기는 했는데, 여전히 풀리지 않는 의문이다.

    ValueError: Input 0 of layer “inception_resnet_v2” is incompatible with the layer: expected shape=(None, 299, 299, 3), found shape=(None, 256, 256, 3)

    이런 에러나,

    ValueError: Input 0 of layer “inception_resnet_v2” is incompatible with the layer: expected shape=(None, 299, 299, 3), found shape=(32, 256, 3)

    이런 에러.

    한 개의 이미지는 3개의 층, R, G, B 층으로 되어 있고 픽셀 값을 각각 행렬로 해두었다. 까진 어떻게 이해하는데 이미지넷으로 소트할 때 왜 층을 하나 더 더해줘야 하는지.

    에러는 해결하지만 원리는 솔직히 헤매고 있다. 내 자신이 이해가 안 됨. 책을 읽으면 그렇쿠나 하지만 막상 실전에선 다시 헤매는 걸 보니 뭔가 이해가 안되는 것 같다.

    # 이런식으로 target_size를 정해주고,
    load_img(FILE_1, target_size=(299, 299))

    .shape를 통해서 확인,

    하면 299, 299, 3 으로 되어 있음 케라스 공식 문서 에서 요구하는 사이즈가 299, 299 였고,

    import numpy as np 로 했으니 np. 으로 넣고 dims를 하나 더 추가…

    np.expand_dims(pic_array, axis=0)

    (1, 299, 299, 3)

    으로 나와서

    inception_model.predict(expanded)

    로 넣었을 때 저런 에러가 나타나지 않는다.

    저 행렬 값의 형태가 중요한데,

    엄 글을 쓰면서도 정리가 잘 되지 않아서…

    다시 공부해야겠단 생각이 들었다. (그래도 쓰다 보니 뭔가 알듯 말듯 하기도 하고)

  • Import Error) cannot import name ‘img_to_array’ from ‘keras.preprocessing.image’

    Import Error) cannot import name ‘img_to_array’ from ‘keras.preprocessing.image’

    현재 기준 2022.10월 말.

    2년 전에 작동되었던 tensor와 keras는 지금과 많이 다르다. 정말 빠르게 변하고 있다고 느낀다. 뭐가 조금만 해도 이미 옛날 버전이 되어 있다.

    텐서플로우와 케라스를 import 하는데 이전에 preprocessing에서 있던 게 지금은 utils에 있다.

    이미지를 행렬로 변환하고 로드하는 코드 에러나는 걸 수정했던 부분.

    ImportError: cannot import name ‘img_to_array’ from ‘keras.preprocessing.image’ (/usr/local/lib/python3.7/dist-packages/keras/preprocessing/image.py

    이 건 하단의 코드로 변경.

    # from keras.preprocessing.image import img_to_array, load_img
    from tensorflow.keras.utils import img_to_array, load_img

    다음으로 # tf.keras.applications.InceptionResNetV2

    공식 문서에서 tf.keras 어쩌구 되어 있는데 이 부분은 import tensorflow as tf로 불러오고 하는데 이상하게 코랩에서 에러가 나서 그냥

    tensorflow.keras.applications. ~ 로 수정했다.

    # from tensorflow.keras.applications.InceptionResNetV2 import InceptionResNetV2
    from tensorflow.keras.applications.inception_resnet_v2 import InceptionResNetV2, decode_predictions, preprocess_input

    코드 관련해서 공식 문서는 케라스 홈페이지에

    https://keras.io/api/applications/vgg/#vgg19-function

    에 들어가면 코드가 뜬다.

  • Python) Reeborg’s World Maze – 알고리즘

    Python) Reeborg’s World Maze – 알고리즘

    일요일에는 Maze 부분 못 풀었는데 정답 보기는 싫고 어떻게든 알아서 풀어보고자 했고,

    퇴근하고 와서 다시 Maze 부분 붙들고 풀다가 풀었습니다.

    뭐 만들 때 안 풀리면 하루 잠을 자고 다음 날 풀거나 산책하고 와서 풀거나, 커피 마시고 돌아와서 풀고, 수학 문제처럼 머리 속에 두고두고 있다가 어떻게 하다보면 풀리는 것 같습니다.

    Reeborg’s World – Maze 편

    python 함수 move() 를 넣으면 움직이고, turn_left()하면 왼쪽으로 돕니다.

    front_is_clear(), wall_in_front(), right_is_clear(), wall_on_right(), at_goal() 이 부분은 True / False 로 반환 받을 수 있습니다받는 부분입니다.

    while로 루프 써서,

    저 미로를 로봇이 도착지점까지 올 수 있도록 코드를 짜는 것이 요 미로 편이였습니다.

    미로 풀기는 하단 링크에서 할 수 있습니다.

    https://reeborg.ca/reeborg.html?lang=en&mode=python&menu=worlds%2Fmenus%2Freeborg_intro_en.json&name=Maze&url=worlds%2Ftutorial_en%2Fmaze1.json

    주어지는 미로 속에서 로봇이 잘 헤쳐나갈 수 있도록 많은 경우의 수를 고려해서 코드를 짜는 걸 알고리즘이라고 합니다.

    로봇이 보는 곳은 동서남북 중 랜덤으로 방향이 정해집니다.

    풀었던 코드:

    이렇게 저렇게 풀어보다가 풀었던 코드는 이 방법이었습니다.

    def turn_north():
        while is_facing_north() != True:
            turn_left()
    
    def turn_west():
        turn_north()
        turn_left()
        turn_left()
        turn_left()
            
    turn_west()            
    while at_goal() != True:
        if front_is_clear() and wall_on_right():
            move()
        if wall_in_front() and right_is_clear():
            turn_left()
            turn_left()
            turn_left()
            move()
        if wall_in_front() and wall_on_right():
            turn_left()
        if front_is_clear() and right_is_clear():
            turn_left()
            turn_left()
            turn_left()
            move()
        elif front_is_clear():
            move()

    이 중에서 약간 핵심이라고 생각하는 조건이 front_is_clear() and right_is_clear()일 때 어느 방향으로 움직일 지 설정해 주는 거였습니다. 미로를 푸는 방법은 벽을 따라 오른쪽으로 쭉 돌다보면 나가는 곳이 보일테니 오른쪽으로 가도록 설정을 하고, 하지만 벽이 막혀 있다면 왼쪽으로 틀어주는 방법. 으로.

    이렇게 저렇게 실험하 듯 짜다보니 코드가 정리되지 않았는데,

    저 turn_left() 3번 쓰는 걸 함수로 묶는

    def turn_right():
       turn_left()
       turn_left()
       turn_left()

    대략 어떻게 움직일지 동작하는 걸 구현했지만 좀 더 깔끔한 코드 리팩토링이 필요할 것 같네요.

    깊이 우선 탐색, 넓이 우선 탐색 이런 걸 뭔가 몸으로 체득하듯이 코드를 짜는 것 같아서 저 사이트 정말 유용하다고 생각합니다.

    문제는 답지 없이 꼭 풀고. 어떻게든 혼자 힘으로 풀어내는 걸 추천합니다 🤖🤖🤖🤖🤖

    굳었던 머리가 말랑해지는?? 좋아지는 느낌도 듭니다.

    치매 예방! 두뇌 회전!

    (무슨 광고 같아ㅋㅋㅋㅋ)

  • python) Reeborg’s World Hurdle4 풀기

    python) Reeborg’s World Hurdle4 풀기

    은근히 안되서 될 때까지 붙잡고 풀었습니다.

    python 코드를 연습하기 좋은. 스크래치 게임과 비슷한 Reeborg’s World 입니다.

    Reeborg's World
    Reeborg’s World

    1, 2, 3 단계는 쉽게 풀릴테고, 4단계부터는 코드 하나에 하나하나 어떻게 돌아가는지 확인이 필요합니다.

    코드를 짜는 건 귀찮으니 빠르게 해결하려고 했던 건데… 가는지 안가는지 확인해야 한다니ㅋㅋㅋ

    사람이라면 장애물이 대략 몇 미터인지 파악해서 4미터면 4번 갔다 도는 것, 1미티 정도면 1번 돌고… 이런 식으로 빠를 텐데.

    귀여운 Reeborg는 눈 앞에 장애물이 없으면 이동해, 우측에는 벽이 있어? 앞에는 장애물이 있어? 만약 우측에 벽이 없다면…

    이라고 하나부터 열까지 하나하나 설정해야 합니다.

    일단 4단계 풀었던 코드는 요렇습니다. 그런데 해결된 코드 복붙해봐야 재미없으니 직접 하는 걸 강추…

    원래 가지고 있던 def와 따로 만들어서 움직이도록 짰습니다.

    하다가 에러나면 오기도 생기고, 될 때까지 한다. 이런 느낌으로 해보면 엄청 재밌습니다.

    사이트 주소:

    https://reeborg.ca/reeborg.html?lang=en&mode=python&menu=worlds%2Fmenus%2Freeborg_intro_en.json&name=Hurdle%201&url=worlds%2Ftutorial_en%2Fhurdle1.json

    def turn_right():
        turn_left()
        turn_left()
        turn_left()
    
    def jump():
        turn_left()
        move()
        turn_right()
        move()
        turn_right()
        move()
        turn_left()
        
    while at_goal() != True:
        if right_is_clear():
            turn_right()
            move()
            turn_right()
            move()
        elif front_is_clear():
            move()
        elif wall_in_front():
            turn_left()
        elif wall_on_right():
            move()
            turn_right()

    그리고 다음 스테이지로 이동!

    또다른 솔루션은

    def turn_right():
        turn_left()
        turn_left()
        turn_left()
    
    def jump():
        turn_left()
        while wall_on_right():
            move()
        turn_right()
        move()
        turn_right()
        while front_is_clear():
            move()
        turn_left()
            
        
    while at_goal() != True:
        if wall_in_front():
            jump()
        else:
            move()

    좀 더 깔끔한 코드

  • C언어 – 포인터 개념2

    C언어 – 포인터 개념2

    #include <stdio.h>
    int main() {
       int a[] = {0, 2, 4, 8};
       int b[3];
       int* p;
       int sum = 0;
       int i;
       for (i=1; i<4; i++) {
           p = a + i;
           b[i-1] = *p - a[i-1];
           sum = sum + a[i] + b[i-1]; }
       printf("%d", sum);
       return 0;
    }
    

    다음의 코드에서 포인터의 개념은 int* p 라고 포인터를 선언한 것과, for 문에서 p값이 a +i 를 합한 것과 같다는 부분에서 볼 수 있다.

    a는 4개가 할당되어 있고, b는 3개가 할당 되어있다. 0으로 시작하기 때문에

    a는 다음과 같고,

    0123
    a0248

    p는 0이 있는 위치부터 가리키고 있다고 할 수 있다. b는 아직 받은 값이 없으니 비어있고,

    012
    b

    p = a + i 부분은 i는 우선 1부터 2, 3 까지로 4보다 적은 숫자까지 돌아간다. 그렇다면 a는 주소 0부터 시작하기 때문에 0 + 1 로 p는 1의 값으로 우선 나온다.

    이 때 b[i-1] = *p – a[i-1]은 *p가 1이라는 주소에 있는 값을 반환받길 원한다.

    즉 a의 2. b[0] = 2 – a[0] = 2 – 0 = 2 이다.

    sum += a[i] + b[i-1]로도 표현할 수 있는데 sum = 0 + a[1] + b[0] = 0 + 2 + 2 = 4

    p = a + i 는 p가 a[i]에서 i값을 가지고 온다고 보면 되고 포인터 *p는 해당 a[i]값을 가지고 온다.

    p = 2,

    b[1] = *p – a[1] = 4 – 2 = 2

    sum = 4 + 4 + 2 = 10

    p=3, b[2] = 8 – 4 = 4, sum = 10 + 8 + 4 = 22

    저 코드를 돌린 값은 22이다.

    b도 for문이 다 돌고 난 뒤라서 채워진다.

    012
    b224
    실제 결과값

    코드를 돌기전에 일단 쭉 나열해서 풀어봤다.

    포인터의 개념은 주소와 값 중에 값을 빨리 반환 받기 위해서 사용하는 게 핵심인 것 같다.

    추가로 좀 더 배웠는데 이것도 포스팅할 예정이다.😎

  • C언어- 포인터 개념 설명 및 예시

    C언어- 포인터 개념 설명 및 예시

    C언어는 빛과 소금과 진리^^

    포인터 개념을 이해해보자!

    우선 다음과 같은 문제를 풀어보자! 정답은? 과연 두구두구두구두구…

    #include <stdio.h>
    int pointfunc (char *);
    int main() {
        char* p1 = "20210107";
        char* p2 = "20221008";
        int n = pointfunc(p1);
        int m = pointfunc(p2);
        printf("%d", n+m);
        }
    
    int pointfunc (char* p) {
    	int count = 0;
        while (*p != '
    #include <stdio.h>
    int pointfunc (char *);
    int main() {
    char* p1 = "20210107";
    char* p2 = "20221008";
    int n = pointfunc(p1);
    int m = pointfunc(p2);
    printf("%d", n+m);
    }
    int pointfunc (char* p) {
    int count = 0;
    while (*p != '\0') {
    count ++;
    p ++;
    }
    return count;
    }
    ') { count ++; p ++; } return count; }

    여기에서 괴상망측한 * 라는 표시가 있다. 이 표시에 대해서 교수님이 포인터 개념에 대해 한 주 수업 시간 내내 설명하시고 폭탄 과제를 잔뜩 내 주신 게 떠오른다. 그 이후로 난 저 * 만 보면 😣 … 인데 C언어 에서는 상당히 중요한 개념이다.

    예전에 삐뚤새뚤하게 포인터 개념에 대해서 정리해서 과제를 제출했다. 모범생 타입답게 제출 시각에 딱! 맞춰서 부랴부랴! 제출했다😎

    “c언어는 python과 다르게 데이터 타입을 반드시 적어주어야 한다. 변수 개념은 포인터 개념과 밀접하게 관련이 있는데, 변수의 값, 변수의 주소에 대해서 c언어가 매우 민감하기 때문이다. 포인터는 변수의 값을 찍는 게 아니라 주소를 알려준다. 역참조는 주소 안의 값이 무엇인지 대신 반환해주는 것이다. 이 포인터 개념은 C언어에서 중요하게 여기는 개념이다” – summerorange 과제 제출

    저 코드의 정답은 저 character 변수의 갯수를 더하면 된다. 갯수를 더하는 걸 코드로 표현한 거니까.

    표로 표현하면 이런 느낌?

    p01234567Null
    *p20210107\0
    count12345678
    Null사랑하지않아

    \0이 아닐 때까지, 즉 null 값이 아닐 때까지 카운트를 하는 거니 char* p1 = “20210107”; 은 총 count 8이 나온다. 그래서 int n = 8 로 할당되고,

    p01234567Null
    *p20221008\0
    count12345678
    계산은 꼼꼼하게

    \0이 아닐 때까지인 char* p2 =”20221008″;은 해당 pointfunc 함수 리턴값인 int m = 8이 나와서

    합한 값은 8 + 8 = 16이 나오게 된다.

    그리고 추가 문제가 더 있어서 추가 포스팅을 하겠다.

    개념 이해에는 문제를 많이 풀어보는 게 좋은 것 같다.

error: Content is protected !!