빅데이터 관련 프로그래밍/Python3 기초 및 업무자동화

파일명 : watch_court.py
필요파일 : 크롬드라이버.exe


나만의 beautifulsuop 객체에 대한 정의

  • ?.태그명 : 해당 태그 하위 전체구조들까지 다 가져오기    ex> soup.body

  • 태그명.find_all( '태그명' ) : 하위의 모든 태그 중 여러개의 특정 태그를 리스트로 가져오기    ex> .find_all('tr')
  • 태그명.find( 속성 = '특정 속성명' ) : 하위의 모든 태그 중  특정 속성으로 검색    ex> .find(id = 'ea_list')

  • 태그명.get('속성') : 해당 태그안의 속성의 내용물을 가져옴   ex> a.get('href')



19.에서 했던 web_scrapping_example.py에 대해서,, 게시판 링크를 타고 추가 정보도 가져와야할 상황이다.
즉, 게시판을 클릭에서 그 글속에 정보도 가져와야한다.
image
image

  • 먼저, 1 ~ 100page까지 스크래핑했던 for문을 range(1, 2)까지로 줄이자. ( 다 완성된 뒤 100으로 수정하자)
    - # TODO 를 활용하였다.
    image


  • 게시판의 각 줄을 의미하는 line안의  각 칸<td> 중 게시글 제목칸인 td_list[1]를 보자.
    .text제외시키고  제목칸 <td>태그 안에는 링크 주소태그 <a> 태그가 있다.
    image


  • *** my) 만약, 이것을 bs4로 scrapping으로 처리한다면, 클릭해서 게시판으로 들어가는 시간 등을 처리 못하게 된다.
    *** 또한, href주소를 main url 뒤에 붙혀넣은 뒤, 홈페이지의 주소가 다르게 바뀌는 것 또한 문제를 발생시킨다
    그래도 한다고 가정하고 시행해보면,
    1. td 태그의 a태그로 이동 : td.a
      image
    2. a 태그의 href 속성의 내용물 가져오기 : a.get('href)
      - ***여기서 /뒤의 주소는 원래 웹사이트의 메인url인 http://watch.peoplepower21.org 뒤에 달리는 것이다.
      image
      image

      *** 하지만, 홈페이지가 로딩이 완료되면 주소가 변해있다.
      *** 이로 인해 문제가 발생할 것이다.

      image

    3. 이제 main url + href의 문자열을 합한 url을 requests.get() -> response.text -> html-> soup -> body 로 접근할 수 있다.
      *** 하지만, 데이터 로딩중이라는 문구와 함께 body치고는 너무 짧은 태그들만 보인다.
      *** 그 이유는 href를 이용한 url은 로딩을 준비하는 페이지로 가기 때문이다.

      image
      image


    4. 이럴 때 사용하는 것이 selenium이다.


selenium의 webdriver & chromedriver 설치

  1. 설치
    image

  2. from selenium import webdriver
    image

  3. 웹드라이버 중 크롬드라이버 이용을 위한 browser객체 만들기
    *** 첫 실행시 오류가 뜬다. 에러 중 마지막 줄 사이트로 이동해서 크롬드라이버 최신버전을 설치하자.
    image


  4. 크롬드라이버 설치
    https://sites.google.com/a/chromium.org/chromedriver/home

    image
    image
    image

    압축푼 파일을 해당 파이참 프로젝트 안에 붙혀넣기하자.
    imageimage
    image

  5. 다시 한번 크롬드라이버 객체browser를 생성하는 것을 실행시켜보자.
    - 크롬창이 하나 뜨면서 자동화된 테스트 소프트웨어에 의해 제어되고 있다고 뜬다.
    - 크롤링이 다 끊나고 browser도 꺼져야 하므로, py파일 맨 마지막에 browser.quit를 생성과 동시에 적어주는 버릇을 들이자.
    image

    image




selenium - webdriver - chromedriver를 이용해서 연결페이지를 가서 추가정보 가져오기

  1. 앞에서 시도 했던 부분 중  게시글td태그안의 a태그 -> href내용물 가져오기의 코드만 살려놓는다.
    - sele - web- chromedriver로 페이지를 타고 갈 때는, requests.get( url )부분을 대체하여 사용하는 것이다.
    - url을 얻은 상태에서 browser.get( url )시작한다.
    - 현재 상태로 실행하면, 작업은 없지만 연결된 페이지가 로딩이 완료되고, 다음 loop로 가는 것을 확인할 수 있다.
    - 그 이후에는

    image
    image


    image
    image
    image


  2. browser.get(url)로 받은 반응은    response = requests.get(url) 에 대응되고
    변수없이 browser객체에 할당된 반응은
    html = broswer.page_source 를 통해 html을 받아와야한다. 이것은 html = response.text에 대응된다.
    image



  3. html을 받았으면, 이전과정과 똑같이, beautifulsoup을 통해 스크래핑 하면 되는 것이다.
    image


  4. body 이후에서는 무엇을 가져와야할지(이전에는 게시판 첫 글을 검색) ctrl + u 를 통해 필요한 내용물의 자리를 살펴보자.
    - 우리는 해당 페이지에서 발의자라고 써있는 부분을 찾아보자.
    image
    image

  5. 우리가 필요한 발의자들 목록의 상위에서 많은 <div>태그들 가운데 id를 가지고 있는 <div>태그가 보인다.
    id는 한 페이지당 고유값이므로 body에서 .find(id = )로 한방에 타고들어간다.
    또한, 해당id <div>태그만 찾으면, 안에 text내용물은 발의자 목록 밖에 안보이므로, 쉽게 내용물을 가져올 수 있을 것 같다.
    image
    image

    하지만, 내용물이 제대로 안보인다.
    .text는 하위태그의 텍스트를 다 가져오긴 하지만,
    단지, selenium-webdriver-chromedriver가 페이지로딩이 완료가 다되고, 다음loop를 도는 기능은 있으나,
    selenium이  최종 페이지를 로딩하자마자, 바로 다음 loop로 넘어가는 식으로 수행하기 때문에
    bs4가 스크래핑할 시간이 없게 된다.
    image


  6. 이 때, 사용하는 것이 크롬드라이버의 객체 broswer를 이용한 암묵적인 기다림을 의미하는 .implicitly_wait( )이다.
    필요한 html코드를 페이지에서 받아오기 전, 5초를 기다려준다고 해봤다.
    하지만, 로딩되자마자 떠나는 것이 문제이므로 이것은 해결책이 안된다.
    image


Selenium의  WebDriverWait() + EC + By클래스를 이용하여 특정속성의 출현 확실히 기다려주기

  1. selenium이 로딩되자마자 떠나는 것을 방지하기 위해,
    해당id태그가 확!실!히! 출현한 이후에---> 다음loop로 빠져나가도록 해주는 selenium의 클래스는 3가지가 필요하다.
    image
    image
    - By. 대문자 ID

  2. WebDriverWait()를 쓰면, 무조건 html정보에 id = collapseTwo 이하의 태그들이 포함되어 있다.
    bs4는 그 정보를 가져온다. 마치 아래처럼 텍스트가 없는 것 처럼 보이나..
    빈칸이 너무 많아서... 콘솔을 오른쪽으로 돌려보면 있다

    image
    image


  3. 이제, 발의자 정보를 2차원 리스트에 추가로 append시킬 수 있도록
    1) append구문을 bs4로 스크래핑 한 뒤쪽자리로 옮기고
    image
    2) pandas의 칼럼 역시 추가해준다. 이 때, 수기로 추가해주자.
    image

    저장된 엑셀파일을 확인하면 아래와 같다. 하지만,,, 빈칸이 너무나도 많다.
    image


  4. 빈칸을 없애주기 위한 .replace( ' ', '')
    image


  5. 마지막으로 page를 수정해서 10page까지만 해보자.
    image
    image

프로젝트 : web_scraping_study_no1
파일명 : watch_court.py

