728x90
반응형

 

 

만삭촬영

 

31주에 만삭촬영을 하고왔다.

90분 정도 촬영했는데

컨디션이 나쁘지 않아서 다행이었다.

 

[결혼, 임신] - 임신 31주:: 더블라썸(the BLOSSOM) 만삭촬영 (Ft. 우현증메르시)

 


 

딸꾹질 태동

 

어느순간 느껴진 딸꾹질 태동!

배꼽아래 한 부분에서

주기적으로 맥박처럼 뛰는 것이 느껴졌다.

딸꾹질 태동이라고 하는데

태아가 딸꾹질을 한다니 신기할따름이다.

 


 

허리통증

 

임신했다는 걸 알고 주위에서 몸은 어떠냐하고 걱정해주시는 말을 많이 해주셨다.

사실 큰 이벤트가 없었고,

특별히 안좋다고 느껴본적도 없었기 때문에,

(불로오는 배가 불편하긴 하지만 몸이 안좋다고 말하긴 애매한 정도..)

임신전이나 임신후나 비슷비슷한데

몸걱정을 많이 해주시네? 했었다.

근데 이제 진짜 몸이 안좋다는걸 느낀다.

여기저기 안쑤시는 곳이 없다.

걸을때는 사타구니 통증으로 절뚝거리고,

자려고 누워서 자세를 바꿀때마다 허리와 골반이 아파서 너무 힘들다..

맨날 아이고 소리를 달고 산다..

 

 

가끔 서있을때는 골반이 전기 통하는 것처럼 찌릿찌릿 거린다.

운동한다고 밖에 나가서 걷다가

집에 돌아올때 택시타야 하나 싶었다.

아파트 단지 내나 돌아다녀야 겠다고 생각했다.

 


 

정기검진 및 백일해 주사

 

정기검진을 받았다.

손가락이 그 사이 통통해져 있었다.

배가 너무 무겁고

내 몸무게가 훅훅 늘어서

애기가 거대아가 되어있으려나 하고 걱정했는데

1.6kg 조금 넘는 몸무게로

평균 이하라고 하셨다.....

 

 

양수가 정상범위긴 하지만 좀 적다고 물을 많이 마시라고 하셨다.

이제부터 2주마다 한번씩 내원하면 된다고 하셨다.

검진 후에 남편이랑 같이 백일해 주사를 맞았다.

남편은 주사맞고 멀쩡했는데

난 맞은 부위 근육통이 4일정도는 갔던것 같다.

주사 맞은 다음날은 특히 너무 아팠다.

검진 비용은 10,800원이었고

백일해 주사비용은 50,000원이었다.

 


 

산전마사지

 

연세아란산후 조리원을 예약했고

산전 마사지가 2회 포함되어 있었다.

잊고 있었는데

먼저 연락을 주셔서 검진날에 맞춰 예약을 했다.

 

[결혼, 임신] - [임신 6주 - 7주] 조리원 예약에서 임밍아웃까지!

 

[임신 6주 - 7주] 조리원 예약에서 임밍아웃까지!

