내일배움캠프 2주차 Weekly I Learned

정형빈·2022년 9월 13일
0

WIL

목록 보기
2/15

내일배움캠프 2주차 회고

2주차 시간표

2주차는 금요일부터 추석 연휴이기 때문에 일과가 더 짧게 느껴졌다. 이번 주에 한 것을 되짚어보면 파이썬 문법 실시간 강의 진행 및 과제, 효율적인 코딩 공부법 특강, 협업을 위한 GIT 활용 기초 원격 강의, Git 활용을 위한 특강, 그리고 매일 해야되는 알고리즘 실습 문제풀이 등이 있었다.

파이썬 문법 실시간강의

-이창호 튜터님

저번주와는 다르게 이번주부터는 원격강의가 아닌 실시간 화상 강의로 튜터님이 직접 우리에게 파이썬 문법 강의를 해 주셨다.

코드 컨벤션

코드 컨벤션이란 코드를 개발하다보면 타인이 작성한 코드를 알아 볼 수 없는 경우가 빈번하게 발생하기 때문에 이를 방지하기 위해 스타일을 통일하는 '약속' 같은 것이다. 코드 컨벤션은 개발하는 언어에 따라서 다르기 때문에 본인이 개발에 사용하는 언어에 따라 코드 컨벤션의 스타일도 바뀌는 것에 유의해야 한다.

파이썬에서는 네이밍 컨벤션으로 변수 / 함수를 네이밍할 때는 Snake 표기법을, Class를 네이밍할 때는 Pascal 표기법을 사용한다.
Pascal 표기법은 각 단어를 대문자로 구분하는 표기법이고(PythonIsVeryGood)
Snake 표기법은 각 단어를 언더바(_)로 구분하는 표기법이다.(python_is_very_good)

변수 선언하기

  • 선언할 변수 명 = 변수에 넣고 싶은 값 과 같은 형태로 변수를 선언할 수 있습니다.
    • description = “변수를 선언 하는 방법입니다.”
  • 변수를 선언할 때에는 두 개 이상의 변수를 한번에 선언할 수도 있습니다.
    • a, b, c = 1, 2, 3
  • 변수의 가장 첫 번째 문자에는 숫자를 사용할 수 없습니다.
  • I(대문자 i), l(소문자 L), O(대문자 o)와 같은 문자를 단일 문자 변수로 선언하는 것을 권장하지 않습니다. (폰트에 따라 I, l, 1 혹은 0, O 문자를 구분하지 못할 수 있기 때문입니다.)
  • list, type, class와 같이 python에서 이미 선언 되어 있는 단어를 변수 명으로 선언하고 싶을 때는 중복을 피하기 위에 변수 명 뒤에 언더바( _ )를 추가하여 선언합니다.
    • list_ = [1,2,3,4]

자료형의 종류와 특징

  • integer
    • 정수 자료형
    • number = 10 과 같이 사용되며, 정수 자료형이기 때문에 소수점은 지원하지 않습니다.
    • 사칙연산과 같은 계산식을 지원합니다.
  • float
    • 실수 자료형
    • number = 10.3 과 같이 사용되며, 소수점을 지원합니다.
    • integer와 마찬가지로 사칙연산과 같은 계산식을 지원합니다.
  • string
    • 문자열 자료형
    • hello = "world!!" 와 같이 사용되며, 변수에 문자를 저장할 수 있습니다.
    • 파이썬에서는 따옴표( ‘ )와 쌍따옴표( “ )를 구분하지 않습니다.
  • list
    • numbers = [1, 2, 3, 4, 5] 와 같이 사용되며 1개 이상의 값을 한 변수에 담아 사용할 수 있습니다.
    • list 요소에는 integer, float, string, dictionary, list 등 다양한 자료형을 담을 수 있습니다.
  • tuple
    • numbers = (1, 2, 3 ,4, 5)와 같이 사용되며 리스트와 동일한 방법으로 선언할 수 있습니다.
    • tuple 자료형은 값을 선언한 후 요소들을 변경하거나 삭제할 수 없습니다.
  • set
    • numbers = {1, 2, 3, 4, 5}와 같이 사용되며 리스트와 동일한 방법으로 선언할 수 있습니다.
    • set 자료형은 중복 된 데이터를 담을 수 없습니다.
  • dict
    • members = {”1”: “lee”, “2”: “park”, “3”: “kim”} 과 같이 사용되며 {key: value} 쌍으로 이루어져 있습니다.
    • key에는 integer, float, string 자료형이, value에는 integer, float, string, dictionary, list 등 다양한 자료형을 담을 수 있습니다.
  • boolean
    • flag = True 와 같이 사용되며 True 혹은 False 두 값만 사용할 수 있습니다.
    • 일반적으로 분기문( if ) 혹은 합격 / 불합격과 같은 상태를 나타낼 때 사용됩니다.

