>

TIL

5주차 Day 5. set 자료형, 소프트웨어 설계

ekdud 2024. 7. 26. 20:04

📑

     

     

    파이썬 Set 자료형

    집합을 구현한 것으로 숫자, 문자, 문자열까지도 포함할 수 있다.

    • 셋 선언하기:  set이름 = { 원소들 또는  = set() 으로 비어있는 set을 선언할 수 있다.

    원소들의 중복을 허용하지 않는다

    순서가 없다. set자료형을 출력하면 매번 다른 순서로 출력된다.

    • 슬라이싱과 인덱싱이 불가하다.

    • set 자료형의 개별 원소에 접근하려면 리스트로 형변환하여 접근해야 한다.

     

    [ 메소드 ]

    • 원소 추가 .add()    여러 개의 원소를 추가하는 경우 .update([ ... , ... , ... ])

    • 원소 삭제 .remove()  *해당 값이 없는 경우 에러가 발생하므로 에러 발생을 원치 않는다면 .discard() 메소드 사용.

    • 집합 연산: set자료형의 독특한 연산으로, 교집합(& 또는 .intersection), 합집합(| 또는 .union), 차집합(-, .difference) 연산을 지원함.

    * 대칭차집합 연산( ^ 또는 .symmetric_difference) ex. set_a = {1, 2, 3, 4, 5}  set_b = {4, 5, 6, 7, 8} 일 때, set_a ^ set_b 의 연산 결과는 {1, 2, 3, 6, 7, 8} 이다.

    issubset() : 부분집합이면 True, 아니면 False 반환.

    issuperset() : 상위 집합이면 True, 아니면 False 반환. (상위집합 = 다른 집합을 포함하는 집합)

    isdisjoint() : 교집합이 있으면 False, 없으면 True 반환.

    리스트 자료형과의 차이점 : set은 값을 hashtable 구조로 저장해, 값 탐색이 리스트에 비해 월등히 빠름. hashtable 구조는 값이 있는지 확인하기 위해 키값으로 한번만 검색하면 되지만 리스트는 값을 하나씩 순회해봐야 하기 때문에 느릴 수밖에 없다. *값은 순차적으로 조회해야만 하는 경우에는 당연히 리스트가 유리함.

     


    파이썬 자료형

    : 정수, 실수, 논리형(boolean), 문자열, 리스트, 튜플(값 변경 불가), 딕셔너리(키는 중복 불가), 세트(중복 불가)

     

     

    자료구조

    : 데이터를 효과적으로 저장하기 위해 어떤 논리나 규칙으로 자료를 모아 놓은 구조.

    1) 선형 구조 - 배열, 리스트(파이썬에서는 배열과 리스트를 구분해서 쓰진 않는다), 스택(일단 후입선출, 선입후출이면 다 스택), 큐(선입선출)

    2) 비선형 구조 - 자료들 간의 관게가 1:N으로 나열되어 있는 것. 그래프, 트리.

    위의 트리를 리스트로 나타내면.. => [A, B, C] - 편향트리.   [A, [B, [D, E]], [C, [F]]] - 이진트리

     

    * 이진트리는 자식 노드가 최대 2개까지만 존재한다. 이진 트리는 자료의 삽입, 삭제 방법에 따라 나뉠 수 있다.

    - 정 이진트리(Full binary tree)는 각 내부 노드가 두 개의 자식 노드를 갖는 순서화된 트리이다. 홀수 개의 자식 노드를 가질 수 없다. (자식이 없거나 2개여야 함.)

    - 포화 이진트리(Perfect binary tree)는 정 이진 트리이면서 완전 이진 트리인 경우를 말한다.

    - 완전 이진 트리(Complete binary tree)는 부모, 왼쪽 자식, 오른쪽 자식 순으로 채워지는 트리를 말한다. 마지막 레벨을 제외하고 모든 노드가 가득 차 있어야 하며, 마지막 레벨의 노드는 전부 차 있지 않아도 되지만 왼쪽이 채워져야 한다.

    - 균형 이진 트리(Balanced binary tree)는 왼쪽 자식, 오른쪽 자식 노드의 갯수가 정확하게 일치해야 할 필요는 없지만 지나치게 한쪽으로 치우치지 않은 트리 구조를 말한다. 트리가 한 쪽으로 치우쳐져 있는 경우, 시간 복잡도가 악화되므로 균형잡힌 트리를 만드는 것이 주안점이다. 

    - 변질 이진 트리(Degenerate binary tree)는 각 부모 노드가 오직 한 개의 연관 자식 노드를 갖는 트리이다. 이는 성능 면에서 트리가 연결 리스트 데이터 구조처럼 동작하는 것을 의미한다.

    https://iq.opengenus.org/degenerate-or-pathological-tree/

     

     


     

    프로그래밍 기본

    컴파일러: 고급 프로그래밍 언어로 작성된 소스코드를 기계어로 번역 및 실행하기 위한 프로그램. 소스코드 전체를 분석하고 그 다음 기계어로 번역 후 실행. C, Java와 같은 언어가 컴파일러에 의해 컴파일 되고 실행됨.

     

    인터프리터: 컴파일러와 마찬가지로 고급 프로그래밍 언어로 작성된 소스코드를 기계어로 번역 및 실행하기 위한 프로그램. 한 줄씩 소스코드를 번역하고 실행함. Python, Javascript와 같은 언어들이 인터프리터에 의해 번역 및 실행됨.

     *파이썬 프로그래밍이 실행되는 과정: 소스코드 작성(.py) → PVM(파이썬 가상 머신)을 통해 바이트코드로 변환(.pyc) → PVM이 바이트코드를 해석하고 기계어로 명령을 실행. 

     

    메모리 영역: 작업을 효율적으로 하기 위해 low memory(낮은 주소)에서 high memory(높은 주소) 까지 코드 영역, 데이터 영역, heap영역(동적 메모리 할당을 위한 곳), stack영역(정적 메모리 할당)이 나누어져 있음. 운영체제가 관리. 

     *heap영역의 경우, 원래 해당 영역에서 사용한 메모리는 사용자가 직접 해제해줘야하지만 파이썬은 가비지컬렉터가 있어서 자동으로 해제 됨.

     

     

    객체지향 프로그래밍(OOP)

    : Object-Oriented Programming. 추상화하고자 하는 객체의 모습을 가상의 공간에 구체화하며 설계해 나가는 것. 즉, 어떤 대상을 소스코드로 그리기 위한 컴퓨터 공학적 사고 방식.

     

    객체: Instance. 현실세계에 있는 어떤 대상을 추상화한 것.

     

    클래스: 객체를 생성하기 위해 어떤 속성과 방법의 집합을 추상화하여 표현한 것을 의미. 클래스 안에는 함수, 변수가 있고 클래스 내에 클래스가 또 있을 수도 있음. 클래스 안에 있는 멤버함수의 변수에 접근하기 위해서는 반드시 객체를 이용해야 함.

      - 상속: 다른 클래스의 기능을 사용하고자 할 때 부모클래스를 상속받는 것.

      - 오버라이딩: 상속받은 클래스에서 어떤 기능을 재정의하는 것.

      - 오버로딩: 함수의 이름은 같으나 매개변수를 다르게 설정하여 사용 목적에 따라 다르게 불러오는 것. 연산자 오버로딩,     메소드 오버로딩, 함수 오버로딩 등이 있다. 파이썬에서 함수오버로딩은 없다고 보면 됨.(구현이 불가능한 것은 아님!) 

     

     


     

     

    소프트웨어 개발 방법론

    1) 폭포수(Waterfall) 방법론

    : 하향식 방법으로, 가장 오래된 개발방법. 일반적으로 계획 → 설계 →개발 → 시험 유지보수 순서로 진행. 

    위의 순서인 SDLC(소프트웨어 개발 생명 주기)가 굉장히 길다. 따라서 매우 큰 규모의 프로젝트에 적합하며 이미 진행된 작업에 대해서는 변경 및 수정이 어렵다는 단점이 있다. 

     

    2) 애자일(Agile)방법론

    : 반복적이고 점진적으로 개발하는 방법. 계획 → 설계 →개발 → 시험 → 유지보수를 순차적으로 진행하되, SDLC가 매우 짧기 때문에 여러번 반복하며 점진적으로 개발해 나간다. 때문에 이해관계자의 피드백을 빠르게 반영할 수 있지만 개발 계획을 세우기 어려울 수 있다. 

    https://www.codestates.com/blog/content/애자일방법론-워터폴방법론

     

     

    각각의 장단점

      폭포수 방법론 애자일 방법론
    장점 단계별로 업무를 분담하기 때문에 맡은 바가 명확함. 계획 단계의 문서화로 단계마다 소요되는 시간이나 현재 상황을 추적하고 병목을 파악하기도 쉬움. 고객의 요구사항, 변화된 환경에 맞게 요구를 더 하고 수정해나가는 탄력적인 방법론. 첫 단계에서 모든 요구사항을 계획하고 분석하지 않기 때문에 디자인, 개발, 배포까지 신속하게 완수할 수 있음.  
    단점
    • 빠듯한 일정으로 인해 프로젝트 전체에 차질이나 문제가 발생할 수 있음.
    • QA와 테스트는 프로세스 마지막 단계에 진행되므로 복잡할 수 있음.
    • 프로젝트 진행 중에 발생하는 클라이언트의 변경 또는 조정 요구에 유연하게 대응할 수 없음.
    • 시간순 접근 방식은 반복적 접근 방식보다 제품 제공에 더 오랜 시간이 걸릴 수 있음.

      ⁕ 속도, 변화에 취약하고 문제가 발생했을 때 전 단계로 되돌리기 어려움. 처음부터 다시 시작해야 함.

    • 일정이 빠듯하지 않으므로 많은 프로젝트를 관리할 수 있어야 함.
    • 진행 중인 여러 단계에서 개별적으로 작업할 수 있는 자기 주도적인 팀이어야 함.
    • 기한과 요건이 변경될 수 있는 유동적인 일정에 대한 유연성을 가져야 함.
    • 프로젝트 구조가 산발적이므로 자금을 철저히 관리해야 함.

      다른 프로젝트 관리 방법론보다 더 많은 시간이 필요한 경우가 많음. 회의가 더 자주 필요하고 더 많은 문서를 작성해야 하기 때문.

     

     

    🔗 애자일 소프트웨어 개발 선언

     

    공정과 도구보다 개인과 상호작용을
    포괄적인 문서보다 작동하는 소프트웨어를
    계약 협상보다 고객과의 협력을
    계획을 따르기보다 변화에 대응하기를

    가치 있게 여긴다.

     

     


     

    디자인 패턴

    : 소프트웨어를 설계 및 구현할 때 어떠한 공통된 구조를 띄는 형태. 비슷한 문제를 해결하기 위해 공통적으로 쓰이는 구조.

     

    비유와 설명

    : 어떤 의도의 소프트웨어인지, 어떤 구조로 되어있는지 쉽게 파악하기 위한 것.

     

    •클라이언트-서버  

    : 소프트웨어 디자인의 하나. 네 트워크 상에서 서비스를 요청하는 클라이언트와 서비스를 제공하는 서버로 구성됨.

     

    MTV 

    : python 기반의 웹 구현을 위한 프레임워크인 Django(장고)가 MTV 디자인 패턴을 지향함.

    M은 model로, DB에 데이터를 적재하고 테이블 정의를 담당.

    T는 Template을 의미. 사용자에게 보여지는 화면을 의미.

    V는 View로, 요청에 따라 필요한 로직을 수행하는 역할을 담당.

     

    * MVC패턴과 MTV패턴은 사실 같은 개념인데 MTV는 장고에 국한된 개념으로 볼 수 있다. (전혀 다른 개념으로 보는 시각도 있다.)

    M(모델), V(뷰), C(컨트롤러) 각각의 개념과 M, T, V의 개념이 대응되기 때문에 !!

     

     


     

    형상관리

    : 소프트웨어의 변경사항을 추적하고 통제하기 위한 작업.

     

    git : 분산 버전 관리 시스템. github과 gitlab은 비슷하지만 gitlab은 기업용으로 설계되어 좀 더 많은 기능 有.

    gerrit : 코드리뷰툴. 효과적으로 코드를 적용할 수 있게 해줌.

    sourcetree : 다소 불편한 git UI를 훨씬 편하게 보며 작업할 수 있게 해주는 툴.

    jira : 협업 툴(형상관리 툴은 아님). 서로의 작업을 확인하고 할당할 수 있게 도와줌. git과 연동됨.

     

     

     

    V&V (Verification & Validation)

    : 검증과 확인. 소프트웨어의 완성도 및 신뢰도를 검증 및 확인하는 작업. 우리의 의도대로 동작하는지, 충분한 성능을 나타내는지, 보안 이슈는 없는지 등을 확인.

     

    - QA(Quality Assurance, 품질보증) 분야의 개념들

    Verification : 검증. 개발자 중심에서 제품이 요구사항에 만족하게 구현되었는지 검증하는 작업.

    Validation : 확인. 사용자 중심에서 제품이 사용감이 만족스럽게 구현되었는지 확인하는 작업.

    Test : 시험. 소프트웨어를 테스트.

     

    - Test의 단위  : 보통, 단위테스트 통합 시스템 인수 테스트를 순차적으로 실행. 상황에 따라 다름.

     1) Unit Test(단위 시험) : 가장 작은 단위의 테스트로, 함수, 모듈 등 제일 작은 단위의 기능 시험.

     2) Integration Test(통합 시험) : 함수 간, 클래스 간, 모듈 간 등 어떤 기능이 합쳐져서 잘 동작하는지 시험.

     3) System Test(시스템 시험) : 실제 적용하려는 하드웨어나 어떤 시스템에 개발한 소프트웨어를 탑재한 뒤 시험.

     4) Acceptace Test(인수 시험) : 출시 및 배포 전 최종 테스트. 

     

    - Test의 종류 

     1) 정적 test : 소프트웨어를 구동하지 않고 테스트하는 방법. 동료 검토, 코드 리뷰, 기술 검토.

     2) 동적 test : 소프트웨어를 구동하며 테스트하는 것. Black Box Test(소프트웨어의 작동 원리를 모르는 상태에서 진행),   White Box Test(소프트웨어의 작동 원리를 보며 진행.) 등.

     *이외에도 종류가 매우 다양함. 

     


     

    ALGORITHM CODE KATA

    Ⅰ. 두 문자열 s와 skip, 그리고 자연수 index가 주어질 때, 다음 규칙에 따라 문자열을 만들려 합니다. 암호의 규칙은 다음과 같습니다. 문자열 s의 각 알파벳을 index만큼 뒤의 알파벳으로 바꿔줍니다. index만큼의 뒤의 알파벳이 z를 넘어갈 경우 다시 a로 돌아갑니다. skip에 있는 알파벳은 제외하고 건너뜁니다. 예를 들어 s = "aukks", skip = "wbqd", index = 5일 때, a에서 5만큼 뒤에 있는 알파벳은 f지만 [b, c, d, e, f]에서 'b'와 'd'는 skip에 포함되므로 세지 않습니다. 따라서 'b', 'd'를 제외하고 'a'에서 5만큼 뒤에 있는 알파벳은 [c, e, f, g, h] 순서에 의해 'h'가 됩니다. 나머지 "ukks" 또한 위 규칙대로 바꾸면 "appy"가 되며 결과는 "happy"가 됩니다. 두 문자열 s와 skip, 그리고 자연수 index가 매개변수로 주어질 때 위 규칙대로 s를 변환한 결과를 return하도록 solution 함수를 완성해주세요. 

    <제한사항>

    - 5 ≤ s의 길이 ≤ 50

    - 1 ≤ skip의 길이 ≤ 10

    - s와 skip은 알파벳 소문자로만 이루어져 있습니다.

    - skip에 포함되는 알파벳은 s에 포함되지 않습니다.

    - 1 ≤ index ≤ 20

    (school.programmers.co.kr)

    def solution(s, skip, index):
        alphabet = 'abcdefghijklmnopqrstuvwxyz'
        skip_set = set(skip) # skip 문자열을 set으로 변환하여 in 연산으로 빠르게 포함 여부를 확인.
        result = [] # 결과 문자들을 저장
    
        for char in s:
            new_char = char
            for _ in range(index): 
                new_char = alphabet[(alphabet.index(new_char) + 1) % 26] 
                # %26 => 모듈러 연산. 알파벳을 원형으로 순환하며 인덱스를 계산.
                while new_char in skip_set: # skip 문자를 만나면 다음 문자로 이동.
                    new_char = alphabet[(alphabet.index(new_char) + 1) % 26]
            result.append(new_char)
    
        return ''.join(result)

     

    실행결과 ↴

    solution("aukks","wbqd",5)
    >>> 'happy'