Example #1
0
def test_channel_format_types():
    with nidcpower.Session(
            '4162', [0, 1], False,
            'Simulate=1, DriverSetup=Model:4162; BoardType:PXIe'
    ) as simulated_session:
        assert simulated_session.channel_count == 2
    with nidcpower.Session(
            '4162', range(2), False,
            'Simulate=1, DriverSetup=Model:4162; BoardType:PXIe'
    ) as simulated_session:
        assert simulated_session.channel_count == 2
    with nidcpower.Session(
            '4162', '0,1', False,
            'Simulate=1, DriverSetup=Model:4162; BoardType:PXIe'
    ) as simulated_session:
        assert simulated_session.channel_count == 2
    with nidcpower.Session(
            '4162', None, False,
            'Simulate=1, DriverSetup=Model:4162; BoardType:PXIe'
    ) as simulated_session:
        assert simulated_session.channel_count == 12
    with nidcpower.Session(
            resource_name='4162',
            reset=False,
            options='Simulate=1, DriverSetup=Model:4162; BoardType:PXIe'
    ) as simulated_session:
        assert simulated_session.channel_count == 12
def example(resource_name, options, voltage, length):
    with nidcpower.Session(resource_name=resource_name,
                           options=options) as session:

        # Configure the session.
        session.measure_record_length = length
        session.measure_record_length_is_finite = True
        session.measure_when = nidcpower.MeasureWhen.AUTOMATICALLY_AFTER_SOURCE_COMPLETE
        session.voltage_level = voltage

        session.commit()
        print('Effective measurement rate: {0} S/s'.format(
            session.measure_record_delta_time / 1))

        print('Channel           Num  Voltage    Current    In Compliance')
        row_format = '{0:15} {1:3d}    {2:8.6f}   {3:8.6f}   {4}'
        with session.initiate():
            channel_indices = '0-{0}'.format(session.channel_count - 1)
            channels = session.get_channel_names(channel_indices)
            for i, channel_name in enumerate(channels):
                samples_acquired = 0
                while samples_acquired < length:
                    measurements = session.channels[
                        channel_name].fetch_multiple(
                            count=session.fetch_backlog)
                    samples_acquired += len(measurements)
                    for i in range(len(measurements)):
                        print(
                            row_format.format(channel_name, i,
                                              measurements[i].voltage,
                                              measurements[i].current,
                                              measurements[i].in_compliance))
def test_fetch_multiple_channels(resource_name, channels, independent_channels,
                                 measurement_channels,
                                 expected_measured_channel):
    options = {
        'Simulate': True,
        'DriverSetup': {
            'Model': '4162',
            'BoardType': 'PXIe'
        }
    }
    with nidcpower.Session(
            resource_name,
            channels,
            options=options,
            independent_channels=independent_channels) as session:
        session.measure_when = nidcpower.MeasureWhen.AUTOMATICALLY_AFTER_SOURCE_COMPLETE
        count = 10
        with session.initiate():
            if measurement_channels is None:
                measurements = session.fetch_multiple(count)
            else:
                measurements = session.channels[
                    measurement_channels].fetch_multiple(count)
            assert len(measurements) == count
            for measurement in measurements:
                assert measurement.channel == expected_measured_channel
def test_measure_multiple_lcr_channels(resource_name, channels,
                                       independent_channels,
                                       measurement_channels,
                                       expected_measured_channels):
    options = {
        'Simulate': True,
        'DriverSetup': {
            'Model': '4190',
            'BoardType': 'PXIe'
        }
    }
    with nidcpower.Session(
            resource_name,
            channels,
            options=options,
            independent_channels=independent_channels) as session:
        session.instrument_mode = nidcpower.InstrumentMode.LCR
        with session.initiate():
            if measurement_channels is None:
                lcr_measurements = session.measure_multiple_lcr()
            else:
                lcr_measurements = session.channels[
                    measurement_channels].measure_multiple_lcr()
            assert [
                lcr_measurement_object.channel
                for lcr_measurement_object in lcr_measurements
            ] == expected_measured_channels