자료형 활용하기

  • 사칙연산

    • 파이썬에서는 integer(정수 자료형)와 float(실수 자료형) 자료형에서 활용할 수 있는 다양한 종류의 사칙연산을 지원하고 있다.(사칙연산,제곱,나누기의 몫,나누기의 나머지 등등)
    • 변수에 값을 할당하고 수식을 사용할 때는 연산 축약 문법을 활용할 수 있다.
      # num에 정수를 할당하고, 할당된 값에 1을 더하고 싶을 때
      
      # case 1
      num = 10
      num = num + 1
      # result: 11
      
      # case 2
      num = 10
      num += 1
      # result: 11
      
      # case 1, 2 모두 동일한 동작을 하고 동일한 결과를 내는 수식이다.
      # 이와 같은 축약식은 + 이외에 다른 수식에서도 사용할 수 있다.
      
      num -= 3  # num = num - 3
      num *= 3  # num = num * 3
      num **= 3 # num = num ** 3
      num /= 3  # num = num / 3
      num //= 3 # num = num // 3
      num %= 3  # num = num % 3
  • string

    • 문자열에서는 + 와 * 연산 기호를 지원한다.
    • python 버전이 3.6일 경우 fstring을 활용해 문자열과 변수를 함께 다룰 수 있다.
  • list

    • list 자료형 선언 시 list 안에 들어있는 각 요소는 0부터 시작해 순서대로 index 번호를 가지며, indexing과 slicing 기능을 활용해 활용해 원하는 값을 가져올 수 있다.
    • list 자료형에서는 값을 원하는대로 추가(append), 수정, 삭제(remove)할 수 있다.
    • list 자료형의 요소에는 숫자나 문자 이외에도 다양한 자료형을 사용할 수 있다.
    • len() 함수를 사용해 list의 길이를 구할수 있다.
  • tuple

    • tuple 자료형 또한 list와 동일한 indexing 기능을 활용할 수 있다.
    • tuple 자료형에서는 요소의 값을 수정하거나 삭제할 수 없으며, 추가만 가능하다.
    • tuple 자료형 또한 list와 동일하게 요소에 다양한 자료형을 사용할 수 있다.
    • len() 함수를 사용해 tuple의 길이를 구할수 있다.
  • set

    • set 자료형은 중복 된 값을 포함하지 않고, indexing과 slicing 기능을 지원하지 않는다.
    • len() 함수를 사용해 set 자료형의 길이를 구할 수 있다.
  • dictionary(중요!!)

    • dictionary 자료형은 key: value로 구성되며, key를 사용해 value를 가져올 수 있다.
    • 만약 존재하지 않는 key로 value를 가져오려 시도할 때에는 에러가 발생한다.(.get을 사용한다면 key가 없을 때 사용될 값을 지정하여 에러가 발생하지 않도록 할 수 있다.)
    • dictionary 자료형에서는 자유롭게 값을 추가, 수정, 삭제(del)할 수 있다.

자료형 변환

  • python에서는 특정 값의 자료형을 조건이 맞을 경우 자유롭게 변환할 수 있다.
    • string → int
    • list → tuple → set
    • any → string
    • 이외에도 다양한 자료형들을 변환할 수 있다.

함수

  • def 함수명(): 과 같은 형태로 선언할 수 있다.
  • 함수를 선언할 때에는 인자를 받고, 원하는 로직을 수행한 후 결과를 리턴해 줄 수 있다.

다른 파일에 있는 코드 import해서 사용하기

  • import “파일명”을 사용해 다른 파일에 선언된 코드를 가져와서 사용할 수 있다.
  • from을 사용하면 더 다양한 방법으로 파일을 import할 수 있다.
    • from a import * : a 파일에 있는 모든 함수를 import 한다.
  • 다른 폴더에 있는 파일을 import하는 것도 가능하다
    • from folder import b : 폴더안에 있는 b를 import 한다.
  • 다른 파일의 변수 또한 함수와 동일한 방법으로 from / import를 사용할 수 있다.
  • from과 import의 이해를 돕기 위한 팁
    • python에서 다른 파일에 있는 코드를 사용할 때에는 어디서(from) 어떤(import) 것을
      가져와서 사용할지 지정해 줘야 한다.

값 비교하기

  • 다양한 비교 연산자들을 사용해 값을 비교하고, 결과가 True인지 False인지 판단할 수 있다. 비교 결과는 조건문에서 많이 사용된다.

조건문

  • 특정 비교 결과 혹은 값이 True 혹은 False일 경우 실행 될 로직을 정의한다.
  • and, or을 사용해 2개 이상의 조건을 복합적으로 사용할 수 있다.
  • 비어있는 string, list 등은 분기문에서 False로 판단한다.
  • 특정 값이 True인지 False인지는 bool() 함수를 사용해 확인할 수 있다.

반복문

  • while 혹은 for문을 사용해 반복문을 사용할 수 있다.
  • for문
    • list, tuple, set 자료형의 요소들로 반복문을 사용할 수 있다.
    • enumerate()를 사용해 반복되는 요소가 몇번째인지 확인할 수 있다.
    • dictionary 자료형의 key 혹은 value로 반복문을 사용할 수 있다.
    • range() 함수를 활용하면 원하는 만큼 반복문을 사용할 수 있다.
    • continue를 활용해 특정 상황에서 아무런 동작도 하지 않고 넘어갈 수 있다.
    • break를 활용해 특정 상황에서 반복문을 중지시킬수 있다.
  • while문
    • 사용 방법은 for문과 크게 다르지 않지만, 조건을 다루는 방식에 차이가 있다.
    • 대부분의 경우 while문은 반복 할 횟수가 정해져 있지 않을 때 사용한다.

자주 사용되는 모듈 및 패턴

  • type() / 값의 자료형 확인해보기
  • split() / string을 list로 변환하기
  • join() / list를 string으로 변환하기
  • pprint() / 코드 예쁘게 출력하기
  • random / 랜덤한 로직이 필요할 때
  • time / 시간 다루기
  • datetime / 날짜 다루기

지금까지 배운 문법들을 활용해 로또 번호를 뽑는 코드 작성하기

import random
lotto = set() # lotto 변수를 set 자료형으로 선언

