728x90
반응형

문제

N*M의 배열에서 (0,0) 에서 (N-1,M-1)까지 가는 최단거리를 구하여라

 

입력예제

첫째줄 N 과 M을 입력받으며, 두번째줄 부터 M개의 숫자들이 N줄 나옴

5 4
10 5 9 5
4 1 1 7
7 5 1 6
3 4 8 6
3 4 3 6

===> 답: 34

풀이 코드

다익스트라를 이용한 풀이 코드입니다. 위 예제를 이력하여 마지막에 나온 dist 배열의 값은 

[10, 15, 24, 28]
[14, 15, 16, 23]
[21, 20, 17, 23]
[24, 24, 25, 29]
[27, 28, 28, 34]

입니다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.PriorityQueue;
import java.util.StringTokenizer;

public class Main {

    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StringTokenizer st;

    static int n, m;
    static int[][] MAP; 
    // Node 생성
    static class Node implements Comparable <Node> {
        int y;
        int x;
        int cost;
        Node(int y, int x, int cost) {
            this.y= y;
            this.x=x;
            this.cost=cost;
        }
        @Override
        public int compareTo(Node next) {
            if(cost < next.cost)
                return -1;
            if(cost > next.cost)
                return 1;
            return 0;
        }
    }

    static int[] ydir = {0, 0, 1, -1};
    static int[] xdir = {1, -1, 0, 0}; 

    static void dijkstra(int y, int x) {
        // 1. PQ 설정
        PriorityQueue<Node>pq = new PriorityQueue<>();
        // MAP[0][0] = 0, 0 위치로 진입하는 비용 
        pq.add(new Node(y, x, MAP[y][x]));

        // 2. dist 설정
        // dist[] = index : 노드번호 value : 최단거리 
        // dist[][] = [y][x] 좌표의 최단거리 
        int[][] dist = new int[n][m];
        // 초기화
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < m; j++) {
                dist[i][j] = Integer.MAX_VALUE;
            }
        }
        dist[y][x] = MAP[y][x]; 

        // dijkstra
        while(!pq.isEmpty()) {
            Node now = pq.poll();
            // 갈 수 있는 인접한 방향 체크 
            for(int i = 0; i < 4; i++) {
                int ny = now.y + ydir[i];
                int nx = now.x + xdir[i];
                // ** 필수체크 ** 범위체크 
                if(ny < 0 || nx < 0 || ny >= n || nx >= m)
                    continue;
                // 다음 노드까지의 비용
                // 지금 좌표까지 오기 위해 사용한 비용 + 다음 좌표로 진입하기 위한 비용
                int ncost = dist[now.y][now.x] + MAP[ny][nx];
                // 지금까지 기록된 [ny][nx]까지의 최소비용보다 같거나 크면 pass
                if(dist[ny][nx] <= ncost)
                    continue; 
                dist[ny][nx] = ncost;
                pq.add(new Node(ny, nx, ncost));
            }
        }
        System.out.println(dist[n-1][m-1]); // N-1,M-1 의 최단거리 출력
    }

    public static void main(String[] args) throws IOException {
        st = new StringTokenizer(br.readLine());
        n = Integer.parseInt(st.nextToken());
        m = Integer.parseInt(st.nextToken());
        // map init
        MAP = new int[n][m];
        // input
        for(int i = 0; i < n; i++) {
            st = new StringTokenizer(br.readLine());
            for(int j = 0; j < m; j++) {
                MAP[i][j] = Integer.parseInt(st.nextToken());
            }
        }
        dijkstra(0, 0); //(0,0) 부터 시작
    }
}

 

다익스트라의 원리는 지난번 설명한 포스트에 있으니 참고하세요.

2021.06.14 - [Programe Note/Algorithm] - [Java] 다익스트라 알고리즘 - 최단경로

728x90
반응형
728x90
반응형

미들웨어

미들웨어는 중간단계 역할을 하는 존재입니다. 즉, 응답과 요청 사이에 express 자체에 있는 기능 외에 추가적인 기능을 넣어주는 것 입니다. npm으로 다운받아서 사용해도 되며 express 자체 미들웨어를 사용해도 됩니다. 미들웨어에는 인증, 예외처리, 세션처리, 라우터 등 많은 종료가 있습니다. 미들웨어는 app.use() 메서드를 사용합니다. 

next() : 다음 미들웨어로 가는 역할
next(error) : 오류 처리 미들웨어로 가는 역할
next('route') : next()로 같은 라우터에서 분기처리를 할 때 사용

express로 서버를 만들때 순서

  1. express를 불러옴
  2. 포트설정
  3. 공통부분 미들웨어 작성
  4. 라우터 구성
  5. 404 처리 미들웨어 구성
  6. 오루처리 미들웨어 구성
  7. 서버 포트를 리스닝

 

자주 사용하는 미들웨어

express.static

static 파일은 이미지, css, 스크립트 파일과 같이 그 내용이 고정되어 있어 파일 내용 그대로를 보여주면 되는 파일을 말합니다. 이러한 파일은 따로 폴더를 지정하여 놓으면 관리가 편합니다. static 은 express 안에 기본적으로 포함이 되어 별도의 설치없이 사용이 가능합니다. 아래와 같이 express_server_static.js 파일을 생성하여 줍니다.

