728x90
728x90

1. 일반적인 객체 생성 방법

// 객체 생성자 함수를 사용하여 객체 생성
function Person(name, age) {
  this.name = name;
  this.age = age;
}

// 새로운 객체 생성
let person1 = new Person("gyodam", 21);
console.log(person1); // 출력: Person { name: 'gyodam', age: 21 }

// 프로토타입을 사용한 메서드 추가
Person.prototype.greet = function() {
  console.log("Hello, my name is " + this.name);
};

person1.greet(); // 출력: Hello, my name is Gyodam

 

객체 생성자 함수를 사용하여 객체를 생성함.

객체 생성자 함수는 new 키워드와 함께 호출되고, 함수 내부에서 this 키워드를 사용하여 객체의 속성을 정의함

또한, Prototype 를 사용하여 객체의 메서드를 추가할 수 있음

 

2. 객체 리터럴을 사용하여 객체 생성

// 객체 리터럴을 사용하여 객체 생성
let person2 = {
  name: "seongbin",
  age: 25,
  greet: function() {
    console.log("Hello, my name is " + this.name);
  }
};

console.log(person2); // 출력: { name: 'seongbin', age: 25, greet: [Function: greet] }
person2.greet(); // 출력: Hello, my name is seongbin

중괄호 {} 내의 속성과 해당 속성의 값을 정의

메서드도 속성으로 추가할 수 있음

이는 함수 표현식이나 어레이 함수 사용 가능

 

3. Object.create() 를 사용한 객체 생성 :

// 프로토타입을 기반으로 새로운 객체 생성
let personPrototype = {
  greet: function() {
    console.log("Hello, my name is " + this.name);
  }
};

let person = Object.create(personPrototype);
person.name = "gyodam";
person.age = 21;

console.log(person); // 출력: { name: 'gyodam', age: 21 }
person.greet(); // 출력: Hello, my name is gyodam

 

지정된 프로토타입 객체를 기반으로 새로운 객체를 생성

프로토타입 객체의 속성과 메서드를 상속받아 새로운 객체를 구성함

 

4. 클래스를 이용한 객체 생성

 

// 프로토타입을 기반으로 새로운 객체 생성
let personPrototype = {
  greet: function() {
    console.log("Hello, my name is " + this.name);
  }
};

let person = Object.create(personPrototype);
person.name = "gyodam";
person.age = 21;

console.log(person); // 출력: { name: 'gyodam', age: 21 }
person.greet(); // 출력: Hello, my name is gyodam

class 키워드를 사용하여 클래스를 정의하고, constructor 메서드를 사용하여 객체를 초기화한다. 

클래스 내의 정의단 다른 메서드들은 클래스의 프로토타입에 할당된다

 

위의 예시 코드에서는 Person 클래스를 정의하고 new 키워드를 사용하여 객체를 생성한다. 

클래스를 사용하여 객체를 생성하면 자동으로 생성자 함수와 프로토타입 객체가 만들어지며, 인스턴스화된 객체를 사용할 수 있다

이는 객체 생성에 유연성을 더한다

 

 

5. 팩토리 함수를 사용한 객체 생성

function createPerson(name, age) {
  return {
    name: name,
    age: age,
    greet: function() {
      console.log("Hello, my name is " + this.name);
    }
  };
}

let person = createPerson("gyodam", 21);
console.log(person); // 출력: { name: 'gyodam', age: 21 }
person.greet(); // 출력: Hello, my name is gyodam

팩토리 함수는 객체를 생성하여 변환하는 함수이다.

원하는 속성과 메서드를 가진 객체를 생성하고 반환한다

 

6. object.assign()을 사용한 객체 생성

let person = {
  name: "gyodam",
  age: 21
};

let extendedPerson = Object.assign({}, person, { city: "busan" });
console.log(extendedPerson);

 

출력: {name: 'gyodam', age :21 , city: 'busan')

Object.assign() 메서드를 사용하면 기존 객체를 확장하거나 병합하여 새로운 객체를 생성할 수 있다.

 

7. 프로토타입 상속을 사용한 객체 생성

let personPrototype = {
  greet: function() {
    console.log("Hello, my name is " + this.name);
  }
};

let person = Object.create(personPrototype, {
  name: { value: "gyodam" },
  age: { value: 21 }
});