requests 패키지 설치 및 requests.get('') 이용하여 홈페이지에서  주소 가져오기

  • 어떤 사이트의 게시판에 들어갔을 때, request url이 안뜰 수 있다.
    image

    - 이럴 때는, 게시판의 2번째 페이지를 눌러서, 다시 1페이지로 오자.

    image
    image

  • 이제 파이썬 파일을 하나 만들고, bs4를 import한 뒤, reponse에다가 requests.get()의 인자에다가
    홈페이지 url을 담아주자.
    image


  • 여기서 빨간줄이 뜨는 이유는 requests.get()함수를 사용하기 위한 패키지가 필요하기 때문이다.
    설정 > interpreter > requests 를 검색해서 패키지를 설치하자.
    *** request가 아니라 requests
    image

    image


  • requests 패키지를 import하고 url은 문자열로 담아주자.
    image

  • response에서도 .text만 받아서 html 변수에 넣어준 뒤,
    html변수에 담긴 것을 print해보면 잘 나오는 것 같다.
    image


requests로 긁어온 html(문자열)을  bs4를 이용해서 정보 빼내기

  • 이전시간과 같이, soup변수에 "lxml"parser를 사용한 beautifulsoup()를 이용해서 정보를 가져오고,
  • soup에서 body만 가져와보자
    image


  • 하지만 body의 양이 방대하게 많으므로, 우리가 필요한 정보만
    해당 사이트 [ Ctrl + u ] 를 이용해서 게시판의 첫번째 글을 검색하여 위치를 찾아보자.
    image
    image

  • 이제 저 부분의 html코드 구조를 파악해야한다.
    • <td>는 한칸이다. ->  한줄을 의미하는 <tr>이 있을 것이다.
    • <tr> = 한줄 상위에는 table이 있을 것이다. 머리말이 있는 게시판이면 ->     <thead>와 <tbody>가 있을 것이다.
    • <thead>바깥에 <table>이 있을 것이다.
    • <table>바깥은 봤더니 ->   구획을 나누어주는 <div>태그 + id속성이 같이 있다.
    • id = 속성은 한 페이지당 단 1개를 특정짓는 것이므로 id = "ea_list"를 가진 <div> 집중공략할 준비를 한다.
      table(게시판)은 한 페이지에 여러개가 있을 수 있기 때문에,
      ==> ea_list라는 id를 가진 <div>태그를 먼저 찾자!


  • body.find(id=) 함수를 이용해, div태그를 적어주는 것 없이 바로 그 위치를 찾아, 그 아래구조들을 다 찾아준다.
    변수명은 div태그까지 포함시켜서 만들어 구조를 파악하기 쉽게해준다.
    image


  • id = 'ea_list'로 검색한 결과는 <div>태그 부터 시작한다.
    div -> table -> tbody 까지 내려가자. 그 안의 tr/td를 받아올 것이다.
    image


  • tbody속에는 여러개의 tr태그를 가지고 있기 때문에,
    .find_all('tr')을 통해 tr들을 다 가져온 뒤 : lines --> for문으로 한줄씩 받은 것을 print로 확인하자.
    image

  • 각 tr안에서도 여러개의 td들을 가지고 있다. ---> find_all('td')를 통해 td들을 개별적으로 다 받아오자.
    • for문 속 각 tr(line)들에 대해    여러개의 tr을 받아오고, 그 중 첫번째 칸만 출력해보자.
      - 날짜 정보는 우리가 원하는게 아니다.
      image

    • 2번째 칸을 출력해보고, 맞으면 .text를 붙혀서 텍스트 정보만 가져오자.
      image

      image


  • for문 안에서 원하는 정보를 각 루프마다 확인했다. 이것을 계속 쓸 수 있는 변수에 받기 위해 for문 전에 미리 리스트를 생성해야하고,
    각 루프속에서 append()로 넣어줘야할 것이다.
    image


  • 이 때, [ 날짜, 의안, 작성자 ]의 3개의 정보 한묶음으로 --> bill_list로 정보를  전달해주려면
    그러므로 위 처럼 1차원 리스트가 아니라 2차원의 리스트형태가 되도록
    미리 리스트형태로  append( [  1, 2, 3] )
    를 해줘야, bill_list는 2차원 리스트가 될 것이다.
    *** 2차원 리스트를 이쁘게 확인하려면, for문을 써서 확인한다.
    *** 2차원 리스트로 만들어야만 -->  pandas에 담을 수 있고 --> 엑셀로 저장할 수 있다!***

    image


  • 한가지 정보를 더 추가해보았다(5번째 칸, 진행상태)
    image


가져온 2차원 리스트의 정보--> pandas에 담고 --> 엑셀로 저장하기

  • pandas 패키지 설치 및 import
  • pandas.to_excel() -> .xlsx 저장을 위한 : openpyxl 패키지 설치
    image
  • pd.DataFrame()으로 bill_list를 df에 담기  *2차원 리스트여야 df에 담을 수 있다!
  • pd.to_excel('bill.xlsx')로 저장하기
    image

    image


  • 엑셀파일을 열어보니,, 칼럼명이 없다.
    my) table -> thead -> th(머리말 한칸)들에서 가져오자.
    그리고 받은 정보를 pandas의 df생성시 columns=[]인자를 이용해서 적어주자.
    *** 그냥 손으로 적어줘도.. 될 듯..
    image

    image

  • my) index(행 번호)도 옵션으로 주어 없애보자.
    image

    image



한 페이지가 아니라 여러 페이지를 다 해보자.

맨 처음 홈페이지 주소를 가져온 url 에서 page=1 ---> page2, 3, 4, ...로 바뀌어야할 것이다.

image

  • 이럴 때, 해야할 게, '문자열' 이므로    '  {} ' . format( i )을 이용하여 변수로 둔 다음, for문으로 돌리는 것!
    이 때 조심해야할 사항이 있다.
    image

    1. for문은 range(1, 100) --> 1page부터 시작할 것

    2. bill_list()는 page를 돌리는 for문보다 더 바깥으로 빼야한다. * 페이지를 돌면서 계속 append될 것
      image

    3. pandas에서 엑셀로 저장하는 부분은 for문 안에 안들어갈 것.
      image

  • 100page 모두 스크래핑 한 결과
    image


프로젝트명 : web_scraping_study_no1
html : example.html
py : web_scrapping_example.py

지난시간에 배운 HTML 기본코드를 바탕으로 py.파일을 생성하고 인터프리터에 beautifulsoup를 추가해보자.


BeautifulSoup4 설치하기

image
image

아직 라이브러리를 설치하지 않아서 빨간줄이 뜬다.

  • BeuatifulSoup 설치하기 *프로젝트를 새로 생성함과 동시에 가상환경을 만드므로, 인터프리터는 새로운 상태임(anaconda꺼 선택도 가능)
    - file > setting ( Ctrl + Alt + S ) > Project > Project Interpreter > 우측 초록색 + 버튼 >
    > beautifulsoup4( 그냥 beautifulsoup 아님!!!) > install package
    image
    image
    image
    image


bs4를 사용하여 example.html 스크래핑 해보기