def get_lotto_number(count):
    result = []
    if count < 1:
        print("1 이상의 값을 입력해주세요")
    
    for _ in range(count): # count만큼 반복해서 실행
        lotto = set()

        while len(lotto) < 8: # lotto의 요소 갯수가 8 이하일 경우 계속해서 반복
            lotto.add(random.randint(1, 45)) # lotto에 1~45 사이의 랜덤 값을 입력
            
        result.append(lotto)
        
    return result

lotto_numbers = get_lotto_number(10)
print(lotto_numbers)

# result print
"""
[
    {1, 3, 4, 6, 9, 44, 18, 22, 26},
    {2, 5, 9, 11, 44, 45, 19, 23, 28},
    {1, 4, 39, 41, 16, 18, 27, 29, 31},
    {2, 5, 8, 9, 14, 20, 22, 24, 31},
    {33, 37, 6, 40, 41, 42, 19, 30, 31},
    {33, 1, 36, 8, 41, 9, 17, 24, 30},
    {5, 39, 41, 10, 12, 16, 23, 25, 26},
    {3, 35, 37, 11, 14, 17, 19, 20, 30},
    {33, 35, 3, 11, 43, 15, 16, 27, 30},
    {33, 36, 38, 6, 43, 24, 25, 30, 31}
]
"""
# 랜덤 값을 사용하기 때문에 코드를 실행할 때마다 결과는 달라진다.

이창호 튜터님이 강의해주신 강의 내용의 핵심 요약이다. 주로 기초 개념과 이론적인 측면들 위주로 강의 해주셨는데 너무 개념적인 측면이라 아직 이해가 안될거라는 설명을 덧붙이면서 강의를 진행해 주셨는데, 확실히 무슨말인지 하나도 모르겠다. 컴파일러, 인터프리터 언어, 코드 컨벤션 등 최근 한달 간 캠프를 준비하며 사전공부를 나름 열심히 했다고 생각했는데 들어보지도 못한 생소한 단어들이 계속 나오니 머리가 하얘졌다. 하지만 이 부분은 튜터님도 말씀하셨듯이 이해가 안되는게 당연한 것이니 너무 깊게 파고들지 않고 파이썬이란 이런것이다 정도로만 머리속에 넣어두기로 했다. 내가 파이썬에 대한 지식이 더 늘어서 훗날 이 WIL을 다시 보게되었을때 이걸 이해 할 수 있는 내가 되어있다면 좋겠다.

효율적인 코딩 공부법 특강

- 강민철 튜터님 특강

전공자이기 때문에 코딩에 대해 겁을 먹고있는 우리를 위해 격려의 말씀을 해 주셨는데 비전공자이기 때문에 기죽어있었던 나 자신에게 아주 큰 힘이 되었다. 그리고나서 공부법에 대한 설명을 해주셨다. 고등학교시절 수능을 공부할 때나 대학에서 학점을 따기 위해 시험공부를 할 때 처럼 공부를 하면 안된다고 하셨는데 마침 내가 그때의 학습법을 그대로 따라하고 있었기 때문에 많이 찔렸다. 아무래도 평생을 공부라고는 전부 성적을 받기위한 공부만 했기 때문에 아무래도 그 습관이 쉽게 안고쳐지는 것 같다. 오늘부터 공부 할 때 계속 이 부분에 신경쓰면서 공부를 진행해야겠다고 생각했다. 다음으로는 프로그래밍 언어 또한 '언어'이기 때문에 계속 사용해보면서 말이 되도록 하는것이 중요하다고 하셨다. 나도 너무 완성된 코드만 만들려고 하다보니 이런 점을 간과한 것 같은데 실패도 해보면서 올바른 코드를 만드는 방법을 찾아가는 것을 중요시해야겠다.

프로그래밍 언어 (언어학자 전직 X 익숙해지기 O)

프레임워크/라이브러리 (프레임워크는 기계! “사용법을 익히자”는 마음가짐으로)

프로젝트 (완벽하게, 면접관 앞에서 설명할 수 있을 정도로)

프로젝트 발전 (배포하기, 사용자 피드백 받고 유지보수하기, 테스트하기) + 코딩 테스트 대비 (개념 잡기, 그림 그리기, 코드로 옮기기)

이런 코딩 학습의 순서도 알려주시고 최종적으로는 결국 TIL 작성을 강조해주셨다. 앞으로도 TIL 작성에는 신경을 쓰도록 해야겠다.

Git 활용 기초 원격 강의

GIT이란 무엇인가?

  • Git은 버전 관리를 하는 프로그램
    • Git을 사용하여 버전 관리도 할 수 있고 무슨 작업을 했는지 히스토리도 볼 수 있다.
      기능을 완성할 때마다 작업 내역을 저장해 어떤 부분을 만들 때 에러가 발생했는지 쉽게 파악할 수 있다.
    • 프로젝트를 나누어서 작업하고 하나로 합치는 것이 편하다. 누가, 언제, 어떤 부분을 수정했는지를 한 눈에 파악할 수 있다.
    • 다른 사람이 작업한 내용을 내 파일로 덮어써버릴 수 있는데, Git을 사용하면 같은 파일명의 내용이 어떤 부분이 다른지를 자동으로 비교하고, 어떤 것을 반영할지 선택할 수 있다.