const express = require("express");
const app = express();

app.set("port", process.env.PORT || 8080);

app.use(express.static(__dirname + "/public"));

app.get("/", (req, res) => {
  res.sendFile(__dirname + "/test2.html");
});

app.listen(app.get("port"), () => {
  console.log(app.get("port") + "포트에서 서버 실행중...");
});

같은 폴더안에 public 폴더를 만들고 그곳에 sample.png 파일을 둡니다. 그리고 test2.html의 내용은 아래처럼 작성합니다.

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <title>test2</title>
  </head>
  <body>
    <h1>Node.js Express Server2 Test html2 page</h1>
    <p>This is Main page.</p>
    <img src="./sample.png" width="500" height="350" />
  </body>
</html>

작성된  express_server_static.js 를 실행하여 localhost:8080 에 접속하면 아래와 같은 화면이 나타납니다.

이렇게 express.static 을 이용하면 html 파일 내에 /public 이라는 경로를 따로 명시해 주지 않아도 자동으로 서버에서 static 폴더로 지정된 곳에 해당 파일을 찾아 화면에 띄어주게 됩니다. 경로를 숨길수 있어 보안에도 도움이 됩니다.

 

router

클라이언트로부터 요청이 왔을대 서버에서 어떤 응답을 보내주어야 할지 결정해주는 미들웨어 입니다. 

아래 예제 코드는 localhost:8080 으로 들어올때와 localhost:8080/member/ty 로 접속했을때 다른 html 화면을 띄어주는 예제입니다. 

const express = require("express");
const app = express();

app.set("port", process.env.PORT || 8080);

app.use(express.static(__dirname + "/public"));

app.get("/", (req, res) => {
  res.sendFile(__dirname + "/test2.html");
});

app.get("/member/:id", (req, res) => {
  res.send(req.params.id + "님의 마이 페이지입니다.");
});

app.listen(app.get("port"), () => {
  console.log(app.get("port") + "포트에서 서버 실행중...");
});

위 코드를 작성하여 실행하면, localhost:8080 로 접속했을 때는 위 express.static에서 만든 화면이 출력이 되지만 localhost:8080/member/ty 로 접속하면 아래와 같은 페이지가 출력됩니다.

express.json, express.urlencoded

클라이언트에서 post, put 요청 시 들어온 정보를 가진 req.body에 접근하기 위해 필요한 미들웨어입니다. 요청 정보가 url에 들어온 것이 아니라 request body에 들어있는데, 이 값을 읽을 수 있는 구문으로 파싱하고 req.body로 옮겨주는 역할을 하는 것입니다.

express.json 은 req.body가 json 형태일 때, express.urlencoded는 폼에 대한 요청일 때 사용합니다.

 

cookie-parser

쿠키는 클라이언트가 요청을 보낼 때마다 키-쌍으로 이루어진 쿠키를 보내고 서버에서는 클라이언트가 보낸 쿠키를 읽어 사용자가 누군지 식별합니다. 처음에 한 번만 서버에서 res.writeHead() 메서드를 통해 'Set-cookie'에 값을 넣어줍니다. 이렇게하면 브라우저에 키-쌍으로 이루어진 쿠기가 헤더에 저장됩니다. 이것을 자동으로 쿠키를 매번 요청할 때마다 서버에게 보냅니다.

728x90
반응형
728x90
반응형

express 모듈을 이용하여 가볍고 빠른 프레임워크를 만드는 방법입니다. 

  • 자바스크립트의 프론트엔드 프레임워크 : React.js, Angular.js, Vue.js
  • 자바스크립트의 백엔드 프레임워크 : node.js 의 express

 

express 설치

터미널을 이용하여 아래의 명령어로 express 를 설치합니다.

C:\dev\nodejs>npm install express

설치가 완료되면 nodejs 폴더 안에 node_modules 라는 폴더가 생성이되고 이곳에 express 동작을 위한 모듈들이 자동으로 설치가 됩니다.

 

express 코드 작성 1

express 사용을 연습하기 위하여 아래와 같이 코드를 작성합니다. 저는 nodejs 폴더 아래 express 폴더를 만들고 express_server.js 라고 파일을 만들어 아래 코드를 작성하였습니다.

const express = require("express");
const app = express();

app.get("/", (req, res) => {
  res.send("Hello World!!!!");
});

app.listen(8080, () => console.log("8080포트에서 서버 실행중..."));

js를 실행하여 브라우저로 localhost의 8080 포트에 접속을 하면 아래와 같이 표시됩니다.

express 코드 작성 2

웹 페이지를 만드는 방법으로 연습을 해봅니다. 우선 test.html 페이지를 만듭니다.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <title>test</title>
  </head>
  <body>
    Node.js Express Server Test html page
  </body>
</html>

이번에는 아래와 같이 js 파일을 수정합니다.

const express = require("express");
const app = express();

app.set("port", process.env.PORT || 8080);

app.get("/", (req, res) => {
  res.sendFile(__dirname + "/test.html");
});

app.listen(app.get("port"), () => {
  console.log(app.get("port") + "포트에서 서버 실행중...");
});