처음 아기집을 보고 쌤이 2주뒤에 보자고 했는데, 2주가 어찌나 길던지... 잘 있는건지 어쩐건지 너무 궁금해서 죽을뻔했다. [분류 전체보기] - [임신 1주 - 5주] 임신 준비부터 아기집 확인까지 [임

ttottoro.tistory.com

반응형

 

자가키트로 코로나 검사를 받고 테라피실로 들어갔다.

 

 

탈의하고 따뜻하게 데워진 침대로 들어갔다.

 

 

산전 마사지 답게 바디필로우와 함께하는 마사지였다.

 

 

머리부터 발끝까지 풀어주셨다.

산전마사지기 때문에 압이 세지 않을거라고 하셨는데

난 딱 좋고 너무 시원했다.

산전 마사지 받고 너무 만족해서 바로 산후마사지 8회 추가 결제하고 나왔다.

 

 

압박스타킹 안하는 날은 저녁되면 다리가 팅팅 붓는데

이 날은 마사지를 잘 받아서 그런가

밤까지 압박 스타킹 없이도

말랑말랑한 다리를 유지할 수 있었다.

조리원 들어가서 마사지 받는 날이 기대된다.

 

아 그전에 산전 마사지 한번 더있다!!!

 

 


 

보험청구

 

임신, 출산 관련해서 실비나 실손보험 청구가 안되는 걸로 알고있는데

남편 회사에서 들어주는 단체 보험에서는

임신, 출산 관련해서도 보장을 해준다고 해서 신청해봤다.

뭐가 되고 뭐가 안되는지 모르니깐

일단 서류 다 뽑아서 제출해봤다.

 

6월부터 12월까지 받은 산부인과 진료비 영수증이랑 세부내역서를 발급받아서 제출했다.

급여-본인부담금: 총 148,700원

급여-전액본인부담: 총 68,130원

비급여: 총 190,000원

여기에 입덧약 처방전을 제출했는데

입덧약은 보상이 안된다고 하셨다.

 

그 외에도 진료비에서 보상항목에서 빠지는 것들이 있다고 하셨는데

전화통화로 설명 들은거라 어떤 항목이 제외되는건지 정확하게 기억이 안난다..

 

여튼 그래도 보험 신청해서 총 91,529원을 받았다!!

 

 

728x90
반응형
728x90
반응형

 

 

3개월 전 쯤 더블라썸에서 만삭촬영을 예약했다.

헤어메이크업은 더블라썸과 제휴중인 우현증메르시로 예약했다.

 

예약날부터 준비물도 꼼꼼히 알려주시고

궁금한 사항도 친절하게 답변 해주셔서 좋았다.

 

만삭촬영 예약일이 다가와서 또 한번 연락 주셨다.

준비물을 다시 한 번 상기시켜주셨고

원하는 느낌의 사진이 있는지 물어보셨다.

그리고 자체적으로 보유하고 있는 드레스 중 마음에 드는 드레스를 골라보라고 사진을 보내주셨다.

드레스 종류가 30가지 정도 되는 것 같았다.

 

코로나 때문에 마지막까지도 찍어야 하나 말아야 하나 고민이 많았지만

촬영하시는 분들도 그렇고

헤어메이크업 하시는 분들도 그렇고

3차 접종까지 완료하셨다고 하셨다.

나도 가기 전에 PCR 검사 음성 확인서를 받았다.

 

정말.. 코로나..

시르다...

 


 

우현증 메르시

 

 

위치: 서울 강남구 도산대로26길 50

(논현동 35-7 우현증메르시 뷰티하우스)

전화: 02-546-7740

블로그: https://blog.naver.com/grace_woo

 

우현증메르시 공식 블로그 : 네이버 블로그

우현증메르시 뷰티하우스 공식블로그 대표☎ 02-546-7740 웨딩☎ 02-546-7745 · MAKE UP · HAIR · NAIL · WEDDING · BEAUTY CLASS 카카오톡 문의 ID : musicwoo

blog.naver.com

 


 

헤어메이크업 예약이 8시였다.

평일에 남편이랑 휴가내고

일찍일어나서 메이크업을 받으러가니

5년전 웨딩촬영 생각도 새록새록 나고 그랬다.

 

 

아침 8시라서 그런지 우리밖에 없었다.

 

 

헤어부터 받았다.

열심히 고데기 해주시는데

흰머리가 보였다.....

흰머리라니!!!

 

 

하ㅠㅠ

뽑아달라는 말이 목구멍까지 차올랐지만 참았다...

(집오자마자 남편한테 뽑아달라고 했다...)

머리하고 메이크업실로 갔다.

 

 

5년전으로 돌아간다면

여기서 헤어메이크업을 받았을꺼다..

 

5년전에는 찾아보고 알아보는게 귀찮아서

그냥 대충 선택했었는데...

지금 다시 돌아간다면

엄청 열심히 찾아보고

스드메 결정했을 것 같다...

 

여튼 약 2시간 동안 헤어메이크업을 받고

오전 10시에 스튜디오로 출발했다.

 


 

더블라썸

 

 

위치: 서울 종로구 대학로12길 22 아트포레스트 4층

(서울 종로구 동숭동 1-66 아트포레스트 4층)

전화: 010-8462-3388

인스타그램: https://www.instagram.com/ean_yoo/

웹사이트: http://www.theblossom.co.kr/

 

the BLOSSOM

더블라썸

theblossom.co.kr

반응형

 


 

만삭촬영을 위해 카톡으로 보내주신 준비물들과 애착인형, 입체초음파 사진을 챙겼다.

(근데!!! 둘다 결혼반지도 안끼고 갔다...ㅠㅠ)

 

 

깔끔한 느낌의 스튜디오였다.

 

 

악세서리, 키높이 신발, 보타이도 준비되어 있었다.

 

 

부케도 종류가 다양했다.

 

 

포즈도 세심하게 잡아주시고

머리 모양, 악세서리도 한번 바꿔주시고

드레스 모양도 계속 잡아주셔서 좋았다.

뭔가 헬퍼비 따로 드려야 할 것 같은 느낌이었다.

 

어색했지만 어색하지 않게 찍어주셨다.

간만에 결혼 준비하던 때 생각도 떠올랐다.

 

원본은 사진 찍은 바로 다음날 보내주셨다.

10장 고르면 보정해서 다시 보내준다고 하셨다.

보정본 받기까지는 40일 정도 걸린다고 하셨다.

그래서 보정본은 아직 못받았다.

보정본 너무 궁금.....

 

드레스로 갈아입는 사이에

요렇게 애착인형과 입체초음파사진도 찍어주셨나보다.

찍어주신지도 몰랐는데

너무 감사했다.

 

 

뭔가 웨딩촬영 느낌..?

 

!보정본 아님 주의!

 

가능하면 돌촬영도 여기서 하고 싶었다.

빨리 보정본을 보고싶다~~ㅎㅎ

 

 

 

++

보정본을 받았다!!!

 

 

728x90
반응형
728x90
반응형

 

 

육아 필수템중 하나인 베이비 브레짜를 구매했다.

 

 

받자마자 사용설명서를 정독했다.

특히 세척부분!!

아직 30주밖에 안됐지만 미리 세척해 놓기로 했다.

 

베이비브레짜 세척방법


장기간 사용하지 않을 경우의 세척 방법도 나와있어서 좋았다.

 

 

▼▼장기보관시 물배출 및 내부세척방법▼▼

https://youtube.com/watch?v=7O-Tgcp12SU&feature=share 

반응형

 

사용설명서에 나온대로

제품 내부 세척을 위해

물통에 식초 한컵과 생수를 넣고

물부족 경고등이 나올때까지 물을 뽑았다.

 

 

식초물을 다 뽑고 4시간 정도 나뒀다.

4시간 후에

물통에 생수를 채워서 또 물을 빼냈다.

 

그리고 장기 보관을 위해

사용설명서에 나온대로 뒷면에 물통 연결부위(입수구)를 눌러서

물을 완전히 빼냈다.

 

처음에 키친 타올로 입수구 물기를 제거하라고 되어있어서

그대로 했는데

이걸로 택도 없었다.

 

 

뒤집어서 입수구를 눌렀더니

물이 콸콸 쏟아졌다.

 

 

기기 내부 물빼는 작업을

2-3일은 반복했던 것 같다.

이제 됐겠지 싶어서 해보면

또 물이나오고 또 물이 나왔다.

여튼 이정도면 물이 말라 비틀어졌겠지 싶을때까지

며칠 확인했다.

 

 

청소까지 해놓으니 든든했다.

나중에 아기한테 사용하기 전에

또 한번더 세척할 예정이다.

 

 

브레짜 깔때기는 4번 사용할 때마다

청소해달라고 울린다고 해서 할인 할때

추가로 더 구매했다.

 

 

 

[결혼, 임신] - 임신 23주 아기용품 구매:: 보르르 분유포트 구매

 

임신 23주 아기용품 구매:: 보르르 분유포트 구매

임신 중기에 들어서면서 그동안 참아왔던 소비 고삐가 풀리기 시작했다. 핫딜 뜨는걸 유심히 보다가 보르르 분유포트가 나와서 살짝 고민하는 척 하고 바로 구매했다. 분유포트는 사실 뭘 사야

ttottoro.tistory.com

 

728x90
반응형
728x90
반응형

 

 

베베폼에서 국민행복카드를 신청했다.

 

http://bebeform.co.kr/kookminhappycard/

 

베베폼 | 부모와 아기의 라이프스타일 큐레이터, bebeform

대한민국 NO. 1 임신축하박스, 베베폼 임신박스! 국민행복카드, 산모교실, 육아용품에 대한 모든 것!

bebeform.co.kr

 

다양한 카드사중 하나를 고를 수 있었다.

 

 

행사를 진행중이었는데

행사기간 동안 10만원을 쓰면 기프트를 증정해준다고 한다.

 

 

 

임신 출산 진료비 지원 바우처는 카드 수령후 카드사를 통해 신청할 예정이다.

 

반응형

 


 

삼성카드로 국민 행복카드를 신청하니

삼성카드에서 선물상자를 배송해줬다.

 

 

스킨케어와 세제 샘플, 젖병과 귀저기 샘플,

애기 지퍼백 등등이 들어있었다.

 

 

베베폼에서 보내준

매직캔까지 잘 받았다.

 

 


 

베베폼 임신박스도 같이 신청했다.

 

 

http://bebeform.co.kr/giftbox/

 

베베폼 | 부모와 아기의 라이프스타일 큐레이터, bebeform

대한민국 NO. 1 임신축하박스, 베베폼 임신박스! 국민행복카드, 산모교실, 육아용품에 대한 모든 것!

bebeform.co.kr

 

728x90
반응형
728x90
반응형

이 글은 Head First에서 나온 Design Patterns 책을 보고 이해한 내용을 나름대로 정리한 내용입니다.

옵저버 패턴(Observer Pattern)은 출판사 와 구독자와 같은 관계를 갖는 패턴이다. 구독자들이 출판사에 구독을 신청하면 출판사는 신문이 출간될 때마다 구독자들에게 신문을 저달한다. 구독자가 구독을 해지하면 더이상 신문을 받지 않는다. 이렇게 옵저버 패턴은 일대다 의존성을 정의하는 패턴이다.

옵저버 패턴에서 일반적으로 출판사 열할을 하는 객체를 Subject 라고 부르고 구독자 객체를 Observer라고 부른다. 모든 Subject는 자신에게 "구독 추가", "구독 해지" 메소드가 있다는 것을 구독자들에게 알려줘야하고, 반드시 알림(신문을 전달하는 행동) 메소드가 필요하다. 이를 추상화 하여 인터페이스로 구현해보자.

public interface ISubject
{
    void AddObserver(IObserver observer);  // 구독자 추가
    void RemoveObserver(IObserver observer); // 구독자 삭제
    void NotifyObserver(); // 구독자들에게 알림
}

이번엔 구독자인 Observer를 보자. 모든 ObserverSubject에게 "나에게는 Update()라는 메소드가 있으니 필요하면 이 메소드를 통해 전달해주세요" 라고 알려줘야한다. 이를 추상화 하여 인터페이스로 만든다.

public interface IObserver
{
    void Update(Object obj); // Subject가 갱신된 내용을 전달하는 메소드
}

* 이 예제에서는 범용적으로 사용하기 위해 Update의 인자로 Object를 넣었는데 구체적인 객체로 받아도 상관 없다.

이제 구체적인 상황을 설정해보자. 나는 WebParser라는 클래스를 Subject로 만들어 3초마다 웹에서 파싱한 내용을 구독자들에게 저달하려고 한다. 시뮬레이션이기 실제 웹파싱을 하진 않고 3초마다 랜덤 String을 만들어 웹에서 긁어온 키워드라고 가정을했다.

public class WebParser : ISubject 
{
    private List<IObserver> _observers = new List<IObserver>();

    public string WebContents { get; set; }

    // 생성자에서 시뮬레이터를 동작시킴
    public WebParser()
    {
        Task.Run(() => SimulateWebParser());
    }

    // 웹 파싱 시뮬레이터 메소드
    private void SimulateWebParser()
    {            
        while(true)
        {
            Thread.Sleep(3000);
            WebContents = RandomStringGenerator();
            NotifyObserver();
        }
    }

    // 랜덤으로 String을 생성해주는 메소드
    private string RandomStringGenerator()
    {
        Random random = new Random();
        const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        return new string(Enumerable.Repeat(chars, 10)
            .Select(s => s[random.Next(s.Length)]).ToArray());
    }

    // Observer가 구독을 신청하는 메소드
    public void AddObserver(IObserver subscriber)
    {
        _observers.Add(subscriber);
    }

    // Observer가 구독을 해지하는 메소드
    public void RemoveObserver(IObserver subscriber)
    {
        if (_observers.Contains(subscriber))
            _observers.Remove(subscriber);
    }

    // 구독중인 Observer들에게 변경을 알려주는 메소드
    public void NotifyObserver()
    {
        foreach(var observer in _observers)
        {
            // Observer의 Update 메소드이용해 갱신해줌.
            observer.Update(this);
        }
    }
}

랜덤 String을 만드는 작업 때문에 코드가 조금 길어졌는데 중요한 부분은 ISubject 인터페이스의 AddObserver(), RemoveObserver(), NotifyObserver()를 어떻게 구현했는지만 보면 된다.

이제 마지막으로 간단한 Observer들을 만들어보자. 나는 WebParser로부터 전달받은 내용을 디스플레이해주는 객체와 이메일로 전달 해주는 두 가지 Observer를 만들었다.

public class DisplayWebContents : IObserver
{
    public DisplayWebContents(WebParser webParser)
    {
        webParser.AddObserver(this);
    }
    public void Update(object obj)
    {
        if (obj is WebParser)
        {
            var webParser = obj as WebParser;
            Console.WriteLine($"Display {webParser.WebContents}"); 
        }
    }
}

public class EmailWebContents : IObserver
{
    public EmailWebContents(WebParser webParser)
    {
        webParser.AddObserver(this);
    }
    public void Update(object obj)
    {
        if (obj is WebParser)
        {
            var webParser = obj as WebParser;
            Console.WriteLine($"Email {webParser.WebContents}");
        }
    }
}

Observer 구상클래스를 보면 알겠지만 구독을 신청하기 위해 Subject의 구상클래스를 반드시 포함하고 있다. 클래스 다이어그램을 보면서 다시 한 번 확인해보자.

이제 마지막으로 Main 함수와 실행 결과를 확인해보자.

class Program
{
    static void Main(string[] args)
    {
        WebParser wp = new WebParser();

        DisplayWebContents display = new DisplayWebContents(wp);
        EmailWebContents email = new EmailWebContents(wp);

        Thread.Sleep(100000);
    }
}

실행결과:

3초에 한번식 랜덤 String이 생성되고 디스플레이와 이메일이 업데이트됨.

이렇게 옵저버 패턴에서는 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들한테 연락이 가고 자동으로 내용이 갱신되는 방식으로 일대다(one-to-many) 의존성을 정의한다.

참고 자료: Head First - Design Pattern

728x90
반응형
728x90
반응형

이 글은 Head First에서 나온 Design Patterns 책을 보고 이해한 내용을 나름대로 정리한 내용입니다.

Stratagy pattern은 알고리즘 집합을 정의하고 각각 캡슐화 하여 교환해서 사용할 수 있도록 한 것이다.

스타크래프트 예제로 두 개의 알고리즘 집합을 정의 하려고 한다. 하나는 '공격'에 대한 알고리즘 집합이고, 다른 하나는 '이동'에 대한 알고리즘 집합이다.

두 개의 알고리즘 집합 :

  • IAttackBehavior (인터페이스)
  • IMoveBehavior (인터페이스)
public abstract class Unit
{
    // 모든 유닛은 '공격'과 '이동'이라는 두가지 행동이 가능함.
    private IAttackBehavior _attackBehavior;
    private IMoveBehavior _moveBehavior;

    public void SetAttackBehavior(IAttackBehavior attackBehavior)
    {
        _attackBehavior = attackBehavior;
    }
    public void SetMoveBehavior(IMoveBehavior moveBehavior)
    {
        _moveBehavior = moveBehavior;
    }
    public void PerformAttack()
    {
        _attackBehavior.Attack();
    }
    public void PerformMove()
    {
        _moveBehavior.Move();
    }
}

public interface IAttackBehavior
{
    void Attack();
}

public interface IMoveBehavior
{
    void Move();
}

각 집합은 인터페이스로 추상화하여 나중에 구체적인 알고리즘을 만들때 이 인터페이스들을 상속받도록 한다.

구체적인 행동(알고리즘) :

// 공격에 대한 구체적인 알고리즘 1. 원거리 공격
public class AttackFar : IAttackBehavior
{
    public void Attack()
    {
        Console.WriteLine("원거리 공격!!");
    }
}

// 공격에 대한 구체적인 알고리즘 2. 근거리 공격
public class AttackNear : IAttackBehavior
{
    public void Attack()
    {
        Console.WriteLine("근거리 공격!!");
    }
}

// 이동에 대한 구체적인 알고리즘 1. 땅에서 이동
public class MoveGround : IMoveBehavior
{
    public void Move()
    {
        Console.WriteLine("땅에서 이동");
    }
}

// 이동에 대한 구체적인 알고리즘 2. 하늘에서 이동
public class MoveSky : IMoveBehavior
{
    public void Move()
    {
        Console.WriteLine("하늘에서 이동");
    }
}

이제 유닛을 만들 준비가 다 되었다.
저글링과 뮤탈리스크를 만들어보자.

public class Zergling : Unit
{
    public Zergling()
    {
        // 저글링은 근거리 공격을 하고 땅에서 이동함.
        SetAttackBehavior(new AttackNear());
        SetMoveBehavior(new MoveGround());
    }
}

public class Mutalisk : Unit
{
    public Mutalisk()
    {
        // 뮤탈리스크는 원거리공격을하고 하늘에서 이동함.
        SetAttackBehavior(new AttackFar());
        SetMoveBehavior(new MoveSky());
    }
}

생성자에 '공격'과 '이동'에 대한 구체적인 행동을 할당해주어 태어나면서 구체적인 행동을 갖도록 했다.

이제 Main 함수와 실행 결과를 확인해보자.

class Program
{
    static void Main(string[] args)
    {
        // 저글링
        Zergling myZergling = new Zergling();
        myZergling.PerformMove();
        myZergling.PerformAttack();


        // 뮤탈리스크
        Mutalisk myMutalisk = new Mutalisk();            
        myMutalisk.PerformMove();
        myMutalisk.PerformAttack();

        // 뮤탈리스크가 갑자기 땅으로 이동하고싶어짐.
        Console.WriteLine("\n땅으로 이동하고싶다~");
        myMutalisk.SetMoveBehavior(new MoveGround());
        myMutalisk.PerformMove();
        myMutalisk.PerformAttack();
    }
}

지금까지 만든 프로그램을 Class Diagram으로 다시한 번 확인해보자.

stratagy 패턴을 사용하면 이렇게 알고리즘 집합을 추상화 함으로써 알고리즘을 동적으로 교환할 수 있도록 한다.

참고 자료: Head First - Design Pattern

728x90
반응형
728x90
반응형

PlantUML은 프로그램언어처럼 코드로 다이어그램을 작성할 수 있도록 도와주는 오픈소스 툴이다. 코드로 작성하기 때문에 빠르게 작성할 수 있다는 장점도 있지만 중요한 키워드들은 외워놓던지 찾아가면서 작성해야한다는 단점도 있다.

VSCode 에도 plantUML을 지원하는 Extension이 있어 설치 및 사용 방법을 정리하고자 한다.

  1. 일반적인 Extension 설치와 마찬가지로 PlantUML을 검색하고 설치한다.
  2. VSCode 안에 새로운 파일을 생성한다. 확장자 명은 다음 중 하나로 해야함. (*.wsd, *.pu, *.puml, *.plantuml, *.iuml)
  3. 예제 코드를 작성해보고 Alt + D 를 눌러서 preview 가 잘 나오는지 확인한다.
example.pu preview (Alt + D)

  • 만약 preview가 보이지 않는다면 Java 또는 Graphviz가 설치되지 않았기 때문일 가능성이 크다. Documnet에는 PlantUML설치시 Graphviz가 같이 설치된다고 써있긴 하지만 이상하게 설치가 안되는 경우가 있는 것 같다. 공식 홈페이지에 가서 직접 설치해주자.
  1. 완성된 다이어그램을 Export 하려면 F1 키를 누르고 plantuml export를 검색하면 세 가지 옵션으로 Export 할 수 있다.

728x90
반응형
728x90
반응형

나는 프로그래밍을 처음 배울 때 컴파일(Compile) 또는 빌드(Build)라는 용어의 개념을 구분해본적이 없었다.
간혹(또는 자주) 주변 사람들도 두 용어를 같은 의미로 함께 사용하기도 하는 것 같았다.

하지만 굳이 따지자면 두 용어는 다른 의미를 지니고 있다.
C언어는 사실 컴퓨터가 이해할 수 있는 언어는 아니고 사람이 읽고 쓸 수 있는 언어이다. 이런 C 언어를 컴퓨터가 이해할 수 있는 언어(기계어)로 번역하는 것이 컴파일(Compile) 이고, 컴파일을 해주는 놈을 (Compiler) 라고 부른다.

그리고 이렇게 컴파일되어 기계어로 작성된 파일을 오브젝트(Object) 파일 이라고 부르는데, 이 오브젝트 파일들과 라이브러리 파일들을 연결시켜 최종적으로 실행파일을 만들게 된다.
이렇게 연결시키는 작업을 링크(Link), 연결시키는 작업을 해주는 놈을 링커(Linker) 라고 부른다. 이렇게 링크를 거치고 나면 최종적으로 실행파일이 생성되게 된다.

마지막으로 빌드(Build)는 이런 일련의 과정을 통칭하는 표현이다.
다시 말해 "빌드 해라" 라는 말을 풀어쓰면 "작성한 코드를 기계어로 번역하고 필요한 파일들을 연결시켜 실행파일을 만들어라" 라는 말이 되는 것이다.

이해를 돕기위해 Visual Studio를 사용하지 않고 간단한 프로그램을 하나 만들어 보았다.
보통 Mac에서는 Xcode를 설치할때 gcc라는 컴파일러가 함께 설치되는데 이것을 이용해 터미널에서 컴파일을 해보자.
터미널에 'gcc -v' 를 입력했을 때 아래와 같이 정보가 나오면 gcc가 설치되어있는 것이다.

$ gcc -v

Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
Apple clang version 12.0.5 (clang-1205.0.22.11)
Target: x86_64-apple-darwin20.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

아무 텍스트 에디터나 열어 아래와 같이 코드를 작성하고 'CompileTest.c'라고 저장해보자.

#include <stdio.h>

int main()
{
  printf("Hello world!\n");
  return 0;
}

그리고 터미널에 아래와 같이 gcc 를 이용해서 작성한 파일을 컴파일하면
[fileName]에 입력한 이름으로 실행파일이 생성된다.

$ gcc -o [fileName] CompileTest.c

생성된 실행파일을 실행시키면 'Hello world!'가 잘 출력되는 것을 확인할 수 있다.
Visual Studio를 이용하면 마술처럼 완성되는 실행파일이 사실 이런 과정을 거쳐 만들어지게 되는 것이다.

728x90
반응형
728x90
반응형

정규식(Regular Expression)은 긴 문자열 안에서 특정한 패턴을 가진 문자열을 찾아내기 위해 사용된다.

예를 들어 웹페이지 안에서 이메일 주소를 추출한다거나 로그파일에서 특정 에러 메시지를 추출할때 매우 편리하게 사용할 수 있다.

우선 regex를 테스트하기 위한 여러 웹 어플리케이션들이 있지만 Regex101이라는 사이트가 가장 사용하기 편리했다. https://regex101.com/

사용 방법은 위에 캡쳐한 이미지처럼 'TEST STRING' 입력창 에 실험 대상이 들어갈 문자열들을 입력해놓고, 'REGULAR EXPRESSTION' 입력창에 찾고자하는 패턴을 입력하면 된다.

나는 이 실험 대상에 임의의 6개 단어를 참가시켰고, 찾고자 하는 패턴 'bo' 를 입력했더니 'MATCH INFORMATION'에 3군데 일치하는 곳이 있음을 알려주고 있다.

'bo'라는 패턴을 조금 더 정확히 해석하면
"b 다음에 o가 나오는 문자열이 있나요?" 라고 질문을 던진 것이다. 이처럼 정규식은 앞에서부터 한글자씩 일치하는지 여부를 확인한다.

문자집합 (Charecter Set)

대괄호('[ ]')를 이용하면 문자집합을 나타낼 수 있다. 문자집합은 대괄호 안에 오는 어떤 문자든 오면 일치시킨다.
같은 예제에 패턴 'bl[ao]'를 입력해보았다. 이를 해석하면 "b 다음에 l이 있고, 그 다음에 a 또는 o가 오는 문자열이 있나요?" 라고 풀이할 수 있다.

수량자 (Quantifier)

중괄호('{ }')를 이용하면 수량을 나타낼 수 있다.
같은 문자가 여러번 나올 때는 그 중괄호 안에 문자가 반복되는 횟수를 입력하여 더 간단하게 표현할 수 있다.
이번엔 기존 예제에 두개의 실험 대상을 더 추가하고 'bo{4}' 라고 패턴을 입력해보았다.
해석하자면 "b 다음에 o가 네번 반복되는 문자열이 있나요?" 라는 질문이다.

그룹화 (Group)

소괄호('( )')를 이용하면 그룹을 나타낸다. 지금까지 본 것 처럼 정규식은 기본적으로 한 단어씩 일치 여부를 확인하지만, 소괄호 안에 여러개의 문자를 넣으면 괄호안에 포함된 단어를 하나의 그룹으로 묶어서 판단한다. 예를 들어 '(bo){2}'라는 패턴을 입력해보자. 소괄호가 없었다면 o 가 두번 반복되는지 여부를 판단하겠지만 bo를 소괄호로 묶어주어 bo 가 두번 반복되는지 여부를 판단한다.

그룹화를 하게되면 기본적으로 캡쳐도 동시에 되는데,
캡쳐된 그룹은 'MATCH INFORMATION' 창을 보면 캡쳐된 그룹을 볼 수 있다. 아래 예제는 날짜 중에 특히 몇월인지 캡쳐하는 방법이다.
(참고로 '\d' 는 '아무 숫자'를 의미하고, '\w' 는 '특수문자를 제외한 아무문자'를 의미한다)

여기까지 잘 이해했다면, 그 다음부터는 특별한 설명 없이 아래 표만 참고해도 충분히 이해 할 수 있을 것 같다. 이 표는 Regex 에서 가장 많이 사용되는 패턴들을 정리한 표이다.

 

패턴 설명 예제
[abc] a,b,c 중에 아무거나
[^abc] a,b,c 를 제외하고 아무거나
[a-z] a 부터 z까지 문자중에 아무거나
[^a-z] a 부터 z까지 문자를 제외하고 아무거나
. 아무 문자 하나
a|b a 또는 b
\s 공백문자 중에 아무거나
\S 공백문자를 제외한 아무거나
\d 숫자 중에 아무거나
\D 숫자를 제외하고 아무거나
\w 알파벳이나 숫자 중에 아무거나
\W 알파벳이나 숫자를 제외하고 아무거나(특수문자)
(?:...) 그룹화하지만 캡쳐는 하지 않음
(...) 그룹화하고 캡쳐
a? a 가 없거나 한개 있거나
a* a 가 없거나 여러개 있거나
a{3} a가 3개
a{3,} a가 3개이거나 그 이상이거나
a{3,6} a가 3개 이상 6개 이하
^ 문자열 시작
$ 문자열 끝
\b 단어의 경계
\B 단어의 경계 아닌 아무거나
728x90
반응형
728x90
반응형

객체 지향 언어의 4대 기본 원칙 중 마지막 원칙인 다형성에 대해 알아보자.

객체 지향 언어의 4대 기본 원칙 :

  • 캡슐화 (Encapsulation)
  • 추상화 (Abstraction)
  • 상속 (Inheritance)
  • 다형성 (Polymorphism)

지난 포스트에서 다룬 상속은 사실 다형성을 위해서 사용되는 경우가 더 많다. 다형성은 "여러가지 형태를 갖는 것을 허용한다"는 뜻이다.

이전 포스트에서 사용했던 예제를 다시 한 번 들여다보자.

class Program
{
    static void Main(string[] args)
    {
        Dog myDog = new Puppy();
        myDog.Bark();
        //실행결과 --> 삑삑!
    }
}
public class Dog
{
    public virtual void Bark()
    {
        Console.WriteLine("멍멍!");
    }
}

public class Puppy : Dog
{
    public override void Bark()
    {
        Console.WriteLine("삑삑!");
    }
}

위 예제에서 Main함수를 보면 myDog라는 변수를 Dog로 선언했는데 실제로 생성한 객체는 Dog의 자식클래스인 Puppy이다.

이렇게 부모클래스로 선언된 변수에 자식클래스들도 할당될 수 있도록 허용한 것이 다형성이다. (반대로 자식클래스에 부모클래스를 할당하는 것은 불가능하다.)

다형성이 왜 필요한지 생각해보기 위해 간단한 예제를 만들어보자.

class Program
    {
    static void Main(string[] args)
    {
        List<Dog> myDogs = new List<Dog>();

        Dog dog1 = new Dog();
        myDogs.Add(dog1);
        Dog dog2 = new Puppy();
        myDogs.Add(dog2);
        Dog dog3 = new FakeDog();
        myDogs.Add(dog3);

        foreach(Dog dog in myDogs)
        {
            dog.Bark();
        }
    }
}

public class Dog
{
    public virtual void Bark()
    { 
        Console.WriteLine("멍멍!");
    }
}

public class Puppy : Dog
{
    public override void Bark()
    {
        Console.WriteLine("삑삑!");
    }
}

public class FakeDog : Dog
{
    public override void Bark()
    {
        Console.WriteLine("야옹~!");
    }
}

위 예제를 보면 Dog를 담을 수 있는 ListDog뿐만 아니라 Dog의 자식 클래스인 PuppyFakeDog도 들어가는 것을 볼 수 있다. 만약 다형성을 허용하지 않았다면. List<Dog>, List<Puppy>, List<FakeDog>를 모두 별도로 만들어 각각 따로 관리해야했을 것이다. 우리는 다형성을 이용해서 자료를 훨씬 체계적으로 관리 할 수 있다. 뿐만 아니라 클래스간의 의존성을 낮춰 느슨한 결합이 가능하게 한다. 느슨한 결합에 대해서는 디자인 패턴을 공부하면서 조금 더 알아보자.

마지막으로 지난 포스트 상속편에서 new키워드를 이용해서 부모클래스의 메소드를 변경했을 때 실행결과가 달라졌던 이유를 다시 한 번 생각해보자.

class Program
{
    static void Main(string[] args)
    {
        Puppy myPuppy = new Puppy();
        myPuppy.Bark();
        //실행결과 --> 삑삑!
        Dog myDog = new Puppy();
        myDog.Bark();
        //실행결과 --> 멍멍!
    }
}

public class Dog
{
    public void Bark()
    { 
        Console.WriteLine("멍멍!");
    }
}

public class Puppy : Dog
{
    public new void Bark() // new 키워드를 이용해 부모 메소드를 가린다.
    {
        Console.WriteLine("삑삑!");
    }
}

위 예제에서 보면 myPuppymyDog 변수 모두 Puppy 객체를 가지고 있지만 선언된 데이터 형태에 따라서 "멍멍"이라고 짖기도 하고 "삑삑"이라고 짖기도 한다. 이건 다형성의 원칙을 훼손하는 케이스다. 선언된 데이터 타입이 어떻든 Puppy는 "삑삑"하고 짖어야하지 않을까? 이러한 이유로 new키워드를 이용해 부모클래스의 함수를 변경하는 것은 지양해야한다.

728x90
반응형

+ Recent posts