1주차 핵심 정리

  • 버전 관리: 프로젝트 상태가 변경되는 정보를 알고 있다는 것. Git 은 가장 널리 쓰이는 버전관리 도구로 commit 을 사용해 관리한다.

  • git 초기화(git initialize) : 컴퓨터에 있는 프로젝트를 Git 이 관리하는 프로젝트로 만드는 것

  • 커밋(commit) :

    • 현재 프로젝트의 상태를 저장하는 것.
    • 누가, 언제 커밋 했는지에 대한 정보와 프로젝트 변경 내용
    • 작업내역이 어떤 것인지 알아볼 수 있게 적는 메시지를 '커밋 메시지'라고 한다.
  • add (혹은 staging, 스테이징) : 커밋에 반영할 파일을 선택하는 것으로 커밋에 반영할지 안할지는 파일 단위로 선택이 가능하다.

  • commit history : 커밋 한 내역을 한눈에 볼 수 있다.

  • repo : 'Git으로 관리되는 프로젝트' 를 Git 에서는 repo(리포, repository 리포지토리의 약자) 라고 부른다.

    • 내 컴퓨터에 저장되어있는 리포지토리를 로컬 repo(local repository)라고 하고, Github 처럼 다른 곳에서 접속할 수 있는 공간에 저장되어있는 것을 원격 repo(remote repository)라고 한다.
  • push : 로컬 repo의 커밋들을 원격 repo에 반영하는 것

  • pull : 원격 repo의 커밋들을 로컬 repo 로 반영하는 것

  • clone : 원격 repo를 내 컴퓨터에 가져와서 초기 repo 세팅하는 것

  • 혼자 Git 프로젝트를 작업 할 때는 pull -> commit -> push 순으로 하는 것이 충돌을 막을 수 있어서 좋다.

2주차 핵심 정리

협업의 단계

  • 1단계 : 누가 이 작업 할 것인지 정한다. - Issue

    • issue 는 내가 할 작업, 기능 추가, 버그 리포트 등 여러 방식으로 사용할 수 있다.
      협업을 하기 위해 issue 를 만들어 누가 작업할지 정하고, 브랜치를 만들어 작업할 공간을 나눈다.
  • 2단계 : 각자 맡은 것을 작업한다. - Branch

    • 브랜치(branch)는 특정 commit 에서 갈라져나와 작업할 수 있다. 우리는 기능별로 이름을 만들어주어 브랜치에 작업해준다.
    • 작업할 브랜치로 바꾸는 것을 체크아웃(checkout)이라고 한다. 체크아웃된 브랜치에만 commit 이 반영된다.
  • 3단계 : 각자 작업을 프로젝트에 합친다. - merge

    • 브랜치의 작업 내역 commit 들을 다른 branch 로 반영(합치기)는 것을 Merge(머지, 병합)이라고 부른다.
    • 개발할 때는 기준이 되는 기본 브랜치를 정해놓고 해당 브랜치에 내용을 merge한다.
    • 브랜치명은 규칙을 가지고 잘 이름 지으면 프로젝트 관리가 쉬워진다.
    • 작업이 완료되면 작업한 브랜치는 보통 삭제한다. 그 이유는 나중에 브랜치 설정이 꼬이는 것을 방지할 수 있기 때문이다.
    • 각 작업 브랜치에서 작업할 때는 다른 브랜치의 영향을 받지 않고 독립적으로 작업할 수 있다.
  • +@단계 : 작업한 내용을 리뷰하고 최종적으로 프로젝트에 반영한다. - PR 후 merge

  • Merge conflict

    • Merge 하는 과정에서 같은 파일이 동일한 부분이 수정된 게 발견되면 Merge conflict(병합 충돌)가 발생한다.
    • Git 이 충돌을 파악할 수 있도록 파일 내용을 고쳐서 충돌 내역을 보여준다.
    • conflict 를 수정하려면 최종적으로 반영할 내역으로 고친 후에 merge commit 하면 된다.
  • 원격 repo

    • tracking 한다는 것은 로컬 repo와 원격 repo의 특정 브랜치를 연결해주는 것이다.
    • push와 pull 은 기본적으로 tracking(추적)되고 있는 브랜치를 기준으로 commit 내역을 반영한다.

3주차 핵심 정리

PR

  • PR(Pull Request, 풀리퀘스트) 는 내 작업내역을 바로 merge 하지 않고, 참여하고 있는 프로젝트에 내 작업(branch)를 merge해달라고 요청(Request) 를 먼저 보내는 것이다.

Commit 관리하기!

  • 작업하다보면 commit 메시지에 오타가 났거나 파일을 까먹고 add(staging)하는 경우가 있다.
    이 때 최신의 commit을 수정하는 것을 amend(어맨드,고치기) 라고 한다.

    • amend로는 가장 최신의 commit 만 고칠 수 있다.
  • 다른 사람들과 같이 협업하고 있다면 어떤 내용이 되돌려졌는지 기록으로 남기는 것이 중요하다. 어떤 내용을 되돌렸는지 새로운 commit을 남기는 것을 revert(리버트) 라고 한다.

    • 최신 commit 뿐만 아니라 이전에 했던 commit도 revert 로 되돌릴 수 있다.
  • reset (리셋) 은 commit 했던 작업내역을 말 그대로 리셋시키는 것이다.

    • reset 이후에 작업내역은 없어진 commit 기록과 관계가 없다.
  • stash(스태시) 는 프로젝트의 변경사항을 임시적으로 보관해둘 때 사용한다.

    • 다른 branch 로 체크아웃 하는 경우 현재 branch 의 변경사항이 사라지게 되는데 아직 작업 중이라서 commit 하지 않고 변경사항만 보관해두고 싶을 때 commit 대신 stash 를 사용한다.