console.log(person); // 출력: { name: 'gyodam', age: 21 }
person.greet(); // 출력: Hello, my name is gyodam

Object.create() 메서드를 사용하여 프로토타입 객체와 속성을 지정하여 객체를 생성하는 방식

 

8. ES6의 구조 분해 할당을 사용한 객체 생성

let name = "Gyodam";
let age = 21;

let person = { name, age };
console.log(person); // 출력: { name: 'gyodam', age: 21 }

변수로부터 속성 이름과 값이 추출되어 객체를 생성할 수 있음

 

이 외에도 정말 많은 방법이 있지만 여기까지 포스팅해보도록 하겠음

728x90
300x250
728x90
728x90

1.개인 레포에서 작업한 변경 내용을 로컬로 커밋한다

2. 원본 레포지토리로 이동하여 작업할 디렉토리로 변경한다

3. 원본 레포지토리에서 개인 레포지토리의 브랜치를 가져온다

git remote add 개인레포지토리명 개인레포지토리URL

*실수로 다른 레포지토리를 연결했을때

 

git remote remove 레포지토리명

 

remove 후 다시 추가해주면 된다

 

 

4. 개인 레포에 변경사항 push

git push 개인레포지토리Url 브랜치이름

 

5. pr (이때 원본 레포지토리에서 이미 branch가 있어야 한다)

gh pr create --base <베이스브랜치> --head <어이디(개인)>:<브랜치이름> --repo <아이디(원본)><레포이름>

 

제대로 pr이 갔는지 확인해보자 

 

제대로 Pr한 것을 확인할 수 있다

728x90
300x250
728x90
728x90

항해 99/ 1일차 과제 

내 기억으로 진행하다가 갑자기 명령어가 안 먹혔다. 

서치해서 찾아보고 오류 해결법까지 정리해보았다

 

 

1. 수정한 파일을 스테이징한 후 커밋한다

(이때 작업 디렉토리 안에 있어야 하며, 브랜치를 확인해준다)

 

2. 새로운 pr을 생성해준다

gh pr create

*로그인이 안되어있다면 로그인을 해야한다.

gh auth login

이렇게 로그인을 진행해준다

로그인을 진행해준 후 정상적으로 진행되었다면

이렇게 뜬다.

 

3. pr 목록 확인

gh pr list

/pull/7 이라고 나와서 넘버가 7인것은 알 수 있지만 다른 경우도 봐야 하기 때문에 확인해준다

 

4. pr 내용 확인

git pr view (number)

이렇게 내용을 확인할 수 있다

 

5. pr merge하기

git pr merge number

를 하면 Merge가 된다

number에는 7이 들어간다(내 기준)

 

 

 

#conflict 오류가 뜬다면 

 

 

충돌(conflict) 가 생겨서 병합이 안되는 경우이다

 

 

1. pull request의 브랜치로 전환한다

gh pr checkout 7

나는 이러한 결과를 얻었다.

일반적으로, Pull Request를 생성하면 해당 Pull Request는 원본 레포지토리의 별도 브랜치로 생성된다. 이 별도 브랜치에는 해당 Pull Request에 대한 변경사항이 포함되어 있다.

보통 병합 충돌에 많은 이유가 된다. 

Pr 브랜치로 전환하여 충돌을 해결하는 것이다

나는 정상적으로 설정되어 있어 다른 방법을 써보았다

 

2. 최신 변경사항을 가져온다

git fetch origin main

 

3. 가져온 최신 변경사항을 현재 브랜치에 병합한다

git merge origin/main

 

 

에러가 뜬다면 

충돌 해결 후 스테이징을 안 했던 것이다

스테이징 한 후 커밋 후 다시 병합해보면

잘 업데이트된걸 볼 수 있다

728x90
300x250
728x90
728x90

 

 

항해 99에서 배운 몽고디비 연결하기

내 야구시뮬레이터 프로젝트에도 괜찮을 것 같아서 써먹기로 했다

방금 전 게시물에서 썼던, 모든 선수들을 저장하는 코드를 조금 바꿔서 몽고디비에 저장할 수 있도록 햇다

 

중간에 db=client.baseball (db를 설정해주는 문장)을 적지 않아 막혔는데 항해 99에서 실습했던 파일을 찾아보니 이게 오류였구나... 했다 ^^ 허허

 

처음부터 끝까지 내가 적다 보니 코드스니펫 쓰던 시절이 그립다 ~~~~

 

