유료 매크로 프로그램 다운로드
http://ngmsoftware.com/bbs/board.php?bo_table=product_review
#매크로 #메크로 #매크로프로그램 #엔지엠소프트웨어 #엔지엠에디터 #엔지엠플레이어 #비활성매크로 #하드웨어매크로 #기계식매크로 #마우스광클릭 #키보드매크로 #이미지서치 #이미지매치 #블로그 #카페 #인스타그램 #유튜브 #소셜네트워크 #카카오톡 #텔레그램 #자동화
- 엔지엠 커뮤니티 월 이용료: 4,500원, 1년 이용료: 55,000원 (전체 기능의 80프로)
- 엔지엠 얼티밋 월 이용료: 6,500원, 1년 이용료: 77,000원 (전체 기능의 90프로)
- 엔지엠 엔터프라이즈 월 이용료: 9,200원, 1년 이용료: 110,000원 (전체 기능 사용)
안녕하세요. 엔지엠소프트웨어입니다. 이전 시간에 배열 정렬에 대해 알아봤는데요. 배열을 정렬할 때 "텍스트를 좀 더 다이나믹하게 정렬할 수 없을까?" 하는 의문이 들었습니다. 그래서 텍스트중에서 특정 단어와 유사한 정도가 높거나 낮은 순서로 정렬하는건 어떨까 생각 해봤습니다. 이 기능이 꼭 필요한건 아닐거예요. 하지만, 어차피 텍스트 유사율을 체크할 수 있는 조건을 만들어야 하고, 이 기능을 접목할 수 있다면 좋을겁니다. 그래서, 배열 정렬에 대한 내용을 잠시 멈추고 텍스트 유사율 체크 조건을 먼저 만들기로 했습니다. 어차피 해야 하니까요^^
아래와 같이 컨디션안에 TextSimilarityCheckModel 모델을 하나 추가했습니다.
텍스트 유사율 체크는 조건이기 때문에 CheckModel을 상속 받아서 구현해야 합니다. 기본 조건의 결과뿐만 아니라 몇가지 정보를 더 제공해야 합니다. 그래서, MatchRateResult와 MismatchCountResult가 데이타 영역에 추가되어 있습니다. 일단 이들은 조건을 어떻게 처리할지에 따라서 결과가 달라지고, 참과 거짓 처리가 결정됩니다.
[LocalizedCategory("Data")]
[LocalizedDisplayName("MatchRateResult")]
[LocalizedDescription("MatchRateResult")]
[Browsable(true)]
[DefaultValue(0d)]
[ReadOnly(true)]
public double MatchRateResult { get; set; }
[LocalizedCategory("Data")]
[LocalizedDisplayName("MismatchCountResult")]
[LocalizedDescription("MismatchCountResult")]
[Browsable(true)]
[DefaultValue(0)]
[ReadOnly(true)]
public int MismatchCountResult { get; set; }
[LocalizedCategory("Action")]
[LocalizedDisplayName("SimilarityRate")]
[LocalizedDescription("SimilarityRate")]
[Browsable(true)]
[DefaultValue(80)]
public int SimilarityRate { get; set; } = 80;
[LocalizedCategory("Action")]
[LocalizedDisplayName("MismatchCount")]
[LocalizedDescription("MismatchCount")]
[Browsable(true)]
[DefaultValue(1)]
public int MismatchCount { get; set; } = 1;
[LocalizedCategory("Action")]
[LocalizedDisplayName("MatchTypeOption")]
[LocalizedDescription("MatchTypeOption")]
[Browsable(true)]
[DefaultValue(typeof(Ai.Definition.MatchTypeOption), "SimilarityRate")]
public Ai.Definition.MatchTypeOption MatchTypeOption { get; set; } = Definition.MatchTypeOption.SimilarityRate;
조건을 처리하는 옵션은 2개를 제공합니다. A와 B 텍스트의 유사율이 80프로 이상이면 참이라고 체크할 수 있고, MismatchCount는 A와 B 텍스트에서 다른 부분의 수를 체크합니다. 따라서, 이 둘은 서로 반대로 동작하게 됩니다. 유사율은 사용자가 설정한 값보다 크면 참이고, 다른 문자 수는 설정 값보다 크면 참이 됩니다.
public enum MatchTypeOption
{
SimilarityRate = 0,
MismatchCount = 1
}
아래는 프로세스 전체 코드입니다.
public override string? Execute(IPlayer player)
{
MatchRateResult = 0d;
MismatchCountResult = 0;
var id = base.Execute(player);
int n = LeftValue.Length;
int m = RightValue.Length;
int[,] d = new int[n + 1, m + 1];
for (int i = 0; i <= n; d[i, 0] = i++);
for (int j = 1; j <= m; d[0, j] = j++);
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
int cost = (RightValue[j - 1] == LeftValue[i - 1]) ? 0 : 1;
int min1 = d[i - 1, j] + 1;
int min2 = d[i, j - 1] + 1;
int min3 = d[i - 1, j - 1] + cost;
d[i, j] = System.Math.Min(System.Math.Min(min1, min2), min3);
}
}
MismatchCountResult = d[n, m];
MatchRateResult = (double)(LeftValue.Length - MismatchCountResult) / LeftValue.Length * 100;
switch (MatchTypeOption)
{
case MatchTypeOption.SimilarityRate:
ConditionResult = MatchRateResult == 100 ? true : MatchRateResult > SimilarityRate;
break;
case MatchTypeOption.MismatchCount:
ConditionResult = MismatchCountResult == 0 ? false : MismatchCountResult > MismatchCount;
break;
}
player.Manager.Output.WriteLine(
$"{player.Manager.Client.ResxCaption.GetString("MatchTypeOption")}:{MatchTypeOption},
{player.Manager.Client.ResxCaption.GetString(nameof(LeftValue))}:
{LeftValue}, {player.Manager.Client.ResxCaption.GetString(nameof(RightValue))}:
{RightValue}", log4net.Core.Level.Debug);
Common.ConditionProcess(this, ref id);
return id;
}
로직은 간단합니다. 왼쪽 텍스트와 오른쪽 텍스트를 변수에 추가하고, 길이를 계산합니다. 그리고, 길이 차이만큼 빼주고 하나씩 비교하면서 차이나는 문자의 수를 세서 배열에 저장합니다. 이 값이 나중에 미스매치 카운트가 됩니다. 매스매치 카운트를 백분율로 변환하면 배율 조건으로 사용할 수 있습니다. 간단한 산수라서 코드를 유심히 보시면 어떻게 동작되는지 쉽게 이해할 수 있습니다.
이제 정상적으로 동작하는지 테스트를 해볼까요? 테스트는 약간 복잡하지만, 아래 동영상 내용을 보면 쉽게 이해할 수 있을겁니다.
다음 시간에는 배열의 정렬 기능을 좀 더 확장 해볼 생각입니다. 가까운 순서와 먼 순서 그리고, 유사도와 특정 숫자와 가깝거나 먼 순서등등... 해야 할 내용들이 많을거 같아요. 아무래도 변수에 추가할 수 있는 자료형이 다양하다보니 유연하게 대응하려면 기능이 많고 복잡해질 수밖에 없습니다. 그래서, 가능하면 기본 기능만 제공하고 사용자가 알아서 커스텀 모듈화 하거나 추상화된 기존 액션을 확장하는 방법으로 사용하도록 하고 싶었는데요.
대부분의 매크로 사용자분들이 개발자가 아닌데다가 쉽게 사용하는게 더 좋기 때문에 미리 만들어진 코드를 자유롭게 사용할 수 있도록 옵션을 제공하는 방식으로 개발하게 되었습니다. 어쩔 수 없는 부분입니다. 그렇다보니 사용하는 몇가지의 핵심 기능 외에도 다양한 기능들이 포함되어 있어서 약간의 성능 저하를 감수해야 합니다. 최적화된 액션 라이브러리를 따로 배포하는 것도 좋은 방법일거 같은데요. 아직 먼~ 이야기입니다. 언젠가는 해야 할 일이긴 하지만, 지금은 아니죠^^
[ 각종 자동화 매크로 및 RPA 프로그램 제작 해드립니다. ]
[ 초보자도 쉽게 따라할 수 있는 기초 학습 강좌 보기 ]
원본 글 보기
http://ngmsoftware.com/bbs/board.php?bo_table=tip_and_tech
댓글