의사소통편

  • commit 메세지 작성하는 규칙은 commit 메시지 컨벤션(commit message convention)!

    • 프로그래밍 세계에서 서로 조직(특정 기술을 사용하는 사람들, 회사 등)에서 합의한 규칙을 convention (컨벤션) 이라고 부른다.
  • 좋은 commit 메시지, 단위로 작성하게 되면

    • 어떤 작업을 했는지 commit history (commit log)만 보고 알 수 있다.
    • 버그를 찾을 때와 코드 고치기 쉽다.
    • 다른 사람이 코드를 리뷰할 때 편하다.
  • 보통 코드리뷰는 아래의 단계에서 많이 일어난다. 주로 PR 한 내역에서 댓글을 달면서 리뷰를 남기는 방식을 많이 사용한다.

  • 코드리뷰를 하는 이유!

    • 코드의 품질을 높일 수 있다!

    • 다른 사람의 눈으로 버그를 빠르게 발견할 수 있다!

    • 서로의 지식을 나누면서, 더 나은 방법을 찾아낼 수 있다!

      → 내가 만든 코드가 아니라 팀의 코드의 품질을 높인다!

  • 공유하거나 공개되면 안되는 파일들이 마치 이런 파일들을 없는 것처럼 무시하게 하는 설정이 바로 .gitignore이다.

  • 프로젝트의 어마어마하게 많은 파일들을 하나하나씩 다 읽어볼 수는 없으니 Github 프로젝트에서도 README.md 를 만들어 프로젝트 소개글을 적어둔다.

이 강의를 듣기 전부터 매니저님이나 튜터님들이 깃허브나 깃에 대한 언급을 많이 해주셔서 자주 사용하게 될 내용이구나하고 어느정도 인식은 하고 있었지만 막상 사용해보니 생각보다 더 중요하고 유용하게 사용 할 수 있는 내용인 것 같았다. 기초적인 내용과 이론적 측면은 여기서 배웠으니 실제로 사용하면서 완전히 익숙해 지는 것이 중요할 것이라는 생각이든다.

협업을 위한 Git 활용 강의

- 강민철 튜터님 특강

기본 명령어

특정 경로로 이동하기
$ cd <경로>

현재 디렉터리의 폴더 및 파일 보기 (숨김파일 및 폴더는 제외)
$ ls

현재 디렉터리에서 숨김파일 및 폴더까지 모두 보기
$ ls -a
$ ls -al

vi/vim 편집기

- vi/vim 편집기가 열리고 나면 바로 어떤 내용을 쓸 수 없다
- a와 i를 입력해 아래와 같이 하단에 INSERT 표시가 나와야 한다
- 입력이 끝났다면 ESC를 누른다 (하단에 INSERT 표시가 사라진다)
- :w 로 저장할 수 있다
- :q 로 (저장하지 않고) vi/vim 창을 닫을 수 있다
- :wq 로 저장 후 닫을 수 있다

버전 만들기


로컬 저장소 만들기
$ git init

스테이지에 추가하기
$ git add <파일이름> <파일이름>

현재 작업 디렉터리의 변경사항을 모두 스테이지에 추가하기
$ git add .

커밋하기 (커밋 메세지의 헤더만을 작성하기)
$ git commit -m "커밋 메세지 헤더"

자세한 커밋 메세지로 커밋하기
$ git commit

스테이지에 추가와 커밋 동시에 하기 (Tracked File에 한해 사용 가능)
$ git commit -am "커밋 메세지 헤더"

버전 조회하기

현재 커밋들의 목록 조회하기
$ git log

현재 커밋들의 목록 한 줄로 조회하기
$ git log --oneline

현재 커밋들의 목록 + 각 커밋들의 변경사항까지 확인하기
$ git log -p

현재 커밋들의 목록을 그래프 형태로 조회하기
$ git log --graph

혼용하여 사용하기
$ git log --oneline --graph
$ git log --oneline -p
...

비교하기

현재 작업 디렉터리에서의 작업 내역과 최신 커밋을 비교하기
$ git diff

스테이지와 작업 내역과 최신 커밋을 비교하기
$ git diff --staged

커밋끼리 비교하기
$ git log <커밋해시> <커밋해시>

되돌리기

revert: 특정 커밋 취소(revert)하기
작업을 취소한 새로운 커밋을 생성한다.

기존의 커밋 내역은 유지된다.

$ git revert <취소할커밋>

reset: 특정 커밋으로 되돌아가기
마치 시간을 되돌리듯 되돌아간다.

기존의 커밋 내역에 영향이 갈 수 있다.

soft reset: 커밋을 했다는 그 사실만을 되돌리기
$ git reset --soft <되돌아갈 커밋>

mixed reset: 스테이지에 추가했다는 사실까지 되돌리기
$ git reset --mixed <되돌아갈 커밋>
$ git reset <되돌아갈 커밋>

hard reset: 변경사항을 만들었다는 사실까지 되돌리기
$ git reset --hard <되돌아갈 커밋>

브랜치로 나누어 관리하기

새로운 브랜치 생성하기
$ git branch <브랜치이름>

해당 브랜치로 체크아웃하기
$ git checkout <브랜치이름>

새로운 브랜치를 만듦과 동시에 체크아웃하기 (수업에서 다루지는 못했지만 유용합니다)
$ git checkout -b <브랜치이름>

브랜치 병합하기
$ git merge <브랜치이름>

충돌(Conflict): 같은 내용을 다르게 수정했을 경우 발생

충돌 해결법

1. 최종적으로 포함할 내용을 직접 선택한다
2. 다시 커밋한다

원격 저장소(깃허브) 다루기

원격 저장소 이름 조회하기
$ git remote

원격 저장소 이름 + URL 조회하기
$ git remote -v 

원격 저장소 추가하기
$ git remote add <원격저장소이름> <원격저장소경로> 

원격저장소와의 네 가지 상호작용

