일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- API
- greedy
- lol
- Django
- 스파르타내일배움캠프TIL
- 그리디
- 자바
- java
- python
- 알고리즘
- 장고
- 파이썬
- 스파르타내일배움캠프
- 백준
- 프로그래머스
- 내일배움캠프
- git
- sort
- github
- 그리디알고리즘
- 코딩테스트
- 라이엇
- drf
- 코딩테스트준비
- programmers
- Riot
- 탐욕알고리즘
- 롤
- SQL
- 리그오브레전드
- Today
- Total
Lina's Toolbox
스파르타 내일 배움 캠프 AI웹개발 | 파이썬 팀 과제 / 클래스 인스턴스(객체) 활용 본문
스파르타 내일 배움 캠프 AI웹개발 | 파이썬 팀 과제 / 클래스 인스턴스(객체) 활용
Woolina 2024. 7. 4. 16:27
과제 내용
- Member 클래스와 Post 클래스를 정의하세요.
- Member 클래스에는 다음과 같은 속성을 가지고 있어야 합니다.
- 회원 이름 (name)
- 회원 아이디 (username)
- 회원 비밀번호 (password)
- Member 클래스에는 다음과 같은 메소드를 가지고 있어야 합니다.
- 회원 정보를 print해주는 display (회원이름과 아이디만 보여주고 비밀번호는 보여줘서는 안됩니다!)
- Post 클래스에는 다음과 같은 속성을 가지고 있어야 합니다.
- 게시물 제목 (title)
- 게시물 내용 (content)
- 작성자 (author) : 회원의 username 이 저장되어야 함!
- 회원 인스턴스를 세개 이상 만들고 members 라는 빈리스트에 append를 써서 저장해주세요
- members 리스트를 돌면서 회원들의 이름을 모두 프린트 해주세요
- 각각의 회원이 게시글을 세개 이상 작성하는 코드를 만들어주세요.(회원이 세명이명 총 9개 이상의 post 인스턴스가 만들어져야 합니다). 만들어진 게시글 인스턴스들은 posts 빈리스트에 append를 써서 저장해주세요
- for 문을 돌면서 특정유저가 작성한 게시글의 제목을 모두 프린트 해주세요
- for문을 돌면서 ‘특정 단어’가 content에 포함된 게시글의 제목을 모두 프린트 해주세요.
추가 도전 과제:
- input을 이용하여 Member 인스턴스 만드는것을 사용자가 터미널에서 할 수 있게 해주세요.
- post도 터미널에서 생성할 수 있게 해주세요.
- (심화)비밀번호 해싱이 무엇인지 공부한 후 hashlib 라이브러리를 써서 회원 비밀번호를 해시화하여 저장하게 해주세요
코드 스니펫
# ----- 코드 정의 ------
class Member:
# TODO : 코드 구현이 필요합니다.
def display(self):
# TODO : 코드 구현이 필요합니다.
pass
class Post:
# TODO : 코드 구현이 필요합니다.
pass
# ----- 코드 실행 ------
members = []
posts = []
# TODO : 코드 구현이 필요합니다.
평가 기준
- 클래스와 인스턴스 개념을 설명할 수 있는가?
- 메소드와 어트리뷰트(속성)을 설명할 수 있는가?
- 클래스를 정의할 수 있는가?
- 인스턴스를 생성할 수 있는가?
과제 난이도가 쉽고 양이 많지 않아 3명이서 역할 분담하는 데에 고민이 많았다.
두명이면 나누기 쉬울 것 같은데.. 클래스도 2개뿐
클래스와 객체 관계를 이해하는 것은 매우 중요한 부분이기 때문에 우리 조는 개인적으로 각자 코드를 완성한 후,
다음날 각자 코드를 설명한 후에 잘 된 부분을 합치기로했다.
naive code
class Member:
def __init__(self, name, username, password):
self.name = name # 회원 이름
self.username = username # 회원 아이디
self.password = password
# 회원 정보 print(회원이름과 아이디만 보여주고 비밀번호는 보여줘서는 안됩니다!)
def display(self):
print(f"회원 이름 : {self.name}, 회원 아이디: {self.username}")
class Post:
def __init__(self, title, content, author):
self.title = title
self.content = content
self.author = author # 작성자 Member.username
# 맴버 리스트 생성 및 객체 생성
members = []
members.append(Member("김우린", "kimwoolina", 1234))
members.append(Member("이상현", "sanghyun", 3456))
members.append(Member("이새예", "saeye", 6789))
# 회원 이름 출력
for member in members:
print(member.name)
# 게시글 리스트 생성 및 게시글 객체 생성
posts = []
posts.append(Post("Title 1", "content of post 1 by Lina Kim", "kimwoolina"))
posts.append(Post("Title 2", "content of post 2 by Lina Kim", "kimwoolina"))
posts.append(Post("Title 3", "content of post 3 by Lina Kim", "kimwoolina"))
posts.append(Post("Title 4", "content of post 4 by Sanghyun Lee", "sanghyun"))
posts.append(Post("Title 5", "content of post 5 by Sanghyun Lee", "sanghyun"))
posts.append(Post("Title 6", "content of post 6 by Sanghyun Lee", "sanghyun"))
posts.append(Post("Title 7", "content of post 7 by Saeye Lee", "saeye"))
posts.append(Post("Title 8", "content of post 8 by Saeye Lee", "saeye"))
posts.append(Post("Title 9", "content of post 9 by Saeye Lee", "saeye"))
# 특정유저(kimwoolina)가 작성한 게시글의 제목을 모두 프린트
for post in posts:
if post.author == "kimwoolina":
print(f"kimwoolina님의 작성한 게시글: {post.title}")
# ‘특정 단어’가 content에 포함된 게시글의 제목을 모두 프린트
for post in posts:
if "Lee" in post.content :
print(f"글 내용에 'Lee'가 포함된 게시글: {post.title}")
직관적으로 요구 사항을 보면서 작성한 코드. (추가 과제 제외)
이렇게 해도 정상적으로 작동하지만 반복되는 코드들이 보기 싫었다.
리팩토링(Refactorying)
class Member:
def __init__(self, name, username, password):
self.name = name # 회원 이름
self.username = username # 회원 아이디
self.password = password
# 회원 정보 print
def display(self):
print(f"회원 이름 : {self.name}, 회원 아이디: {self.username}")
class Post:
def __init__(self, title, content, author):
self.title = title
self.content = content
self.author = author # 작성자 Member.username
# 함수 정의
def add_members(member_list, member_data):
for name, username, password in member_data:
member_list.append(Member(name, username, password))
def add_posts(post_list, post_data):
for title, content, author in post_data:
post_list.append(Post(title, content, author))
def display_member_names(member_list):
for member in member_list:
print(f"회원 이름: {member.name}")
# 데이터 준비
member_data = [
("김우린", "kimwoolina", "password1"),
("이상현", "sanghyun", "password2"),
("이새예", "saeye", "password3")
]
post_data = [
("Title 1", "post 1 content by Lina Kim", "kimwoolina"),
("Title 2", "post 2 content by Lina Kim", "kimwoolina"),
("Title 3", "post 3 content by Lina Kim", "kimwoolina"),
("Title 4", "post 4 content by Sanghyun Lee", "sanghyun"),
("Title 5", "post 5 content by Sanghyun Lee", "sanghyun"),
("Title 6", "post 6 content by Sanghyun Lee", "sanghyun"),
("Title 7", "post 7 content by Saeye Lee", "saeye"),
("Title 8", "post 8 content by Saeye Lee", "saeye"),
("Title 9", "post 9 content by Saeye Lee", "saeye")
]
# Members 리스트 생성 및 회원 인스턴스 추가
members = []
add_members(members, member_data)
# Members 리스트를 돌면서 회원들의 이름 프린트
display_member_names(members)
# Posts 리스트 생성 및 게시글 인스턴스 추가
posts = []
add_posts(posts, post_data)
# 특정 유저가 작성한 게시글의 제목 프린트
username_to_check = "kimwoolina"
print(f"\nPosts written by {username_to_check}:")
for post in posts:
if post.author == username_to_check:
print(post.title)
# 특정 단어가 content에 포함된 게시글의 제목 프린트
keyword_to_check = "Lee"
print(f"\nPosts containing '{keyword_to_check}' in content:")
for post in posts:
if keyword_to_check in post.content:
print(post.title)
산발적으로 작성되어있던 코드들을 각각 함수로 작성하여 묶어주었다.
그리고 데이터들은 한번에 넣어주기 위해 튜플을 사용하여 함수를 실행하기 전에 데이터를 먼저 준비했다.
검색에 이용되는 값들도 최대한 변수에 넣어주었다.
가독성이 올라가고 함수별로 관리할 수 있어 유지보수에 더 쉬운 코드로 수정하였다!
추가 과제 1 : 비밀번호 해시화하여 저장
과제 조건에 따라 hashlib 라이브러리를 사용하였다.
SHA256 방식으로 해싱하였다.
해싱할 문자열을 인수로 update() 함수를 호출하면 해당 문자열이 해싱된다.
이 함수에 전달하는 문자열은 바이트 문자열이어야 하므로,
encode('utf-8')을 이용하여 유니코드 문자열을 UTF-8 형식의 바이트 문자열로 변환한다.
💡 만약 해싱할 문자열을 추가하고 싶으면 추가할 문자열과 함꼐 update 함수를 추가로 호출하면 됨
🚨 해싱한 문자열은 복구할 수 없음 주의 (해시 함수는 단방향 함수!)
- 해싱(Hashing)
- 어떤 항목의 Key만을 가지고 바로 항목이 들어 있는 배열의 인덱스를 결정하는 기법
- 원본 문자열을 알아볼 수 없는 난해한 문자열로 정의하는 방법
- 시간복잡도 O(1)
- 해시 함수
- 키(Key) 값을 값(Value)이 저장되는 주소 값으로 바꾸기 위한 수식
- 임의의 길이를 갖는 임의의 데이터를 고정된 길이의 데이터로 매핑하는 단방향 함수.
- 아무리 큰 숫자를 넣더라도 정해진 크기의 숫자가 나오는 함수이다. 예를 들면 어떤 숫자를 10으로 나누었을 때 그 나머지를 구하는 함수도 해시 함수이다.
- SHA256 방식: 유추나 복호화가 불가능함
- 인코딩 : 문자를 어떻게 출력할 지에 대한 약속
- 아스키코드(ASCII)
- 128개의 문자조합을 제공하는 7비트 부호.
- 아스키코드만으로는 각 나라별 언어를 표현할 수 없다. 이를 해결한 코드가 유니코드.
- 알파벳, 숫자, 특수기호, 그 외 컴퓨터에 필요한 몇 가지만 정의되어 있어서점차 여러 나라에서 컴퓨터를 사용하게 되고 통신이 발달하다보니 기존의 아스키 인코딩보다더 많은 문자들을 정의한 새로운 인코딩이 필요해짐
- 컴퓨터 내에서 문자 A는 65로 저장됨
- 유니코드(Unicode)
- 각 나라별 언어를 모두 표현하기 위해 나온 코드 체계가 유니코드숫자와 글자, 즉 키 값이 1:1로 매핑된 형태의 코드
- 사용중인 운영체제, 프로그램, 언어에 관계 없이 문자마다 고유한 코드 값을 제공하는 새로운 개념의 코드
- 16비트를 표현하므로 최대 65,536자 표현 가능
- 영문/숫자/한글/한자 등 모든 글자는 이론적으로 2바이트. 아주 희귀한 문자들은 2바이트를 초과할 수도 있다.
- UTF-8은 유니코드가 파일에 저장될 때 영문/숫자는 아스키코드와 똑같이 1바이트 사용
- 한글 등은 3바이트로 파일에 저장
- UTF-8(가변길이 인코딩)
- 유니코드를 사용하는 인코딩 방식 중 하나
- 영문/숫자/기호는 1바이트로, 한글/한자는 3바이트로 표현
- 전 세계의 모든 언어를 하나의 파일에 쓸 수 있다
- UTF-8 유니코드는 아스키 코드와 영문 영역에서는 100% 호환
- 만약, UTF-8 유니코드 문서에 한글 등이 전혀 없고 영문과 숫자로 이루어져 있다면 그 카드는 아스키코드와 동일
- 유니코드를 위한 가변 길이 문자 인코딩 방식 중 하나
- 유니코드 한 문자를 나타내기 위해 1바이트에서 4바이트까지 사용
추가 과제 2,3: input으로 객체 생성
def create_member_from_input():
name = input("Enter member name: ")
username = input("Enter username: ")
password = input("Enter password: ")
return Member(name, username, password)
def create_post_from_input():
title = input("Enter post title: ")
content = input("Enter post content: ")
author = input("Enter post author: ")
return Post(title, content, author)
사용자가 input으로 입력한 값으로 객체를 생성할 수 있는 함수를 작성하였다.
if __name__ == "__main__":
members = []
post = []
# 사용자 입력을 통한 회원 생성
while True:
members.append(create_member_from_input())
another = input("Add another member? (yes/no): ")
if another.lower() != 'yes':
break
# 사용자 입력을 통한 글 생성
while True:
posts.append(create_post_from_input())
another = input("Add another Post? (yes/no): ")
if another.lower() != 'yes':
break
사용자가 원할 때 까지 입력을 받기 위해서 while문 안에 넣어서 작성해주었다.
이를 위해 특정한 시작 지점이 필요하여 main 함수를 작성해서 분리해주었다.
포스트 검색도 input을 받아 처리하는 방식으로 변경하였다.
전체 완성 코드는
Github : https://github.com/kimwoolina/programmers/blob/main/class_practice.py
'스파르타 내일 배움 캠프 AI 웹개발 과정 > python' 카테고리의 다른 글
파이썬 문법 심화 / 튜플, 집합(Set), f-string, 파일 불러오기, map, filter, lambda, *args, **kwargs 등 (0) | 2024.07.08 |
---|---|
스파르타 내일 배움 캠프 AI 웹개발 과정 복습 | 파이썬 기초 문법 / 리스트, 딕셔너리, 인덱싱, 슬라이싱, split() 등 (0) | 2024.07.05 |
스파르타 내일배움캠프 AI웹개발 과정 | 6일차 복습/Pycharm 설치 (2) | 2024.07.01 |
Pythonanywhere로 내 코드 배포하기 (0) | 2024.06.28 |
파이썬 Flask 활용해 DB 연동하기 (SQLite) (0) | 2024.06.28 |