수정 후 js 파일을 실행고 브라우저로 접속을 하면 아래와 같이 html 페이지를 화면에 표시하는 것을 확인 할 수 있습니다.

 

728x90
반응형
728x90
반응형

간단하게 Node.js를 이용하여 서버를 만드는 방법입니다.

 

아래와 같이 간단하게 코드를 작성하여 js파일을 만듭니다. 저는 simple_server.js 라고 하겠습니다.

const http = require("http");

http
  .createServer((req, res) => {})
  .listen(8080, () => {
    console.log("8080포트에서 서버 연결 중...");
  });

 

만들고나서 http://localhost:8080 으로 접속하면 아래와 같은 화면이 나타납니다.

이번에는 위에서 작성한 js파일을 실행하여 봅니다. 실행은 아래와 같이 실행 할 수 있습니다.

C:\dev\nodejs\test> node simple_server.js

위처럼 실행하면 "8080포트에서 서버 연결 중..."이라는 메시지가 나오면 성공입니다. 이런 상태에서 다시한번  http://localhost:8080에 접속해 봅니다.

아까와는 다르게 로딩중으로 표시되지만 아무런 변화는 없습니다. 이는 서버가 실행되고 있으나 아직 아무것도 등록해주지 않았기 때문에 계속 로딩만 표시되는 것 입니다. 서버를 종료하기 위해서는 명령어를 입력했던 터미널에서 ctrl+c 를 입력하면 서버가 종료됩니다.

 

요청에 대한 응답

이번에는 페이지를 한번 만들어보도록 하겠습니다. 아까 simple_server.js 파일을 아래와 같이 수정하여 주십시오.

const http = require("http");

http
  .createServer((req, res) => {
    res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
    res.write("<h1> Node.js Server </h1>");
    res.end("<p>http page test ... </p>");
  })
  .listen(8080, () => {
    console.log("8080포트에서 서버 연결 중...");
  });

수정 후 다시한번 node 명령어를 실행하여 서버를 실행 후  http://localhost:8080에 접속해 봅니다. 그러면 아래와 같은 화면이 표시되는 것을 확인할 수 있습니다. 

간단히 코드에 대한 설명을 해보겠습니다. .createServer() 함수는 말 그대로 서버를 만드는 함수입니다. res.writeHead()는 응답에 대한 헤더 정보를 기록하는 함수이고 res.write()에는 클라이언트로 보낼 데이터를 넣어주면 됩니다. res.end()는 응답을 종료하는 메서드로 응답을 종료합니다.

createServer()함수 뒤에 .listen()을 붙여 클라이언트와 연결할 포트번호와 서버가 연결되면 실행할 콜백 함수를 넣습니다.

 

파일을 보내는 응답 코드

이번에는 html 문서를 응답으로 보내도록 하겠습니다. 일단 아래와 같이 html 을 만들어 줍니다. 저는 test.html 이라고 하겠습니다.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <title>test</title>
  </head>
  <body>
    Node.js Server Test html page
  </body>
</html>

그리고 js 파일을 아래와 같이 수정합니다.

const http = require("http");
const fs = require("fs").promises;

http
  .createServer(async (req, res) => {
    try {
      const f = await fs.readFile("./test.html");
      res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
      res.end(f);
    } catch (err) {
      console.error(err);
      res.writeHead(500, { "Content-Type": "text.html; charset=utf-8" });
      res.end(err.message);
    }
  })
  .listen(8080, () => {
    console.log("8080포트에서 서버 연결 중...");
  });

다시한번 서버를 실행하여 http://localhost:8080 에 접속하면 아래와 같은 페이지를 볼 수 있습니다.

728x90
반응형
728x90
반응형

Node.js 로 서버를 만들어보려 합니다. 간단히 Node.js 와 자바스크립트에 대하여 간단히 정리를 해보았습니다.

개요

  1. Node.js 란, 자바스크립트 런타임을 의미합니다.
  2. Node.js는 논블로킹/비동기 처리 방식이기 때문에 사용하기 어렵다고 합니다. 
    논블로킹/비동기는 작업 흐름이 순차적이지 않고, 응답을 기다리지 않습니다. 블로킹/동기 방식보다 자원 낭비가 적습니다.
  3. Node.js 는 싱글 스레드이지만 이벤트 루프가 있습니다. 
    이벤트 루프는 이벤트를 감지하며 작업을 위한 스레드를 생성하여 이벤트를 처리합니다.

 

ECMAScript(=ES)

ECMAScript 는 자바스크립트, J스크립트, 액션스크립트가 따르는 표준을 말합니다. 스크립트 언어들의 표준을 지키기 위하여 매년 6월마다 새로운 기능 혹은 규칙을 개정합니다. ES6(=ES2016) 버전에서 자바스크립트가 혁신적이게 바뀌게 되며 이 시점을 전후로 최신인지 구식인지를 판가름합니다.

 

간단한 자바스크립트 문법 정리

변수, 호이스팅

ES6 이전에는 변수 선언시 var를 사용했지만, ES6 이후로 되도록 const, let 를 사용해야합니다. 이유는 var의 변수 호이스팅과 function-level-scope로 인해 생기는 문제 때문입니다.

  • 변수 호이스팅(Hoisting) : 변수의 선언과 초기화가 동시에 이루어져, 아직 값이 없음에도 오류가 나지 않는 현상
  • function-level-scope: 함수의 블록 범위 내에서 선언한 변수는 함수 내에서만 인정하고 함수 외부에서 선언한 변수는 모두 전역변수가 된다

