Проверка обработки исключений в простых функциях

Beginner

This tutorial is from open-source community. Access the source code

Введение

В этом практическом занятии (лабораторной работе) вы научитесь проверять определения простых функций на Python и изучать обработку исключений. Функции - это ключевой концепт программирования, который позволяет структурировать код на переиспользуемые сегменты. Обработка исключений, с другой стороны, представляет собой метод обработки ошибок и непредвиденных ситуаций в ваших программах.

Основные цели этого практического занятия (лабораторной работы) - проверить процесс определения простых функций и узнать о обработке исключений на Python. Файл, который будет изменен, - pcost.py.

Это Guided Lab, который предоставляет пошаговые инструкции, чтобы помочь вам учиться и практиковаться. Внимательно следуйте инструкциям, чтобы выполнить каждый шаг и получить практический опыт. Исторические данные показывают, что это лабораторная работа уровня начальный с процентом завершения 90%. Он получил 97% положительных отзывов от учащихся.

Определение функции

На этом этапе мы научимся создавать функции. Функция в Python представляет собой блок организованного, переиспользуемого кода, который используется для выполнения одной связанной операции. Здесь наша функция будет считывать данные о портфеле из файла и вычислять общую стоимость. Это полезно, так как после создания этой функции мы можем использовать ее несколько раз с разными файлами портфелей, избавляясь от необходимости повторно писать один и тот же код.

Понимание проблемы

В предыдущем практическом занятии (лабораторной работе) вы, возможно, написали код для считывания данных о портфеле и вычисления общей стоимости. Однако этот код, вероятно, был написан таким образом, что его нельзя легко переиспользовать. Теперь мы преобразуем этот код в переиспользуемую функцию.

Файлы с данными о портфеле имеют определенный формат. Они содержат информацию в виде "Символ Количество_акций Цена". Каждая строка в файле представляет собой позицию в портфеле акций. Например, в файле с именем portfolio.dat вы можете увидеть строки следующего вида:

AA 100 32.20
IBM 50 91.10
...

Здесь первая часть (например, "AA" или "IBM") - это символ акции, который является уникальным идентификатором акции. Вторая часть - это количество акций, которые вы владеете, а третья часть - это цена за одну акцию.

Создание функции

Создадим файл Python с именем pcost.py в директории /home/labex/project. Этот файл будет содержать нашу функцию. Вот код, который мы поместим в файл pcost.py:

def portfolio_cost(filename):
    """
    Computes the total cost (shares*price) of a portfolio file

    Args:
        filename: The name of the portfolio file

    Returns:
        The total cost of the portfolio as a float
    """
    total_cost = 0.0

    ## Open the file and read through each line
    with open(filename, 'r') as f:
        for line in f:
            fields = line.split()
            ## Extract the data (symbol, shares, price)
            shares = int(fields[1])
            price = float(fields[2])
            ## Add the cost to our running total
            total_cost += shares * price

    return total_cost

## Call the function with the portfolio.dat file
if __name__ == '__main__':
    cost = portfolio_cost('/home/labex/project/portfolio.dat')
    print(cost)

В этом коде мы сначала определяем функцию с именем portfolio_cost, которая принимает filename в качестве аргумента. Внутри функции мы инициализируем переменную total_cost со значением 0.0. Затем мы открываем файл с помощью функции open в режиме чтения ('r'). Мы используем цикл for для прохода по каждой строке в файле. Для каждой строки мы разбиваем ее на поля с помощью метода split(). Затем мы извлекаем количество акций и преобразуем его в целое число, а цену - в число с плавающей точкой. Мы вычисляем стоимость данной позиции в портфеле, умножив количество акций на цену, и добавляем ее к total_cost. Наконец, мы возвращаем total_cost.

Часть if __name__ == '__main__': используется для вызова функции, когда скрипт запускается напрямую. Мы передаем путь к файлу portfolio.dat в функцию и выводим результат.

Тестирование функции

Теперь запустим программу, чтобы проверить, работает ли она. Мы должны перейти в директорию, где находится файл pcost.py, и затем запустить скрипт Python. Вот команды для этого:

cd /home/labex/project
python3 pcost.py

После выполнения этих команд вы должны увидеть следующий вывод:

44671.15

Этот вывод представляет общую стоимость всех акций в портфеле.

Понимание кода

