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

[bug] Fix SettingWithCopyWarning and export error #2481

Merged
merged 6 commits into from
Sep 2, 2022
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)