반응형

오랫만에 Python 관련 포스팅을 하나 할까 합니다. 최근에 Python보다 35,000배 빠른 언어가 나타났다는 기사를 봤습니다. 잉? 뭐지? 인터프리터 언어가 아닌건가? 속도로만 치면 빠른 언어는 많은데...무슨 소리지? 하는 궁금증이 들더군요. 오늘은 Python의 새로운 대안언어라는 타이틀을 들고 나온 "Mojo언어"에 대해 알아보도록 하겠습니다.

 

Mojo �

 

Mojo 🔥: Programming language for all of AI

Mojo combines the usability of Python with the performance of C, unlocking unparalleled programmability of AI hardware and extensibility of AI models.

www.modular.com

 

1. 탄생 배경

Mojo 언어는 Swift의 개발자로 잘 알려진 크리스 래트너(Chris Lattner)가 개발했습니다. Python의 장점은 다양한 라이브러리와 풍부한 문서화로 인해 데이터 분석 분야에 널리 쓰이고 있지만 치명적인 단점이 있습니다. 인터프린터 언어가 내재하고 있는 속도의 한계로 인해 대용량 데이터 처리나 실시간 처리를 하기에는 너무 느리다는 거였죠. LLVM과 Clang의 공동 개발자였던 크리스 래트너역시 본인이 세운 Machin Learning회사인 Modular Inc.에서 Python으로 수행하던 머신러닝 태스크를 돌리기 위해서는 C, C++을 빌리지 않을 수 없었는데요, 이런 불편함을 해소하고자 개발하게 된 것이 Mojo의 탄생 배경입니다.

 

2. 상세

Mojo는 Python의 한계를 극복하고자 만들어진 새로운 패러다임의 언어입니다. 기존의 python 문법을 그대로 유지하면서도 빠른 속도를 자랑합니다. 문법 뿐만 아니라 기존의 Python 라이브러리들을 사용할 수 있다고 하는데 아직 100% 호환이 되는지 밝혀지진 않았지만 이게 사실이라면 엄청난 장점이 아닐 수 없습니다. 또한 컴파일러 언어이기 때문에 단일 패키지로 배포도 가능합니다.

 

3. 빠른 속도

망델브로 집합 연산을 실시한 결과를 바탕으로 보면 Python 3.10.9버전과 비교하여 35,000배의 속도를 나타내고 있습니다. 이는 C++보다도 빠른 수준인데, 어떻게 이렇게 빠른 수행이 가능할까요?

  Mojo언어는 JIT 컴파일러 방식을 채택하여 기존의 Python과 비교하여 높은 실행 속도를 자랑하고 있습니다. 하지만 단순히 JIT컴파일러 방식만으로는 충분치 않음이 최근 문제로 제기되었습니다. 이를 해소하고자 도입된 방법이 멀티쓰레드 기술과 MLIR 활용입니다.

 

  기존의 Python은 싱글쓰레드로 동작하는데 반해 Mojo는 멀티스레드를 이용한 병렬처리가 가능합니다. 작성된 코드를 동시에 병렬 처리하게 되면 빠른 실행과 함께 효율적인 메모리 관리가 가능하여 대용량 데이터처리에 유리해집니다.

 

  MLIR(Multi-level Intermediate Representation)는 Mojo언어를 중간코드로 변환하고 최적화하는 기술입니다. 이를 통해 최적화된 최종 코드를 생성할 수 있으며 성능을 더욱 개선하는데 큰 기여를 합니다.

 

4. 시작방법

아직은 초기 개발단계인 관계로 일반 유저들에게 Open되기 전입니다. 대신 waitlist를 받아 일부 개발자들에게 허용하고 있습니다. 아래의 사이트에서 신청하면 되고 아래의 사이트에서 이름, 메일주소 등을 입력하여 신청할 수 있습니다.

Modular: Get started today

 

Modular: Get started today

Get started with Modular and tell us how we can help you scale your AI workloads with our next generation developer platform.