def example(resource_name, channels, options, voltage, length):
    with nidcpower.Session(resource_name=resource_name,
                           channels=channels,
                           options=options) as session:

        # Configure the session.
        session.measure_record_length = length
        session.measure_record_length_is_finite = True
        session.measure_when = nidcpower.MeasureWhen.AUTOMATICALLY_AFTER_SOURCE_COMPLETE
        session.voltage_level = voltage

        session.commit()
        print('Effective measurement rate: {0} S/s'.format(
            session.measure_record_delta_time / 1))

        samples_acquired = 0
        print('  #    Voltage    Current    In Compliance')
        row_format = '{0:3d}:   {1:8.6f}   {2:8.6f}   {3}'
        with session.initiate():
            while samples_acquired < length:
                voltage_measurements, current_measurements, in_compliance = session.fetch_multiple(
                    count=session.fetch_backlog)
                samples_acquired += len(voltage_measurements)
                for i in zip(range(len(voltage_measurements)),
                             voltage_measurements, current_measurements,
                             in_compliance):
                    print(row_format.format(i[0], i[1], i[2], i[3]))
def test_default_channels_argument():
    with nidcpower.Session(
            resource_name='4162',
            reset=False,
            options='Simulate=1, DriverSetup=Model:4162; BoardType:PXIe'
    ) as simulated_session:
        assert simulated_session.channel_count == 12
Example #7
0
def example(resource_name, channels, options, voltage1, voltage2, delay):
    timeout = datetime.timedelta(seconds=(delay + 1.0))

    with nidcpower.Session(resource_name=resource_name,
                           channels=channels,
                           options=options) as session:

        # Configure the session.
        session.source_mode = nidcpower.SourceMode.SINGLE_POINT
        session.output_function = nidcpower.OutputFunction.DC_VOLTAGE
        session.current_limit = .06
        session.voltage_level_range = 5.0
        session.current_limit_range = .06
        session.source_delay = datetime.timedelta(seconds=delay)
        session.measure_when = nidcpower.MeasureWhen.AUTOMATICALLY_AFTER_SOURCE_COMPLETE
        session.voltage_level = voltage1

        with session.initiate():
            print('Voltage 1:')
            print_fetched_measurements(
                *session.fetch_multiple(count=1, timeout=timeout))
            session.voltage_level = voltage2  # on-the-fly set
            print('Voltage 2:')
            print_fetched_measurements(
                *session.fetch_multiple(count=1, timeout=timeout))
            session.output_enabled = False
def test_init_issues_deprecation_warnings(resource_name, channels,
                                          independent_channels):
    """Tests for deprecation warnings for legacy initialization options.

    A deprecation warning should occur any time independent_channels is False or a channels
    argument is supplied.
    """
    options = {
        'Simulate': True,
        'DriverSetup': {
            'Model': '4162',
            'BoardType': 'PXIe'
        }
    }
    with pytest.deprecated_call() as dc:
        with nidcpower.Session(resource_name,
                               channels,
                               options=options,
                               independent_channels=independent_channels):
            pass
    assert len(dc.list) == 1  # assert only 1 deprecation warning was thrown
    message = dc.list[0].message.args[
        0]  # grabs the deprecation warning message
    if not independent_channels:
        assert message.find(
            'Initializing session without independent channels enabled.') != -1
    if channels and independent_channels:
        assert message.find(
            'Attempting to initialize an independent channels session with a channels argument.'
        ) != -1
Example #9
0
def test_self_test():
    # TODO(frank): self_test does not work with simulated PXIe-4162 modules due to internal NI bug.
    # Update to use the session created with 'session' function above after internal NI bug is fixed.
    with nidcpower.Session('', '', False, 'Simulate=1, DriverSetup=Model:4143; BoardType:PXIe') as session:
        result, message = session.self_test()
        assert result == 0
        assert message == 'Self test passed'
def example(resource_name, options, voltage1, voltage2, delay):
    timeout = hightime.timedelta(seconds=(delay + 1.0))

    with nidcpower.Session(resource_name=resource_name,
                           options=options) as session:

        # Configure the session.
        session.source_mode = nidcpower.SourceMode.SINGLE_POINT
        session.output_function = nidcpower.OutputFunction.DC_VOLTAGE
        session.current_limit = .06
        session.voltage_level_range = 5.0
        session.current_limit_range = .06
        session.source_delay = hightime.timedelta(seconds=delay)
        session.measure_when = nidcpower.MeasureWhen.AUTOMATICALLY_AFTER_SOURCE_COMPLETE
        session.voltage_level = voltage1

        with session.initiate():
            channel_indices = '0-{0}'.format(session.channel_count - 1)
            channels = session.get_channel_names(channel_indices)
            for channel_name in channels:
                print('Channel: {0}'.format(channel_name))
                print('---------------------------------')
                print('Voltage 1:')
                print_fetched_measurements(
                    session.channels[channel_name].fetch_multiple(
                        count=1, timeout=timeout))
                session.voltage_level = voltage2  # on-the-fly set
                print('Voltage 2:')
                print_fetched_measurements(
                    session.channels[channel_name].fetch_multiple(
                        count=1, timeout=timeout))
                session.output_enabled = False
                print('')