html 객체에 예제 html코드를 넣어야하는데, 이 때 사용되는 것이 작은 따옴표 3개(''')이다.
이안에다가 여러줄의 String을 하나의 String으로 입력할 수 있다.

원래는 서버의 홈페이지에서 받아와야하는 html코드인데 ,여기서만 예시로 하는 것이다.
image
image
image


# 서버에서 받은 html코드를 이용하여 BeautifulSoup객체를 만드는데, 
# 받아올 때 필요한 양식이 "lxml"이며, 인스톨이 필요하다
  • lxml 패키지 설치

image

image


  • 이제 이 soup 객체에서 body만 꺼낼 수 있다.
    image

  • 다음으로 body안에서 h1만 꺼낼 수 있다
    image

    뒤에 .text를 붙히면 h1태그안의 텍스트만 꺼낼 수 있다.
    image


  • 다음으로 body태그안에 table을 꺼내보자.
    image

  • table은 특별히 thead와 tbody 태그를 나누어줬었다.
    tbody안에도 여러개의 tr(줄)이 존재했다. 여러개의 태그를 받을 때는 .find_all('태그명') 으로 받아온다.
    image

    tbody안에 tr들을 리스트로 받고,
    리스트를 이용한 for문으로 각 tr(줄)에 존재하는 여러개의 td(칸)들 중 첫번째 칸만 확인해보자.
    image

    뒤에 .text를 붙히면 태그안의 문자열만 가져올 수 있다.
    image

HTML 이해해보기


image

  1. 위의 사이트와 같이 게시판 글을 긁어오고 싶다. 먼저, 크롬창을 띄운 상태에서 [ Ctrl + U ] 를 해보자.
    image
    - html 소스코드가 보인다.

  2. 게시판의 글 아무거나 하나를 복사한 뒤, 소스코드에서 검색해보자.
    image
    - html 태그안에 갖혀있는 것을 확인할 수 있다. 이정보들을 가져와야한다.

  3. 파이참에서 프로젝트를 생성하고,
    Alt+ insert를 통해 HTML file을 하나 만들어보자. 아래와 같이 기본 양식이 형성되어있다.
    image
    image


  4. [ Alt + F2 ] 혹은 코드창 우측상단에 뜨는 브라우저를 통해 한번 띄워보자.
    image
    image
    image
    - Title만 있고뜨고, 아무 화면도 뜨지않는다.

  5. HTML 구성에는
    크게 <html>태그 안에
    <head>태그와 <body>태그가 있고,
    <head>태그 안에는 <title>태그가 있다.

  6. <title>태그를 바꿔보고,
    <body>태그 안에는
        <h1>태그로서 제일 큰 글자를 적어보자.
        <h2> 조금더 작은 글자를 적어보자.
        <p>은 제목이 아닌, 단순 문단을 의미한다.
    image
    image

  7. 마찬가지로 <body>태그안에서,
    <table>태그를 만들어보자. table 태그는 벌려서, 안에 여러 태그를 포함시킨다.
         <tr>태그는 table안에서 한 줄을 의미한다.  벌려서 <td>태그를 포함한다.
             <td>를 한 칸을 의미한다.
    image
    image


    같은 <tr>태그 안에 <td>를 여러개 쓰면, 옆으로 한칸씩 붙는다.
    image
    image


CSS를 Bootstrap을 이용하여 작성하기

  • 위에서 작성한 table은 모양이 안이쁘다. 그래서 대부분
    <head>안에 css를 작성하며,
    css를 쉽게 작성하기 위해서 bootstrap을 이용할 수 있다.
    사이트는 [ 부트스트랩 와치.com ] : https://bootswatch.com/ 을 이용한다.
    image


  • 사용법은, Themes > 아무거나 선택 > Ctrl + U 를 통해, <head>태그 안에 있는 모양 정의 태그를 복사해오는 것이다.
    - 이 때, ...으로 줄여진 정보는, 클릭해서 해당 사이트에 접속 후, 그 주소를 복사해서 가져오면 된다.
    image
    image
    image
    image

    image
    - 클릭후 사이트 주소 전체 복사하기
    image
    image

    image
    image


    Before
    image

    Bootstrap - Darkly themes 적용 after
    image


이제 CSS를 이용해서 table모양을 바꿔보자.

  • <table>태그에 class="table" 속성(css에서 온 정보)을 넣어주면, 아래와 같이 바뀐다.
    image
    image

  • <table class="table">의 따옴표에 이어서 table table-striped 까지 넣어주면, 줄무늬가 생긴다.
    image
    image
    image


  • 표의 머리말을 굵은 글씨로 넣어주고 싶다면,
    (1) <thead>태그를 생성후 -->
               <tr> 한줄 안에 -->
                  <th> 로 한 칸씩 채운다.
    (2) 기존 내용들을 <tbody>안에 채워넣는다.
    image
    image

프로젝트명 : studying_pandas
차트 그리는 py : pandas_excel.py

  • pandas의 df(DataFrame)으로 차트를 그리려면, matplotlib이라는 모듈이 필요하다. 이전과 같은 방법으로 설치하자.
    image_thumb1

  • 설치가 되었으면,
    • import matplotlib을 통해서 모듈을 가져온다. -> 사실상 지금은 필요없다...
    • import matplotlib.pyplot as plt 를 통해 내부 파이플롯이라는 클래스를 plt로 가져온다.
      -> df의특정열.plot()을 통해 차트를 그린다.  ->  plt.show 로 화면에 띄운다.
  • 특정열(만두생산)을 .plot()을 통해 kind는 bar 차트로 그리고
    plt.show() 로 화면에 띄워보우는데, block을 띄울껀지인자를 True로 주자..
    -df['만두생산'].plot(kind='bar')
    - plt.show(block=True)
    *우측에 있떤 SciView를 설정 > FloatingMode를 통해 창으로 확인할 수 있다.
    image_thumb6
    image_thumb8
    - 여기서 x축이 이름이 아니라, index로 뜬다.

  • plot()을 차트로 그리기전에, 항상 띄울 DataFrame을 미리 print로 찍어보자.
    - x축으로 나올 index가 숫자로 찍혀있다.
    image_thumb1[1]

  • index를 0,1,2,3,4가 아니라, '이름'열로 하고 싶다.
    df.set_index('칼럼명')으로 특정칼럼을 -> index로 옮겨보자( df자체를 먼저 바꾸는 작업이다)
    image_thumb3


  • 다시 .plot()으로 출력시켜보자.
    이제 문제는 index여서 x축으로 출력되는 한글이 깨지는 문제

    1. 인코딩 문제
    2. 폰트가 영어만 써지는 폰트
    image

  • matplotlib에서 제공하는 font_manager를 통해 폰트를 설정해보자.
    1. 컴퓨터에 설치된 폰트의 이름을 가져오게 한다. -> 2. matplotlib함수에 적용한다.
    from matplotlib import font_manger를 통해 font_manager를 사용할 수 있게 한다.
    폰트매니져의, 폰트프로퍼티스의 인자로 폰트네임fname=실제 한글 폰트의 경로를 지정해주고 .get_name()을 붙혀 해당 폰트의 name을 가져와 font_name이라는 변수로 받는다.
    그리고 나서 matplotlib.rc('font', family= font_name)함수를 이용해서(드디어 쓰이네..) 차트의 폰트를 지정해준다.
    image

  • #matplotlib의 폰트를 지정해주는 방법
    font_name = font_manager.FontProperties(fname='C:/Windows/Fonts/malgun.ttf').get_name()
    matplotlib.rc('font', family=font_name)
    • 윈도우 환경에서는 c:/windows/fonts/ 폴더가 폰트가 있는 경로이다.
      모든 윈도우에 기본적으로 다 있는 malgun.ttf 를 사용할 것이다.
      image

  • 다른 칼럼을 그리고 싶다면, 최종df에서 df['만두생산'] -> df[' 다른칼럼명'] 으로 바꿔주면 될 것이다.
    차트를 저장하는 함수도 존재한다. plt.savefig('파일명*.png')을 통해 png파일로 저장해보자.
    반드시 plt.show(block=True)로 화면에 띄우기전에 저장해야한다. 순서가 바뀌면(show->savefig) 빈파일이 저장된다.
    image
    image
    image

  1. 감사합니다 2021.12.24 15:44

    특정 칼럼을 index로 옮기는걸 하루종일 찾아헤메었는데 여기서 찾네요... 감사합니다 ㅠㅠ

pandas_excel.py
불러올 엑셀파일 : mandoo_management.xlsx
저장된 엑셀파일 : result.xlsx

  1. 새로운 파이썬 파일을 만든다.
  2. 불러올 엑셀파일을 만들고, 해당 프로젝트(studying_pandas)에 mandoo_management.xlsx 엑셀파일을 저장하자(csv아님)
    image
  3. 이제 파이썬에서 pandas모듈을 이용해 엑셀파일을 불러오고, 테스트로 출력까지 해보자.
    - df = pd.read_excel('mandoo_management.xlsx', sheet_name='Sheet1')와 같이
    Pandas -> DataFrame으로 불러오는데, pd.read_excel()함수를 사용하고, 인자에는 ('파일명', sheet_name='시트명')이 필요하다
    *엑셀의 기본시트명은 Sheet1 이다.
    - 불러온 것을 print(df) 으로 확인하려 했더니, install xlrd라는 어떠한 Excel support가 필요하다고 에러가 난다.
    image

  4. Settings > Project Interpreter > + > xlrd를 검색해서 설치하고, 다시 출력시켜보자.
    image
    image

    확인해보았더니, 판다스에서는 첫row를 자동으로 칼럼명으로 인지한 것을 확인할 수 있다.

    CSV를 다룰 때는,
    읽을 때, 첫ROW를 제외하고
    쓸때는 첫ROW를 따로 쓰고 나머지를 FOR문에서 썼다.

  5. 첫row로 인지된 칼럼명row 중 하나의 칼럼을 출력시켜보자
    - print( df['칼럼명'] )
    image

  6. 출근시간 퇴근시간 칼럼을 이용하여, 근무시간 칼럼즈를 추가해보자
    - df['근무시간'] = df['퇴근시간'] - df['출근시간']
    image

    마찬가지로, 시간당 만두생산 칼럼을 추가해보자.
    - df['시간당 만두'] = df['만두생산'] / df['근무시간']
    image


  7. 이제 시간당 만두를 잘만드는 사람의 순위를 메겨보여주도록 해보자.
    특정 칼럼을 기준으로 df를 새롭게 위치시켜 보여준다.
    df.sort_values()함수로 정렬을 하는데,
    by=['칼럼명']  -> 해당칼럼을 기준으로 정렬한다.
    ascending=[False] -> 오름차순을 False로 두어, 내림차순으로 정렬된다.

    - df = df.sort_values(by=['시간당 만두'], ascending=[False])

    image

    기준칼럼이 똑같은 경우에는, 2순위의 칼럼을 지정할 수 있다. 이 때, ascending인자에도 False로 내림차순 만들어줘야한다.
    위에서는 시간당만두가 100.0 으로 같은 조재성과 안철수 중 근무시간은 안철수가 더 많다.
    - df = df.sort_values(by=['시간당 만두' , '근무시간' ], ascending=[False, False])
    image

  8. DataFrame이 완성되었다면, 엑셀로 저장할 수 있다. 마찬가지로 시트명을 같이 명시해줘야한다.
    - df.to_excel('result.xlsx',  sheet_name='Sheet1)
    바로 실행시키면 아래와 같이 openpyxl모듈이 없다고 뜬다. 마찬가지로 설치해주면된다.
    image
    image
    image
    image


결론적으로, 기본 엑셀파일이 -> pandas를 거쳐 ->

계산식을 통한 새로운 칼럼 추가 & sorting(1순위>2순위)이 되어서 저장


pandas에서 엑셀파일을

열때는-->  xlrd

저장할 때는--> openpyxl

모듈이 필요했다.

pandas_basic.py

Pandas

엑셀로 다 할 수 있겠지만, 파이썬 & pandas를 사용하면 반복되는 업무 큰 데이터를 쉽게 다룰 수 있다.
판다스 공식 홈페이지

사용해보기

새로운 프로젝트를 만들어보자. (studying_pandas)
새로운 파이썬 파일을 만들자.(pandas_basic.py)


  1. 먼저, 판다스 모듈을 설치해야한다. pip로 하는 방법도 있겠지만,
    File> Settings [ Ctrl+ Alt +S ] > Project : ~ > Project Interpreter > + > pandas를 검색해서 설치한다.
    - pandas를 설치하면, Numpy 와 matplotlib을 함께 설치하므로 많은 시간이 걸린다.
    image

  2. pandas_basic.py에서 import pandas를 하자.
    Numpy에서 array를 주로 사용했다면,
    pandas에서는 DataFrame을 가장 많이 사용한다.
    인자로는 df= pandas.DataFrame( [    [1,2,3], [4,5,6]   ]) 와 같이, 리스트안에 리스트가 들어가는 것이 DataFrame이다.
    - 출력해보면, 행렬처럼, 엑셀형태처럼 나온다.
    image


  3. 칼럼즈에 대해서 먼저 print를 해보자.
    - df.columns 를 print해보면, 0부터 3 까지, 스텝은 1씩 올라간다
    df.columns =  [리스트] 형식으로 칼럼명을 대입해보자.
    - 칼럼명이 바뀐다.
    imageimage

  4. 인덱스도 마찬가지로 리스트형식으로 대입해준다.
    - df.index = [ 리스트 ]
    image

  5. DataFrame 선언과 동시에 columnsindex를 지정해줘도 된다.
    image


  6. pandas를 import할 때, pd로 줄여서 입력시킬 수 있다.
    - import pandas as pd
    image


  7. 새로운 칼럼즈을 추가해보자.
    추가는 그냥 DataFrame[ '칼럼명' ] 만 해주면 새로 생성된다. 여기에 a열과 b열을 뺀 값을 넣어보자.
    - df['d'] = df['a'] - df['b']
    image


  8. 인덱스(행)를 추가할 때는, 기존 df에다가 새로운 것을 대입하는 방식으로 하는데,
     df = df.append()로 추가하는데, 기존인덱스를 무시해야지만 추가 할 수있다.
    만약, 각 열의 합을 요소로 가지는 행을 추가한다면, 인자로 df.sum()를 해주면 된다.
    - df = df.append( df.sum(), ignore_index=True)
      *만약 행 추가시, ignore_index 옵션을 안주면 에러난다.
    image

    무시되어, 0부터 차례되로 출력되는 index는 다시 df.index = [리스트]로 index값을 넣어주면된다.
    image

csv_to_python_to_csv_practice 프로젝트 : practice_by_csv_module.py
나의 클래스 모듈 : employee.py
시작 엑셀(csv)데이터 : emplyee_list.csv
시작 문서 양식(form) : form.docx ( 제목0,1,2  / paragraph / circle , check)
-시작 문서 양식 내용포함(form) : form_save.docx
결과 엑셀(csv)데이터 : result.csv
결과 문서(docx)데이터 : result.docx

image_thumb2

  1. 엑셀형태로 구성하고 싶은 데이터가 있다고 가정하고,  칼럼들을 클래스의 필드로 만든다.
  2. 상수를 제외하고, 생성자로 정의하여 클래스( , , , )로 인스턴스생성과 동시에 입력받도록 해준다.
    *만약, 상수로 먼저 선언하고서, 인자로 받아도 되고, 안받아도 되도록 설정하려면,
    (1) 생성자의 인자로서 wage_per_hour = None으로 default로 둔다.
    (2) 기본적으로 self.wage_per_hour = wage_per_hour는 바로 입력하지 않고,
    (3) if wage_per_hour: 를 통해 default인 None이 아닌 값이 넘어와서 True를 가질 때,
         상수였던 필드(wage_per_hour = 7530) 에 self.wage_per_hour = wage_per_hour를 대입하도록 한다.
      image_thumb5_thumb_thumb

  3. 칼럼 중에 함수식이 필요한 것은, 클래스 내부의 함수로 정의하여 self.필드들을 이용해서 (return에다가) 계산식을 만든다.
    ex> 퇴근시간 - 출근시간 = 근무시간
  4. 만약, 함수식 계산을 한 칼럼에 또 함수식을 써야하는 경우에는
    클래스에 정의된 함수식을 또 호출하는 함수를 생성하면 된다. 필드와 마찬가지로 return에다가 self.함수()로 호출해서 계산식을 만든다.
    ex> 일당 = 근무시간(퇴근시간 - 출근시간) * 시급
  5. 클래스를 정의한 부분을 모듈화 시키기 위해
    (1) 새로운 파이썬 파일 : employee.py 를 만들고
    (2) 클래스 정의 코드를 잘라내서 붙혀넣는다.
    (3) 기존 파이썬 파일에서는 from employee(파이썬 파일) import Employee(클래스명)으로 가져온다.

    ------CSV 읽어들이는 코드-----


  6. 이제 인스턴스 인자로 들어갈 데이터들을 엑셀파일에서 받아오기 위해, CSV (쉼표로분리)로 프로젝트내에 다른이름 저장
  7. f = open('파일명.csv', 'r')를 통해 열고 / f.close()도 미리 같이 작성
    f.readlines()를 통해 각 row을 list로 받음 -> (리스트이므로) for문을 통해 개별 출력시켜본다.
    import csv 를 통해 모듈을 가져온다(아나콘다로 설치시 미리 깔려있음)
    lines = csv.reader(f)를 통해 csv의 모든 라인을 리스트로 받아온다( f.readlines()와 달리, 4개로 미리 쪼개어져있다)
  8. 첫 줄은 칼럼명row이므로, 2번째줄 부터 읽기 위해선, while문과 비슷하게
    i =0 작성 -> for안에서 읽어진 lines를 i > 0부터 콤마로쪼개는 작업 등등을 하도록 하고, for문 마지막에 i += 1를 달아준다.
  9. 각 리스트는 콤마(,)를 통해 4개의 요소가 붙어있으므로 .split(',')를 통해 다시 리스트로 쪼개어 받는다.
    4개로 쪼개진 요소를 담는 list를 for문을 돌면서 출력시켜본다.

    4개 요소를 담고 있는 리스트는 리스트[0], [1], [2], [3] 형태로 개별접근이 가능해진다.
  10. 이제 for문을 돌면서 4개의 요소를 입력받아 생성될 인스턴스들을 관리할 리스트를 for문전에 만든다.
    ex> employee_list = []    or   employee_list = list()
  11. for문을 돌면서, 인스턴스관리 리스트에 .append()안에 인스턴스를 생성하면서, 생성자4개를 입력해준다.
    ex> employee_list.append( 클래스( 필드[0], 필드[1], 필드[2], 필드[3]) )
    * 이 때, csv에서 받은 요소들은 모두 문자열로 가져온다. 정수 데이터인 출근시간, 퇴근시간, 시급int()로 감싸주어야 클래스에서 계산된다.
    ex> employee_list.append( 클래스( 필드[0], int( 필드[1]), int(필드[2]), int(필드[3]) ) )
  12. 인스턴스관리리스트를 확인해보기 위해
    (1) print(len())로 전체 길이를 살펴보고
    (2)  <리스트를 이용한 for문>을 통해, 세부적으로 인스턴스 안의 필드나 함수를 하나씩 확인하는데, 
    print()로 , {}\t{}\t .format( 인스턴스.필드1, 인스턴스.필드2,.., 인스턴스.함수1(), 인스턴스.함수2(),) 형식으로 한 줄로 출력해보자.

  13. csv파일쓰기위해, 위에서 인스턴스 필드/함수 세부 확인한 print문을 고치면 된다. print->write 수정시 줄바꿈을 항상기억 + 칼럼명row출력
    (1) for문 전에 open()  '파일명', 'w' 이 들어갔다. + 3번째 인자로서, newline=''을 넣어줘야, csv_writer.writerow([])후에 자동 줄바꿈이 x
    (2) for문 전에 csv_file.write( 칼럼명row \n')
        csv_writer = csv.write(f)를 통해 쓰기 변수를 생성해준다.
        첫줄(칼럼명)은 csv_writer.writerow( [ 배,열,형,태] ) 로 넣어준다. 줄바꿈은 안해줘도 자동으로 된다.
    (3) for문 안에 print-> csv_file.write csv_writer.writerow([ , , , ]) 로 고치고,  새로운 칼럼{} 만들어주고, \t 를 콤마(,)로 수정하고,    \n줄바꿈 해주기
    (4) for문 끝나면 close()


    ----- 문서화 하는 코드 -----



  14. 12강 자료를 이용해, docx형식의 양식 파일(form_save.docx)을 만든다. -> 편의성을 위해, 내용은 지운다(form.docx)
  15. [설정 > Project Interpreter ]에서 add를 통해 [python-docx]를 검색하여 모듈을 추가한다
  16. docx_practice.py를 참고하여
    • import / 양식파일을 포함한 Document객체 생성 / 제목을 넣는다
    • 제목1 수준으로 소제목을 만든 뒤, 
      본문 수준으로 리스트를 작성해보자.
      인스턴스관리 리스트를 이용한 for문으로 각 행의 정보(각 인스턴스.필드, 함수)를 뽑아내는데,
      .format을 활용하여 문장형식으로 작성해보자
  17. 제목2수준으로 하나 넣어준 뒤, table을 생성해보자
    • table객체는 document.add_table( rows=1, cols=6 )로 한 행씩 몇개의 정보가 들어가는지 더해가는 기준을 만든다.
    • table.style = ' ' 로 미리 문서양식에서 만든 사용자지정양식을 기입해 스타일을 지정한다
    • 첫 행for문 전에 미리 작성해준다. 첫 행table.rows[0].cells를 통해 첫 행들의 각 셀들리스트 변수로 받아준다.
      받은 첫 행의 각 셀들의 리스트변수[0], [1].text, .. 형식으로 접근하여 문자열형식칼럼명을 적어준다.
    • 2번째 행부터는 정보가 들어가므로, 인스턴스관리 리스트를 이용한 FOR문에서 table.add_row().cells 로 각 셀들을 변수로 받는다
      그리고 각 셀들을 리스트요소 접근방식으로 접근 하되, 마찬가지로 .text를 붙히고 str( 인스턴스.필드, 함수()) 형식으로 문자열만 오로지 대입한다.
      만약, 정수로 표현되야 한다면 str()안에 int()로 감싸준다
  18. 저장은 document.save('파일명')으로 한다.

mandoo_wage_calculator.py에서는 employee.py의 Employ클래스를 가져다 쓰고있는 상태였다.

  1. 먼저 from docx import Document
  2. Document('양식.docx')로 변수를 생성해주는데, 인자에는 양식.docx를 지정해준다.
    동시에, 까먹지 않도록, document.save('저장할 파일명.docx')를 지정해준다.
  3. 그 사이에다가 document.add_heading('', 0)을 통해 제목(0)을 작성해주고, 확인해보자
    image_thumb5
    image_thumb8

  4. 출근한 직원인스턴스관리 리스트를 이용해 for문을 이용해 뽑아보자.
    - '{}님은 {}시 출근, {}시 퇴근'.format( 인스턴스.필드, ~~) 형태로 문장형태로 작성할 수도 있다.
    image_thumb14

    image_thumb15
    image_thumb22
    image_thumb24

  5. docx_practice.py에서 연습했던 테이블작성 코드를 가져와서, 근무시간, 일당을 포함한 테이블을 작성할 수 있다.
    * 자료가 담긴 인스턴스들을 관리하는 employee_list를 이용한 for문에서,  각 인스턴스.필드들을 -> 각 셀에 대입해주는데
    각 셀 접근[n].text  = str( 인스턴스.필드) 형식으로 문자열만 입력 가능하다!
    image_thumb30
    image_thumb32

  6. 시급과 일당 같은 경우, 정수로 표현되어야 하므로, str()안에 int()로 변환시킨다.
    image_thumb34
    image_thumb40


  7. 이제, input이 되는, employee_list.csv 파일을 수정하여서 바뀌는 상황을 살펴보자.
    1. employee_list.csv 에 row 추가
      image_thumb45

    2. 파이참에서 프로젝트 실행
      image_thumb49


    3. 자동으로
      (1) 근무시간 계산(노동법 고려) 과 일당 계산한 csv파일 생성 ( employee_result.csv)
      image_thumb51
      (2) 자동으로 MS WORD의 docx문서 생성( mandoo_wage.docx)
      image_thumb58

docx_practice.py
form.docx : docx문서 양식파일(내용 없음)
form_save.docx : docx문서 양식파일(양식 내용 보존)

python-docx 공식 사이트

설치

구글에서 [ python-docx ]를 검색해서 공식홈페이지 들어간 뒤 설치해보자.

image

  • csv모듈과는 다르게, 아나콘다 설치를 하더라도 자동으로 설치되지 않기 때문에 수동으로 설치를 해줘야한다.
  • 방법은 2가지가 있다.
    (1) 파이썬 프롬프트(터미널)에서 pip(핍)을 이용하는 방법이 있다. (생략)
    (2) 파이참의 Setting > Project : mandoo_management > Project interpreter 를 이용하는 방법이 있다.(실습)
    image
    image

  • Project Interpreter에 가면, 해당 프로젝트의 환경설정이 모두 나타나있다.
    우측의 초록색 플러스 버튼을 누른 뒤, [ python-docx ]를 검색한 후, 왼쪽하단의 Install Package를 눌러 설치하자.
    - 닫아보면 Interpreter에 설치된 것을 확인할 수 있다.
    *다른 프로젝트에서는 설치되지 않는 것을 확인해보았음.
    image
    image
    image

  • mandoo_management프로젝트에서 새로운 파이선 파일 docx_practice.py를 만들고 공식문서의 import부분을 복사해오자.
    image
    image


사용법

  • 클래스처럼 Document()를 document변수에 넣는다.
  • document.add_heading( '제목명' , 0)을 통해서 제목을 넣을 수있다.
  • document.save('파일명')을 통해 docx파일로 저장한다.
    image


  • 제목 양식인 2번째 인자를 바꿔가며 작성해보자.
    imageimage

  • 본문은 .add_paragraph('')함수로 추가할 수 있다.
    image
    image



docx의 글자체 등 스타일은 미리 양식을 만들어 놓아야한다.

  • add_heading( '',0) ->  MS WORD의 [제목]
  • add_heading( '',1) ->  MS WORD의 [제목1]
  • add_heading( '',2) ->  MS WORD의 [제목2]
  • add_heading( '',3) ->  MS WORD의 [제목3]

  • add_paragraph('') -> MS WORD의 [표준]

이므로 미리 양식을 지정해놓고 , 프로젝트 폴더내 위치시켜서, Document('파일명')선언시 빈칸이 아닌, '파일명'을 넣어준다.

양식을 만드는 방법은

  1. form.docx를 프로젝트내에서 생성하고
  2. 해당 양식에서, 원하는 스타일로 바꾼 뒤
  3. 블록으로 선택해놓고
  4. 우측상단의 스타일에서 해당 [ 양식 >우클릭> 선택영역과 일치하도록 제목 업데이트 ]
  5. 필요한 모든 것 위와 같은 방법으로 (2~4) 다 바꾼 뒤, 저장
  6. document = Document( 'form.docx') 폼 양식 지정
  7. 파일 확인후, 맨 처음의 양식 지우기
    image
    image
    image
    image
    image


새로운 스타일을 만든 다음, 파이썬-docx에서 지정해줄 수 있다.

제목이 아닌 add_paragraph로 들어간다.

  • 마찬가지로, 동그라미 스타일로 작성후 ->
  • 블록지정 한 다음,
  • 스타일메뉴 중 새로운 스타일을 클릭하여, 이름을 지정해준다.
  • 파이썬에서는 document.add_paragraph( ' 내용 ', style = '스타일명' ) 으로 스타일인자를 추가시켜주면 된다.
    image
    image
    image
    image



테이블도 만들어보자. 공식문서에서 일단 가져오자.

  • 공식문서의 테이블 부분을 복사해서 가져온다.
    - 이 때, for문의 in리스트인 recordset이 빨간줄이 뜬다. 위에서  문서상에도 선언을 안해놨다..
    image
    image

  • 코드를 확인하니,
    - table = document.add_table( row =1 , cols = 3)로 table을 하나 생성하여 변수에 담는다. row는 1줄 칼럼은 3개
    - hdr_cells = table.rows[0].cells 을 통하여 칼럼명row0번째row모든 cell들에 대한 변수를 생성한다.
    - hdr_cells[0], [1], [2] .text 를 통해서, 해당row의 각 cell들에 접근하여 문자열로 데이터를 집어넣는다.
  • 리스트는 없으므로, for문을 지우고, 안에 내용은 띄워쓰기를 삭제시켜서 해석해본다.
    - row_cells =  table.add_row().cells 를 통해    새로운 row를 하나 추가하고, 동시에 그 row의 모든 셀을 받도록 한다.
    - 해당row의 0번째, 1, 2번째 셀들에 접근하여 문자열 데이터를 집어넣는다.
    image
    image


표도 스타일을 미리 정해줄 수 있다.

  • 아무표나 작성한 뒤
  • 더블클릭하고 -> 표 스타일 메뉴 -> 표스타일 새로 만들기
  • 스타일 이름 지정해주고, 양식 고르기
  • 파이썬에서 table 변수 생성한 다음 줄에,
    table.style
    = '스타일명' 을 통해 표 스타일 지정해주기

    image
    image
    image

    image



form.docx에서는 이미 양식이 저장되어 있기 때문에,

docx파일 생성후, 양식 지우기를 하기 싫다면,

form.docx내용을 다 지워놓으면 된다.

  • form.docx의 내용을 다 지우자. 양식은 저장되어있다.
  • 그리고 나서 다시한번 demo.docx를 생성해보자.
    - 앞에는 양식이 그대로 나와서 지워줬던 것을 안지워도 된다.

imageimage
image

정의

모듈은 쉽게 말해 남들이 만들어 놓은 것을 갖다 쓰는 것을 말한다.

직접 만드는 것이 아니라.. 갖다 쓰는 것! import를 통해 갖다 쓴다.

다른 사람들의 솔루션을 활용하여 개발속도, 신뢰도 향상을 꾀할 수 있다.

image

  • 모듈, 라이브러리 : 연장이 되어, 간단한 프로그램을 만들 수 있다.
  • 프레임워크 : 좀 더 큰 개발, 웹/기계학습 등을 체계 안에서 개발할 수 있다


CSV 모듈

기존 9강. mandoo_management 프로젝트를 그대로 사용한다.
csv_read_practice.py

먼저 csv모듈을 이용한 읽기 방법

  • 사용방법 : import csv
    *csv모듈은 아나콘다 설치시, 이미 미리 설치되었으므로, import만 해주면 된다.
  • csv파일 여는 법/닫는 법은 기존과 똑같다.
  • 라인을 읽는 readlines()대신 -> csv.reader(f)로 읽는다. 읽은 lines를 for문을 통해 출력해보자.
    - 이전에서는 읽은 csv를 콤마기준으로 짜르는 .split(')의 과정이 필요없게 된다. 자동으로 나누어져 있다.
    image


기존의 프로젝트를 바꾸어 개선해보자.

  1. 먼저 import csv
  2. lines = f.readlines() -> csv.reader(f)
  3. for문 안에서,
    info = line.split(',') -> 삭제
    info[n]->line[n]으로 변경
    image


csv모듈을 이용한 쓰기 방법

csv_write_practice.py

  • 여는법/닫는법은 동일하나, 열 때, 마지막인자에 newline=''을 비워주는 인자를 넣어줘야 작성후 한줄바꾸기가 없어진다.
  • f.write('{}, {}, {}'.format(, , )의 방식에서 ->
    (1)  (읽기처럼)변수를 한번 거쳐준다. csv_writer =  csv.write(f)
    (2)  변수를 이용해서, csv_writer.writerow(  [리,스,트,형,태] ) 만 넣어주면,   '{},{},{}\n'.format 줄바꿈을 하지 않아도 된다.
    image
    image
    *csv쓰기를 할 때, f = open시 3번째 인자 newline=''을 주지않으면, writerow 이후 줄바꿈1줄이 자동으로 시행된다.

  • csv쓸 때, open시 newline=''을 주면, 자동으로 줄바꿈이 생기지 않는다.
    image
    image

기존 프로젝트를 개선해보자.

  • f_output = open('employee_result.csv', 'w' , newline='') 3번째 인자 추가
  • 읽기처럼 쓸 때도, 쓰기변수 생성 : csv_writer = csv.write(f) 
  • 기존의 f.write('이름, 출근시간, 퇴근시간, 시급, 근무시간, 일당\n') -> 쓰기변수로 writerow함수 + 내용물은 배열로 + 줄바꿈\n은 삭제
    csv_writer.writerow(['이름', '출근시간', '퇴근시간', '시급', '근무시간', '일당'])
  • for문안에서는, f.write( ' {}, {} \n '.format( , ) )했던 것을 주석처리[ ctrl + / ] ->
    csv_writer.writerow( [
                                              배열로 각 인스턴스.필드, 함수 채워줌
    ])
    image
    image





내가 만든 파이썬 파일 분할하고 import하기

employee.py

내가 만든 class 정의 부분과 <---> 본격적인 f = open 읽기 ~ 작업 ~ 쓰기 까지를 분리하고 싶다.

  1. 새로운 파이썬 파일을 만들자. employee.py
  2. class Employee: 정의부분만을 잘라내서 붙힌다.
    image
  3. 기존의 mandoo_wage_calculator.py 에서는 클래스가 빠져나갔을 것이므로, 클래스의 인스턴스 생성시 빨간색 오류가 뜰 것이다.
    from employee import Employee
    - from같은 프로젝트내 py파일 employee.py를 불러오고
    - import는 py파일안의 클래스를 가져온다는 뜻이다.
    image
    image
    image


practice.py(깃허브) in csv_to_python_to_csv_practice 프로젝트

왼쪽과 같은 단순 데이터 csv->

파이참에서 클래스의 인스턴스생성 인자로 받아 수식을 함수로 정의->

오른쪽과 같은 수식계산완료후 csv

image_thumb70


  1. 엑셀형태로 구성하고 싶은 데이터가 있다고 가정하고,  칼럼들을 클래스의 필드로 만든다.
  2. 상수를 제외하고, 생성자로 정의하여 클래스( , , , )로 인스턴스생성과 동시에 입력받도록 해준다.
    *만약, 상수로 먼저 선언하고서, 인자로 받아도 되고, 안받아도 되도록 설정하려면,
    (1) 생성자의 인자로서 wage_per_hour = None으로 default로 둔다.
    (2) 기본적으로 self.wage_per_hour = wage_per_hour는 바로 입력하지 않고,
    (3) if wage_per_hour: 를 통해 default인 None이 아닌 값이 넘어와서 True를 가질 때,
         상수였던 필드(wage_per_hour = 7530) 에 self.wage_per_hour = wage_per_hour를 대입하도록 한다.
      image_thumb5

  3. 칼럼 중에 함수식이 필요한 것은, 클래스 내부의 함수로 정의하여 self.필드들을 이용해서 (return에다가) 계산식을 만든다.
    ex> 퇴근시간 - 출근시간 = 근무시간
  4. 만약, 함수식 계산을 한 칼럼에 또 함수식을 써야하는 경우에는
    클래스에 정의된 함수식을 또 호출하는 함수를 생성하면 된다. 필드와 마찬가지로 return에다가 self.함수()로 호출해서 계산식을 만든다.
    ex> 일당 = 근무시간(퇴근시간 - 출근시간) * 시급
    ---------------------------------------------------------------------------------------------------------------------------------

  5. 이제 인스턴스 인자로 들어갈 데이터들을 엑셀파일에서 받아오기 위해, CSV (쉼표로분리)로 프로젝트내에 다른이름 저장
  6. f = open('파일명.csv', 'r')를 통해 열고 / f.close()도 미리 같이 작성
    f.readlines()를 통해 각 row을 list로 받음 -> (리스트이므로) for문을 통해 개별 출력시켜본다.
  7. 첫 줄은 칼럼명row이므로, 2번째줄 부터 읽기 위해선, while문과 비슷하게
    i =0 작성 -> for안에서 읽어진 lines를 i > 0부터 콤마로쪼개는 작업 등등을 하도록 하고, for문 마지막에 i += 1를 달아준다.
  8. 각 리스트는 콤마(,)를 통해 4개의 요소가 붙어있으므로 .split(',')를 통해 다시 리스트로 쪼개어 받는다.
    4개로 쪼개진 요소를 담는 list를 for문을 돌면서 출력시켜본다.
    4개 요소를 담고 있는 리스트는 리스트[0], [1], [2], [3] 형태로 개별접근이 가능해진다.
  9. 이제 for문을 돌면서 4개의 요소를 입력받아 생성될 인스턴스들을 관리할 리스트를 for문전에 만든다.
    ex> employee_list = []    or   employee_list = list()
  10. for문을 돌면서, 인스턴스관리 리스트에 .append()안에 인스턴스를 생성하면서, 생성자4개를 입력해준다.
    ex> employee_list.append( 클래스( 필드[0], 필드[1], 필드[2], 필드[3]) )
    * 이 때, csv에서 받은 요소들은 모두 문자열로 가져온다. 정수 데이터인 출근시간, 퇴근시간, 시급int()로 감싸주어야 클래스에서 계산된다.
    ex> employee_list.append( 클래스( 필드[0], int( 필드[1]), int(필드[2]), int(필드[3]) ) )
  11. 인스턴스관리리스트를 확인해보기 위해
    (1) print(len())로 전체 길이를 살펴보고
    (2)  <리스트를 이용한 for문>을 통해, 세부적으로 인스턴스 안의 필드나 함수를 하나씩 확인하는데, 
    print()로 , {}\t{}\t .format( 인스턴스.필드1, 인스턴스.필드2,.., 인스턴스.함수1(), 인스턴스.함수2(),) 형식으로 한 줄로 출력해보자.

  12. csv파일쓰기위해, 위에서 인스턴스 필드/함수 세부 확인한 print문을 고치면 된다. print->write 수정시 줄바꿈을 항상기억 + 칼럼명row출력
    (1) for문 전에 open()  '파일명', 'w' 이 들어갔다.
    (2) for문 전에 csv_file.write( 칼럼명row \n')
    (3) for문 안에 print-> csv_file.write 로 고치고,  새로운 칼럼{} 만들어주고, \t 를 콤마(,)로 수정하고,    \n줄바꿈 해주기
    (4) for문 끝나면 close()

mandoo_wage_calculator.py

기존에 만들었던 엑셀형태의 데이터를 -> 클래스를 통해 인스턴스로 칼럼들을 채우도록하고 -> 리스트로 관리하기를 다시 반복해보자.
image


그런데 인스턴스를 계속 파이참에서 하나씩 생성하기는 좀 그렇다.

엑셀을 사용해서 생성해보자.

  • 엑셀에서, 칼럼명 없이, 생성자 순( name, work_start, work_finish, wage_per_hour)으로 작성하자.
    image

  • 다음으로, 저장을 할 때, 파이참프로젝트 폴더내 csv(쉼표로분리)로 저장하자.
    *csv utf-8(쉼표로 분리)는 아니다.
    파이참이 utf-8을 선호를 하지만, csv에서 만큼은 한글관련해서 깨져버리는 것을 확인했었다.
    image

  • 이제 파이참 프로젝트 내에 생성된 csv파일을 읽어보자.
    - 이전에는 파일쓰기를 해서 -> open('파일명', 'w') 였지만, 이번에는 파일읽기 이므로, open('파일명', 'r') 이다.
    - 까먹을 수 있으니,  f = open()작성과 함께 밑에는 f.close()도  미리 작성해주자.
    - 잘은 모르겠지만, 파일을 여는 f라는 변수의 타입을 확인해보자. 어떠한 클래스의 하나이며, 그래서 f.write함수도 쓸 수 있었다.
    image

  • csv파일을  쓸 때에  f.write()가 있었다면,
    csv파일을 읽을 때는 f.readlines()를 이용한다. 문자열의 .join('')처럼, csv을 모두 읽어들인 다음, list를 반환한다.
    - 읽어들인 list를 len()으로 길이를 확인해보면, 엑셀에서 작성한 row수과 같다.
    image

  • open 'r' -> readlines -> lines변수에 읽어들인 리스트들for문을 이용하여 하나씩 불러내서 확인해보자
    image


각 리스트안에는 인스턴스 생성할 때 필요한 인자들이 콤마를 통해 붙어있다.

우리는 콤마로 구분된 놈들을 4개로 다시 나누어서, 인스턴스생성시 인자로

들어가도록 해야한다


  1. 먼저, for문을 들어가기 전에 인스턴스를 관리할 빈 리스트를 생성해 놓는다.
    image

  2.  for문 안에서는line.split(',')를 이용해 콤마를 기준으로 각 라인을 4개로 쪼갠 뒤, info라는 리스트변수에 담아놓고, print로 확인해보았다.
    image


  3. 제대로 각 line들이 4개로 쪼개어진 것을 확인했다면,
    info라는 리스트의 각 요소를 [0], [1], [2], [3]으로서 접근하여 인스턴스를 생성과 동시에 append해준다.
    image


  4. 그런데, 첫번째 인스턴스인 employ_list[0].worked_hours를 print해보면 에러가 난다.
    - 대입은 되긴 되나,, 사실 name을 제외하면 다 정수이다.
    - 파일을 읽었을 때는, 모두 str로 인식되기 때문이다. ( csv의 15 -> 파이참 1과 5가 붙어있는 문자열로 인식)
      그렇기 때문에, 함수안의 계산식 str- str 의 에러가 나는 것이다.
    - for문 속에서, name인자 위치의 info[0]을 제외하고 전부 int(  )함수로 감싸주어, 정수로 만들어주자.

    image


    image

  5. 확인을 위해 인스턴스 리스트(employee_list)를 출력시켜보자.
    (1) 전체적으로는 len()함수로 길이를 확인한다.
    (2) 세부적으로는 for문을 돌면서, 각 인스턴스의 필드들을, print( , , , )로 한번에 확인한다.
    image



인스턴스들의 인자들을 받아들이기 위해서,

첫 줄 부터 데이터를 입력하여 칼럼명row가 매우 아쉽다.

  • 만약 첫줄에 칼럼명을 입력하고 실행한다면 에러가 난다.
    - 에러라인으로 가보면, 출근시간 인자에 int(   '숫자'  )  가 아닌  int(  '출근시간'  ) 으로서,  문자열을 정수로 바꿔버렸기 때문
    image
    image


엑셀(csv)의 2번 째 줄 부터 읽는 방법은?

  1. while문 처럼, for문 전에i = 0이라는 변수를 들어오기 전에 미리 생성하고,
  2. for문 안에서는, if i > 0  일때만,  쪼개어서, 인스턴스 생성하는 작업을 하도록 하고
                      if문 끝나는 곳에서 i += 1 을 넣어준다.
    image



클래스의 인스턴스를 이용해 생성된 엑셀 형태의 데이터에

파일쓰기를 통해 근무시간과 일당 칼럼을 더해서 csv로 배출해보자.

  • 인스턴스 리스트(employee_list)를 세부적으로 확인하기 위해 for문안에서 각 인스턴스의 필드를 print(, , , )했던 것을
    --> 그대로 파일쓰기에 활용한다.
    *앞에 빠진 시급도 채워넣었다.
  • print-> f.write로 고칠 때csv파일이므로 '문, 자, 열'을 콤마로 나눠야하므로 '{}, {}, {}'.format( , , )의 형태가 필요하다
    • f = open() 한 다음 f.write( ' 첫,줄,칼,럼,멍\n')
    • '{}, {}, {}, {}, {}, {}\n'.format() 을 앞에 붙혀준다. 그리고 각 요소들이 채워지도록 한다
    • \n의 줄바꿈도 빠지면 안된다 (print에서는 줄바꿈 자동, f.write에서는 직접 해줘야한다)
      image


이제 employee_list.csv 로 읽고 - > 파이썬에서 데이터를 추가처리( 근무시간 , 일당 계산) -> employee_result.csv 파일로 쓰기 과정을 가진다.

즉, 읽는 파일을 수정하면 쓰는 파일도 변경된다.

  • 읽는 파일 수정전 결과파일
    image

  • 읽는파일 수정후 결과 파일
    image


노동법에 의해 4시간마다 30분 break_time 가지는 것을 고려한

근무시간 계산 함수를 수정해보자.


image

프로젝트명 : mandoo_management

문자열 클래스에서 제공하는 함수들 연습

practice_string.py

  • split()함수는, 구분자를 인자로 입력받아서 문자열을  구분자로 쪼갠 다음  list형태로 반환한다.
    - 문자열을 .split(',')을 이용하여 쪼갠 다음, 타입을 확인했더니 list타입이다.
    - 쪼개어져 리스트가 된 문자열을 for문으로 출력했더니 2개의 문자열이 나왔다.
    image

  • 콤마가 아닌 공백(space)를 구분자로 주고 쪼개어보자.
    - message.split(' ')
    image


  • join()함수는 ' '.join(배열)의 형태로 함수앞에서는 사이를 붙혀주는 붙힘자를 받아, 쪼개어진 배열(리스트)를 하나로 합쳐주는 함수다.
    - 타입을 확인하보면 str 클래스가 된다.
    image


  • replace( , ) 함수는 2개의 인자를 받아서  ( ' 바꾸고싶은 문자열 ' ,  ' 바꿀 문자열 ' ) 형태를 가진다.
    - 공백을 물결표시로 바꾸려면 인자를 ( ' ', '~') 형식으로 주면된다.
    - 한글 '이'를 숫자'2'로 바꾸고 싶드면 ( '이', '2') 형식으로 주면 된다.
    image
    image

  • upper()와 lower() 함수는 전부 대문자 혹은 전부 소문자로 바꿔준다.
    *참고) 문자열 시작을 ' 로 했는데, 문자열 중간에 '를 쓰고싶다면 앞에 \만 붙히면 된다.
    image


  • startswith()함수는 인자로 받은 문자열로 시작하는지 안하는지 boolean형태로 뱉어낸다.
    마찬가지로 endswith()
    함수도 받은 인자로 끝나는지 안나는지 boolean형태로 뱉어낸다.
    - 끝날 때, 공백까지 같아야한다.
    image
    image
  1. 엑셀형태로 구성하고 싶은 데이터가 있다고 가정하고,  칼럼들클래스의 필드로 만든다.
  2. 상수를 제외하고, 생성자(def __init(self, 받,을,변수):로 정의하여    클래스명( , , , )로 인스턴스생성과 동시에 입력받도록 해준다.
    *만약, 상수로 먼저 선언하고서, 인자로 받아도 되고, 안받아도 되도록 설정하려면,
    (1) 인자로서 wage_per_hour = None으로 default로 둔다.
    (2) 기본적으로 self.wage_per_hour = wage_per_hour는 바로 입력하지 않고,
    (3) if wage_per_hour: 를 통해 default인 None이 아닌 값이 넘어와서 True를 가질 때,
         상수였던 필드(wage_per_hour = 7530) 에 self.wage_per_hour = wage_per_hour를 대입하도록 한다.
      image

  3. 칼럼 중에 함수식이 필요한 것은, 클래스 내부의 함수로 정의하여 self.필드들을 이용해서 (return에다가) 계산식을 만든다.
    ex> 퇴근시간 - 출근시간 = 근무시간
  4. 만약, 함수식 계산을 한 칼럼에 또 함수식을 써야하는 경우에는
    클래스에 정의된 함수식을 또 호출하는 함수를 생성하면 된다. 필드와 마찬가지로 return에다가 self.함수()로 호출해서 계산식을 만든다.
    ex> 일당 = 근무시간(퇴근시간 - 출근시간) * 시급

  5. 본격적으로, 데이터를 관리하기 위해서, 빈 리스트를 생성하자.
    ex> employee_list = []    or   employee_list = list()
  6. 빈 리스트에다가 인스턴스를 생성함과 동시append로 리스트에 추가 해주자.
    ex> employee_list.append( 클래스( 필드1, 필드2, 필드3, 필드4) )
          employee_list.append( 클래스( 필드1, 필드2, 필드3, 필드4) ) ...
  7. 리스트에 채워진 인스턴스를  <리스트를 이용한 for문>을 통해, 하나씩 인스턴스를 받아서 .필드 or .함수()에 접근하여
    print()로 확인하는데, {}\t{}\t .format( 인스턴스.필드1, 인스턴스.필드2, ,) 형식으로
    한 줄로 출력해보자.
  8. csv파일쓰고 싶다면,
    (1) for문 전에 open()  '파일명', 'w' 이 들어갔다.
    (2) for문 전에 csv_file.write( 칼럼명 첫줄 \n')
    (3) for문 안에 print-> csv_file.write 로 고치고,   \t 를 콤마(,)로 수정하고,    \n줄바꿈 해주기
    (4) for문 끝나면 close()


+ Recent posts