728x90
호이스팅
JavaScript에서 호이스팅(hoisting)이란, 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미합니다. var로 선언한 변수의 경우 호이스팅 시 undefined로 변수를 초기화합니다. 반면 let과 const로 선언한 변수의 경우 호이스팅 시 변수를 초기화하지 않습니다.호이스팅을 설명할 땐 주로 "변수의 선언과 초기화를 분리한 후, 선언만 코드의 최상단으로 옮기는" 것으로 말하곤 합니다. 따라서 변수를 정의하는 코드보다 사용하는 코드가 앞서 등장할 수 있습니다. 다만 선언과 초기화를 함께 수행하는 경우, 선언 코드까지 실행해야 변수가 초기화된 상태가 됨을 주의하세요.

https://developer.mozilla.org/ko/docs/Glossary/Hoisting

 

호이스팅 - 용어 사전 | MDN

JavaScript에서 호이스팅(hoisting)이란, 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미합니다. var로 선언한 변수의 경우 호이스팅 시 undefined로 변수를 초기화합니다

developer.mozilla.org

 

728x90

'study > 프론트엔드' 카테고리의 다른 글

[Frontend] Webpack + typescript  (0) 2024.04.17
[이것저것 코드] .eslint.js => no-unused-vars  (0) 2023.02.09
[CSS] 텍스트 ... 처리  (0) 2022.09.07
728x90

[AWS] 계정 만들기


계정 생성!

728x90

'project > aws' 카테고리의 다른 글

[AWS] 2024-05-24 EC2  (0) 2024.05.24
[AWS] 예산 설정  (0) 2024.05.24
[AWS] TIL 2024-05-22  (0) 2024.05.22
728x90

react 빌드시 react-snap을 사용할때 발생한 에러

TimeoutError: Navigation Timeout Exceeded: 30000ms exceeded

 

처리방법

참고 https://github.com/stereobooster/react-snap/issues/541

 

TimeoutError: Navigation Timeout Exceeded: 30000ms exceeded · Issue #541 · stereobooster/react-snap

client@0.1.0 postbuild D:\OfficiaL\blog\client react-snap ?? error at / TimeoutError: Navigation Timeout Exceeded: 30000ms exceeded at D:\OfficiaL\blog\client\node_modules\puppeteer\lib\LifecycleWa...

github.com

node_modules -> puppeteer -> LifecycleWatcher.js -> _createTimeoutPromise functions line 137

메소드 이름 바로 아래 

return new Promise(() => {});

추가

728x90
728x90

[Project][SVG] Text를 그려보자!


SVG 에는 text 태그를 이용해 원하는 text를 표현할 수 있습니다.

x,y 속성을 통해서 위치를 정하고, textAnchor 나 alignmentBaseline 등으로 text를 좌표기준 정렬 시킬수 있습니다.

https://developer.mozilla.org/en-US/docs/Web/SVG/Element/text

전체 코드


// src\project\s\svg\components\text.js

// modules
import React, { useRef, forwardRef, useEffect, useState } from "react";

const Text = forwardRef(({ x, y, children, config = {} }, ref) => {
  const textRef = ref || useRef();
  const [options, setOptions] = useState({
    textAnchor: "middle",
    alignmentBaseline: "middle",
  });
  useEffect(() => {
    setOptions((p) => ({ ...p, ...config }));
  }, [config]);
  return (
    <text x={x} y={y} {...options} ref={textRef}>
      {children}
    </text>
  );
});

export default Text;

Arc를 그릴때와 마찬가지로 forwardRef 를 통해 부모 컴포넌트에서 tex 컴포넌트를 접근할 수 있도록합니다.

Arc 그리지 → https://twentytwentyone.tistory.com/122

이번에는 props로 넘어온 options을 text에 spread operator로 넘겨주어 따로 props 값을 지정해주는 수고를 덜었습니다.

데모는 아래의 링크에서 확인할 수 있습니다.

http://localhost:8080/work/s/svg

728x90

'project > svg' 카테고리의 다른 글

[Project][SVG] Arc 를 그려보자!  (0) 2022.07.06
728x90

[Project][SVG] Arc 를 그려보자!


SVG 로 Arc를 그리기 위해서는 path를 사용해야합니다.

path의 d 속성에는 여러개의 명령어가 있는데, 그중 M 과 A 를 이용해 그려보는 react 용 Arc Component를 만들어 봅니다.

https://developer.mozilla.org/ko/docs/Web/SVG/Tutorial/Paths

 

A 명령어


원호를 그릴수 있는 명령어인 A는

A rx ry x축-회전각 큰-호-플래그 쓸기-방향-플래그 x y 로 이루어져있습니다.

rx 는 x축 반지름

ry 는 y축 반지름 입니다.

큰-호-플래그 는 180도를 기준으로 중심각을 결정합니다.

 

M 명령어


M 명령어는 Move To 호를 그릴 시작 좌표를 지정해줍니다.

 

Arc Components


Arc component는 A명령어의 파라미터를 채우기위해 2가지의 유틸성 함수를 사용하고,

parameter로

className = "", id = "", cx, cy, r, startDeg, endDeg, fill = "none", stroke = "#446688", strokeWidth = "2",

를 받습니다.

중심 좌표 cx,cy와 반지름 r, 시작각도 startDeg,끝 각도 endDeg, 원호를 꾸며줄 속성들입니다.

 