let과 const 의 차이

let과 const는 block-level-scope 입니다. 둘의 차이를 보면 let은 값을 재할당 할 수 있어 값의 변경이 가능합니다. const는 값을 재할당할 수 없어 변경할 수 없습니다. 

클로저

내부 함수가 외부 함수의 scope에 접근할 수 있는 것을 이야기합니다. 자바스크립트에서 scope는 함수 단위로 생성이됩니다. 한 함수의 inner()함수의 scope가 outer()함수의 scope를 참조하고 있고 outer()의 실행이 끝나고 소멸된 이후에도 inner()함수가 outer()함수의 스코프에 접근할 수 있다 것을 이야기합니다.

 

자주 사용하는 내장 함수

함수 설명 함수 설명
forEach() for문을 짧게 줄임 indexOf() 원소의 인덱스를 반환
findIndex() 배열의 요소가 객체,배열 일 때 판별 함수를 만족하는 첫 식별자 반환 find() 찾은 값을 반환
shift() 첫 번재 원소 제거 및 반환 unshift() 맨 앞에 새 원소를 추가
filter() 조건을 만족하는 배열 생성 splice() 인덱스로 특정 항목을 제거
slice() 항목을 제거해 새 배열 생성 pop() 마지막 원소 제거 및 반환
join() 배열 요소를 문자열로 합침 concat() 배열합침
reduce() 누적 값을 계산 map() 배열 각 원소 반원

자바스크립트의 비동기 처리

콜백함수, Promise

 콜백은 나중에 실행되는 코드를 의미합니다. A()라는 함수가 있을때, 인자로 어떤 함수를 넣어주었다고 한다면 A함수의 모든 명령어를 실행한 후 마지막으로 넘겨받은 인자 callback을 실행하게 될것이고 여기서 인자로 들어가는 함수를 콜백 함수라고 합니다. 콜백함수를 사용하는 이유는 이를 이용하여 비동기 작업을 동기적으로 처리할 수 있기때문입니다.

 Promise는 코드의 중첩이 많아지는 콜백 지옥을 해결하게 해주는 자바스크립트 API입니다. 보낸 요청에 대해 응답이 준비되었을 때 알림을 주는 알리미 역할을 합니다.

async/await

ES7.6부터 사용할 수 있는 문법으로 Promise의 단점을 보안해주는 패턴입니다. Node.js는 8버전부터 async/await를 지원합니다. async/await를 사용하면 new Promise로 Promise 객체를 선언하고 resolve, reject를 넘겨주는 부분은 숨기겨 코드의 양이 줄어듭니다. try/catch를 통해 오류를 다룰수 있다는 장점도 존재합니다.

await는 async 키워드를 붙인 함수 안에 lock을 걸어 놓고 싶은 부분에 await를 붙이기만하면 됩니다. async/await를 이용하게 되면 비동기로 처리하고 싶은 함수에 async를 붙이고, 비동기 처리를 할 특정 부분에 await를 붙이기만 하면 됩니다.

비동기 상황에서의 예외 처리

비동기 상황에서의 예외처리는 Promise의 .catch()를 이용하거나, Promise의 .then()을 이용하는 방법이 있습니다. 또한, async/await의 예외처리 방식으로 사용이 가능합니다.

 

 

 

 

 

 

728x90
반응형
728x90
반응형

파이썬을 이용하여 마우스를 특정한 위치에 자동으로 클릭하는 프로그램을 만들어 보겠습니다. 특정 위치에 대한 정보를 얻고 그 위치에 마우스 포인터를 이동 시키고 몇초 간격으로 클릭을 실행하는 프로그램입니다. 프로그램은 GUI를 이용하여 만들어 볼 건데, 저도 처음 사용하는 라이브러리인 tkinter 를 사용해 보겠습니다. 간단한 설명 문서는 아래 사이트를 참조 하면 됩니다.

https://docs.python.org/ko/3/library/tkinter.html
 

tkinter — Tcl/Tk 파이썬 인터페이스 — Python 3.10.2 문서

tkinter — Tcl/Tk 파이썬 인터페이스 소스 코드: Lib/tkinter/__init__.py The tkinter package (《Tk interface》) is the standard Python interface to the Tcl/Tk GUI toolkit. Both Tk and tkinter are available on most Unix platforms, including mac

docs.python.org

 

마우스를 제어하기 위하여 키보드나 마우스를 제어할 수 있는 pyput 과 pyautogui 을 이용합니다. 관련 사이트는 아래를 참조하면 됩니다.

https://pypi.org/project/pynput/
 

pynput

Monitor and control user input devices

pypi.org

https://pyautogui.readthedocs.io/en/latest/
 

Welcome to PyAutoGUI’s documentation! — PyAutoGUI documentation

Welcome to PyAutoGUI’s documentation! PyAutoGUI lets your Python scripts control the mouse and keyboard to automate interactions with other applications. The API is designed to be simple. PyAutoGUI works on Windows, macOS, and Linux, and runs on Python 2