clone: 원격 저장소의 내용을 내 컴퓨터로 복제해오기
$ git clone <원격저장소경로>

push: 로컬의 변경사항을 원격저장소로 밀어넣기
$ git push <원격저장소이름> <로컬브랜치이름>

* 참고) 아래와 같이 -u 옵션과 함께 push하면 이후로 <원격저장소이름> <로컬브랜치이름> 생략 가능
$ git push -u <원격저장소이름> <로컬브랜치이름>

fetch: 원격저장소의 변경사항을 로컬로 '일단 갖고만' 오기 (로컬 브랜치에는 변함이 없다!)
$ git fetch <원격저장소이름> <로컬브랜치이름>

pull: 원격저장소의 변경사항을 로컬로 갖고와서 합치기
$ git pull <원격저장소이름> <로컬브랜치이름>

Pull Request로 협업하기

Pull Request를 보내는 단계

1. 기여하려는 저장소를 본인의 계정으로 fork하기
2. fork한 저장소를 clone하기
3. 브랜치 생성 후 생성한 브랜치에서 작업하기
4. 작업한 브랜치 Push 하기 
5. Pull Request 보내기

소스트리 프로그램이 아닌 Git Bash를 이용한 명령어 만으로 GitHub에 커밋하고 기타 작업들을 하는 법에 대한 특강이었기 때문에 사용되는 명령어 위주로 정리하게 되었다. 튜터님이 실제로 사용하는 모습을 보면서 따라하긴 해봤지만 실전에서 사용해봐야 어느정도 감을 잡을 수 있을 것 같다.

파이썬 이번 주의 과제

- 계산기 만들기, 숫자야구게임 만들기

계산기 만들기

요구조건

  • main.py 파일에서 사용자의 입력을 받아 기능을 처리해주세요
  • 사용자가 입력한 숫자와 연산기호(+, -, *, /)에 따른 연산 결과를 출력해주세요
  • 더하기, 곱하기, 빼기, 나누기 기능을 하는 함수는 main.py가 아닌 다른 파일에서 작성해주세요
  • 사용자의 입력을 받는 방식은 자유롭게 작성하셔도 무관합니다. 다만, 입력받기 전 사용자가 어떤 방식으로 입력해야 하는지 가이드 출력해주세요

main.py

from calculator import calc

num1, operator, num2 = input().split()
num1 = int(num1)
num2 = int(num2)

calc(num1, operator, num2)

calculator.py

def calc(num1, operator, num2):
    if operator == '+':
        print(num1 + num2)
    elif operator == '-':
        print(num1 - num2)
    elif operator == '*':
        print(num1 * num2)
    elif operator == '/':
        if num2 == 0:    
            print('0으로는 나눌 수 없습니다.')
        else:
            print(num1 / num2)
    else:
        print('error!')

calculator.py에 사칙연산을 하는 함수를 만들고 해당 함수를 main.py에서 import를 통해 가져와 계산식을 넣으면 답을 알려주는 방식으로 만들었다.

숫자야구 게임 만들기

요구조건

  • 프로그램이 시작되면 슷자야구 게임을 몇 자리 숫자로 할 건지 입력 받아 주세요
    • 3을 입력할 경우 해당 숫자야구 게임은 3자릿수로 진행, 최대 10자리
  • 첫 번째 입력을 받은 자릿수 만큼 후 파이썬으로 중복 없는 랜덤한 수를 생성해 주세요
  • 사용자가 숫자를 입력 했을 때 숫자야구 게임의 규칙에 맞게 ball / out count를 출력해 주세요
  • 사용자가 정답을 맞춘 경우 아래 항목들을 출력해 주세요
    • 사용자가 정답을 맞추기까지 입력 한 횟수
    • 사용자가 게임을 시작해서 정답을 맞추기까지 소요된 시간
    • 정답을 맞춘 시점의 날짜/시간
  • 게임을 진행하던 도중, “exit”을 입력할 경우 프로그램을 종료해 주세요

numbaseball.py

from random import randint
import time
import datetime

print('숫자야구 게임을 몇 자리 숫자로 하시겠습니까?(최대 10자리까지 선택 가능합니다.)')

N = int(input())
if 0 < N <= 10:
    print(f'{N}자리로 게임을 시작합니다.')
else:
    print('최대 10자리까지만 선택이 가능합니다.')    

def get_numbers(): # 무작위로 숫자 3개를 뽑는 함수
    numbers = []
    
    while len(numbers) < N:
        num = randint(0, 9)
        if num not in numbers:
            numbers.append(num)
            
    print(f'{N}자리의 숫자가 선정되었습니다.')
    return numbers

def take_guess(): # 플레이어에게 숫자 3개를 입력받는 함수
    print('숫자 3개를 차례대로 입력하세요.')
    
    new_guess = []
    while len(new_guess) < N:
        new_num = int(input("{}번째 숫자를 입력하세요:".format(len(new_guess) + 1)))
        
        if new_num < 0 or new_num > 9:
            print('범위를 벗어나는 숫자입니다. 다시 입력하세요.')
        elif new_num in new_guess:
            print('중복되는 숫자입니다. 다시 입력하세요.')
        else:
            new_guess.append(new_num)
                
    return new_guess

def get_score(guess,answer): # 무작위로 뽑힌 숫자 3개와 플레이어가 입력한 숫자 3개를 비교해 스트라이크, 볼, 아웃 점수를 계산하는 함수
    strike_count = 0
    ball_count = 0
    out_count = 0
    
    for i in range(N):
        if guess[i] == answer[i]:
            strike_count += 1
        elif guess[i] in answer:
            ball_count += 1
        else:
            out_count += 1
            
    return strike_count, ball_count, out_count