get Points


먼저 시작 좌표와 끝좌표를 구해야합니다.

구하기 위해서는 각도를 호도로 변환하여 한 좌표와 반지름을 알고있으므로 cos,sin을 이용해 다른 2좌표를 구합니다.

 

const getPoint=(cx, cy, r, deg)=> {   const rad = ((deg - 90) * Math.PI) / 180.0;    return {     x: cx + r * Math.cos(rad),     y: cy + r * Math.sin(rad),   }; }

 

get Attribute d


이렇게 구한 좌표를 가지고, path 태그의 d속성에 넣어줄 명령어 문자열을 만들어 주어야합니다.

const getAttrD=(cx, cy, r, startDeg, endDeg)=> {   const startPos = getPoint(cx, cy, r, startDeg);   const endPos = getPoint(cx, cy, r, endDeg);   const largeArcFlag = endDeg - startDeg > 180 ? 1 : 0;   return `M${startPos.x},${startPos.y}A${r},${r},0,${largeArcFlag},1,${endPos.x},${endPos.y}`; }

getPoint를 이용해 구한 start Point 와 endPoint를 각각 M과 A에 넣어주고, 나서

largetArcFlag를 구해줍니다.

시작각도와 끝각도의 차이가 180도가 넘어가면 1을 아니면 0을 지정해줍니다.

 

전체 코드


 

// src\project\s\svg\components\arc.js
// modules
import React, { useRef, useEffect, useState, forwardRef } from "react";

const Arc = forwardRef(
  (
    {
      className = "",
      id = "",
      cx,
      cy,
      r,
      startDeg,
      endDeg,
      fill = "none",
      stroke = "#446688",
      strokeWidth = "2",
    },
    ref
  ) => {
    const pathRef = ref || useRef();
    const [d, setD] = useState("");
    useEffect(() => {
      setD(getAttrD(cx, cy, r, startDeg, endDeg));
    }, [cx, cy, r, startDeg, endDeg]);
    return (
      <path
        className={className}
        id={id}
        ref={pathRef}
        d={d}
        fill={fill}
        stroke={stroke}
        strokeWidth={strokeWidth}
      ></path>
    );
  }
);

export default Arc;

const getPoint = (cx, cy, r, deg) => {
  const rad = ((deg - 90) * Math.PI) / 180.0;

  return {
    x: cx + r * Math.cos(rad),
    y: cy + r * Math.sin(rad),
  };
};

const getAttrD = (cx, cy, r, startDeg, endDeg) => {
  const startPos = getPoint(cx, cy, r, startDeg);
  const endPos = getPoint(cx, cy, r, endDeg);
  const largeArcFlag = endDeg - startDeg > 180 ? 1 : 0;
  return `M${startPos.x},${startPos.y}A${r},${r},0,${largeArcFlag},1,${endPos.x},${endPos.y}`;
};

 

추가적으로 forwardRef 를 통해 부모 컴포넌트에서 arc 컴포넌트를 접근할 수 있도록합니다.

 

데모는 아래의 링크에서 확인할 수 있습니다.

http://localhost:8080/work/s/svg

728x90

'project > svg' 카테고리의 다른 글

[Project][SVG] Text를 그려보자!  (0) 2022.07.07
728x90

VSCode 로 github 사용하기


다양한 IDE에디터 들이 있지만, 제가 주로 사용하는 에디터는 VSCode 입니다.

여러 extention을 설치해 사용하면 정말 좋은것 같습니다.

vscode로 github 원격 저장소를 연결해 코드를 손쉽게 받아오거나, commit / push 할수 있습니다.

1. 폴더에서 vscode 열기


VSCode를 실행해 폴더를 여는 방법도 있지만, window 환경에서 저는 열려고 하는 폴더에 들어가 cmd 실행 후, code 명령어를 통해 vscode를 실행합니다.

이전에 만들어 두었던, hiio420 repository를 이용하기 위해서 바탕화면에 새로운 폴더를 만들어 줍니다.

project → hiio420

폴더 경로 부분에 cmd를 입력하고 엔터! 를 누르면 명령 프롬프트 가 실행됩니다.

커맨드 라인에 아래의 명령어를 실행하면 VSCode 가 실행됩니다.

code ./

2. git init


먼저, git을 초기화 시켜 줍니다.

실행된 VSCode 에서 터미널을 실행합니다.

