Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update metar.py default year, month to keyword-only and None #1523

Merged
merged 2 commits into from Oct 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
34 changes: 25 additions & 9 deletions src/metpy/io/metar.py
Expand Up @@ -61,7 +61,7 @@


@exporter.export
def parse_metar_to_dataframe(metar_text, year=datetime.now().year, month=datetime.now().month):
def parse_metar_to_dataframe(metar_text, *, year=None, month=None):
"""Parse a single METAR report into a Pandas DataFrame.

Takes a METAR string in a text form, and creates a `pandas.DataFrame` including the
Expand All @@ -76,9 +76,9 @@ def parse_metar_to_dataframe(metar_text, year=datetime.now().year, month=datetim
metar_text : str
The METAR report
year : int, optional
Year in which observation was taken, defaults to the current year
Year in which observation was taken, defaults to current year. Keyword-only argument.
month : int, optional
Month in which observation was taken, defaults to the current month
Month in which observation was taken, defaults to current month. Keyword-only argument.

Returns
-------
Expand Down Expand Up @@ -116,6 +116,12 @@ def parse_metar_to_dataframe(metar_text, year=datetime.now().year, month=datetim
and altimeter value, float

"""
# Defaults year and/or month to present reported date if not provided
if year is None or month is None:
now = datetime.now()
year = now.year if year is None else year
month = now.month if month is None else month

# Use the named tuple parsing function to separate metar
# Utilizes the station dictionary which contains elevation, latitude, and longitude
metar_vars = parse_metar_to_named_tuple(metar_text, station_info, year, month)
Expand Down Expand Up @@ -176,8 +182,7 @@ def parse_metar_to_dataframe(metar_text, year=datetime.now().year, month=datetim
return df


def parse_metar_to_named_tuple(metar_text, station_metadata, year=datetime.now().year,
month=datetime.now().month):
def parse_metar_to_named_tuple(metar_text, station_metadata, year, month):
dcamron marked this conversation as resolved.
Show resolved Hide resolved
"""Parse a METAR report in text form into a list of named tuples.

Parameters
Expand All @@ -186,10 +191,15 @@ def parse_metar_to_named_tuple(metar_text, station_metadata, year=datetime.now()
The METAR report
station_metadata : dict
Mapping of station identifiers to station metadata
year : int
Reported year of observation for constructing 'date_time'
month : int
Reported month of observation for constructing 'date_time'

Returns
-------
`pandas.DataFrame`
metar : namedtuple
Named tuple of parsed METAR fields

Notes
-----
Expand Down Expand Up @@ -424,7 +434,7 @@ def parse_metar_to_named_tuple(metar_text, station_metadata, year=datetime.now()


@exporter.export
def parse_metar_file(filename, year=datetime.now().year, month=datetime.now().month):
def parse_metar_file(filename, *, year=None, month=None):
"""Parse a text file containing multiple METAR reports and/or text products.

Parameters
Expand All @@ -433,9 +443,9 @@ def parse_metar_file(filename, year=datetime.now().year, month=datetime.now().mo
If str, the name of the file to be opened. If `filename` is a file-like object,
this will be read from directly.
year : int, optional
Year in which observation was taken, defaults to the current year
Year in which observation was taken, defaults to current year. Keyword-only argument.
month : int, optional
Month in which observation was taken, defaults to the current month
Month in which observation was taken, defaults to current month. Keyword-only argument.

Returns
-------
Expand Down Expand Up @@ -473,6 +483,12 @@ def parse_metar_file(filename, year=datetime.now().year, month=datetime.now().mo
and altimeter value, float

"""
# Defaults year and/or month to present reported date if not provided
if year is None or month is None:
now = datetime.now()
year = now.year if year is None else year
month = now.month if month is None else month

# Function to merge METARs
def merge(x, key=' '):
tmp = []
Expand Down
17 changes: 17 additions & 0 deletions tests/io/test_metar.py
Expand Up @@ -6,6 +6,7 @@

import numpy as np
from numpy.testing import assert_almost_equal, assert_equal
import pytest

from metpy.cbook import get_test_data
from metpy.io import parse_metar_file, parse_metar_to_dataframe
Expand Down Expand Up @@ -98,6 +99,14 @@ def test_date_time_given():
assert df.northward_wind.values == 0


def test_parse_metar_df_positional_datetime_failure():
"""Test that positional year, month arguments fail for parse_metar_to_dataframe."""
# pylint: disable=too-many-function-args
with pytest.raises(TypeError, match='takes 1 positional argument but 3 were given'):
parse_metar_to_dataframe('K6B0 261200Z AUTO 00000KT 10SM CLR 20/M17'
'A3002 RMK AO2 T01990165=', 2019, 6)


def test_named_tuple_test1():
"""Test the named tuple parsing function."""
df = parse_metar_to_dataframe('KDEN 012153Z 09010KT 10SM FEW060 BKN110 BKN220 27/13 '
Expand All @@ -118,6 +127,14 @@ def test_parse_file():
assert test.air_pressure_at_sea_level.values == 1016.76


def test_parse_file_positional_datetime_failure():
"""Test that positional year, month arguments fail for parse_metar_file."""
# pylint: disable=too-many-function-args
input_file = get_test_data('metar_20190701_1200.txt', as_file_obj=False)
with pytest.raises(TypeError, match='takes 1 positional argument but 3 were given'):
parse_metar_file(input_file, 2016, 12)


def test_parse_file_bad_encoding():
"""Test the parser on an entire file that has at least one bad utf-8 encoding."""
input_file = get_test_data('2020010600_sao.wmo', as_file_obj=False)
Expand Down