from pymongo import MongoClient
import requests
from bs4 import BeautifulSoup

team_codes = ["sk", "wo", "lg", "ht","nc", "ss","hh","lt","kt","ob"]
client = MongoClient('mongodb+srv://sparta:test@sparta.rqx1qlk.mongodb.net/?retryWrites=true&w=majority')  

db = client.baseball

for team_code in team_codes:
    url = f"http://eng.koreabaseball.com/Stats/BattingByTeams.aspx?codeTeam={team_code}"

    response = requests.get(url)
    soup = BeautifulSoup(response.content, 'html.parser')

    table = soup.find_all('table')[0]

    data = []

    tr_tags = table.find_all('tr')
    for tr in tr_tags:

        td_tags = tr.find_all('td')

        row = {}
        for td in td_tags:

            title = td.get('title')
            if title:

                row[title] = td.text
            elif 'stats_player' in td.get('class', []):

                row['Player'] = td.text
        if row:
            data.append(row)
    collection = db[team_code]
    collection.insert_many(data)
728x90
300x250
728x90
728x90

나머지 사진들은 안 찍음!

 

 

각 팀별로 엑셀 파일 추출 성공!!!!!!!!

 i. 행에서 모든 'td' 태그를 찾는다

 ii. 해당 행의 데이터를 저장할 빈 딕셔너리를 만든다

 iii. 각 'td' 태그에 대해 다음을 수행하는 루프를 시작힌디:

     - 'td' 태그의 'title' 속성을 찾습니다. 이는 야구 통계의 종류를 나타낸다. 예: AVG, G, PA 등).

     - 만약 'title' 속성이 존재한다면, 이 값을 딕셔너리에 추가한다

     - 만약 'td' 태그가 선수의 이름을 나타낸다면 (즉, 'class' 속성이 'stats_player'라면), 이를 딕셔너리에 추가한다

 iv. 완성된 행 딕셔너리를 메인 데이터 리스트에 추가한다.

 

 

 


import requests
from bs4 import BeautifulSoup
import pandas as pd

team_codes = ["sk", "wo", "lg", "ht","nc", "ss","hh","lt","kt","ob"]
for team_code in team_codes:
    url = f"http://eng.koreabaseball.com/Stats/BattingByTeams.aspx?codeTeam={team_code}"
    response = requests.get(url)
    soup = BeautifulSoup(response.content, 'html.parser')

    table = soup.find_all('table')[0]
    data = []
    tr_tags = table.find_all('tr')
    for tr in tr_tags:
        td_tags = tr.find_all('td')
        row = {}
        for td in td_tags:
            title = td.get('title')
            if title:
                row[title] = td.text
            elif 'stats_player' in td.get('class', []):
                row['Player'] = td.text
        if row:
            data.append(row)


    df = pd.DataFrame(data)

    df.to_excel(f'scraped_batters_{team_code}.xlsx', index=False)

 


 

 

여담

 

팀 코드 찾느라 개발자 도구 둘러봤는데, 쓱이 아직 sk였고, 두산이 아직 Ob로 되어있었다 ㅋㅋㅋ

hh한화, ht 기아 , kt 케이티. nc 엔씨, lg 엘지, wo키움 lt 롯데 ss 삼성 

바뀐지 꽤나 된 팀도 있는데 안 바꾸고 뭐하냐 ㅡㅡ

물론 실제 창에서는 저렇게 안 뜸.

 

728x90
300x250
728x90
728x90

 

 

otp 길이에 원하는 자릿수를 입력하면

otp값을 출력해준다

 

 

import time

class LFSR:
def __init__(self, seed, taps):
self.state = seed
self.taps = taps

def step(self):
nextbit = sum([self.state[i] for i in self.taps]) % 2
self.state.append(nextbit)
return self.state.pop(0)

def lfsr_otp(length):
seed = int(time.time() * 1000) #밀리세컨드까지 사용
seed = [int(i) for i in bin(seed)[-16:].zfill(16)]
lfsr = LFSR(seed, [15, 13, 12, 10])
return ''.join(str(lfsr.step()) for _ in range(length))