def test_error_message():
    with pytest.raises(nidcpower.Error) as e:
        # We pass in an invalid model name to force going to error_message
        with nidcpower.Session(
                '4162', [0, 1], False,
                'Simulate=1, DriverSetup=Model:invalid_model; BoardType:PXIe'):
            pass
    assert e.value.code == -1074134964
def test_error_message():
    try:
        # We pass in an invalid model name to force going to error_message
        with nidcpower.Session('4162', [0, 1], False, 'Simulate=1, DriverSetup=Model:invalid_model; BoardType:PXIe'):
            assert False
    except nidcpower.Error as e:
        assert e.code == -1074134964
        assert e.description.find('The option string parameter contains an entry with an unknown option value.') != -1
Example #13
0
def test_configure_digital_edge_pulse_trigger():
    # 4162 does not support pulsing... yet?
    with nidcpower.Session(
            '', '0', False,
            'Simulate=1, DriverSetup=Model:4139; BoardType:PXIe') as session:
        expected_trigger_terminal = "/4139/PXI_Trig0"
        session.configure_digital_edge_pulse_trigger(expected_trigger_terminal)
        assert expected_trigger_terminal == session.digital_edge_pulse_trigger_input_terminal
Example #14
0
def test_measure():
    with nidcpower.Session('', '0', False, 'Simulate=1, DriverSetup=Model:4162; BoardType:PXIe') as session:
        session.source_mode = nidcpower.SourceMode.SINGLE_POINT
        session.output_function = nidcpower.OutputFunction.DC_VOLTAGE
        session.voltage_level_range = 6
        session.voltage_level = 2
        with session.initiate():
            reading = session.measure(nidcpower.MeasurementTypes.MEASURE_VOLTAGE)
            assert session.query_in_compliance() is False
        assert reading == 2
Example #15
0
def test_reset_device():
    # TODO(frank): reset_device does not work with simulated PXIe-4162 modules due to internal NI bug.
    # Update to use the session created with 'session' function above after internal NI bug is fixed.
    with nidcpower.Session('', '', False, 'Simulate=1, DriverSetup=Model:4143; BoardType:PXIe') as session:
        channel = session.channels['0']
        default_output_function = channel.output_function
        assert default_output_function == nidcpower.OutputFunction.DC_VOLTAGE
        channel.output_function = nidcpower.OutputFunction.DC_CURRENT
        session.reset_device()
        function_after_reset = channel.output_function
        assert function_after_reset == default_output_function
def example(resource_name, options, voltage_max, current_max,
            points_per_output_function, delay_in_seconds):
    timeout = hightime.timedelta(seconds=(delay_in_seconds + 1.0))

    with nidcpower.Session(resource_name=resource_name,
                           options=options) as session:

        # Configure the session.
        session.source_mode = nidcpower.SourceMode.SEQUENCE
        session.voltage_level_autorange = True
        session.current_limit_autorange = True
        session.source_delay = hightime.timedelta(seconds=delay_in_seconds)
        properties_used = ['output_function', 'voltage_level', 'current_level']
        session.create_advanced_sequence(sequence_name='my_sequence',
                                         property_names=properties_used,
                                         set_as_active_sequence=True)

        voltage_per_step = voltage_max / points_per_output_function
        for i in range(points_per_output_function):
            session.create_advanced_sequence_step(set_as_active_step=False)
            session.output_function = nidcpower.OutputFunction.DC_VOLTAGE
            session.voltage_level = voltage_per_step * i

        current_per_step = current_max / points_per_output_function
        for i in range(points_per_output_function):
            session.create_advanced_sequence_step(set_as_active_step=False)
            session.output_function = nidcpower.OutputFunction.DC_CURRENT
            session.current_level = current_per_step * i

        with session.initiate():
            session.wait_for_event(nidcpower.Event.SEQUENCE_ENGINE_DONE)
            channel_indices = '0-{0}'.format(session.channel_count - 1)
            channels = session.get_channel_names(channel_indices)
            measurement_group = [
                session.channels[name].fetch_multiple(
                    points_per_output_function * 2, timeout=timeout)
                for name in channels
            ]

        session.delete_advanced_sequence(sequence_name='my_sequence')
        line_format = '{:<15} {:<4} {:<10} {:<10} {:<6}'
        print(
            line_format.format('Channel', 'Num', 'Voltage', 'Current',
                               'In Compliance'))
        for i, measurements in enumerate(measurement_group):
            num = 0
            channel_name = channels[i].strip()
            for measurement in measurements:
                print(
                    line_format.format(channel_name, num, measurement.voltage,
                                       measurement.current,
                                       str(measurement.in_compliance)))
                num += 1