www.modular.com

반응형
반응형

[ 목차 ]

내 사이트가 Netlify에 배포된 이후에도 아직 검색이 안되고 있습니다. 주소가 아니면 아직 접근할 방법이 없네요. 구글에 노출시키는 작업이 필요합니다. 이걸 설정해주는게 구글 서치 콘솔(Google Search Console)입니다. 여기에 등록해주면 구글에서 검색도 되고, 그 외에 모니터링도 가능해집니다. 오늘은 서치 콘솔에 등록하고, sitemap.xml, robots.txt 파일을 적용하는 방법에 대해 알아보겠습니다.

    1.구글 서치콘솔 등록

    구글 서치콘솔에 로그인한 후 속성 추가를 해 줍니다. 

    [ 속성 유형 선택 ]

    다음으로 속성 유형에서 "URL 접두어" 부분으로 가서 추가하고자 하는 URL을 적어주고 "계속" 을 클릭해줍니다.

     

    [ 소유권 확인 ]

    다음으로 소유권 확인창이 뜹니다. 여기서 HTML 태그의 드랍다운 버튼을 누르면 내부에 방법이 나옵니다. meta 태그를 복사후 창을 닫아버리면 안되고, 내 프로젝트로 가서 입력을 해줘야합니다. 

     

    [ 태그 입력 ]

    HTML meta태그여서 vuepress에 그대로 옮겨줄 순 없고, 아래와 같이 config.js파일에 name과 content 속성에 분리해서 입력해줍니다.

    module.exports = {
      title:"Hello, Vuepress",
      head:[
        [
          "meta", 
          {
            name: "google-site-verification",
            content: "본인 코드"
          }
        ]
      ],
    }

     

    [ 소유권 확인 완료 ]

    수정 후 배포가 완료되면 소유권 확인 창에서 "확인" 버튼을 눌러줍니다. 

     

    2. sitemap적용

    sitemap.xml파일을 어딘가에 생성하는게 아니라 플러그인으로 설정합니다. 우선 아래의 명령으로 vuepress용 sitemap 생성 플러그인을 설치합니다.

    npm i -D vuepress-plugin-sitemap

     

    플러그인은 config.js에서 추가해주고, 추가 시 호스트 네임을 적어주면 됩니다.

    module.export = {
    	plugin: [["sitemap", { hostname: "https://unaffected.netlify.com/"}]]
    }

    배포 이후, 구글 서치콘설의 sitemap 제출란에 https://unaffected.netlify.com/sitemap.xml 로 등록하면 됩니다.

     

    3. robots.txt

    웹 크롤러같은 봇들의 접근을 제어하는 파일입니다. 보여줄 수 있는 페이지와 그렇지 않은 페이지를 설정합니다.

    위치는 .vuepress/public/robots.txt입니다.

    User-agent: *
    Allow: /
    Sitemap: https://unaffected.netlify.com/sitemap.xml

    배포 확인은 본인 https://unaffected.netlify.com/robots.txt 에 접속해서 robots.txt파일이 잘 뜨는지 확인해보면 됩니다.

     

     

     

    반응형
    반응형

    Node 18버전에서 vuepress 1.9.9 버전 설치에 오류가 있어서 포기했다가, 다시 Node 16버전으로 낮춰서 설치했습니다. 아직 Beta버전인 2.0.0 보다 오류가 적은 것 같습니다. 설치하니 기본적으로 검색 툴이 활성화되고, Vue 컴포넌트 추가도 components 폴더에 만드니 별다른 설정없이 인식이 됩니다. 그리고 무엇보다도 태그 요소 추가가 너무 쉽게 진행됩니다. Vuepress2로 하려고 시도하며 공부해서인지 금방금방 작성이 되네요. 다시 Vuepress 1으로 재작성해야겠습니다...ㅠㅠ

     

    1. 설치

    npm init
    
    npm i -D vuepress@next

     

    2. ./docs/README.md 파일 생성

    ### Hello Vuepress

     

    3. ./gitignore 파일 생성

    node_modules
    .cache
    .temp
    

     

    4. package.json파일 수정

    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "dev": "vuepress dev docs",  // 추가
        "build": "vuepress build docs"  // 추가
      },
    

     

    5. 실행

    npm run dev

     

    6. 구조

    .
    ├── docs
    │   ├── .vuepress (Optional)
    │   │   ├── components (Optional)
    │   │   ├── theme (Optional)
    │   │   │   └── Layout.vue
    │   │   ├── public (Optional)
    │   │   ├── styles (Optional)
    │   │   │   ├── index.styl
    │   │   │   └── palette.styl
    │   │   ├── templates (Optional, Danger Zone)
    │   │   │   ├── dev.html
    │   │   │   └── ssr.html
    │   │   ├── config.js (Optional)
    │   │   └── enhanceApp.js (Optional)
    │   │ 
    │   ├── README.md
    │   ├── guide
    │   │   └── README.md
    │   └── config.md
    │ 
    └── package.json
    

     

    7. docs/.vuepress/config.js

    화면구성 참조용으로 제가 작업했던 내용 공유해놓겠습니다.

    module.exports = {
      title:"Hello, Vuepress",
      themeConfig: {
        logo: '/assets/img/logo.png',
        nav: [
          { text: 'Home', link: '/' },
          { text: 'Guide', link: '/guide/' },
          { text: 'External', link: 'https://google.com' }
        ],
        sidebar: [
          {
            title: 'Today I Learned',  // required
            path: '/foo/',      // optional, link of the title, which should be an absolute path and must exist
            collapsable: false, // optional, defaults to true
            sidebarDepth: 1,    // optional, defaults to 1
            children: [
              {title: '1 설치(v2)',path:'/pages/1_설치.md'}, 
              {title: '2 레이아웃(v2)',path: '/pages/2_레이아웃.md'},
              {title: '3 검색창(v2)',path: '/pages/3_검색창.md'},
              {title: '4 Vue컴포넌트(v2)',path: '/pages/4_Vue컴포넌트.md'},
              {title: '5 태그(v2)',path: '/pages/5_태그.md'},
              {title: '6 vuepress v1설치',path: '/pages/6_v1설치.md'}
            ],
          },
          {
            title: 'Group 2',
            children: [ /* ... */ ],
            initialOpenGroupIndex: -1 // optional, defaults to 0, defines the index of initially opened subgroup
          }
        ]
      }
    }

     

    8. 태그 리스트 컴포넌트 만들기

    태그 리스트 컴포넌트를 생성 후 README.md에서 확인해보겠습니다.

     

    docs/.vuepress/components/TagList.vue

    <template>
      <div class="tag-list">
        <h3>Tags :</h3>
        {{ tags }}
      </div>
    </template>
    
    <script>
    export default {
      computed:{
        tags() {
          // 모든 태그를 가져옵니다.
          const tagSet = new Set()
          this.$site.pages.forEach(page => {
            if (page.frontmatter.tags) {
              page.frontmatter.tags.forEach(tag => {
                tagSet.add(tag)
              })
            }
          })
          return [...tagSet].sort()
        }
      }
    }
    </script>

     

    9. README.md

    대쉬 3개(---) 사이에 적어놓은 부분을 frontmatter라고 합니다. 이 부분은 해당 md파일의 주요 정보들을 적어놓는 용도로 사용하는데, docs폴더 내부에 테스트를 위해 몇가지 md파일들을 생성해놓고 아래와 유사하게 frontmatter를 작성해둡니다. tags에 1.js, 2.js 등 여러가지 키워드를 넣었습니다.

    ---
    title: 'Vuepress2 태그시스템'
    date: '2023-07-06'
    tags:
      - JavaScript
      - 2.js
    ---
    
    # KMS Data 검색 속도 건 관련
    
    이 문서에서 사용하는 태그 목록을 출력합니다.
    <!-- {{ $site }} -->
    
    <TagList />

     

    <결과>

    반응형
    반응형

    1. 플러그인 추가

    npm i -D @vuepress/plugin-register-components@next

     

    2. .vuepress/config.js파일에 플러그인 추가

    import { registerComponentsPlugin } from '@vuepress/plugin-register-components'
    import { getDirname, path } from '@vuepress/utils'
    
    // const __dirname = getDirname(import.meta.url)  // 인식 오류시 사용
    
    export default {
      title:"Hello, Vuepress",
      plugins: [
        registerComponentsPlugin({
          componentsDir: path.resolve(__dirname, './components'),   // 컴포넌트 폴더를 등록하는 방법
          // components:{
          //   TagList: path.resolve(__dirname, './components/TagList.vue'),   // 개별 컴포넌트를 등록하는 방법
          //   MyComponent: path.resolve(__dirname, './components/MyComponent.vue'),   // 개별 컴포넌트를 등록하는 방법
          // } 
        })
      ],
    }

    참고로 현재 등록하고자 하는 파일은 아래의 파일입니다.

    <!-- docs/.vuepress/components/MyComponent.vue -->
    <template>
      <div>
        <p>Component Test</p>
      </div>
    </template>
    
    <script>
    export default {
      name: 'MyComponent'
    }
    </script>

     

    3. .vuepress/clientAppEnhance.js 생성

    아래도 컴포넌트를 등록해줍니다. 원래대로라면 플러그인에 의한 방법, clientAppEnhance.js로 등록하는 방법으로 나뉠 수 있는데, 저는 등록이 안되어 같이 적용해주니 작동되었습니다.

    // .vuepress/clientAppEnhance.js
    
    import MyComponent from './components/MyComponent.vue';
    
    export default ({ app }) => {
      app.component(MyComponent.name, MyComponent);
    };

     

    4. README.md파일에 적용

    <MyComponent />

    반응형
    반응형

    [ 목차 ]

      블로그 같은걸 만들다보니 순수 Vue.js보다는 SSR 또는 정적 사이트 생성기 SSG가 필요하게 되었습니다. React에는 유명한 Gatsby가, 그 이전에 Ruby에는 Jekyll 이라는 정적 사이트가 있었는데, Vue에는 마땅한게 없나 살펴보던 중 Vuepress 라는 걸 알게되었습니다. 오늘은 Vuepress를 이용하여 간단한 블로그를 생성해보겠습니다.

       

      Vuepress2 

       

      Home | VuePress

       

      v2.vuepress.vuejs.org

       

       

       

      1. 설치

      설치는 npm으로 간단히 아래와 같이 진행하면 됩니다.

      npm init
      
      npm install -D vuepress@next

       

      2. 구성

      처음 라이브러리를 설치하면 위 이미지처럼 아무것도 나타나지 않습니다. 여기에 몇가지 수동으로 폴더 및 파일을 생성해줘야합니다.

      1) 우선 docs라는 폴더를 만들고 내부에 README.md파일을 만들어줍니다. 그리고 내용은 적당히 아래와 같이 넣어줍니다.

      # Hello Vuepress

      2) package.json에 실행하기 위한 아래의 스크립트를 넣어줍니다.

      "scripts": {
          "test": "echo \"Error: no test specified\" && exit 1",
          "dev": "vuepress dev docs",  // 추가
          "build": "vuepress build docs"  // 추가
        },

      3) "npm run dev"를 실행해줍니다. 그러면 docs 아래에 .vuepress폴더 및 하위 구성이 생성됩니다.

      4) .gitignore파일을 생성해줍니다. (optional, 나중에 github에 올릴때 불필요한 부분을 제거하기 위해...)

      node_modules
      .temp
      .cache

       

      3. 실행/확인

      실행하여 화면을 확인해봅니다.

      npm run dev

      드디어 나왔습니다. 보이는 것처럼 우리가 작성한 각각의 markdown파일이 하나의 화면으로 구성되어 나타납니다.

       

      4. 내비게이션 바 (nav bar ) / 사이드바 (sidebar) 추가

      테마 / 레이아웃 등은 config.js파일에서 수정할 수 있습니다. .vuepress폴더 아래 config.js파일을 생성하고 아래의 코드를 넣어줍니다. 기본적인 navbar와 sidebar 구성만 추가해보겠습니다. 

      import { defaultTheme } from '@vuepress/theme-default'
      
      export default {
        title:"Hello, Vuepress",
        theme: defaultTheme({
          sidebar:[
            {
              text: 'Group',
              children: [
                {
                  text: 'SubGroup',
                  children: ['/group/foo.md', '/group/bar.md'],
                },
              ],
            }
          ],
          navbar: [
            // nested group - max depth is 2
            {
              text: 'Group',
              children: [
                {
                  // text: 'SubGroup',
                  children: ['/group/foo.md', '/group/bar.md'],
                },
              ],
            },
            // control when should the item be active
            {
              text: 'Group 2',
              children: [
                {
                  text: 'Always active',
                  link: '/',
                  // this item will always be active
                  activeMatch: '/',
                },
                {
                  text: 'Active on /foo/',
                  link: '/not-foo/',
                  // this item will be active when current route path starts with /foo/
                  // regular expression is supported
                  activeMatch: '^/foo/',
                },
              ],
            },
          ],
        }),
      }

      반응형
      반응형

      오늘은 자바스크립트에서 자르고 나누는 함수지만 헷갈리는 세가지 함수, slice, splice, split 에대해 알아보도록 하겠습니다.

      [ 목차 ]

        1. slice()

        slice는 원하는 부분을 복사하여 새로운 배열로 리턴합니다. 원본을 변경시키지 않습니다.

        //slice(시작점, 끝점) ...0부터 시작
        
        let my_array=['test1', 'test2','test3','test4'];
        second_array=my_array.slice(2,3)
        
        // output:['test3','test4']

         

        2. splice()

        splice는 원본이 수정됩니다.

        //splice(시작점, 잘라낼 갯수, 추가할 요소,,,n개)
        
        
        // 요소 제거
        let my_array=['test1', 'test2','test3','test4'];
        my_array.splice(1,3);
        console.log(my_array);
        
        // output: ['test1']
        
        
        // 요소 제거 후 신규요소 추가
        let my_array=['test1', 'test2','test3','test4'];
        my_array.splice(1,3,'test5','test6');
        console.log(my_array);
        
        // output: ['test1','test5','test6']
        
        
        // 신규 요소 추가
        let my_array=['test1', 'test2','test3','test4'];
        my_array.splice(1,0,'test5','test6');
        console.log(my_array);
        
        // output: ['test1', 'test5', 'test6', 'test2', 'test3', 'test4']

         

        3. split()

        split은 문자열을 다루는 메서드로, 구분 문자를 기준으로 잘린 배열을 반환합니다. 원본 문자열이 바뀌거나 하진 않습니다.

        // split("구분 문자");
        
        
        // 공백으로 나누기
        const my_string = "Goodmorning everyone. Nice to meet you";
        my_array=my_string.split(" ")
        console.log(my_array);
        
        // output: [ 'Goodmorning', 'everyone.', 'Nice', 'to', 'meet', 'you' ]
        
        
        // 모든문자로 나누기
        const my_string = "Goodmorning everyone. Nice to meet you";
        my_array=my_string.split("")
        console.log(my_array);
        
        // output: 
        // [
        //   'G', 'o', 'o', 'd', 'm', 'o', 'r',
        //   'n', 'i', 'n', 'g', ' ', 'e', 'v',
        //   'e', 'r', 'y', 'o', 'n', 'e', '.',
        //   ' ', 'N', 'i', 'c', 'e', ' ', 't',
        //   'o', ' ', 'm', 'e', 'e', 't', ' ',
        //   'y', 'o', 'u'
        // ]
        
        // 문자열 뒤집기
        const my_string = "Goodmorning everyone. Nice to meet you";
        my_array=my_string.split("").reverse().join("");  // 나누고, 뒤집고, 다시합친다.
        console.log(my_array);
        
        // output: "uoy teem ot eciN .enoyreve gninromdooG"
        반응형
        반응형

        오늘은 Nuxt 프로젝트를 Netlify에 배포해보도록 하겠습니다. 동시에, 도메인 하나를 구매해서 적용해보겠습니다.

        [ 목차 ]

           

          1. 도메인 구매 (hosting.kr)

          저는 Hosting.KR이란 곳에서 도메인을 구매했습니다. 아래와 같이 이벤트중인 도메인 종류들도 있는데, 중간 즈음에 "도메인 가격안내"를 클릭하면 이벤트중인 싸고 좋은 것들도 찾으실 수 있습니다. 

          저는 likeapianist.blog라는 이름으로 블로그를 하나 만들어보겠습니다.

           

          2. Netlify-Gitlap 연동 배포

          사전에 Nuxt 프로젝트를 gitlap(또는 github)에 배포를 해 놓습니다. 어느정도 배포가 가능한 모양새는 갖추고 있어야겠죠?

          본인의 깃 저장소를 고르고...

           

           

          Vue 프로젝트의 빌드는 "npm run build"이지만, nuxt 프로젝트 배포시의 빌드 명령어 "npm run generate"입니다.

          npm run generate

           

          잠시 기다리면 배포가 완성됩니다.

           

          3. 도메인 설정 (Hosting.kr)

          Netlify에서 도메인 설정을 하기에 앞서 우선 Hosting.kr에서 Netlify의 네임서버를 등록합니다.

          dns1.p01.nsone.net
          
          dns2.p01.nsone.net
          
          dns3.p01.nsone.net
          
          dns4.p01.nsone.net

           

          그러면 Netlify에서 인식할 준비가 되었습니다.

           

          다음으로 Netlify로 넘어와서 해당 사이트를 클릭하고,

          Domain management > Domains > Add a domain을 클릭합니다.

          구매한 도메인을 넣고 Verify버튼을 눌러주고, Add domain을 눌러주면 됩니다. (처음 시도시에는 등록되지 않았다는 메시지가 나오지만 무시하고 Add domain을 누릅니다.)

           

          다음으로 Check DNS configuration을 클릭하면 정상적으로 등록이 됩니다.

           

          4. 접속확인

          다음으로 해당 주소로 접속하면.... 

           

          옴마야 세상에~~~ 내가 산 주소로 블로그가 보입니다~~~~~

          반응형
          반응형

          전개연산자는 ES6에서 추가된 기능으로 배열이나 객체를 분해된 값으로 전달하는 기능입니다. 배열 등 모든 순환 가능한 것들은 펼쳐서 가져올 수 있습니다. 

           

          1. 배열 예

          const arr1 = ['a', 'b', 'b'];
          const arr2 = ['d', 'e', 'f'];
          const arr3 = ['g', 'h', 'i'];
          const sum_array = [...arr1, ...arr2, ...arr3];
          
          console.log(sum_array); 
          // ['a', 'b', 'b', 'd', 'e', 'f', 'g', 'h', 'i']

           

          2. 객체배열 예

          const obj_array=[
            {
              name: "one",
              age: 1,
            },
            {
              name: "two",
              age: 2,
            },
            {
              name: "three",
              age: 3,
            }
          ]
          
          const obj_array2=[
            {
              name: "four",
              age: 4,
            }
          ]
          
          
          let new_array = [];
          new_array.push(...obj_array,...obj_array2);
          
          
          console.log(new_array);
          
          //[
          //  { name: 'one', age: 1 },
          //  { name: 'two', age: 2 },
          //  { name: 'three', age: 3 },
          //  { name: 'four', age: 4 }
          //]

           

          반응형

          + Recent posts