Почему часть моего кода Python интерпретируется по-разному, когда я добавляю, казалось бы, не связанную часть?

Некоторая предыстория: я реализую графический интерфейс для взаимодействия с оборудованием через GPIB. Проблема возникает в этом методе:

from tkinter import *
from tkinter import ttk
import visa #PyVisa Package. pyvisa.readthedocs.io
from time import sleep
import numpy as np #NumPy Package. Scipy.org

def oneDSweep():
Voltage =[]
Current =[]
Source = []
try:
    #Gate = parseGate(Gate1Input.get()) #Not implemented yet.
    Min = float(Gate1MinInput.get()) #Add a check for valid input
    #if Min < .001:
            #Throw exception
    Max = float(Gate1MaxInput.get()) #Add a check for valid input
    VoltageInterval = .02 #Prompt user for interval?
    rm = visa.ResourceManager()
    SIM900 = rm.open_resource("GPIB0::1::INSTR") #Add a check that session is open.

    x = 0
    Volt = Min
    while Volt <= Max:
        SIM900.write("SNDT 1, 'VOLT " + str(Volt) + "'") #Set voltage.
        SIM900.write("SNDT 7, 'VOLT? 1'") #Ask a port for voltage.
        Vnow = SIM900.query("GETN? 7, 50") #Retrieve data from previous port.
        Vnow = Vnow[6:15]
        Vnow = float(Vnow) ############Error location
        Voltage = np.append(Voltage, Vnow)

        SIM900.write("SNDT 1, 'VOLT?'") #Ask a different port for voltage.
        Snow = SIM900.query("GETN? 1, 50") #Retrieve data.
        print(Snow) #Debugging method. Probably not problematic.
        Snow = Snow[4:]
        Snow = float(Snow)

        sleep(1) #Add a delay for science reasons.
        #The code below helps the while loop act like a for loop.
        x = x+1
        Volt = Min + VoltageInterval*x
        Volt = float(truncate(Volt, 7))

finally:
    print(Voltage)
    print(Source)
    Voltage.tofile("output.txt.",sep=",")
    SIM900.write("FLSH")#Flush the ports' memories to ensure no bad data stays there.

Я получаю простую ошибку ValueError в отмеченном месте во время первого прохода цикла while; Python говорит, что не может преобразовать строку в число с плавающей запятой (подробнее об этом позже). Однако просто удалите эти пять строк кода:

    SIM900.write("SNDT 1, 'VOLT?'")
    Snow = SIM900.query("GETN? 1, 50")
    print(Snow)
    Snow = Snow[4:]
    Snow = float(Snow)

и программа работает отлично. Я понимаю источник ошибки. С добавлением этих строк, когда я отправляю эти две строки на свой инструмент:

    SIM900.write("SNDT 7, 'VOLT? 1'")
    Vnow = SIM900.query("GETN? 7, 50")

Я получаю по существу нулевую ошибку. #3000 возвращается, что является пустым сообщением, которое машина отправляет, когда ее просят вывести данные, а ей нечего выводить. Однако те же самые две строки выдают что-то вроде #3006 00.003, когда из программы исключаются четыре строки, о которых я упоминал. Другими словами, простое добавление этих четырех строк в мою программу изменило сообщение, отправляемое прибору в начале цикла while, несмотря на то, что они были добавлены ближе к концу.

Я убежден, что здесь виноват интерпретатор Python. Ранее я очищал свой код и обнаружил, что один конкретный набор кавычек при изменении с ' на " вызывал ту же ошибку, несмотря на то, что ни одна другая пара кавычек не проявляла такого поведения даже в одной строке. Мой вопрос: почему выполнение моего кода изменяется в зависимости от несвязанных изменений в коде (также был бы признателен за исправление)? Я понимаю, что эту проблему трудно воспроизвести, учитывая мое довольно специфическое приложение, поэтому, если есть дополнительная информация, которую я могу предоставить, пожалуйста, дайте мне знать.