pyautogui.readthedocs.io

 

위 이미지와 같이 tkinter를 사용하여 다이얼로그를 만들도록 하겠습니다. 우선 tkinter를 사용하기 위해서 import를 해줍니다. 그리고 아래와 같이 소스를 코딩하면 위와 같이 나타납니다.

from tkinter import *

root = Tk() # Tk클래스 객체 생성
root.title("마우스 자동 클릭") # 타이틀 이름 설정
root.geometry("550x180") # grid 형식으로 너비x높이 설정(픽셀단위)

root.mainloop() # Tk 클래스 객체의 mainloop 실행하여 다이얼로그 표시함함

빈 다이얼로그 창에 코드를 추가하여 버튼과 입력창을 만들어 보겠습니다. 

from tkinter import *

root = Tk() # Tk클래스 객체 생성
root.title("마우스 자동 클릭") # 타이틀 이름 설정
root.geometry("550x180") # grid 형식으로 너비x높이 설정(픽셀단위)

################
label1 = Label(root, text="X좌표")
label1.grid(row=1, column=1)

entry1 = Entry(root, width=10)
entry1.grid(row=1, column=2)

label2 = Label(root, text="Y좌표")
label2.grid(row=1, column=3)

entry2 = Entry(root, width=10)
entry2.grid(row=1, column=4)

button1 = Button(root, text="마우스위치")
button1.grid(row=1, column=5)

#################
label3 = Label(root, text="반복횟수")
label3.grid(row=2, column=1)

entry3 = Entry(root, width=10)
entry3.grid(row=2, column=2)
entry3.insert("end","120")

label4 = Label(root, text="인터벌(초)")
label4.grid(row=2, column=3)

entry4 = Entry(root, width=10)
entry4.grid(row=2, column=4)
entry4.insert("end","30")

##################
label5 = Label(root, text="* 120 회 * 30초 = 3600초(60분) 동안 동작")
label5.grid(row=3, column=2, columnspan=4)

##################
button2 = Button(root, text="클릭 시작")
button2.grid(row=4, column=3)
##################

root.mainloop() # Tk 클래스 객체의 mainloop 실행하여 다이얼로그 표시함함

위 소스로 실행되면 다이얼로그 창에 원하는 위치에 버튼과 입력창을 만들 수 있습니다.

이제 버튼이 클릭했을 때 동작하는 함수를 만들어 보겠습니다. 각 버튼에 아래와 같이 클릭시 실행하는 함수를 선언 할 수 있습니다.

button1 = Button(root, text="마우스위치", command=lambda: mousePointerPos())
# (중략)
button2 = Button(root, text="클릭 시작", command = lambda:startMacro())

위에서 실행될 함수를 작성하여 줍니다.

def mousePointerPos():
    with mouse.Listener(
        on_click=posClick
    ) as listener: listener.join()
    entry1.insert("end", x1)
    entry2.insert("end", y1)

def posClick(x, y, button, pressed):
    if pressed:
        global x1
        global y1
        x1 = x
        y1 = y

    if not pressed:
        return False

def startMacro():
    click_num = int(entry3.get())
    intervalSec = int(entry4.get())

    ##반복시작
    for a in range(0, click_num):
        time.sleep(intervalSec)
        pyautogui.click(x1, y1)

아래는 전체 코드입니다.

 

from tkinter import *
from pynput import mouse
import pyautogui
import time

root = Tk() # Tk클래스 객체 생성
root.title("마우스 자동 클릭") # 타이틀 이름 설정
root.geometry("550x180") # grid 형식으로 너비x높이 설정(픽셀단위)

################
label1 = Label(root, text="X좌표")
label1.grid(row=1, column=1)

entry1 = Entry(root, width=10)
entry1.grid(row=1, column=2)

label2 = Label(root, text="Y좌표")
label2.grid(row=1, column=3)

entry2 = Entry(root, width=10)
entry2.grid(row=1, column=4)

button1 = Button(root, text="마우스위치", command=lambda: mousePointerPos())
button1.grid(row=1, column=5)

#################
label3 = Label(root, text="반복횟수")
label3.grid(row=2, column=1)

entry3 = Entry(root, width=10)
entry3.grid(row=2, column=2)
entry3.insert("end","120")

label4 = Label(root, text="인터벌(초)")
label4.grid(row=2, column=3)

entry4 = Entry(root, width=10)
entry4.grid(row=2, column=4)
entry4.insert("end","30")

# checkbutton1 = Checkbutton(root, text="무한")
# checkbutton1.grid(row=2, column=5)
##################
label5 = Label(root, text="* 120 회 * 30초 = 3600초(60분) 동안 동작")
label5.grid(row=3, column=2, columnspan=4)

##################
button2 = Button(root, text="클릭 시작", command = lambda:startMacro())
button2.grid(row=4, column=3)
##################


def mousePointerPos():
    with mouse.Listener(
        on_click=posClick
    ) as listener: listener.join()
    entry1.insert("end", x1)
    entry2.insert("end", y1)

def posClick(x, y, button, pressed):
    if pressed:
        global x1
        global y1
        x1 = x
        y1 = y

    if not pressed:
        return False

