Создание пользовательского допуска

В этом примере показано, как создать пользовательский допуск, чтобы определить, имеют ли две последовательности ДНК расстояние Хемминга в пределах заданного допуска. Для двух последовательностей ДНК одинаковой длины Расстояние Хемминга является количеством положений, в которых нуклеотиды (буквы) одной последовательности отличаются от других.

В файле, DNA.m, в вашей рабочей папке, создайте простой класс для последовательности ДНК.

classdef DNA
    properties(SetAccess=immutable)
        Sequence
    end
    
    methods
        function dna = DNA(sequence)
            validLetters = ...
                sequence == 'A' | ...
                sequence == 'C' | ...
                sequence == 'T' | ...
                sequence == 'G';
            
            if ~all(validLetters(:))
                error('Sequence contained a letter not found in DNA.')
            end
            dna.Sequence = sequence;
        end
    end
end

В файле в вашей рабочей папке создайте класс допуска, чтобы можно было проверить, что последовательности ДНК находятся в пределах заданного расстояния Хемминга. Конструктору требуется Value свойство, которое определяет максимальное Расстояние Хемминга.

classdef HammingDistance < matlab.unittest.constraints.Tolerance
    properties
        Value
    end
    
    methods
        function tolerance = HammingDistance(value)
            tolerance.Value = value;
        end
    end
end

В methods блок со HammingDistance определение класса, включите следующий метод, чтобы допуск поддерживал объекты ДНК. Классы допуска должны реализовать supports способ.

    methods
        function tf = supports(~, value)
            tf = isa(value, 'DNA');
        end
    end

В methods блок со HammingDistance определение класса, включите следующий метод, который возвращает true или false. Классы допуска должны реализовать satisfiedBy способ. Среда тестирования использует этот метод, чтобы определить, находятся ли два значения в пределах допуска.

    methods
        function tf = satisfiedBy(tolerance, actual, expected)
            if ~isSameSize(actual.Sequence, expected.Sequence)
                tf = false;
                return
            end
            tf = hammingDistance(actual.Sequence,expected.Sequence) <= tolerance.Value;
        end
    end

В HammingDistance.m задайте следующие вспомогательные функции за пределами classdef блок. The isSameSize функция возвращает true если две последовательности ДНК имеют одинаковый размер, и hammingDistance функция возвращает Расстояние Хемминга между двумя последовательностями.

function tf = isSameSize(str1, str2)
tf = isequal(size(str1), size(str2));
end

function distance = hammingDistance(str1, str2)
distance = nnz(str1 ~= str2);
end

Функция возвращает Diagnostic объект с информацией о сравнении. В methods блок со HammingDistance определение класса, включите следующий метод, который возвращает StringDiagnostic. Классы допуска должны реализовать getDiagosticFor способ.

    methods
        function diag = getDiagnosticFor(tolerance, actual, expected)
            import matlab.unittest.diagnostics.StringDiagnostic
            
            if ~isSameSize(actual.Sequence, expected.Sequence)
                str = 'The DNA sequences must be the same length.';
            else
                str = sprintf('%s%d.\n%s%d.', ...
                    'The DNA sequences have a Hamming distance of ', ...
                    hammingDistance(actual.Sequence, expected.Sequence), ...
                    'The allowable distance is ', ...
                    tolerance.Value);
            end
            diag = StringDiagnostic(str);
        end
    end

 Определение класса HammingDistance Сводных данных

В командной строке создайте TestCase для интерактивной проверки.

import matlab.unittest.TestCase
import matlab.unittest.constraints.IsEqualTo

testCase = TestCase.forInteractiveUse;

Создайте два объекта ДНК.

sampleA = DNA('ACCTGAGTA');
sampleB = DNA('ACCACAGTA');

Проверьте, что последовательности ДНК равны друг другу.

testCase.verifyThat(sampleA, IsEqualTo(sampleB))
Interactive verification failed.

---------------------
Framework Diagnostic:
---------------------
IsEqualTo failed.
--> ObjectComparator failed.
    --> The objects are not equal using "isequal".

Actual Object:
      DNA with properties:
    
        Sequence: 'ACCTGAGTA'
Expected Object:
      DNA with properties:
    
        Sequence: 'ACCACAGTA'

Проверьте, что последовательности ДНК равны друг другу в пределах расстояния Хемминга 1.

testCase.verifyThat(sampleA, IsEqualTo(sampleB,...
    'Within', HammingDistance(1)))
Interactive verification failed.

---------------------
Framework Diagnostic:
---------------------
IsEqualTo failed.
--> ObjectComparator failed.
    --> The objects are not equal using "isequal".
    --> The DNA sequences have a Hamming distance of 2.
        The allowable distance is 1.

Actual Object:
      DNA with properties:
    
        Sequence: 'ACCTGAGTA'
Expected Object:
      DNA with properties:
    
        Sequence: 'ACCACAGTA'

Последовательности не равны друг другу в пределах допуска 1. Среда тестирования отображает дополнительную диагностику от getDiagnosticFor способ.

Проверьте, что последовательности ДНК равны друг другу в пределах расстояния Хемминга 2.

testCase.verifyThat(sampleA, IsEqualTo(sampleB,...
    'Within', HammingDistance(2)))
Interactive verification passed.

См. также