Разберем пошагово, что делает наша функция:

  1. Она принимает filename в качестве входного параметра. Это позволяет нам использовать функцию с разными файлами портфелей.
  2. Она открывает файл и читает его построчно. Это делается с помощью функции open и цикла for.
  3. Для каждой строки она разбивает строку на поля с помощью метода split(). Этот метод разбивает строку на список строк на основе пробелов.
  4. Она преобразует количество акций в целое число и цену в число с плавающей точкой. Это необходимо, так как данные, считанные из файла, имеют строковый формат, и мы должны выполнять арифметические операции с ними.
  5. Она вычисляет стоимость (количество_акций * цена) для каждой позиции в портфеле и добавляет ее к текущей общей стоимости. Это дает нам общую стоимость портфеля.
  6. Она возвращает окончательную общую стоимость. Это позволяет нам использовать результат в других частях нашей программы, если это необходимо.

Эта функция теперь может быть переиспользована. Мы можем вызывать ее с разными файлами портфелей, чтобы вычислить их стоимость, что делает наш код более эффективным и легким в поддержке.

Добавление обработки ошибок

При работе с реальными данными очень часто встречаются несоответствия или ошибки. Например, данные могут иметь пропущенные значения, неправильный формат или другие проблемы. Python предлагает механизмы обработки исключений для элегантного решения таких ситуаций. Обработка исключений позволяет программе продолжать работу даже при возникновении ошибки, вместо того чтобы аварийно завершиться.

Понимание проблемы

Рассмотрим файл portfolio3.dat. Этот файл содержит некоторые данные о портфеле, такие как символ акции, количество акций и цена за одну акцию. Чтобы просмотреть содержимое этого файла, можно использовать следующую команду:

cat /home/labex/project/portfolio3.dat

При выполнении этой команды вы заметите, что в некоторых строках файла вместо чисел для количества акций используются дефисы (-). Вот пример того, что вы можете увидеть:

AA 100 32.20
IBM 50 91.10
C - 53.08
...

Если мы попытаемся запустить текущий код на этом файле, он аварийно завершится. Причина в том, что наш код предполагает преобразование количества акций в целое число, но он не может преобразовать дефис (-) в целое число. Попробуем запустить код и посмотрим, что произойдет:

python3 -c "import sys; sys.path.append('/home/labex/project'); from pcost import portfolio_cost; print(portfolio_cost('/home/labex/project/portfolio3.dat'))"

Вы увидите сообщение об ошибке следующего вида:

ValueError: invalid literal for int() with base 10: '-'

Эта ошибка возникает, потому что Python не может преобразовать символ - в целое число при попытке выполнить int(fields[1]).

Введение в обработку исключений

В Python обработка исключений использует блоки try и except. Блок try содержит код, который может вызвать исключение. Исключение - это ошибка, которая возникает во время выполнения программы. Блок except содержит код, который будет выполнен, если в блоке try возникнет исключение.

Вот пример того, как работают блоки try и except:

try:
    ## Code that might raise an exception
    result = risky_operation()
except ExceptionType as e:
    ## Code to handle the exception
    print(f"An error occurred: {e}")

Когда Python выполняет код в блоке try, если возникает исключение, выполнение сразу переходит в соответствующий блок except. ExceptionType в блоке except указывает тип исключения, которое мы хотим обработать. Переменная e содержит информацию об исключении, например, сообщение об ошибке.

Модификация функции с использованием обработки исключений

Обновим файл pcost.py, чтобы обработать ошибки в данных. Мы будем использовать блоки try и except для пропуска строк с некорректными данными и вывода предупреждающего сообщения.

def portfolio_cost(filename):
    """
    Computes the total cost (shares*price) of a portfolio file
    Handles lines with bad data by skipping them and showing a warning.

    Args:
        filename: The name of the portfolio file

    Returns:
        The total cost of the portfolio as a float
    """
    total_cost = 0.0

    ## Open the file and read through each line
    with open(filename, 'r') as f:
        for line in f:
            fields = line.split()
            try:
                ## Extract the data (symbol, shares, price)
                shares = int(fields[1])
                price = float(fields[2])
                ## Add the cost to our running total
                total_cost += shares * price
            except ValueError as e:
                ## Print a warning for lines that can't be parsed
                print(f"Couldn't parse: '{line}'")
                print(f"Reason: {e}")

    return total_cost

## Call the function with the portfolio3.dat file
if __name__ == '__main__':
    cost = portfolio_cost('/home/labex/project/portfolio3.dat')
    print(cost)

В этом обновленном коде мы сначала открываем файл и читаем его построчно. Для каждой строки мы разбиваем ее на поля. Затем мы пытаемся преобразовать количество акций в целое число и цену в число с плавающей точкой. Если это преобразование завершается неудачно (т.е. возникает исключение ValueError), мы выводим предупреждающее сообщение и пропускаем эту строку. В противном случае мы вычисляем стоимость акций и добавляем ее к общей стоимости.

Тестирование обновленной функции

Теперь запустим обновленную программу с проблемным файлом. Сначала нужно перейти в директорию проекта, а затем можно запустить скрипт Python.

cd /home/labex/project
python3 pcost.py