ANSWER = get_numbers()
tries = 0
start = time.time()

while True:
    user_guess = take_guess()
    strike, ball, out = get_score(user_guess, ANSWER)
    
    print("{}S {}B {}O".format(strike, ball, out))
    tries += 1
    
    if strike == N:
        break

sec = time.time()-start
times = str(datetime.timedelta(seconds=sec)).split(".")
times = times[0]
now = datetime.datetime.now()
nowDatetime = now.strftime('%Y-%m-%d %H:%M:%S')
    
print(f"정답입니다! 시도한 횟수 : {tries}회, 걸린 시간 : {times}, 맞힌 시간 : {nowDatetime}")

random의 randint 기능을 가져와 0에서 9사이의 숫자중 N개의 숫자를 뽑아 순서를 랜덤하게 설정하였고 내가 입력하는 N가지의 숫자 중 숫자와 순서가 모두 맞으면 스트라이크, 숫자만 맞고 순서는 틀릴경우 볼, 숫자가 맞지 않는 경우 아웃으로 하여 각각 그 횟수를 카운팅해서 알려주도록 하였고 N개의 숫자가 모두 스트라이크가 되었을 경우 정답으로 표기되며 시도한 횟수, 걸린 시간, 맞힌 시간이 표시되도록 설정하였다. 이 과정에서 그동안 배운 for문,while문,if문이 모두 사용되었으며 시간 표시하는 법은 구글링을 통해 time과 datetime의 사용법을 배워서 적용하였다. 내가 지금까지 만들어본 파이썬 파일 중 가장 어렵고 가장 많은 기능이 들어간 것 같다. 그만큼 시간도 많이 걸려서 추석연휴를 거의 다 날려버린 것 같지만 완성되었을 때의 그 기분은 말로 표현할 수 없었다.

알고리즘 실습

매일 진행되는 알고리즘 실습 문제 풀이 역시 빼놓을 수 없다. 이번 주는 반복문, 1차원 배열, 함수, 문자열을 주제로 문제들이 나왔는데 저번주보다 난이도가 올라간 것을 느낄 수 있었다. 역시나 이번주도 많은 문제가 있었지만 그 중에서 특히 어려웠던 문제 몇가지만 뽑아서 정답과 풀이를 정리해보도록 하겠다.

1110번 더하기 사이클

문제
0보다 크거나 같고, 99보다 작거나 같은 정수가 주어질 때 다음과 같은 연산을 할 수 있다. 먼저 주어진 수가 10보다 작다면 앞에 0을 붙여 두 자리 수로 만들고, 각 자리의 숫자를 더한다. 그 다음, 주어진 수의 가장 오른쪽 자리 수와 앞에서 구한 합의 가장 오른쪽 자리 수를 이어 붙이면 새로운 수를 만들 수 있다. 다음 예를 보자.

26부터 시작한다. 2+6 = 8이다. 새로운 수는 68이다. 6+8 = 14이다. 새로운 수는 84이다. 8+4 = 12이다. 새로운 수는 42이다. 4+2 = 6이다. 새로운 수는 26이다.

위의 예는 4번만에 원래 수로 돌아올 수 있다. 따라서 26의 사이클의 길이는 4이다.

N이 주어졌을 때, N의 사이클의 길이를 구하는 프로그램을 작성하시오.

입력
첫째 줄에 N이 주어진다. N은 0보다 크거나 같고, 99보다 작거나 같은 정수이다.

출력
첫째 줄에 N의 사이클 길이를 출력한다.

original_num = input()
if len(original_num) == 1:
    original_num = "0"+ original_num
    
    
current_num = original_num
count = 0
while True:
    sum_num = int(current_num[0]) + int(current_num[1])
    sum_num = str(sum_num)
    current_num = current_num[-1] + sum_num[-1]
    count += 1
    if current_num == original_num:
        print(count)
        break

풀이
첫 줄에서 original_num으로 input값을 받는다. original_num의 값이 10보다 작을경우는 한 자리 수라는 뜻이기 때문에 len(original_num) == 1이다. 이때 앞에 0을 붙여서 두 자리 수로 만들어준다. 그리고 current_num를 original_num로 count를 0으로 선언해둔 뒤 original_num의 첫 번째 자리 수와 두 번째 자리 수를 서로 더한 다음 이 값을 문자열로 변환해 준다. 이 값을 sum_num이라 하고 current_num의 값은 current_num의 맨 뒷 자리 수와 sum_num의 맨 뒷 자리 수를 더한 값이 current_num의 값이 되며 한 사이클이 돌았기 때문에 count의 값을 +1 해준다. 이렇게 사이클을 돌리다 current_num의 값이 처음 설정한 original_num의 값과 같아지면 함수를 멈추고 몇 사이클이 돌았는지 출력하도록 설정하였다.

8958번 OX퀴즈

문제
"OOXXOXXOOO"와 같은 OX퀴즈의 결과가 있다. O는 문제를 맞은 것이고, X는 문제를 틀린 것이다. 문제를 맞은 경우 그 문제의 점수는 그 문제까지 연속된 O의 개수가 된다. 예를 들어, 10번 문제의 점수는 3이 된다.

"OOXXOXXOOO"의 점수는 1+2+0+0+1+0+0+1+2+3 = 10점이다.

OX퀴즈의 결과가 주어졌을 때, 점수를 구하는 프로그램을 작성하시오.

입력
첫째 줄에 테스트 케이스의 개수가 주어진다. 각 테스트 케이스는 한 줄로 이루어져 있고, 길이가 0보다 크고 80보다 작은 문자열이 주어진다. 문자열은 O와 X만으로 이루어져 있다.