def startMacro():
    click_num = int(entry3.get())
    intervalSec = int(entry4.get())

    ##반복시작
    for a in range(0, click_num):
        time.sleep(intervalSec)
        pyautogui.click(x1, y1)

root.mainloop() # Tk 클래스 객체의 mainloop 실행하여 다이얼로그 표시함함

 

지금 까지 간단하게 다이얼로그에 버튼, 입력창을 만들고 이것을 마우스 위치를 알아내여 마우스 클릭을 자동으록 실행하는 프로그램을 만들어 보았습니다. 

728x90
반응형
728x90
반응형

Java를 주 언어로 사용하는 사람에게 이클립스 혹은 인텔리J등의 Tool 익숙합니다. Vue.js를 공부하면서 느낀점은 별도의 Visual Studio Code 를 설치해서 Tool을 따로 써야하는 불편함이 있어서 찾아보았습니다. 미약하지만 이클립스에도 플러그인이 존재를 합니다.

 

우선 이클립스의 Help 메뉴의 Eclipse Marketplace 메뉴를 클릭합니다.

Marketplace에서 vue를 검색하면 아래와 같이 플러그인이 나옵니다. 이중에서 "Vue.js :: CodeMix 3 Cl 2020.07.22"를 인스톨 해줍니다.

 

저는 이미 설치를 해서 Installed 라고 나타납니다. 설치 후 이클립스를 재기동하여 프로젝트를 새로 만들어줍니다. New > Project 선택하면 아래와 같은 창이 나오는데 거기서 vue라고 입력하면 아래와 같이 나타납니다.

 

Vue Project를 선택하고 프로젝트명은 임의로 입력을 합니다. 저는 vue-test라고 했습니다. 여기서 Initialize project contents with 부분을 "A Vue CLI-built application (recommended for production-grade apps)"를 선택하여 줍니다.

 

이렇게 프로젝트를 생성하면 처음으로 아래와 같은 화면이 열립니다.

일단 terminal 을 열어서 "npm install"을 하고 그리고 "npm run serve"를 실행하여 http://localhost:8080 으로 화면을 볼수 있다고 합니다.

여기서 npm install은 프로젝트의 package.json(or package-lock.json)에 정의된 관련 모듈을 받아주는 것입니다. 이부분도 향후에 자세히 설명을 다시하겠습니다. 일단 기본적으로 설정하고 돌려보겠습니다. 실행전에 vue-cli(npm install -g vue-cli)가 설치되어 있어야합니다.

 

명령어를 실행하면 무엇인가 설치가 되고 완료가 되면 프로젝트에 node_modules 폴더가 생성됩니다.

이 폴더를 열어보면 엄청나게 많은 모듈이 폴더별로 들어있습니다. 이렇게 저희가 사용하는 모듈의 정의를 package.json(or package-lock.json)에 하면 npm install을 통해서 자동 설치를 할 수 있게됩니다. 그러므로 node_modules 라는 폴더는 팀개발시 공유하지 않고 package.json(or package-lock.json) 파일의 정의된 모듈을 각자 npm intall을 통해 설치하도록 하면 관리가 쉬울 것 같습니다.

 

다음으로 npm run serve 를 실행해보도록 하겠습니다. 

실행하면 위와 같이 나타나고, http://localhost:8080 으로 접속을 하면 아래와 같이 Vue.js 화면이 나타납니다.

 

 

이렇게 Vue.js 프로젝트를 이클립스에서 생성하고 사용을 도와주는 플러그인을 확인해 보았습니다. 화면에 npm run build 는 배포를 하기위한 명령어 인데 나중에 관련하여 글을 남기도록 하겠습니다.

728x90
반응형
728x90
반응형

Vue.js 의 3.0 버전으로 개발을 진행하기 위해서 편리한 개발 환경 구성을 정리해 보았습니다. 이 글은 책을 보면서 실습하며 작성하였습니다. 기존에 보던 책은 버전도 낮고 너무 이론적인 면이 강해서 실무에 어떻게 적용을 해야할지 난애하였지만, 이번에 구입한 책은 실무 위주로 되어 있어 바로 실무에 적용하기 쉬울 것 같습니다.

개발환경 구성

1. Visual Studio Code 설치

Visual Studio Code는 마이크로 소프트에서 제공하는 개발 IDE 툴입니다. 아래 사이트로 접속해 설치 파일을 받아 설치합니다. 

https://code.visualstudio.com 
 

Visual Studio Code - Code Editing. Redefined

Visual Studio Code is a code editor redefined and optimized for building and debugging modern web and cloud applications.  Visual Studio Code is free and available on your favorite platform - Linux, macOS, and Windows.

code.visualstudio.com

2. Node.js 설치

Node.js의 공식 사이트에 접속해서 node.js를 다운로드 받아서 설치합니다.

https://nodejs.org 
 

Node.js

Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.

nodejs.org

다운로드 페이지를 보면 두개의 다운로드 버튼이 있습니다. 왼쪽 다운로드 버튼은 LTS 버전으로 가장 안정화가 된 버전을 뜻하고, 오른쪽 버튼은 현재 최신 버전입니다. LTS 버전으로 설치를 합니다.

 

 

