Skip to content

Commit

Permalink
[bug] Fix SettingWithCopyWarning and export error (#2481)
Browse files Browse the repository at this point in the history
* fixed Pandas SettingWithCopyWarnings

* fixed typo in test_google_view

* fixed typo in test_google_view
  • Loading branch information
boyestrous authored Sep 2, 2022
1 parent 3da5c35 commit db844a5
Show file tree
Hide file tree
Showing 9 changed files with 1,074 additions and 16 deletions.
6 changes: 3 additions & 3 deletions openbb_terminal/common/behavioural_analysis/google_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def get_regions(symbol: str) -> pd.DataFrame:


@log_start_end(log=logger)
def get_queries(symbol: str) -> pd.DataFrame:
def get_queries(symbol: str) -> dict:
"""Get related queries from google api [Source: google]
Parameters
Expand All @@ -60,8 +60,8 @@ def get_queries(symbol: str) -> pd.DataFrame:
Returns
-------
pd.DataFrame
Dataframe of related queries
dict : {'top': pd.DataFrame or None, 'rising': pd.DataFrame or None}
"""
pytrend = TrendReq()
pytrend.build_payload(kw_list=[symbol])
Expand Down
31 changes: 21 additions & 10 deletions openbb_terminal/common/behavioural_analysis/google_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,23 +211,34 @@ def display_queries(symbol: str, limit: int = 5, export: str = ""):
Ticker symbol
limit: int
Number of regions to show
export: str
export: {"csv","json","xlsx","png","jpg","pdf","svg"}
Format to export data
Returns
-------
None
"""

df_related_queries = google_model.get_queries(symbol)
df = df_related_queries.copy()
df_related_queries = df_related_queries[symbol]["top"].head(limit)
df_related_queries["value"] = df_related_queries["value"].apply(
lambda x: str(x) + "%"
)
# Retrieve a dict with top and rising queries
dict_related_queries = google_model.get_queries(symbol)

# Select the DataFrame "top" from the dict
df_top_queries = dict_related_queries[symbol]["top"].head(limit).copy()
df_export = (
df_top_queries.copy()
) # export the raw values, prior to string manipulation

# convert to strings and add %
df_top_queries["value"] = df_top_queries["value"].apply(lambda x: str(x) + "%")
print_rich_table(
df_related_queries,
headers=list(df_related_queries.columns),
df_top_queries,
headers=list(df_top_queries.columns),
title=f"Top {symbol}'s related queries",
)

export_data(export, os.path.dirname(os.path.abspath(__file__)), "queries", df)
export_data(
export, os.path.dirname(os.path.abspath(__file__)), "queries", df_export
)


@log_start_end(log=logger)
Expand Down
4 changes: 2 additions & 2 deletions openbb_terminal/stocks/options/op_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,6 @@ def __init__(
Parameters
----------
type : int
Option type, 1 for call and -1 for a put
s : float
The underlying asset price
k : float
Expand All @@ -182,6 +180,8 @@ def __init__(
The number of days until expiration
vol : float
The underlying volatility for an option
opt_type : int
put == -1; call == +1
"""
self.Type = int(opt_type)
self.price = float(s)
Expand Down
2 changes: 1 addition & 1 deletion openbb_terminal/stocks/options/yfinance_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def get_full_option_chain(
if calls:
df_list.append(call_df)
option_factor.append(1)
df_list = [x[x["impliedVolatility"] > 0] for x in df_list]
df_list = [x[x["impliedVolatility"] > 0].copy() for x in df_list]
# Add in greeks to each df
# Time to expiration:
dt = (datetime.strptime(expiration, "%Y-%m-%d") - datetime.now()).seconds / (
Expand Down

Large diffs are not rendered by default.

104 changes: 104 additions & 0 deletions tests/openbb_terminal/common/behavioural_analysis/test_google_view.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# IMPORTATION STANDARD

# IMPORTATION THIRDPARTY
import pandas as pd
import pytest

# IMPORTATION INTERNAL
from openbb_terminal.common.behavioural_analysis import google_view

# pylint: disable=E1101
# pylint: disable=W0603
# pylint: disable=E1111
# pylint: disable=W0621
# pylint: disable=W0613


@pytest.fixture
def get_queries_response():
"""
mock response from get_queries function in google_model
"""
top_list = [
["stock aapl", 100],
["aapl price", 29],
["stock price aapl", 24],
["amzn", 19],
["tsla", 19],
["msft", 15],
["tsla stock", 12],
["amzn stock", 11],
["fb stock", 10],
["msft stock", 9],
["nvda", 7],
["dow", 6],
["tesla", 6],
["amd", 5],
["goog", 5],
["baba", 5],
["aapl premarket", 5],
["nvda stock", 5],
["tesla stock", 5],
["amd stock", 4],
["aapl stock price today", 4],
["nflx", 4],
["nio", 4],
["baba stock", 4],
["nio stock", 4],
]

resp = {
"AAPL": {
"top": pd.DataFrame(top_list, columns=["query", "value"]),
"rising": pd.DataFrame(top_list, columns=["query", "value"]),
}
}

return resp


@pytest.mark.default_cassette("test_google_view")
@pytest.mark.vcr
@pytest.mark.parametrize(
"symbol, limit, export",
[
(
# standard run without export
"AAPL",
10,
"",
),
(
# standard run WITH export
"AAPL",
10,
"csv",
),
],
)
def test_display_queries(mocker, symbol, limit, export, get_queries_response):
# MOCK VISUALIZE_OUTPUT
mocker.patch(target="openbb_terminal.helper_classes.TerminalStyle.visualize_output")

# MOCK GOOGLE_MODEL
mocker.patch(
target="openbb_terminal.common.behavioural_analysis.google_model.get_queries",
return_value=get_queries_response,
)

# MOCK EXPORT_DATA
export_mock = mocker.Mock()
mocker.patch(
target="openbb_terminal.common.behavioural_analysis.google_view.export_data",
new=export_mock,
)

google_view.display_queries(symbol, limit, export)

if export:
pd.testing.assert_frame_equal(
export_mock.call_args[0][3], # fourth positional arg is the df
pd.DataFrame(
get_queries_response[symbol]["top"].head(limit)
), # expected DF
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
query value
0 stock aapl 100%
1 aapl price 29%
2 stock price aapl 24%
3 amzn 19%
4 tsla 19%
5 msft 15%
6 tsla stock 12%
7 amzn stock 11%
8 fb stock 10%
9 msft stock 9%
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
query value
0 stock aapl 100%
1 aapl price 29%
2 stock price aapl 24%
3 amzn 19%
4 tsla 19%
5 msft 15%
6 tsla stock 12%
7 amzn stock 11%
8 fb stock 10%
9 msft stock 9%
99 changes: 99 additions & 0 deletions tests/openbb_terminal/test_helper_funcs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# IMPORTATION STANDARD
from pathlib import Path

# IMPORTATION THIRDPARTY
import pandas as pd
import pytest

# IMPORTATION INTERNAL
from openbb_terminal.helper_funcs import export_data

# pylint: disable=E1101
# pylint: disable=W0603
# pylint: disable=E1111
# pylint: disable=W0621
# pylint: disable=W0613


@pytest.fixture
def mock_compose_export_path(monkeypatch, tmp_path):
# files in tmp_dir will remain (in separate folders) for 3 sequential runs of pytest
def mock_return(func_name, *args, **kwargs):
return tmp_path, f"{func_name}_20220829_235959"

monkeypatch.setattr("openbb_terminal.helper_funcs.compose_export_path", mock_return)


@pytest.mark.parametrize(
"export_type, dir_path, func_name, df",
[
(
"csv",
"C:/openbb_terminal/common/behavioural_analysis",
"queries",
pd.DataFrame(),
),
(
"json",
"C:/openbb_terminal/common/behavioural_analysis",
"queries",
pd.DataFrame(),
),
(
"xlsx",
"C:/openbb_terminal/common/behavioural_analysis",
"queries",
pd.DataFrame(),
),
(
"png",
"C:/openbb_terminal/common/behavioural_analysis",
"queries",
pd.DataFrame(),
),
(
"jpg",
"C:/openbb_terminal/common/behavioural_analysis",
"queries",
pd.DataFrame(),
),
(
"pdf",
"C:/openbb_terminal/common/behavioural_analysis",
"queries",
pd.DataFrame(),
),
(
"svg",
"C:/openbb_terminal/common/behavioural_analysis",
"queries",
pd.DataFrame(),
),
],
)
def test_export_data_filetypes(
mock_compose_export_path, export_type, dir_path, func_name, df, tmp_path
):
export_data(export_type, dir_path, func_name, df)

assert Path(tmp_path / f"{func_name}_20220829_235959.{export_type}").exists()
# TODO add assertions to check the validity of the files?


@pytest.mark.parametrize(
"export_type, dir_path, func_name, data",
[
(
# Dict instead of DataFrame
"csv",
"C:/openbb_terminal/common/behavioural_analysis",
"queries",
dict({"test": "dict"}),
),
],
)
def test_export_data_invalid_data(
mock_compose_export_path, export_type, dir_path, func_name, data
):
with pytest.raises(AttributeError):
assert export_data(export_type, dir_path, func_name, data)

0 comments on commit db844a5

Please sign in to comment.