print(lfsr_otp(int(input("OTP 길이: "))))

 

 

  1. import time: time 모듈을 임포트합니다. 이 모듈은 현재 시간을 사용하기 위해 사용됩니다.
  2. class LFSR: LFSR 클래스를 정의합니다. LFSR은 비트 시프트 연산을 통해 이전 상태의 비트들을 조합하여 다음 상태를 생성하는 레지스터입니다.
  3. def __init__(self, seed, taps): LFSR 클래스의 생성자 함수를 정의합니다. 이 함수는 seed와 taps 매개변수를 받습니다. seed는 초기 상태를 나타내는 이진수 리스트이고, taps는 피드백을 받을 비트의 인덱스를 나타내는 리스트입니다.
  4. self.state = seed: 현재 상태를 나타내는 변수 state를 초기화합니다.
  5. self.taps = taps: 피드백을 받을 비트의 인덱스를 저장합니다.
  6. def step(self): step 함수를 정의합니다. 이 함수는 LFSR의 한 단계를 수행하고 다음 비트를 반환합니다.
  7. nextbit = sum([self.state[i] for i in self.taps]) % 2: 다음 비트를 생성하기 위해 taps에 해당하는 비트들을 XOR 연산하여 합을 구합니다. 그리고 2로 나눈 나머지를 구하여 nextbit 변수에 저장합니다. 이 값을 다음 단계에서 반환할 것입니다.
  8. self.state.append(nextbit): nextbit을 현재 상태에 추가합니다.
  9. return self.state.pop(0): 현재 상태의 첫 번째 비트를 제거하고 반환합니다.
  10. def lfsr_otp(length): lfsr_otp 함수를 정의합니다. 이 함수는 OTP를 생성하기 위해 LFSR을 사용합니다. length 매개변수는 생성할 OTP의 길이를 나타냅니다.
  11. seed = int(time.time() * 1000): seed 변수에 현재 시간을 밀리세컨드 단위로 가져와 저장합니다.
  12. seed = [int(i) for i in bin(seed)[-16:].zfill(16)]: seed를 이진수로 변환하고, 뒤에서부터 16비트를 선택하여 리스트로 만듭니다. zfill 함수를 사용하여 리스트의 길이가 항상 16이 되도록 왼쪽을 0으로 채웁니다.
  13. lfsr = LFSR(seed, [15, 13, 12, 10]): seed와 피드백을 받을 비트의 인덱스 [15, 13, 12, 10]를 사용하여 LFSR 객체를 생성합니다.
  14. return ''.join(str(lfsr.step()) for _ in range(length)): length 만큼 lfsr.step()을 호출하여 OTP를 생성합니다. 각 호출 결과를 문자열로 변환하고, 이들을 연결하여 최종 OTP를 생성합니다.
  15. print(lfsr_otp(int(input("OTP 길이: ")))): OTP의 길이를 입력 받고, lfsr_otp 함수를 호출하여 생성된 OTP를 출력합니다.
728x90
300x250
728x90
728x90

결과물

밑에 쭉 이어진다

모든 팀의 투수진을 전부 저장함

import requests
from bs4 import BeautifulSoup
import pandas as pd  # pandas import 확인

# 웹 페이지 URL
url = "http://eng.koreabaseball.com/Teams/PlayerSearch.aspx"

# GET 요청으로 HTML 가져오기
response = requests.get(url)
html = response.text

# BeautifulSoup을 사용하여 HTML 파싱
soup = BeautifulSoup(html, "html.parser")

# 선수 정보를 저장할 리스트 생성
player_info_list = []

# 모든 팀에 대한 정보를 가져옵니다.
for team in soup.select('.sub_tab.team_select ul li'):
    # 팀 이름을 가져옵니다.
    team_name = team.find('h4').text

    # 이 팀의 모든 선수 정보를 가져옵니다.
    for player_row in soup.select('tbody tr'):
        player_info = {"팀 이름": team_name}

        # 선수 이름을 가져옵니다.
        player_info["이름"] = player_row.th.a.text.strip()

        # 선수 번호, 포지션, 생년월일, 신장/체중 정보를 가져옵니다.
        for td in player_row.find_all("td"):
            title = td.get("title")
            if title:
                player_info[title] = td.text.strip()

        # 가져온 선수 정보를 리스트에 추가
        player_info_list.append(player_info)

# 리스트를 데이터프레임으로 변환
df = pd.DataFrame(player_info_list)

# 엑셀 파일로 저장
df.to_excel("players.xlsx", index=False)

 

 

 

 

 라이브러리를 import한다 :

