프로그래머스 파이썬 기초 해석 :: 조건 문자열(eval, replace)

프로그래머스 URL 

https://school.programmers.co.kr/learn/courses/30/lessons/181934


프로그래머스 코딩테스트 카테고리 

코딩 기초 트레이닝

Day 4 연산, 조건문 - 조건 문자열

Lv.0





문제 설명  

문자열에 따라 다음과 같이 두 수의 크기를 비교하려고 합니다.

두 수가 n과 m이라면

">", "=" : n >= m

"<", "=" : n <= m

">", "!" : n > m

"<", "!" : n < m

두 문자열 ineq와 eq가 주어집니다. ineq는 "<"와 ">"중 하나고, eq는 "="와 "!"중 하나입니다. 그리고 두 정수 n과 m이 주어질 때, n과 m이 ineq와 eq의 조건에 맞으면 1을 아니면 0을 return하도록 solution 함수를 완성해주세요.



문제 이해 

문자열 ineq, eq 

정수 n, m 

출력값 : 정수 0 / 1 (False/True 활용 가능)

조건에 맞는지 확인하기 위한 if문 작성



내가 쓴 코드     

def solution(ineq, eq, n, m):
    if ineq == "<" :
        return int(n <= m)   if eq == "="  else int(n < m)
    return int(n >= m) if eq == "=" else  int(n > m)

중첩 if문 활용, ineq 변수의 "<" or ">" 먼저 확인하고, "="인지 "!" 인지 판별해서 값 출력 

결과값은 정수여야하는데, bool 값을 활용하는거기 때문에 int(bool)형 변환해줌 




업그레이드 

고수들의 풀이를 보니, 이 문제는 eval() 와 replace 메서드를 활용이 가능해보였다. 
eval() 이랑 replace() 매서드를 잘 몰라서, 공부해봄

1. eval () 

내장함수로, 문자열로 이루어진 식(연산)을 받아서 계산하고, 출력한다. 

"3+4" 로 이루어진 문자열과 정수로 이뤄진 3+4은 완전 다른 자료형을 가지고 있어서, 출력값도 다르다. 
print("3+4")는 그냥 문자열 "3+4"이지만, print(3+4)은 사칙연산이 이뤄진 7로 출력이된다. 

eval 함수는 전자처럼 "3+4"로 이뤄진 문자열을 넣더라도 사칙연산을 해주는 신기한 함수이다. 별도로 int형 변환이 필요가 없다. 

가능한 사칙연산은 꽤나 많다. 
기본연산인 + - * / % // 은 물론, 절댓값(abs()), 리스트길이, 반올림(round()) 등 ~ 



math = eval("a * b + 3")   #eval() 값을 변수에 저장 가능

lenth = eval("len(list)")

print(eval("abs(-231)"))      #print로 바로 출력 

print(eval("round(5.531, 2)"))


문자열로 감싸져있는 값을 봉인해제해서 값을 출력하는 것이기 때문에, 보안상 문제점이 발생할 수도 있다. 
사용자가 입력한 값을 그대로 eval 함수에 전달해서 쓸 때, 일반적인 사칙연산은 괜찮지만 만약 사용자가 입력한 문자열이 운영체제를 건드리는 코드일 경우 eval()가 실행해버리면 보안 위협이 생기게 된다.



print(eval('os.system('rm -rf *')')) 
위 코드는 운영체제 명령을 실행해 모든 파일을 삭제하는 코드이다. 
이 위험한 문자열을 사용자가 입력했을 때, 문자열 자체로는 실행이 안되지만,  실행해버리면 시스템에 피해가 생긴다. 




2. 객체명.replace () 메서드

문자열 메서드
문자열 내의 특정 부부을 다른 문자열로 교체해준다. 

객체명.replace(old, new, count) 
첫번째 매개변수 old (필수): 바꿀려는 리스트가 가지고 있는 원래의 문자열
두번째 매개변수 new (필수): 교체할 새로운 문자열
세번째 매개변수 count (선택): old를 new로 교체할 횟수. 생략하면 문자열 내의 모든 old가 new로 교체됨


text = "AbcAbcAAbc"

new_text = text.replace("A", "a")
#출력값은 "abcabcaabc" 

new_text2 = text.replace("A", "a", 2)
#출력값은 "abcabcAAbc" 
replace() 메서드로 새롭게 바뀐 리스트를 저장하기 위해서, 
리스트변수명 = 객체명.replace(old, new, count) 이렇게 사용 가능



다른 사람의 풀이

원래 ! 기호는 부정의 뜻을 가지지만 이 문제에서는 공백과 같은 뜻을 가진다. 
eval함수로 코드를 작성할때, eq 변수가 ! 값일때는 공백("")으로 바꿔줘서 코드를 써야되는데, ! 문자열을 ""으로 변환하는 방법이 두가지가 있다. 

1. if문 사용


def solution(ineq, eq, n, m):
    if eq == '!':
        eq = ''
    return int(eval(f'{n} {ineq}{eq} {m}'))


2. replace() 메서드 사용


def solution(ineq, eq, n, m):
    return int(eval(str(n)+ineq+eq.replace('!', '')+str(m)))


------------------------


느낀점 

프로그래머스 기초 문제를 풀고, 고수들의 풀이를 보면서 많이 배운다. 내가 아직 배우지 못한 함수나 메서드, 문법들을 하나씩 알아가면서 또 적용해보는 맛이 있다. 메서드와 일반 내장함수 간의 차이도 점점 익히고 있고, eval 이라는 새로운 함수도 알게되었다. 아직까지 나의 코드는 중복성이 있는것 같다. 같은 코드를 어떻게 줄일지 계속 고민하면서 공부해야겠다. 





댓글

이 블로그의 인기 게시물

[KT 에이블스쿨 - IT 트랜드] 국내외 AI 관련 규제

KT 에이블스쿨 : 핀테크 아이디어 공모전

KT 에이블스쿨 : 6-7차 미니프로젝트 - 제안서 기반 솔류션 기획 및 설계