출력
각 테스트 케이스마다 점수를 출력한다.

T = int(input())

for _ in range(T):
    answers = input()
    total_score = 0
    point = 1
    for answer in answers:
        if answer == 'O':
            total_score += point
            point += 1
        else:
            point = 1
    print(total_score)

풀이
첫 줄에서 테스트 케이스의 갯수를 input으로 받는다. 두번째 줄 부터 OX문자열을 input으로 받는다. 문제의 총점의 값을 total_score라 하고 0으로 선언해 둔다. point는 정답을 맞출 때 마다 얻는 점수이고 처음엔 1로 설정해 둔다. 만약 정답을 맞췄을 경우 얻는 점수가 1점식 추가되고 오답일 경우 얻는 점수는 다시 1점으로 초기화가 되도록 if문을 설정해 둔다. 마지막에 총점을 print하면 코드작성은 끝이 난다. 막상 풀이를 보니 생각보다는 쉬운 문제였는데 문제 자체의 이해가 난해하다보니 코드작성을 어떻게 해야할 지 몰랐었고 결국 해설을 보고 나서야 겨우 이해하고 문제를 풀 수 있었다.

4344번 평균은 넘겠지

문제
대학생 새내기들의 90%는 자신이 반에서 평균은 넘는다고 생각한다. 당신은 그들에게 슬픈 진실을 알려줘야 한다.

입력
첫째 줄에는 테스트 케이스의 개수 C가 주어진다.

둘째 줄부터 각 테스트 케이스마다 학생의 수 N(1 ≤ N ≤ 1000, N은 정수)이 첫 수로 주어지고, 이어서 N명의 점수가 주어진다. 점수는 0보다 크거나 같고, 100보다 작거나 같은 정수이다.

출력
각 케이스마다 한 줄씩 평균을 넘는 학생들의 비율을 반올림하여 소수점 셋째 자리까지 출력한다.

C = int(input())

for _ in range(C):
    scores = list(map(int, input().split()))
    sum_score = 0
    num_people = scores[0]
    for i in range(1, num_people+1):
        sum_score += scores[i]
    avg_score = sum_score / num_people
    
    above_avg = 0
    for i in range(1,num_people+1):
        if scores[i] > avg_score:
            above_avg += 1
            
    print(f"{above_avg/num_people*100:.3f}%")

풀이
첫 줄에서 테스트 케이스의 개수 C를 input값으로 받고 각 학생의 수와 그 학생들의 점수를 input받아 list로 저장한다. 이 값을 scores라고 한다. 점수의 총합은 0으로 선언해 두고 학생의 수는 둘째줄에서 입력한 값 중 가장 첫번째로 오는 값이 학생 수이기 때문에 scores의 0번째 값을 받으면 된다. 다음으로 list내의 값중에 0번째는 학생의 수이기 때문에 범위를 1번째부터 학생수 +1번째의 값까지로 지정하면 모든 학생들의 점수를 범위로 지정할 수 있다. 이제 이 점수들의 합 나누기 학생의 수가 평균점수가 되는 것이다. 이제 평균점수를 넘은 사람의 수를 above_avg로 잡고 0으로 지정해둔 다음 평균보다 점수가 높은 사람의 수만큼 above_avg의 숫자를 더해주도록 for문을 만들었다. 마지막으로 평균점수보다 높은 점수를 받은 학생 수에서 전체 학생 수를 나누고 백분율이니 100을 곱한뒤 %를 붙여주고 입력값에 따라 결과가 나오도록 f스트링을 설정해 두면 끝! .3f는 소숫점 셋째자리까지만 표기한다는 뜻이므로 외워두면 유용하게 쓸 수 있다.
그동안 풀었던 알고리즘 문제 중 가장 어려웠던 것 같다. for문도 많이 쓰이고 범위 지정에 있어 실수가 있을 수도 있는데 풀이를 보며 차근차근 다시 풀어보면 그래도 어느정도 이해가 되는 편이다.

이번주를 마치며

드디어 내일배움캠프 2주차도 끝이 났다. 이번 주차는 프로젝트가 없이 강의와 과제, 문제풀이가 계속 반복되다보니 아무래도 개념적인 측면에서의 요약이 많을 수 밖에 없는 주차였다. 2주차에는 1주차에 비해 난이도가 오른 것이 체감이 되어 고생도 많이 했지만 아직까지 이해하려고 시간을 오래 들인다면 이해를 못하고 넘어갈 수준은 아닌 것 같다. 하지만 방심을 할 수는 없는 것이 이 모든 내용을 한 주만에 정리하고 따라가는데 시간이 부족했고 다음주에는 난이도가 더 올라갈 수 있기 때문에 더 많은 노력을 해야만 할 것이다. 그리고 이번주는 추석 연휴 직전이라 들뜬 마음이 있어서 그런 것일지도 모르겠지만 집중력이 조금씩 흐트러지고 있는 것을 스스로 느끼기 시작했다. 캠프는 장기간 진행되고 아직 초반부 중 극 초반부임에도 벌써 이런 현상이 발생하는 것은 좋지 않은 징조이다. 갈수록 집중력 싸움이 될 것인데 마음 단단히 먹고 그날 당일에 해야하는 것들만이라도 당일에 끝낼 수 있도록 더욱 집중해 보겠다. 그리고 단 것을 많이 챙겨먹어야 할 것 같다. 머리를 많이 썼더니 당이 부족해...

profile
스파르타 내일배움캠프 3기 수강생 정형빈

0개의 댓글