Example #17
0
def test_config_aperture_time():
    with nidcpower.Session('', '0', False, 'Simulate=1, DriverSetup=Model:4162; BoardType:PXIe') as session:
        expected_default_aperture_time = 0.01666
        default_aperture_time = session.aperture_time
        assert session.aperture_time_units == nidcpower.ApertureTimeUnits.SECONDS
        default_aperture_time_in_range = abs(default_aperture_time - expected_default_aperture_time) <= max(1e-09 * max(abs(default_aperture_time), abs(expected_default_aperture_time)), 0.0)  # https://stackoverflow.com/questions/5595425/what-is-the-best-way-to-compare-floats-for-almost-equality-in-python
        assert default_aperture_time_in_range is True
        session.configure_aperture_time(5, nidcpower.ApertureTimeUnits.POWER_LINE_CYCLES)
        assert session.aperture_time_units == nidcpower.ApertureTimeUnits.POWER_LINE_CYCLES
        aperture_time = session.aperture_time
        expected_aperture_time = 5
        aperture_time_in_range = abs(aperture_time - expected_aperture_time) <= max(1e-09 * max(abs(aperture_time), abs(expected_aperture_time)), 0.0)  # https://stackoverflow.com/questions/5595425/what-is-the-best-way-to-compare-floats-for-almost-equality-in-python
        assert aperture_time_in_range is True
def test_init_raises_driver_errors_for_invalid_arguments_legacy_session(
        resource_name, channels):
    """Tests invalid initializer arguments for legacy initialize with channels sessions.

    Multi-instrument resource names are valid for simulated initialize with channels sessions. So,
    we attempt to initialize a true session and assert an unsupported device exception is raised.
    """

    with pytest.raises(nidcpower.errors.DriverError) as e:
        with nidcpower.Session(resource_name,
                               channels,
                               independent_channels=False):
            pass
    assert e.value.code == -1074118656
def example(resource_name, channels, options, steps, voltage_start,
            voltage_final, current_start, current_final):

    # The Python API should provide these values. But it doesn't. Issue #504. For now, put magic values here.
    attribute_ids = [
        1150008,  # output_function
        1250001,  # voltage_level
        1150009,  # current_level
    ]

    with nidcpower.Session(resource_name=resource_name,
                           channels=channels,
                           options=options) as session:

        session.source_mode = nidcpower.SourceMode.SEQUENCE
        session.source_delay = datetime.timedelta(seconds=0.1)
        session.voltage_level_autorange = True
        session.current_level_autorange = True
        session._create_advanced_sequence(sequence_name='my_sequence',
                                          attribute_ids=attribute_ids)
        voltages = create_sweep(voltage_start, voltage_final, steps)
        currents = create_sweep(current_start, current_final, steps)

        for v in voltages:
            session._create_advanced_sequence_step()
            session.output_function = nidcpower.OutputFunction.DC_VOLTAGE
            session.voltage_level = v

        for c in currents:
            session._create_advanced_sequence_step()
            session.output_function = nidcpower.OutputFunction.DC_CURRENT
            session.current_level = c

        with session.initiate():
            session.wait_for_event(nidcpower.Event.SEQUENCE_ENGINE_DONE)
            measurements = session.fetch_multiple(count=steps * 2)

        # Print a table with the measurements
        programmed_levels = voltages + currents
        units = ['V'] * steps + ['A'] * steps
        row_format = '{:<8} {:4} {:<25} {:<25} {}'
        print(
            row_format.format('Sourced', '', 'Measured voltage',
                              'Measured current', 'In-compliance'))
        for i in range(steps * 2):
            print(
                row_format.format(programmed_levels[i], units[i],
                                  measurements[i].voltage,
                                  measurements[i].current,
                                  measurements[i].in_compliance))
