NGMsoftware

NGMsoftware
로그인 회원가입
  • 매뉴얼
  • 학습
  • 매뉴얼

    학습


    C# C# .NET 매크로 프로그램 만들기. (숫자 체크 액션 만들기)

    페이지 정보

    본문

    안녕하세요. 엔지엠소프트웨어입니다. 대부분의 액션들이 중요한 내용을 담고 있겠지만, 이번에 새롭게 추가된 숫자 체크 액션은 개발자로써 정말 많은 고민을 하게한 액션입니다. 일반적으로 문자열을 처리하는건 간단합니다. 그리고, 다양한 방식으로 값을 처리해서 자동화 할 수 있는데요. 문제는 숫자입니다. 숫자는 문자가 아니기 때문에 매크로 속성에서 몇가지 제약이 따릅니다. 일단 크다, 작다를 판단하려면 숫자여야 하고 숫자는 int, double, decimal, float 형식이 있습니다. 그렇다보니 소수점 자리수를 어떻게 처리해야 할까를 고민할수밖에 없습니다.

     

    그리고, 숫자형식은 각각 허용하는 자리수가 다릅니다. 이런 모든 제약을 뚫고 플레이스홀더 기능까지 적용하려면 무조건, 문자열로 값을 받아서 내부 처리를 거쳐야 하는 번거로움이 발생합니다. 큰 문제는 아니지만 코드의 가독성이 떨어지고 예측하지 못한 문제들이 발생할 수 있습니다. 그렇더라도 사용자의 편의를 위해 플레이스홀더를 포기할 수 없었는데요. 앞으로 더 많은 속성과 기능이 추가될테지만, 현재는 문자열로 좌항과 우항 값을 받아서 플레이스홀더까지 적용되도록 구현했습니다.

     

    NumbercheckModel의 속성은 2가지입니다. 좌항과 우항을 비교할 옵션과 소수점 몇번째 자리수까지 비교할지 사용자가 선택할 수 있습니다.

    public class NumberCheckModel : CheckModel
    {
        [Category("Action")]
        [LocalizedDisplayName("NumberCheckOption")]
        [LocalizedDescription("CheckOption")]
        [Browsable(true)]
        [DefaultValue(typeof(Ai.Definition.NumberCheckOption), "Equals")]
        public Ai.Definition.NumberCheckOption CheckOption { get; set; } = Definition.NumberCheckOption.Equals;
    
        [Category("Action")]
        [LocalizedDisplayName("DecimalPlaces")]
        [LocalizedDescription("DecimalPlaces")]
        [Browsable(true)]
        [DefaultValue(0)]
        public int DecimalPlaces { get; set; }

     

    NumberCheckOption은 아래와 같이 비교 방법을 제공합니다.

    public enum NumberCheckOption
    {
        Equals = 0,
        LessThan = 1,
        GreaterThan = 2,
        EqualsLessThan = 3,
        EqualsGreaterThan = 4
    }

     

    각각의 비교 옵션의 LessThanGreaterThan은 보다 작다와 보다 크다입니다. Equals가 붙으면 같거나 작다와 같거나 크다입니다. 간단한 내용인데요. 수식에서는 아래와 같이 표현할 수 있습니다. 아래 내용은 "10이 11보다 작다"입니다. 항상 좌항을 기준으로 크다 작다 비교된다는 점을 기억해야 합니다.

    • 10 LessThan 11 (True)
    • 10 < 11 (True)

    S8BzAoc.png

     

     

    GreaterThen은 아래와 같이 False 나옵니다. 10은 11보다 작기 때문입니다. 항상 좌항을 기준으로 처리됩니다.

    DvWEaI2.png

     

     

    소수점은 기본적으로 정수만 비교합니다. 10.123과 10.12의 정수 부분만 잘라서 비교하기 때문에 Equals는 True가 나옵니다.

    K7jhpq4.png

     

     

    소수점 자리수를 3으로 입력하고, 실행하면 결과는 False가 됩니다.

    pm2OA1p.png

     

     

    아마도, 다음에는 형식 속성도 추가될거 같은데요. 아무래도, float와 decimal, double은 자리수를 표현할 수 있는 한계가 다르고, 정밀도에 대한 영향도 있어서 좀 더 많은 테스트가 필요합니다. 프로그래밍 언어에서 숫자 형식의 정밀도에 대해서는 관련 자료들을 한번 찾아보세요. 정말 재미있는 내용입니다.

     

    모델의 Execute 메소드는 아래와 같이 구현할 수 있습니다. 플레이스홀더를 사용하기 위해서 내용이 많이 복잡해졌습니다. 그렇더라도 편의 기능은 포기할 수 없죠^^;

    public override string? Execute(Ai.Interface.IPlayer player)
    {
        string? id = base.Execute(player);
    
        string leftValue = Ai.Common.Helper.GetMatches(player, this.GetType().GetProperty(nameof(LeftValue)), LeftValue);
        string rightValue = Ai.Common.Helper.GetMatches(player, this.GetType().GetProperty(nameof(LeftValue)), RightValue);
    
        if (leftValue.Contains("."))
        {
            var dp = leftValue.Split('.');
            leftValue = dp[0] + "." + (dp[1].Length < DecimalPlaces ? dp[1] : dp[1].Substring(0, DecimalPlaces));
        }
    
        if (rightValue.Contains("."))
        {
            var dp = rightValue.Split('.');
            rightValue = dp[0] + "." + (dp[1].Length < DecimalPlaces ? dp[1] : dp[1].Substring(0, DecimalPlaces));
        }

     

    비교 옵션은 일단 double만 처리할 수 있도록 했는데요. 만약, 숫자 형식에 대한 옵션을 제공하게되면 Casting하는 방식이 달라져서 이 코드도 형식 수 만큼 case가 늘어날듯 합니다.

    switch (CheckOption)
    {
        case Definition.NumberCheckOption.EqualsGreaterThan:
            ConditionResult = double.Parse(leftValue) >= double.Parse(rightValue);
            break;
        case Definition.NumberCheckOption.GreaterThan:
            ConditionResult = double.Parse(leftValue) > double.Parse(rightValue);
            break;
        case Definition.NumberCheckOption.EqualsLessThan:
            ConditionResult = double.Parse(leftValue) <= double.Parse(rightValue);
            break;
        case Definition.NumberCheckOption.LessThan:
            ConditionResult = double.Parse(leftValue) < double.Parse(rightValue);
            break;
        default:
            ConditionResult = leftValue == rightValue;
            break;
    }

     

    결과는 위에서 미리 테스트했기 때문에 이 내용을 실행하면 정상적으로 동작할겁니다. 이 내용을 토대로 다음에 만들 숫자 연산들도 조금만 바꾸면 쉽게 만들 수 있을겁니다. 대부분의 프로세스 메소드를 추가해두었기 때문에 재사용만 잘 하면 쉽게쉽게 기능을 만들어 나갈 수 있을겁니다. 물론, 완전 새롭게 만들어야 하는 것들도 존재하겠지만, 숫자와 텍스트 처리 관련된 내용들을 어느정도 구현해두었기 때문에 이제 코딩 속도가 좀 붙을거 같네요^^

     

    개발자에게 후원하기

    MGtdv7r.png

     

    추천, 구독, 홍보 꼭~ 부탁드립니다.

    여러분의 후원이 빠른 귀농을 가능하게 해줍니다~ 답답한 도시를 벗어나 귀농하고 싶은 개발자~

    감사합니다~

    • 네이버 공유하기
    • 페이스북 공유하기
    • 트위터 공유하기
    • 카카오스토리 공유하기
    추천0 비추천0

    댓글목록

    등록된 댓글이 없습니다.