РЕДАКТИРОВАТЬ: функциональность улучшилась после перехода из командной строки в IDLE. Я все еще озадачен тем, что произошло, но из-за моих скудных навыков командной строки я не могу предоставить никаких доказательств. Пожалуйста, закройте этот вопрос.


person B. Bush    schedule 15.07.2016    source источник
comment
Можете ли вы опубликовать ошибку и трассировку стека? Мне трудно думать, что проверенный в боях интерпретатор Python +10 сломан.   -  person Adam Hughes    schedule 15.07.2016
comment
Вы должны включить полную трассировку ошибок, которую вы получаете   -  person Brendan Abel    schedule 15.07.2016
comment
Распечатайте значение с плавающей запятой, прежде чем сопоставлять его со строкой, и посмотрите, что оно говорит. Скорее всего, он имеет нечисловые символы   -  person Adam Hughes    schedule 15.07.2016
comment
добавление этих четырех строк в мою программу изменило сообщение, отправляемое инструменту в начале цикла while, несмотря на то, что они были добавлены ближе к концу. Я убежден, что виноват интерпретатор Python Почему? Вы уже изолировали проблему. Отладьте Voltage, и вы, вероятно, впервые увидите допустимое значение в цикле, прежде чем оскорбительный код вызовет нулевой ответ от вашего устройства.   -  person Juan Tomas    schedule 15.07.2016
comment
Как я уже сказал, я понимаю источник ошибки. Мой прибор возвращает строку, которая не работает с моим кодом нарезки строк, и я получаю ошибку ValueError. Проблема в том, что эта ошибка ValueError возникает ТОЛЬКО при добавлении блока Snow. Без блока Snow, который не влияет на блок Vnow, ошибка не отправляется.   -  person B. Bush    schedule 15.07.2016
comment
Согласен с @Juan Tomas. Кажется, вы предполагаете, что эти строки влияют на что-то, что происходит до их, но гораздо более вероятно, что они влияют на будущую итерацию цикла.   -  person user94559    schedule 15.07.2016
comment
@AdamHughes: трассировка: файл beta.py, строка 70, в oneDSweep. Vnow = поплавок (Vnow). ValueError: не удалось преобразовать строку в число с плавающей запятой. РЕДАКТИРОВАТЬ: Кроме того, я не утверждаю, что интерпретатор сломан. Возможно, он просто делает что-то по дизайну, что не согласуется с моим приложением. Я хотел бы знать, что это такое.   -  person B. Bush    schedule 15.07.2016
comment
Без блока Snow, который не влияет на блок Vnow, ошибка не отправляется. Часть, которую я подчеркнул, почти наверняка не соответствует действительности (основываясь на ваших собственных доказательствах). Почему ты в это веришь?   -  person user94559    schedule 15.07.2016
comment
@smarx, потому что цикл while дает сбой на первой итерации, до того, как будет затронут блок Snow. Ранее я намеренно изменил блок Snow, чтобы он выдавал ошибку времени выполнения, но цикл так и не дошел до этой точки. Но опять же, когда этот блок был удален, программа работала нормально.   -  person B. Bush    schedule 15.07.2016
comment
@B.Bush Вы делаете экстраординарное заявление, поэтому вам нужно предоставить экстраординарные доказательства. Упростите код до минимума, чтобы воспроизвести ошибку, поместите везде операторы print и поделитесь выводом.   -  person user94559    schedule 15.07.2016
comment
@B.Bush Еще одно предложение: полностью избавиться от цикла while, поскольку вы утверждаете, что на самом деле это не цикл.   -  person user94559    schedule 15.07.2016
comment
Согласовано. Я хочу увидеть серьезную отладочную арматуру вокруг блока Vnow, прежде чем смириться с тем, что она дает сбой на первой итерации.   -  person Juan Tomas    schedule 15.07.2016
comment
Использование имитации инструмента также было бы полезно. Я не знаком с используемым прибором, но мне интересно, SNDT 7, 'VOLT? 1' должен быть запросом, а не записью. Использование макета, который определенно не отвечает на запись, устранит эту возможную проблему.   -  person Jeanne Pindar    schedule 20.07.2016