Native 모듈을 설치할 때 필요한 툴을 설치할지에 대한 옵션 선택 단계입니다. 체크 박스를 선택한 후 Next 버튼을 선택해서 다음 단계로 넘어갑니다.

Install 버튼을 선택해서 Node.js 설치를 시작합니다. 사용자 계정 컨트롤 창이 나오면 '예' 버튼을 선택합니다.

Node.js 설치가 완료되면 추가 도구 설치 화면이 아래와 같이 나타납니다. 아무 키나 눌러서 설치를 진행합니다.

설치하는 중간에 Windows PowerShell에 대한 사용자 계정 컨트롤 창이 나타나면 '예' 버튼을 선택합니다. 여기서 '예'를 선택하지 않으면 나중에 Visual Studio Code 의 터미널에서 노드 관련 명령어가 실행이 되지 않기 때문에 반드시 '예'를 선택하여야 합니다.

설치가 모두 완료가 되면 엔터리를 입력해서 종료합니다.

 

3. 설치확인

Visual Studio Code 를 실행하여 'View > Terminal' 을 실행합니다. 아래와 같이 'node -v' 와 'npm -v' 명령어를 입력하여 설치된 버전이 나타나면 정상적으로 설치가 된것 입니다. Terminal 을 실행 하였을때 cmd 가 아닌 Powershell이 실행되는 경우 정상적으로 버전이 보이지 않는 경우가 있습니다. 이럴경우 'View > Command Palette' 메뉴로 이동하여 검색부분에 'Terminal: Selected Default Profile' 을 입력하고 검색된 결과를 선택합니다. 그리고 거기에 "Command Prompt" 를 선택하고 Visual Studio Code를 재기동하여 주면 아래와 같이 cmd로 나타납니다.

 

4. Vue 개발을 위한 유용한 Visual Studio Code Extension 설치

Visual Studio Code 에서 Vue 개발을 좀 더 편리하게 할 수 있도록 확장프로그램을 설치 할 수 있습니다. 확장 프로그램 검색은 Visual Studio Code 의 좌측 Extensions 메뉴를 입력하면 나타납니다.

검색창에 'vue'를 입력하면 vue와 관련된 다양한 확장 프로그램이 검색되어 나옵니다.

 

4.1 Vetur

Vetur 는 Vue 개발을 할때 가장 먼저 설치 하는 확장 프로그램입니다. Vue의 경우 개발되는 파일의 확장자가 .vue 이기 때문에, 처음 vue 파일을 열면 일반적인 프로그램 코드 처럼 코드 안의 변수 혹은 메소드명과 같은 코드의 색상을 다르게 하는 Syntax Highlighting을 지원하지 않고, 일반적인 텍스트 처럼 보이게 됩니다. Vetur는 Vue의 프로그램 문법에 맞는 Syntax Hightlighting을 지원해 줍니다. Vue 프로그램 코드 작성시 사용할 수 있는 프로그램 문법에 대한 가이드를 제공해 줍니다. 또한, 프로그램 코드를 실행하기 전에 문법에 맞지 않는 오류는 물론 잠재적으로 문제가 될 수 있는 코드에 대해서 알려줍니다..

 

4.2 JavaScript (ES6) code snippets

이 확장 프로그램은 ES6를 포함한 자바스트립트 코드 자동완성을 지원해 줍니다. 여러분은 프로그래밍 언어를 공부하면서 snippet이란 용어를 자주 보게 될것입니다. 여기서 snippet는 재사용 가능한 코드의 작은 조각이라고 보면 됩니다. 이 확장 프로그램을 설치하면 자바스크립트 코드를 구현할 때 일부 코드를 작성하기 시작하면 해당 코드로 등록된 코드 블록이 있으면 화면에 나타나게 되고, 이를 선택하면 코드 블록 전체가 자동으로 완성이 되게 됩니다. 예를들어 for 키워드를 입력하면 snippet에 등로된 4개의 코드 불록을 선택할 수 있도록 가이드가 나타나며, 이 중 하나를 선택하면 자동으로 코드가 완성이 되게 됩니다.

즉, snippet라는 이름을 가지고 있는 확장 프로그램들은 미리 등록된 코드 블록을 바탕으로 코드를 좀 더 빠르고 정확하게 작성할 수 있도록 도와주는 확장 프로그램이라고 이해하시면 됩니다.

 

4.3 ESLint

ESLint는 ES와 Lint를 합친 말입니다. ES는 ECMA Script의 줄임말이고, Lint는 소스 코드를 분석하여 프로그램 오류, 버그, 스타일 오류, 의심스러운 구조체에 표시를 달아놓기 위한 도구입니다. 즉, ESLint는 자바스크립트 문법의 오류를 찾아주는 확장 프로그램입니다.

 

4.4 Prettier - Code formatter

자바스크립트, 타입스크립트, JSX, JSON, CSS, SCSS, HTML 코드를 미리 지정한 코드 포멧 스타일로 자동으로 변경해 주는 확장 프로그램입니다. 탭사이즈, 문자열, 코드 들여쓰기, 줄 바꿈 등에 대한 코드 포맷을 미리 지정해 두면, 코드 작성 후 저장 버튼을 누르면 자동으로 정의된 고트 포맷으로 변경을 해줍니다.