def test_init_with_independent_channels(resource_name, channels):
    """Tests that independent channels sessions open without exception for valid arguments."""
    options = {
        'Simulate': True,
        'DriverSetup': {
            'Model': '4162',
            'BoardType': 'PXIe'
        }
    }
    with nidcpower.Session(resource_name,
                           channels,
                           options=options,
                           independent_channels=True):
        pass
def test_init_raises_driver_errors_for_invalid_arguments(
        resource_name, channels):
    """Tests for driver errors that should occur for invalid initialization arguments."""
    options = {
        'Simulate': True,
        'DriverSetup': {
            'Model': '4162',
            'BoardType': 'PXIe'
        }
    }
    with pytest.raises(nidcpower.errors.DriverError) as e:
        with nidcpower.Session(resource_name, channels, options=options):
            pass
    assert e.value.code == -1074097793
def test_init_backwards_compatibility_with_initialize_with_channels(
        resource_name, channels):
    """Tests that legacy sessions open without exception for valid arguments."""
    options = {
        'Simulate': True,
        'DriverSetup': {
            'Model': '4162',
            'BoardType': 'PXIe'
        }
    }
    with nidcpower.Session(resource_name,
                           channels,
                           options=options,
                           independent_channels=False):
        pass
Example #23
0
def test_fetch_multiple():
    with nidcpower.Session('', '0', False, 'Simulate=1, DriverSetup=Model:4162; BoardType:PXIe') as session:
        session.source_mode = nidcpower.SourceMode.SINGLE_POINT
        session.configure_aperture_time(0, nidcpower.ApertureTimeUnits.SECONDS)
        session.voltage_level = 1
        count = 10
        session.measure_when = nidcpower.MeasureWhen.AUTOMATICALLY_AFTER_SOURCE_COMPLETE
        with session.initiate():
            voltage_measurements, current_measurements, in_compliance, actual_count = session.fetch_multiple(count)
            assert len(voltage_measurements) == count
            assert len(current_measurements) == count
            assert len(in_compliance) == count
            assert actual_count == count
            assert isinstance(voltage_measurements[1], float)
            assert isinstance(current_measurements[1], float)
            assert in_compliance[1] in [True, False]
            assert voltage_measurements[1] == 1.0
            assert current_measurements[1] == 0.00001
def test_measure_multiple_error_invalid_channels(resource_name,
                                                 measurement_channels):
    options = {
        'Simulate': True,
        'DriverSetup': {
            'Model': '4162',
            'BoardType': 'PXIe'
        }
    }
    with nidcpower.Session(resource_name,
                           channels=' ',
                           options=options,
                           independent_channels=True) as session:
        with session.initiate():
            with pytest.raises(nidcpower.errors.DriverError) as e:
                session.channels[measurement_channels].measure_multiple()
            assert e.value.code == -1074135008
            assert 'Unknown channel or repeated capability name.' in e.value.description
def test_init_raises_value_error_for_multi_instrument_resource_name_and_channels_argument(
):
    """Combining channels with multiple instruments is invalid.

    Tests that a value error is thrown when a multi-instrument resource name is provided with
    a channels argument. How to combine the two arguments is undefined.
    """
    options = {
        'Simulate': True,
        'DriverSetup': {
            'Model': '4162',
            'BoardType': 'PXIe'
        }
    }
    with pytest.raises(ValueError):
        with nidcpower.Session("Dev1,Dev2",
                               "0",
                               options=options,
                               independent_channels=True):
            pass
def test_init_issues_deprecation_warnings(resource_name, channels,
                                          independent_channels):
    """Tests for deprecation warnings for legacy initialization options.

    A deprecation warning should occur any time independent_channels is False or a channels
    argument is supplied.
    """
    options = {
        'Simulate': True,
        'DriverSetup': {
            'Model': '4162',
            'BoardType': 'PXIe'
        }
    }
    with pytest.deprecated_call():
        with nidcpower.Session(resource_name,
                               channels,
                               options=options,
                               independent_channels=independent_channels):
            pass