ctrl + ` 또는 메뉴항목에서 터미널→새 터미널을 클릭!!! 합니다.

위와 같이 터미널이 실행됩니다.

여기에 git init을 입력!

git init

성공 적으로 실행되면, 초기화 되었다는 출력이 나오고 , .git 폴더가 숨김 상태로 생성됩니다.

3. github 정보를 등록하자!


git init으로 초기화된 상태에서 원격 저장소 주소와 , github name , github email 등을 등록해 줍니다.

git remote add origin "<원격 저장소 url>"
git config --global user.name "<github username>"
git config --global user.email "<github email>"

원격 저장소의 url은 이전에 생성함 repository로 접속하여 위 주소를 가져와 붙여넣기 합니다.

또는

https://github.com/<username>/<repository name>.git

위 양식에 맞춰 입력하면됩니다.

3가지 명령어를 다 입력하여 등록해 줍니다.

4. checkout !!! → readme.md


아직은 아무것도 없습니다.

git checkout -b main

checkout 명령어를 통해 main branch를 생성합니다.

이전에 repository를 만들때 readme파일을 만들지 않았기 때문에

readme.md 파일을 만들어 줍니다.

그리고 여기에 쓰고 싶은데로 씁니다.

저는 AweSome Things with My Ideas 라고 적어 봤습니다.

사실 맞는지는 잘 모르겠지만, 우선 적습니다.

저장!

합니다.

5. git add * 그리고 커밋 →!


git status

터미널에 위와 같은 명령어를 치면 현재 commit 가능한 파일 목록이 나옵니다.

그냥 모두 add → commit 합니다. (하나 밖에 없네여 ㅎㅎ )

커밋 메세지는 “[CREATE] New Project”로 하겠습니다.

git add *
git commit -m “[CREATE] New Project”

커밋까지 완료 하였습니다.

6. Push!!


커밋을 완료하였으니 원격 저장소에 push 합니다.

main branch로 push !

git push origin main

정상 실행 되었습니다!!!

끝!!

728x90

'모음집 > git' 카테고리의 다른 글

[Github] Repository 만들기  (0) 2022.05.23
728x90

VSCode 터미널 변경


VSCode 에서 터미널을 실행할때 윈도우일 경우 powershell이 기본적으로 실행됩니다.

이때 cmd로 변경하는 방법은 아주 간단합니다.

1. 새로 터미널 선택


현재 터미널의 상태를 나타내고 있는 부분에서 ˇ 부분을 클릭! 하시면,

위와 같이 실행가능한 터미널의 종류가 나옵니다. 이중에서 Command Prompt 를 선택!! 하면 됩니다.

2. cmd 를 기본값으로 !!


cmd 터미널을 기본값으로 선택하는 방법도 너무나 간단합니다.

기본 프로필 선택

Command Prompt 선택!!

끝!!!

728x90

'기록' 카테고리의 다른 글

[SQL] 쿼리 쿼리 쿼리  (0) 2023.02.04
[주저리주저리] 오늘은 꼭 해야지  (0) 2022.10.11
블로그 컨셉 잡기  (0) 2022.04.25
[TIL] React-google-chart / d3.js ...etc  (0) 2022.02.21
[기록 #10] db,aggregate,null,nan  (0) 2022.02.18
728x90

Github Repository 만들기


github는 git을 이용한 형상관리, 버전 관리, 프로젝트 관리, 이슈등록 등 협업을 위한 서비스로 많이 사용되고 있습니다. git을 전문적으로 다루지 못하더라도, 간단한 명령어들을 알고 사용한다면, 편리한 서비스인것은 확실합니다.

github를 이용하기위해서 처음으로는 github에 가입하여 repository를 생성해야합니다.

너무나 간단하게 만들수 있습니다.

1. New!


github에 가입해 로그인하게 되면, 화면 우측 상단에 repository 섹션이 있습니다.

이부분의 new 버튼을 클릭하면 새로운 repository를 만들수 있습니다.

 

클릭!

 

2. 정보 입력!!


 

repository 생성을 위한 정보들을 입력하는 화면으로 넘어갑니다.

이름을 정하고, description도 써봅니다.

저는 hiio420 이라는 repository 이름을 사용했습니다.

 

Publicprivate 는 repository 의 공개 여부를 결정합니다.

저는 public으로 만들었습니다.

 

그리고 아래의 설정들은 그냥 체크하지 않고, none으로 만들었습니다.

앞으로 하나씩 채워나가는 방법으로 진행해 보고 싶네요.

하하하 ㅎㅎ

 

끝!

728x90

'모음집 > git' 카테고리의 다른 글

[Github] vscode에서 git을 사용 해보자  (0) 2022.05.23
728x90

개요


  • 개발할때 필요한 이름이 들어간 데이터를 빈번히 수동으로 입력하는 불편함을 해소 하기위한 방법을 고민하던중 첫번째로 이름을 무작위로 생성하는 시뮬레이터를 만들어보기로 했다.
  • 전자가족관계등록시스템에서 제공하는 통계데이터를 활용하였다.
  • 이름의 경우 서울특별시를 기준으로 2008년,2012년,2022년 , 3년도의 데이터를 다운로드받아 사용하였다.
    • 상위 출생신고 이름 현황 링크
    • 가족관계등록부상 성씨 현황 링크

github 링크

1. 개발환경 세팅


  • OS : window 64bit
  • python 3.10.x
  • Editor : vscode + python extention
  • python-packages : pandas

1. 디렉토리 만들기

먼저 디렉토리 및 파일들을 만들어 주겠습니다.

simulator 라는 최상위 디렉토리를 만들어 주고 data가 있는 upload 디렉토리안에 xlsx,json 디렉토리를 차례대로 만들어 줍니다.

 

디렉토리를 만드는 것은 여러가지 방법이 있지만, cmd에 명령어로 생성 해주고, 해당 디렉토리로 이동합니다.

mkdir simulator; simulator\upload;simulator\upload\xlsx;simulator\upload\json cd .\simulator

2. 파이썬 가상환경

이동한 디렉토리에서 파이썬 가상환경을 만들어 줍니다.

이름은 simulator로 하겠습니다.

python -m venv simulator

 

3.VScode 설정

code ./

vscode를 열어 줍니다.

vscode에 python extention이 설치가 되어있으면, F1 또는 명령 팔레트를 통해 python select 검색후 디버깅시 사용할 python을 선택해 줍니다.

 

 

 

4. 파일 이동

  • 전자가족관계등록시스템에서 받은 이름 + 성씨 파일을 upload→ xlsx 폴더로 옮겨줍니다.

 

2. 파일 정제


이름 생성기는 성씨 파일에서 가져온 성씨 + 이름 파일에서 가져온 이름을 랜덤하게 조합해 생성합니다.

하지만 현재 다운로드 받은 파일들은 불필요한 데이터가 있기때문에 이러한 데이터들을 제거하고, 3년도로 나뉘어진 파일들을 모두 불러와 성씨 + 이름 데이터가 있는 1개의 json 파일로 만들어 주겠습니다.

 

1. package 설치

 

먼저 터미널을 열어 엑셀 파일을 다루기 위해 pandas 와 xlrd 패키지를 설치해 줍니다.

python -m pip install pandas xlrd

 

2. merge_files 함수 생성

name.py 함수에 merge_files함수를 생성해 주겠습니다.

merge_files 함수는 모든 이름 + 성씨 파일을 불러와 정제후 하나로 합치고, json 파일로 저장하는 기능을 합니다.

 

 

먼저 pandas 를 import 한후 merge_files 함수를 정의합니다.

 

import pandas as pd  def merge_files():     pass

이제 pass 부분에 필요한 코드들을 작성합니다.

 

먼저 pandas의 read_excel 함수를 사용해 모든 파일들을 불러와 변수에 대입합니다.

 

import pandas as pd  def merge_files():     family_names = pd.read_excel('.\\upload\\xlsx\\가족관계등록부상 성씨 현황.xls')     name_2022 = pd.read_excel('.\\upload\\xlsx\\상위 출생신고 이름 현황_2008.xls')     name_2012 = pd.read_excel('.\\upload\\xlsx\\상위 출생신고 이름 현황_2012.xls')     name_2008 = pd.read_excel('.\\upload\\xlsx\\상위 출생신고 이름 현황_2022.xls')

이쯤 각각의 변수를 출력해 보면서 디버깅을 해보겠습니다.

하기전에 다음의 코드를 추가해 줍니다.

import pandas as pd  def merge_files():     family_names = pd.read_excel('.\\upload\\xlsx\\가족관계등록부상 성씨 현황.xls')     name_2022 = pd.read_excel('.\\upload\\xlsx\\상위 출생신고 이름 현황_2008.xls')     name_2012 = pd.read_excel('.\\upload\\xlsx\\상위 출생신고 이름 현황_2012.xls')     name_2008 = pd.read_excel('.\\upload\\xlsx\\상위 출생신고 이름 현황_2022.xls')     print(family_names)     print(name_2022)     print(name_2012)     print(name_2008)  if __name__=="__main__":     merge_files()

F5를 눌러 실행시켜줍니다.

각각 의 파일들의 헤더가 1 행씩 밀려서 나오기 때문에 read_excel 함수에 header 매개변수를 1 로 넣어 줍니다.

import pandas as pd  def merge_files():     family_names = pd.read_excel('.\\upload\\xlsx\\가족관계등록부상 성씨 현황.xls',header=1)     name_2022 = pd.read_excel('.\\upload\\xlsx\\상위 출생신고 이름 현황_2008.xls',header=1)     name_2012 = pd.read_excel('.\\upload\\xlsx\\상위 출생신고 이름 현황_2012.xls',header=1)     name_2008 = pd.read_excel('.\\upload\\xlsx\\상위 출생신고 이름 현황_2022.xls',header=1)     print(family_names)     print(name_2022)     print(name_2012)     print(name_2008)  if __name__=="__main__":     merge_files()

 

각각의 데이터를 살펴 보면

성씨의 경우

성씨라는 컬럼의 데이터가 필요하고 여기에 입력 된 데이터를 번호. 성씨로 되어있습니다.

이 번호를 지원주는 코드를 추가하면 됩니다. 그리고 성별이 남녀로 2개씩 중복되기때문에 unique함수를 써주면 좋을것 같습니다.

이름의 경우

이름 컬럼의 데이터만 가져오면 될것같습니다. 그리고 3개를 1개로 합쳐 주면 됩니다.

이제 위에서 생각해본 대로 해당 코드를 이어서 작성해 줍니다.

 

import pandas as pd  def merge_files():     family_names = pd.read_excel('.\\upload\\xlsx\\가족관계등록부상 성씨 현황.xls',header=1)['성씨'].iloc[:-1].apply(lambda x: x[4]).unique().tolist()     name_2022 = pd.read_excel('.\\upload\\xlsx\\상위 출생신고 이름 현황_2008.xls',header=1)['이름'].iloc[:-1]     name_2012 = pd.read_excel('.\\upload\\xlsx\\상위 출생신고 이름 현황_2012.xls',header=1)['이름'].iloc[:-1]     name_2008 = pd.read_excel('.\\upload\\xlsx\\상위 출생신고 이름 현황_2022.xls',header=1)['이름'].iloc[:-1]     names = pd.concat([name_2022,name_2012,name_2008]).tolist()     print(family_names)     print(names) if __name__=="__main__":     merge_files()

출력된 결과를 보면 기타 라는 데이터가 들어가 있고, 중복된것도 있는거 같습니다. 이를 처리해 주는 코드를 작성해 주고, 각각의 리스트들을 key에 담아 딕셔너리로 만들어 json파일로 저장하는 과정을 코드로 작성합니다.

 

먼저 filter 함수로 기타를 삭제하고, set으로 names의 중복을 제거후 다시 list함수로 리스트로 만들어 줍니다.

import pandas as pd  def merge_files():     family_names = pd.read_excel('.\\upload\\xlsx\\가족관계등록부상 성씨 현황.xls',header=1)['성씨'].iloc[:-1].apply(lambda x: x[4]).unique().tolist()     name_2022 = pd.read_excel('.\\upload\\xlsx\\상위 출생신고 이름 현황_2008.xls',header=1)['이름'].iloc[:-1]     name_2012 = pd.read_excel('.\\upload\\xlsx\\상위 출생신고 이름 현황_2012.xls',header=1)['이름'].iloc[:-1]     name_2008 = pd.read_excel('.\\upload\\xlsx\\상위 출생신고 이름 현황_2022.xls',header=1)['이름'].iloc[:-1]     names = pd.concat([name_2022,name_2012,name_2008]).tolist()     names.remove('기타')     names = list(set(names))     print(family_names)     print(names) if __name__=="__main__":     merge_files()

 

 

이제 json 모듈을 import 한 후 각각의 리스트를 담은 딕셔너리를 만들어 json으로 저장합니다.

json은 upload → json 에 names.json이라는 파일로 저장하겠습니다.

 

import pandas as pd import json def merge_files():     family_names = pd.read_excel('.\\upload\\xlsx\\가족관계등록부상 성씨 현황.xls',header=1)['성씨'].iloc[:-1].apply(lambda x: x[4]).unique().tolist()     name_2022 = pd.read_excel('.\\upload\\xlsx\\상위 출생신고 이름 현황_2008.xls',header=1)['이름'].iloc[:-1]     name_2012 = pd.read_excel('.\\upload\\xlsx\\상위 출생신고 이름 현황_2012.xls',header=1)['이름'].iloc[:-1]     name_2008 = pd.read_excel('.\\upload\\xlsx\\상위 출생신고 이름 현황_2022.xls',header=1)['이름'].iloc[:-1]     names = pd.concat([name_2022,name_2012,name_2008]).tolist()     names.remove('기타')     names = list(set(names))     names_dic = {'f':family_names,'n':names}     with open('.\\upload\\json\\names.json','w',encoding='utf-8') as f:         json.dump(names_dic,f)     print(family_names)     print(names) if __name__=="__main__":     merge_files()

file이 생성 잘 생성되었습니다.

 

이제 이 파일을 불러와 데이터가 정상적으로 들어가있는지 확인해 봅니다.

import pandas as pd import json def merge_files():     family_names = pd.read_excel('.\\upload\\xlsx\\가족관계등록부상 성씨 현황.xls',header=1)['성씨'].iloc[:-1].apply(lambda x: x[4]).unique().tolist()     name_2022 = pd.read_excel('.\\upload\\xlsx\\상위 출생신고 이름 현황_2008.xls',header=1)['이름'].iloc[:-1]     name_2012 = pd.read_excel('.\\upload\\xlsx\\상위 출생신고 이름 현황_2012.xls',header=1)['이름'].iloc[:-1]     name_2008 = pd.read_excel('.\\upload\\xlsx\\상위 출생신고 이름 현황_2022.xls',header=1)['이름'].iloc[:-1]     names = pd.concat([name_2022,name_2012,name_2008]).tolist()     names.remove('기타')     names = list(set(names))     names_dic = {'f':family_names,'n':names}     with open('.\\upload\\json\\names.json','w',encoding='utf-8') as f:         json.dump(names_dic,f)     print(family_names)     print(names) if __name__=="__main__":     merge_files()     with open('.\\upload\\json\\names.json','r',encoding='utf-8') as f:         names_dic = json.load(f)         print(names_dic)

정상적으로 잘 들어있네요.!

 

 

3.class Name


파일을 정제해 하나의 json 파일로 만들었습니다. 이제 이 파일에 들어있는 데이터를 통해 이름을 생성하는 기능들을 담고 있는 class를 만들어 주겠습니다.

 

merge_files 함수 밑으로 class Name을 선언합니다.

print 와 if __name__... 밑으로 작성된 코드들은 삭제 처리 해주겠습니다.

그리고 if __name__..밑으로는 Name 클래스를 불러와 줍니다.

import pandas as pd import json def merge_files():     family_names = pd.read_excel('.\\upload\\xlsx\\가족관계등록부상 성씨 현황.xls',header=1)['성씨'].iloc[:-1].apply(lambda x: x[4]).unique().tolist()     name_2022 = pd.read_excel('.\\upload\\xlsx\\상위 출생신고 이름 현황_2008.xls',header=1)['이름'].iloc[:-1]     name_2012 = pd.read_excel('.\\upload\\xlsx\\상위 출생신고 이름 현황_2012.xls',header=1)['이름'].iloc[:-1]     name_2008 = pd.read_excel('.\\upload\\xlsx\\상위 출생신고 이름 현황_2022.xls',header=1)['이름'].iloc[:-1]     names = pd.concat([name_2022,name_2012,name_2008]).tolist()     names.remove('기타')     names = list(set(names))     names_dic = {'f':family_names,'n':names}     with open('.\\upload\\json\\names.json','w',encoding='utf-8') as f:         json.dump(names_dic,f)   class Name:     pass if __name__=="__main__":     n = Name()

 

1. 생성자

class Name 에 필요한 생성자를 만들어 봅니다.

class Name:     def __init__(self):         pass

필요한 것은 위에서 만든 json 파일안의 데이터가 들어와있어야 합니다.

이 json파일을 불러오는 기능을 하는 read_json() 함수를 만들어 주고, self.names_dic 변수에 이 함수의 반환값을 넣어 주겠습니다.

class Name:               def __init__(self):         self.names_dic = self.read_json()              def read_json(self):         with open('.\\upload\\json\\names.json') as f:             data = json.load(f)         return data

이때 파일 경로는 상대적 경로로 지정해 주었습니다.

os 모듈을 사용해 실행되는 파일의 절대 경로와 합쳐 주겠습니다.

상단에 os 모듈을 import 시켜 줍니다.

print(n.names_dic)으로 데이터가 잘 있는지 확인해 줍니다.

import pandas as pd import json import os   def merge_files():     family_names = pd.read_excel('.\\upload\\xlsx\\가족관계등록부상 성씨 현황.xls',header=1)['성씨'].iloc[:-1].apply(lambda x: x[4]).unique().tolist()     name_2022 = pd.read_excel('.\\upload\\xlsx\\상위 출생신고 이름 현황_2008.xls',header=1)['이름'].iloc[:-1]     name_2012 = pd.read_excel('.\\upload\\xlsx\\상위 출생신고 이름 현황_2012.xls',header=1)['이름'].iloc[:-1]     name_2008 = pd.read_excel('.\\upload\\xlsx\\상위 출생신고 이름 현황_2022.xls',header=1)['이름'].iloc[:-1]     names = pd.concat([name_2022,name_2012,name_2008]).tolist()     names.remove('기타')     names = list(set(names))     names_dic = {'f':family_names,'n':names}     with open('.\\upload\\json\\names.json','w',encoding='utf-8') as f:         json.dump(names_dic,f)   class Name:               def __init__(self):         self.names_dic = self.read_json()              def read_json(self):         file_ = os.path.abspath(os.path.dirname(__file__))         filepath = os.path.join(file_,'upload','json','names.json')         with open(filepath,'r',encoding='utf-8') as f:             data = json.load(f)         return data           if __name__=="__main__":     n = Name()         print(n.names_dic)

잘 나오네요.

이제 이중에 키 f의 값들은 self.f에 n 값들은 self.n에 대입해 줍니다.

 

2. 이름 1개 무작위 생성

이름 1개를 무작위로 생성하는 기능을 하는 함수 generate() 를 만들어 줍니다.

random 모듈의 randint 함수를 활용해 무작위로 나온 정수로 self.f 와 self.n 의 값을 무작위로 가져와 합쳐줍니다. 각각의 randint 의 마지막값으로는 self.f 와 self.n의 길이에서 -1을 해준값을 넣어 줍니다.

코드작성후 5번 정도 실행해 출력값을 확인해 보겠습니다.

print(n.generate()) print(n.generate()) print(n.generate()) print(n.generate())

class Name:               def __init__(self):         self.names_dic = self.read_json()         self.f = self.names_dic['f']         self.n = self.names_dic['n']      def read_json(self):         file_ = os.path.abspath(os.path.dirname(__file__))         filepath = os.path.join(file_,'upload','json','names.json')         with open(filepath,'r',encoding='utf-8') as f:             data = json.load(f)         return data          def generate(self):         fr = random.randint(0,len(self.f))         fn = random.randint(0,len(self.n))         fr = self.f[fr]         fn = self.n[fn]         result = fr + fn         return result      if __name__=="__main__":     n = Name()     		print(n.generate())     print(n.generate())     print(n.generate())     print(n.generate()) 		print(n.generate())

 

 

5개 모두 잘 나오네요!

 

4. Generate 많이 많이


이름을 여러개 만들기 위해서 generate 함수를 여러번 돌려야 합니다.

차라리 generate 함수에서 num 매개변수를 받아 for문을 돌려서 list형태로 반화하도록 수정합니다.

기본값을 1로 하여 generate함수에 매개변수를 입력하지 않을경우에는 1개의 이름이 들어있는 리스트를 반환하도록 합니다.

기존에 만들었던 generate 함수 앞에 언더스코어 2개를 붙여 맹글링 처리를 하고, 새로운 generate함수를 선언하여 리스트 컴프리핸션으로 __generate 함수를 불러오는 방식으로 코드를 작성했습니다.

 

작성한 코드를 테스트 하기위해 매개변수를 다 다르게 넣어 출력값을 확인해 봅니다.

class Name:               def __init__(self):         self.names_dic = self.read_json()         self.f = self.names_dic['f']         self.n = self.names_dic['n']      def read_json(self):         file_ = os.path.abspath(os.path.dirname(__file__))         filepath = os.path.join(file_,'upload','json','names.json')         with open(filepath,'r',encoding='utf-8') as f:             data = json.load(f)         return data          def __generate(self):         fr = random.randint(0,len(self.f)-1)         fn = random.randint(0,len(self.n)-1)         fr = self.f[fr]         fn = self.n[fn]         result = fr + fn         return result          def generate(self,num=1):         return [self.__generate() for _ in range(num)]      if __name__=="__main__":     n = Name()       n_default =  n.generate()     print('기본',len(n_default))     for i in [10,100,500,900]:         n_g = n.generate(i)         print(f'이름 {i}개 생성',len(n_g))

 

 

잘 생성 되었네요!!

 

5. 좀 더 괜찮게? 수정을 해보자


num에 넣어준 개수 만큼 이름이 생성되지만, 중복을 제거하면, 입력된 num 보다 더 적은 수만큰 생성됩니다.

중복을 허용하지 않으면서 원하는 개수만큼 만들어 주고 싶네요.

그런데 조합의 수를 고려하면 현재 데이터로는 일정 개수 이상으로는 만들수가 없습니다.

현재 데이터에 포함된 성씨는 20개 , 이름은 40개 입니다.

조합의 수를 생각해 보면 800개 입니다.

최대 조합의 수를 늘리기 위해 self.n에 있는 이름에 쓰이는 한글을 1글자씩 중복되지 않는 한글 리스트로 만들어 주고, 이름의 첫번째에 쓰인 것은 2번째는 쓰이지 않도록 하는 과정을 거쳐 최대 조합의 수를 늘려 보도록 하겠습니다.

 

1. 데이터 수정

먼저 self.n에 있는 데이터를 중복되지 않는 한글 1자를 요소로 가지는 리스트로 변환하여 줍니다.

names_to_char라는 함수를 만들어 사용해 보겠습니다.

그리고 self.c에 이 데이터를 담아 출력해 봅니다.

class Name:               def __init__(self):         self.names_dic = self.read_json()         self.f = self.names_dic['f']         self.n = self.names_dic['n']         self.c = self.__names_to_char(self.n)      def read_json(self):         file_ = os.path.abspath(os.path.dirname(__file__))         filepath = os.path.join(file_,'upload','json','names.json')         with open(filepath,'r',encoding='utf-8') as f:             data = json.load(f)         return data          def __generate(self):         fr = random.randint(0,len(self.f)-1)         fn = random.randint(0,len(self.n)-1)         fr = self.f[fr]         fn = self.n[fn]         result = fr + fn         return result          def __names_to_char(self,name=[]):         result = []         for s in name:             result += list(s)         result = list(set(result))         return result                   def generate(self,num=1):         return [self.__generate() for _ in range(num)]      if __name__=="__main__":     n = Name()       print(n.c)     print(len(n.c))

 

 

 

총 29개의 한글이 생겼습니다. 이제 이 self.c를 이용하면 20 * 29 * 28 = 16240 개의 이름 조합을 생각해 볼수 있습니다.

이 최대 조합의 수를 self.max_num 에 담아 주고,

__generate 함수와 generate 함수를 수정해 줍니다.

class Name:               def __init__(self):         self.names_dic = self.read_json()         self.f = self.names_dic['f']         self.n = self.names_dic['n']         self.c = self.__names_to_char(self.n)         self.max_num = 16240       def read_json(self):         file_ = os.path.abspath(os.path.dirname(__file__))         filepath = os.path.join(file_,'upload','json','names.json')         with open(filepath,'r',encoding='utf-8') as f:             data = json.load(f)         return data          def __generate(self):         result = ''         i = random.randint(0,len(self.f)-1)         result += self.f[i]         ic = random.randint(0,len(self.c)-1)         s = self.c[ic]         result += self.c[ic]         self.c.remove(s)         i = random.randint(0,len(self.c)-1)         result += self.c[i]         self.c.insert(ic,s)         return result                    def __names_to_char(self,name=[]):         result = []         for s in name:             result += list(s)         result = list(set(result))         return result                   def generate(self,num=1):         i = 1         result = {}         while i<=num:             print(f'{i}\r',end='')             k = self.__generate()             try:                 g = result[k]                 if self.max_num+1 ==i:                     break             except:                 result[k] = 0                 i+=1         result = list(result.keys())         return result        if __name__=="__main__":     n = Name()       n_default = n.generate()     n_500 = n.generate(500)     n_16241 = n.generate(16241)      print(n_default,len(n_default))     print(len(n_500))     print(len(n_16241))

 

 

6. txt 파일로 저장!


생성된 이름들을 txt 파일로 저장하는 함수를 만들어 줍니다.

함수명을 save로 하고, 파라미터로는 저장할 데이터 리스트와 저장되는 경로를 받아옵니다.

class Name:               def __init__(self):         self.names_dic = self.read_json()         self.f = self.names_dic['f']         self.n = self.names_dic['n']         self.c = self.__names_to_char(self.n)         self.max_num = 16240       def read_json(self):         file_ = os.path.abspath(os.path.dirname(__file__))         filepath = os.path.join(file_,'upload','json','names.json')         with open(filepath,'r',encoding='utf-8') as f:             data = json.load(f)         return data          def __generate(self):         result = ''         i = random.randint(0,len(self.f)-1)         result += self.f[i]         ic = random.randint(0,len(self.c)-1)         s = self.c[ic]         result += self.c[ic]         self.c.remove(s)         i = random.randint(0,len(self.c)-1)         result += self.c[i]         self.c.insert(ic,s)         return result                    def __names_to_char(self,name=[]):         result = []         for s in name:             result += list(s)         result = list(set(result))         return result                   def generate(self,num=1):         i = 1         result = {}         while i<=num:             print(f'{i}\r',end='')             k = self.__generate()             try:                 g = result[k]                 if self.max_num+1 ==i:                     break             except:                 result[k] = 0                 i+=1         result = list(result.keys())         return result      def save(self,data=[],filepath='./names.txt'):         with open(filepath,'w',encoding='utf-8') as f:             f.write('\n'.join(data))      if __name__=="__main__":     n = Name()       n_500 = n.generate(500)     n.save(n_500,'.\\names.txt')

 

 

7. 파이썬 실행을 위한 argument 받아 오기


이제 파이썬으로 해당 파일을 실행할때 필요한 인자를 받아 오기 위해 argparse 모듈을 사용해 추가적인 코드를 작성해 줍니다.

실행 하면서 완료되는 출력문들도 넣어 줍니다

전체코드 입니다.

# 전체 코드 import pandas as pd import json import os import random import argparse  def merge_files():     family_names = pd.read_excel('.\\upload\\xlsx\\가족관계등록부상 성씨 현황.xls',header=1)['성씨'].iloc[:-1].apply(lambda x: x[4]).unique().tolist()     name_2022 = pd.read_excel('.\\upload\\xlsx\\상위 출생신고 이름 현황_2008.xls',header=1)['이름'].iloc[:-1]     name_2012 = pd.read_excel('.\\upload\\xlsx\\상위 출생신고 이름 현황_2012.xls',header=1)['이름'].iloc[:-1]     name_2008 = pd.read_excel('.\\upload\\xlsx\\상위 출생신고 이름 현황_2022.xls',header=1)['이름'].iloc[:-1]     names = pd.concat([name_2022,name_2012,name_2008]).tolist()     names.remove('기타')     names = list(set(names))     names_dic = {'f':family_names,'n':names}     with open('.\\upload\\json\\names.json','w',encoding='utf-8') as f:         json.dump(names_dic,f)   class Name:               def __init__(self):         self.names_dic = self.read_json()         self.f = self.names_dic['f']         self.n = self.names_dic['n']         self.c = self.__names_to_char(self.n)         self.max_num = 16240       def read_json(self):         file_ = os.path.abspath(os.path.dirname(__file__))         filepath = os.path.join(file_,'upload','json','names.json')         with open(filepath,'r',encoding='utf-8') as f:             data = json.load(f)         return data          def __generate(self):         result = ''         i = random.randint(0,len(self.f)-1)         result += self.f[i]         ic = random.randint(0,len(self.c)-1)         s = self.c[ic]         result += self.c[ic]         self.c.remove(s)         i = random.randint(0,len(self.c)-1)         result += self.c[i]         self.c.insert(ic,s)         return result                    def __names_to_char(self,name=[]):         result = []         for s in name:             result += list(s)         result = list(set(result))         return result                   def generate(self,num=1):         print('이름을 생성합니다.')         i = 1         result = {}         while i<=num:             print(f'{i}\r',end='')             k = self.__generate()             try:                 g = result[k]                 if self.max_num+1 ==i:                     break             except:                 result[k] = 0                 i+=1         result = list(result.keys())         print('이름 생성 완료')         return result      def save(self,data=[],filepath='./names.txt'):         with open(filepath,'w',encoding='utf-8') as f:             f.write('\n'.join(data))         print(f'{filepath} 저장 완료')           if __name__=="__main__":     n = Name()       parser = argparse.ArgumentParser()     parser.add_argument('--num',default=1,help="생성하는 이름의 개수 지정")     parser.add_argument('--filepath',default='.\\names.txt',help="저장 경로(default=현재 경로 names.txt )")      args =parser.parse_args()     num = int(args.num)     filepath =args.filepath     data= n.generate(num)     n.save(data,filepath) 

 

파일을 저장하고 터미널에 아래와 같은 명령어를 입력해 테스트 해봅니다.

 

python name.py --num 30 --filepath .\\names_text.txt

 

 

아주 잘 되는 군요 ㅎㅎ

 

회고


이름 생성기를 만들면서 다른 정보를 포함한 개인정보 생성 모듈을 만들면 좋겠다는 생각이 들었스니다.

 

이름 생성을 위해 한글을 좀더 추가 해 준다면, 더 많은 조합을 생성해 볼수 있지 않을까 합니다.

다음은 다른걸 만들어 봐야겠습니다.

 

 

728x90

'Programming > Python' 카테고리의 다른 글

[Python] Ubuntu 20.04에 python 3.10 설치  (0) 2024.03.11
[Python] Tensoflow F1 score metrics  (0) 2022.09.22
[#1] 파이썬에 대하여 개인적인 생각  (0) 2021.12.24
[#0] 파이썬  (0) 2021.12.06
728x90

컨셉은?

이것 저것 만들어보자!!!!

 

블로그를 왜 쓰려고 할까?


현재 작성하려고 하는 블로그 이외에 1개의 블로그가 더 있는 상태이다. 20년 11월 까지 글을 작성하다가 중단한 블로그인데 그때 당시에는 코딩에 관련된 지식들을 담으려고 노력하였다.

이번에 새롭게 시작하려고하는 블로그에서는 다양한 프로젝트를 진행하는 과정에 중점을 두고 글을 작성해 보려고 한다.

코드를 깨끗하게 작성하지는 못하더라도 프로젝트를 하나씩 완성해 나가는 것을 목표로 진행해 보고자 한다.

 

728x90

+ Recent posts