프로그램을만들다 보면 함수가 다양해짐에 따라 관리하기가 어려워지는 문제가 발생한다.
이에 함수를 관리하기 위해서 물리적으로 분리시켜 별도의 파일로 관리할 필요가 있다.
모듈
한 개의 개별 소스파일을 말한다. 모듈을 사용하는 방법으로는 <<import 모듈이름>>을 이용한다.
모듈에는 시스템에 구성되어있는 표준모듈, 내가만든 모듈, 다른사람이 만든 모듈이 있다.
모듈 만들시에 참고할 것.
1. 파일 이름이 모듈 이름이 된다.일반적으로는 함수와 상수로만 이루어져있다.
2. 모듈화 시키기위해서는 전역변수를 포함해서는 안된다. 왜냐하면 전역변수는 프로그램 전체에서 영향을 미치기 때문에 함수의 분리가 어렵기 때문이다.
3. 모듈을 선언하는 것은 2가지방법이있으나 첫번째 방법이 선호된다. 왜냐하면 FROM을 사용 하는 두번째 방법은 함수이름이 같을 때 충돌이 일어나 as를 써야하는 번거로운 일이 발생하기 때문이다.
예제
로그인 기능을 구현하고자 한다. 관리자계정은 모든 데이터에 권한을갖게 하고 학생계정은 그 본인의 정보 권한을 갖고자 한다.
1. 개개인마다 식별해야할 정보가 필요한데 수업시간에 key인 ID를 추가해서 구별했다. 그로인하여 인덱스의 순서가 뒤틀렸는데, 이 때 상수로 만든 이유를 알 수 있었다. 숫자로 코드를 짰다면 순서를 바꿔야 할 때 매우 번거로운 일이 되었을게 분명하기 때문이다.
2.전체적인 논리는 user_id를찾는것과 그 user_id에 맞는 데이터를 출력하는것이다.
2-1user_id를 찾기
def find_by_user_id(scores,user_id):
for scorein scores:
if user_id== score[_USER_ID_IX]:
return score
return None #id가 없을경우엔 none을 리턴하여 로그인 실패라는 것을 알 수 있다.
Id를 사용한이유는 동명이인이 있을수 있기 때문이다.
2-2user_id 에맞는 점수를 출력
def print_mydata(scores,user_id):#자신의 데이터를 출력하기위해서 필요한 매개변수?
myscore = find_by_user_id(user_id)
show_student([myscore])# show_student는 리스트에 대한 리스트를 받게 되어있다. 그리하여 myscore를 리스트화 시켰다.
2-3 로그인 함수를 모듈로 만듬. 로그인 모듈에는 변수와 로그인 함수가 있다.
members = { … }
def login():
userId = None
for tryCount in range(3):
if userId == None: # 아이디 입력 시도.
print(' 아이디를 입력하세요 ')
userId = input()
print(' 비밀번호를 입력하세요')
userPasswd = input()
if userId in members.keys(): #members 에서 key를 매칭시켜
passWd = members[userId]
if userPasswd == passWd:
return userId
else:
print("%s의 비밀번호가 틀렸습니다.."%(userId))
else:
return None
2-4 학생용과 관리자용으로 나눌 필요가 있다.
def do_by_admin():
while(True):
print("성적 관리 메뉴")
print("출력(P) | 검색(S) | 종료 (X)")
selection = input()
if selection == 'P':
scoreprogram.show(students)
elif selection == 'S':
scoreprogram.find(students)
elif selection == 'X':
print('종료합니다.')
exit()
else : print('잘 못 입력하셨습니다. \n 다시 입력하세요.')
def do_by_student():
while(True):
print("성적 관리 메뉴")
print("출력(P) | 종료 (X)")
selection = input()
if selection == 'P':
scoreprogram.show(students)
elif selection == 'X':
print('종료합니다.')
exit()
else : print('잘 못 입력하셨습니다. \n 다시 입력하세요.')
3.모듈과 함수가 준비되었으니 프로그램이 돌아가게 logic을 짠다.
user_Id=login()
if user_Id :
if user_Id =='admin': #관리자인 경우
do_by_admin()
else:
do_by_student(user_Id) # 학생이 누구인지 알려줘야함
else: # 로그인 실패
print('로그인 실패 - 다시 실행하세요')
다만 student같은 경우엔 누구인지 알아야 출력이 가능하므로 인자를 받아야 하고 그로인해 기존 do_by_student() 대신 do_by_student(user_id)로인자를 받게 만들어준다
<수정후do_by_student()>
def do_by_student(userId):
while(True):
scoreprogram.print_menu(False)
selection = input()
if selection == 'P':
scoreprogram.print_mydata(students,userId) # (각각의 학생에 맞는 data를 출력시키기위해 2-2에서 만든 함수 사용.)
elif selection == 'X':
print('종료합니다.')
exit()
else : print('잘 못 입력하셨습니다. \n 다시 입력하세요.')
여기 까지 하면 기존 프로그램은 다돌아가는 것을 확인 할 수 있다. 여기서 또 다른 기능을 추가하고싶을 경우엔 어떻게 처리하는 것이 좋을까?
추가하고싶을 기능을 두가지로 나누어서비교하였다.
첫번째 : 관리자로써 추가하고 싶은 기능(사용자 추가 및 점수수정)
두번째 : 학생으로써 추가하고싶은 기능 ( passwd, Id 변경)
그렇다면 기존에 함께있던 do by admin 과 do by student를 나눌 필요가 있다. 즉 관리자가 다루는
admin이 다루는 함수를 갖고있는 admin 모듈 ,student가 다루는 함수를 갖고있는 student 모듈
admin디렉토리를 하나 만들면 ,
def do_by_admin(students):
while(True):
scoreprogram.print_menu(True)
selection = input()
if selection == 'P':
scoreprogram.show(students)
elif selection == 'S':
scoreprogram.find(students)
elif selection == 'X':
print('종료합니다.')
exit()
else : print('잘 못 입력하셨습니다. \n 다시 입력하세요.')
여기서 하나 달라지는 점이 있는데 doByAdmin()에서 student라는 매개변수가 들어갔다는 점이다.
그리고 scoreprogram의 함수를 사용하기위해
import scoreprogram <<< 도 추가해주어야한다.
Admin 에서 구현하고 싶은 기능이 user를 추가하는 것과 점수수정인데 먼저 user를 추가할때를 살펴보자.
User를 추가하고자 할 때 무엇이 필요할까? Logic을 살펴보자면
1) user의 아이디 와 비밀번호를 입력받은뒤 이름을 설정하고
2) 그 유저의 점수를 추가해주는 식으로 실행하면 되겠다.
1-1) user의 아이디를 넣자
def get_user_id(students):
while True:
name = input('새로운 사용자 아이디')
if name =='c' or name =='C': // 아이디 취소할 때
return None
elif name=='': // 아이디에 공백이 있을경우
continue
# student 는 데이터 name은 확인하고자 할 ID
student=scoreprogram.find_by_user_id(students,name) // 아이디 중복검사를 위해
if student:
print('%s는 이미 사용된 아이디입니다',name)
else:
return name // 모든 검사를 통과했을 경우 반환
1-2) user의 이름을 넣자
def get_user_name():
while True:
name = input(' 사용자 이름')
name = name.strip() # 공백없애기
if name == '':
continue
return name
1-3) userpassword를 넣자
def get_user_password():
while True:
password1 = input('비밀번호')
password2 = input('비밀번호 확인')
if password1==password2:
return password1
## if가 충족되지않으면 false
print('비밀번호가 일치하지 않습니다. 다시 입력하세요')
1-4)1~3번 항목을 합쳐 user_add라고 명명하고 기능을 집어넣는다.
def add_student(students):
user_id=get_user_id(students)
if not user_id:
return
user_name = get_user_name() # 사용자 이름 입력
password= get_user_password() # 사용자 비번 입력
data = [user_id,user_name,kor,eng,math,-1,-1,-1]
students.append(data)
members[user_id]=password # 사용자 id와 비밀번호 설정 dic은 없는 key를 선언할시 새로 추가한다.
#총점, 평균 계산, 등수 조정
scoreprogram.calc_total(students)
scoreprogram.calc_avg(students)
scoreprogram.calc_rank(students)
2) 점수를 추가하자
2-1)
# 점수를 입력하는 함수
# title = 점수
def get_score(title):
while True:
score=input(title)
if(score.isnumeric()):
return int(score)
print('숫자만 입력하세요')
2-2)# 과목에 점수를 입력하는 함수
def get_scores():
kor =get_score('국어점수는 몇점입니까?')
eng =get_score('영어점수는 몇점입니까?')
math=get_score('수학점수는 몇점입니까?')
return kor,eng,math # 튜플로 리턴된다.
이것을 user_add에 넣으면 # students = import해온 데이터
def add_student(students):
user_id=get_user_id(students)
if not user_id:
return
user_name = get_user_name() # 사용자 이름 입력
password= get_user_password() # 사용자 비번 입력
kor,eng,math =get_scores() # 점수 입력 # unpacking을 이용해 튜플이 데이터 입력됨
data = [user_id,user_name,kor,eng,math,-1,-1,-1]
students.append(data)
members[user_id]=password # 사용자 id와 비밀번호 설정 dic은 없는 key를 선언할시 새로 추가한다.
#총점, 평균 계산, 등수 조정
scoreprogram.calc_total(students)
scoreprogram.calc_avg(students)
scoreprogram.calc_rank(students)
마지막으로 add_student를 만들게 되면 members 변수를 가져와야 id와 비밀번호를 매칭 시킬수 있으므로 from loginProgram import members
를 추가할 수 있다.



덧글