Prettier를 설치했다고 해서 바로 적용이 되는 것이 아니라, 설정에서 코드에 대한 포맷터로 Prettier를 선택해 주어야 합니다. Settings 메뉴로 이동합니다.

  • File > Preference > Settings

검색창에 'formatter'라고 입력하면 'Editor: Default Formatter'를 찾을 수 있습니다. 여기서 "Prettier - Code formatter"를 찾아서 선택합니다. 그리고 아래 보면 'Editor: Format On Save' 라는 옵션이 있습니다. 체크박스를 선택하여줍니다. 저장을 할 때 마다 자동으로 Prettier가 동작되고, 코드 포맷을 맞춰줍니다.

다음으로 Formatter를 적용할 프로그램 언어를 선택합니다. 아래와 같이 HTML > Format 과 JavaScript > Format 을 체크하여 줍니다.

728x90
반응형
728x90
반응형

프로그램을 만들다 보면 많은 오류를 만나게 됩니다. 이러한 오류에 대해 예외적으로 오류를 처리할 수 있는 방법을 알아보도록 하겠습니다.

 

예외처리

오류 예외 처리 기법

아래의 형식으로 예외처리를 어떻게 할 수 있는지 알아보겠습니다.

# 1. try, except만 쓰는 방법
try:
    ...
except:
    ...
# =>  오류 종류에 상관없이 오류가 발생하면 except 블록을 수행


# 2. 발생 오류만 포함한 except문
try:
    ...
except 발생 오류:
    ...
# => 이 경우는 오류가 발생했을 때 except문에 미리 정해 놓은 오류 이름과 일치할 때만 except 블록을 수행

# 3. 발생 오류와 오류 메시지 변수까지 포함한 except문
try:
    ...
except 발생 오류 as 오류 메시지 변수:
    ...
# => 이 경우는 두 번째 경우에서 오류 메시지의 내용까지 알고 싶을 때 사용하는 방법

try ... finally

finally 절은 try 수행 도중 예외 발생 여부와 상관없이 무조건 수행이 됩니다. 이는 파일을 열고 닫는 부분에서 많이 사용을 합니다.

f = open('c:\\dev\\new.txt', 'w')
try:
    # 수행
finally:
    f.close()

여러개의 오류처리하기

try 문 안에서 여러개의 오류를 처리하기 위해서는 다음과 같은 형식을 사용합니다.

try:
    ...
except 발생 오류1:
   ... 
except 발생 오류2:
   ...

만약 발생 오류1, 발생 오류2 를 동일하게 처리하기 위해서는 괄호로 묶어 except (발생 오류1, 발생 오류2) as e 와 같은 형식으로 사용을 합니다.

 

오류 발생시키기

파이썬에서는 raise 명령어를 사용해 오류를 강제로 발생시킬 수 있습니다. 아래와 같은 형식으로 사용합니다.

raise 발생오류

 

예외 만들기

예외는 직접 만들어서 사용할 수 있습니다. 바로 상속을 이용을 하는 것입니다. 이때 상속을 받을 부모는 Exception 클래스입니다.

class MyError(Exception):
    pass

직접 만든 예외를 이용한 프로그램 코드 입니다.

class MyError(Exception):
    pass


def say_nick(nick):
    if nick == '바보':
        raise MyError()
    print(nick)


try:
    say_nick("천사")
    say_nick("바보")
except MyError:
    print("허용되지 않는 별명입니다.")
    
    
### 결과
천사
허용되지 않는 별명입니다.
728x90
반응형
728x90
반응형

모듈이란 함수나 변수 또는 클래스를 모아 놓은 파일입니다. 모듈은 다른 파이썬 프로그램에서 불러와 사용할 수 있게끔 만든 파이썬 파일이라고 할 수 있습니다. 파이썬은 굉장히 많은 모듈을 사용합니다. 모듈에 대해서 알아보겠습니다.

 

모듈

모듈 만들기

파이썬으로 아래와같이 파일을 하나 만들어 보겠습니다.

# test.py

def printStr():
    return "test 입니다."

def add(a,b):
    return a+b

그리고 같은 위치에 아래와 같이 test를 import 하여 test에 작성한 함수를 호출하여 보도록 하겠습니다.

# test2.py

import test

print(test.printStr())
print(test.add(1,1))

### 결과
test 입니다.
2

만약에 바로 함수를 사용하고 싶다면 아래와 같이 사용하면 됩니다.

# test2.py

from test import printStr, add

print(printStr())
print(add(1,1))

### 결과
test 입니다.
2

improt 시 printStr, add 대신에 * 를 넣어 모든 함수를 불러서 사용할 수도 있습니다.

 

if __name__ == "__main__": 의미 

if __name__=="__main__": 를 사용하면 해당 파일을 직접 실행했을 경우에만 하위 코드가 실행이 됩니다. 만약 import를 하여 사용한다면 하위 코드는 실행이 되지 않습니다.

# test.py

def printStr():
    return "test 입니다."

def add(a,b):
    return a+b


if __name__ == "__main__":
    print(printStr())
    print(add(4, 2))
    
### test.py 실행시 결과
test 입니다.
6

 

728x90
반응형

+ Recent posts