Ответы (2)


Python точно сообщает вам, что не так с вашим кодом — файл ValueError. Он даже дает вам точный номер строки и значение, которое вызывает проблему.

'#3006 00.003'

Это значение SNOW, которое выводится. Затем вы делаете это

SNOW = SNOW[4:]

Теперь SNOW

'6 00.003'

Затем вы пытаетесь вызвать float() в этой строке. 6 00.003 нельзя преобразовать в число с плавающей запятой, потому что это бессмысленное число.

person Brendan Abel    schedule 15.07.2016
comment
Это НЕ ценность Сноу. Это значение, которое я получаю для Vnow, когда исключается блок Snow. Когда добавляется блок Snow, я получаю Vnow = #3000, нулевой результат. Блок Snow даже не трогается во время выполнения, потому что при его включении блок Vnow дает сбой. - person B. Bush; 15.07.2016
comment
Что ж, оба блока взаимодействуют с одним и тем же объектом — SIM900 — поэтому неудивительно, что добавление или удаление одного блока влияет на другой. Вы убедились, что цикл while еще не прошел цикл? Может быть, напечатать что-нибудь в начале цикла while. - person Brendan Abel; 15.07.2016
comment
Да, я проверял это раньше, сейчас работаю над доказательством. - person B. Bush; 15.07.2016

Я убежден, что здесь виноват интерпретатор Python. Ранее я очищал свой код и обнаружил, что один конкретный набор кавычек при изменении с ' на "выдавал ту же ошибку, несмотря на то, что ни одна другая пара кавычек не проявляла такого поведения даже в одной строке.

Python генерирует точно такой же байт-код для строк в одинарных и двойных кавычках (если, конечно, не задействованы встроенные кавычки). Таким образом, либо среда, в которой вы запускаете свой скрипт, серьезно нарушена (я считаю интерпретатор Python частью «среды»), либо ваш диагноз неверен. Я бы поставил деньги на второй.

Вот альтернативное объяснение. По какой-то причине подключенное оборудование дает противоречивые результаты. Итак, в один раз вы получаете то, что ожидаете, в следующий раз, когда вы получаете ошибку, вы думаете, что ваши изменения в коде учитывают различия, но между причиной и следствием нет никакой связи, и в конечном итоге вы рвете на себе волосы. Когда вы запускаете один и тот же код несколько раз подряд, получаете ли вы одинаковые результаты? т.е. вы постоянно получаете странное поведение? Даже если вы это сделаете, проблема должна быть связана с оборудованием или подключением, а не с Python.

person alexis    schedule 15.07.2016
comment
Да, я получил последовательное поведение. Дело в том, что код, который я добавил, так и не достиг инструмента, с которым я взаимодействовал. Инструмент может изменить поведение при отправке нового кода, но добавленный код никогда не был отправлен на инструмент. Предыдущий блок, который раньше работал правильно, дал сбой и вызвал выход из программы. - person B. Bush; 16.07.2016
comment
Ну, я сомневаюсь, можете ли вы действительно быть уверены, что то, что вы утверждаете, правда. Знаете ли вы, что stdout и stderr имеют разные режимы буферизации и могут отображаться не по порядку? Печатайте в stderr, а не в stdout, и вы можете быть удивлены. - person alexis; 18.07.2016
comment
Интересно, я не знал об этом. Тем не менее, я использую сторонний инструмент, который отслеживает все действия на рассматриваемом инструменте и обратно, и это подтверждает мою историю. Означает ли это, что операторы печати ненадежны при отладке? - person B. Bush; 19.07.2016
comment
Операторы печати очень надежны, если вы используете их правильно: не смешивайте stdin и stderr и не настраивайте буферизацию. Но вы используете какое-то неопознанное оборудование и сторонний инструмент, имя которого вы не назвали, и вы уверены, что неисправным компонентом является Python, наиболее широко используемый из трех? Удачи с этим. - person alexis; 20.07.2016