Вы должны увидеть вывод следующего вида:

Couldn't parse: 'C - 53.08
'
Reason: invalid literal for int() with base 10: '-'
Couldn't parse: 'DIS - 34.20
'
Reason: invalid literal for int() with base 10: '-'
44671.15

Теперь программа делает следующее:

  1. Она пытается обработать каждую строку файла.
  2. Если строка содержит недопустимые данные, она перехватывает исключение ValueError.
  3. Она выводит полезное сообщение о проблеме.
  4. Она продолжает обработку остальной части файла.
  5. Она возвращает общую стоимость на основе допустимых строк.

Такой подход делает нашу программу гораздо более устойчивой при работе с неидеальными данными. Она может элегантно обрабатывать ошибки и по-прежнему предоставлять полезные результаты.

Интерактивное экспериментирование

Python предлагает интерактивный режим, который позволяет сразу запускать код. Это очень полезно для тестирования кода и опробования новых идей. На этом этапе мы научимся вызывать функции непосредственно из интерпретатора Python.

Запуск Python в интерактивном режиме

Для запуска скрипта Python и перехода в интерактивный режим можно использовать флаг -i. Этот флаг сообщает Python продолжать работу в интерактивном режиме после выполнения скрипта. Вот как это делается:

cd /home/labex/project
python3 -i pcost.py

Разберем, что делает эта команда:

  1. Сначала cd /home/labex/project изменяет текущую директорию на /home/labex/project. Именно здесь находится наш скрипт pcost.py.
  2. Затем python3 -i pcost.py выполняет скрипт pcost.py. После завершения выполнения скрипта Python остается в интерактивном режиме.
  3. В интерактивном режиме вы можете напрямую вводить команды Python в терминал.

После выполнения команды вы увидите вывод скрипта pcost.py, за которым следует приглашение Python (>>>). Это приглашение означает, что вы теперь можете вводить команды Python.

Вызов функции в интерактивном режиме

Как только вы войдете в интерактивный режим, вы можете вызывать функцию portfolio_cost() с разными именами файлов. Это позволяет увидеть, как функция ведет себя с различными входными данными. Вот пример:

>>> portfolio_cost('/home/labex/project/portfolio.dat')
44671.15
>>> portfolio_cost('/home/labex/project/portfolio2.dat')
19908.75
>>> portfolio_cost('/home/labex/project/portfolio3.dat')
Couldn't parse: 'C - 53.08
'
Reason: invalid literal for int() with base 10: '-'
Couldn't parse: 'DIS - 34.20
'
Reason: invalid literal for int() with base 10: '-'
44671.15

Используя такой интерактивный подход, вы можете:

  • Тестировать функцию с разными входными данными, чтобы убедиться, что она работает как ожидается.
  • Экспериментировать с поведением функции в различных условиях.
  • Отлаживать код на лету, наблюдая за непосредственными результатами вызовов функций.

Преимущества интерактивного режима

Интерактивный режим имеет несколько преимуществ:

  1. Вы можете быстро тестировать разные сценарии без необходимости каждый раз запускать весь скрипт.
  2. Вы можете сразу проверить значения переменных и результатов выражений, что помогает понять, что происходит в вашем коде.
  3. Вы можете тестировать небольшие фрагменты кода без создания полноценной программы. Это отлично подходит для обучения и опробования новых идей.
  4. Это отличный способ изучать и экспериментировать с Python, так как вы получаете мгновенный отклик.

Выход из интерактивного режима

Когда вы закончите экспериментировать, вы можете выйти из интерактивного режима двумя способами:

  • Введите exit() и нажмите Enter. Это простой способ завершить интерактивную сессию.
  • Нажмите Ctrl+D (на Unix/Linux). Это сочетание клавиш также позволяет выйти из интерактивного режима.

В процессе изучения программирования на Python техника определения функций и их интерактивного тестирования будет чрезвычайно ценной для разработки и отладки. Она позволяет быстро вносить изменения в код и находить и исправлять ошибки.

Резюме

В этом лабораторном занятии вы изучили несколько ключевых концепций программирования на Python. Во - первых, вы узнали, как определять и использовать функции, что делает ваш код повторно используемым. Во - вторых, вы овладели реализацией обработки исключений, что повышает надежность ваших программ. И, наконец, вы узнали, как использовать Python в интерактивном режиме для тестирования и экспериментирования.

Эти навыки являются фундаментальными для написания надежных программ на Python. Функции помогают организовать и повторно использовать код, обработка исключений позволяет элегантно справляться с непредвиденными ситуациями, а интерактивный режим предоставляет мощную среду для тестирования и отладки. По мере продвижения в изучении Python эти концепции будут становиться все более ценными для разработки более крупных и сложных приложений.