def test_init_raises_driver_errors_for_invalid_arguments(
        resource_name, channels, independent_channels, expected_error_code):
    """Tests for driver errors that should occur for invalid initialization arguments."""
    options = {
        'Simulate': True,
        'DriverSetup': {
            'Model': '4162',
            'BoardType': 'PXIe'
        }
    }
    with pytest.raises(nidcpower.errors.DriverError) as e:
        with nidcpower.Session(
                resource_name,
                channels,
                options=options,
                independent_channels=independent_channels) as session:
            # multi-instrument resource names are valid for simulated initialize with channels
            # sessions, so we make a driver call on channels and ensure that errors
            session.channels[
                channels].output_function = nidcpower.OutputFunction.DC_VOLTAGE
    assert e.value.code == expected_error_code
def test_measure_multiple_channels(resource_name, channels,
                                   independent_channels, measurement_channels,
                                   expected_measured_channels):
    options = {
        'Simulate': True,
        'DriverSetup': {
            'Model': '4162',
            'BoardType': 'PXIe'
        }
    }
    with nidcpower.Session(
            resource_name,
            channels,
            options=options,
            independent_channels=independent_channels) as session:
        with session.initiate():
            if measurement_channels is None:
                measurements = session.measure_multiple()
            else:
                measurements = session.channels[
                    measurement_channels].measure_multiple()
            assert [measurement.channel for measurement in measurements
                    ] == expected_measured_channels
def session(request):
    """Creates an NI-DCPower Session.

    Markers can be used to override the default initializer arguments. For example,
    @pytest.mark.resource_name('4162/0') will override the default resource name.

    Available markers include:
        @pytest.mark.resource_name
        @pytest.mark.channels
        @pytest.mark.reset
        @pytest.mark.options
        @pytest.mark.independent_channels

    By default, all dependent tests will run once with an Independent Channels session. Dependent
    tests can override this behavior by using custom markers. Refer to the documentation in
    pytest_generate_tests for more information.
    """

    # set default values
    init_args = {
        'resource_name': '4162',
        'channels': '',
        'reset': False,
        'options': 'Simulate=1, DriverSetup=Model:4162; BoardType:PXIe',
        'independent_channels': request.param
    }

    # iterate through markers and update arguments
    for marker in request.node.iter_markers():
        if marker.name in init_args:  # only look at markers with valid argument names
            init_args[marker.name] = marker.args[
                0]  # assume single parameter in marker

    # initialize and yield session
    with nidcpower.Session(**init_args) as simulated_session:
        yield simulated_session
Example #30
0
def example(resource_name, channels, options, voltage_max, current_max, points_per_output_function, delay_in_seconds):
    timeout = datetime.timedelta(seconds=(delay_in_seconds + 1.0))

    with nidcpower.Session(resource_name=resource_name, channels=channels, options=options) as session:

        # Configure the session.
        session.source_mode = nidcpower.SourceMode.SEQUENCE
        session.voltage_level_autorange = True
        session.current_limit_autorange = True
        session.source_delay = datetime.timedelta(seconds=delay_in_seconds)
        properties_used = ['output_function', 'voltage_level', 'current_level']
        session.create_advanced_sequence(sequence_name='my_sequence', property_names=properties_used, set_as_active_sequence=True)

        voltage_per_step = voltage_max / points_per_output_function
        for i in range(points_per_output_function):
            session.create_advanced_sequence_step(set_as_active_step=False)
            session.output_function = nidcpower.OutputFunction.DC_VOLTAGE
            session.voltage_level = voltage_per_step * i

        current_per_step = current_max / points_per_output_function
        for i in range(points_per_output_function):
            session.create_advanced_sequence_step(set_as_active_step=False)
            session.output_function = nidcpower.OutputFunction.DC_CURRENT
            session.current_level = current_per_step * i

        with session.initiate():
            session.wait_for_event(nidcpower.Event.SEQUENCE_ENGINE_DONE)
            measurements = session.fetch_multiple(points_per_output_function * 2, timeout=timeout)

        session.delete_advanced_sequence(sequence_name='my_sequence')
        line_format = '{:,<4} {:,.6g} {:,.6g} {:<6}\n'
        print('{:<4} {:<10} {:,<10} {:<6}'.format('Num', 'Voltage', 'Current', 'In Compliance'))
        i = 0
        for measurement in measurements:
            print(line_format.format(i, measurement.voltage, measurement.current, str(measurement.in_compliance)))
            i += 1