request는 웹 페이지에 get 요청을 보내기 위해 사용된다

beautifulsoup는 html 파싱을 위해 사용된다

pandas 는 데이터프레임을 생성하고 관리하기 위해 사용된다

 

  1. URL을 설정하고 해당 URL에 GET 요청을 보내서 HTML을 가져온다
  2. BeautifulSoup을 사용하여 HTML을 처리한다
  3. player_info_list라는 빈 리스트를 만든다. 이 리스트는 모든 선수 정보를 저장한다.
  4. .sub_tab.team_select ul li 선택자를 사용하여 모든 팀 정보를 가져온다.
  5. 각 팀에 대해 반복문을 실행한다. team.find('h4').text를 사용하여 팀 이름을 가져온다.
  6. 'tbody tr' 선택자를 사용하여 해당 팀의 모든 선수 정보를 가져온다.
  7. 각 선수에 대해 반복문을 실행한다.
  8. player_info라는 빈 딕셔너리를 만든다. 이 딕셔너리는 선수 정보를 저장하는 용도로 사용된다. "팀 이름" 키에는 위에서 가져온 팀 이름을 저장한다.
  9. 선수 이름을 가져와서 player_info 딕셔너리에 "이름" 키에 저장한다.
  10. 선수 번호, 포지션, 생년월일, 신장/체중 정보를 가져와서 player_info 딕셔너리에 해당 정보를 추가한다.
  11. 가져온 선수 정보를 player_info_list 리스트에 추가한다
  12. 모든 선수 정보를 수집하면, player_info_list 리스트를 사용하여 데이터프레임인 df를 생성한다
  13. df.to_excel() 메서드를 사용하여 "players.xlsx"라는 파일로 데이터프레임을 엑셀 파일로 저장한다. 인덱스를 엑셀 파일에 포함시키지 않도록 index=False로 설정한다.

코드를 실행하면 선수 정보가 스크래핑되어 데이터프레임으로 변환되고 "players.xlsx"라는 엑셀 파일로 저장된다

728x90
300x250
728x90
728x90

 

쓱의 투수진을 출력해보았다

 

import requests
from bs4 import BeautifulSoup
import pandas as pd

# 웹 페이지 URL
url = "http://eng.koreabaseball.com/Teams/PlayerSearch.aspx"

# GET 요청으로 HTML 가져오기
response = requests.get(url)
html = response.text

# BeautifulSoup을 사용하여 HTML 파싱
soup = BeautifulSoup(html, "html.parser")

# 모든 선수 요소를 찾음
player_elements = soup.select('th[title="player"]')

# 모든 선수에 대한 정보를 저장할 리스트
all_players_info = []

for player_element in player_elements:
    player_name = player_element.text.strip()

    # 선수 정보가 있는 table row 찾기
    player_row = player_element.find_parent("tr")

    # 선수 정보 추출
    player_info = {'name': player_name}
    for td in player_row.find_all("td"):
        # 각 td 요소의 title 속성을 가져와서 선수 정보에 추가
        title = td.get("title")
        if title:
            player_info[title] = td.text.strip()

    # 선수 정보를 리스트에 추가
    all_players_info.append(player_info)

# DataFrame 생성
df = pd.DataFrame(all_players_info)

# 엑셀 파일로 저장
df.to_excel('ssg_pitcher.xlsx', index=False)
  • 필요한 라이브러리를 가져왔다: requests, BeautifulSoup, pandas.
  • KBO 선수 검색 페이지의 URL을 url 변수에 저장했디
  • GET 요청으로 해당 URL에서 HTML을 가져왔다. 응답은 response 변수에 저장되었다.
  • response.text를 사용하여 HTML 코드를 가져왔다.
  • BeautifulSoup을 사용하여 HTML을 파싱하고 데이터를 추출할 수 있도록 설정했다.
  • soup.select('th[title="player"]')를 사용하여 선수 요소를 선택했다.
  • 각 선수 요소에서 선수 이름을 추출하고, 해당 요소의 상위 행을 찾아 선수 정보를 추출했다.
  • 선수 정보를 딕셔너리로 저장하고, all_players_info 리스트에 추가했다.
  • 추출한 선수 정보를 pd.DataFrame을 사용하여 DataFrame으로 변환했다.
  • DataFrame을 엑셀 파일로 저장했다.
728x90
300x250

+ Recent posts