From faabe5977566f9fa9a033cc07d9c3c1427a8b9e6 Mon Sep 17 00:00:00 2001
From: Crinibus <57172157+Crinibus@users.noreply.github.com>
Date: Sat, 1 Oct 2022 00:49:03 +0200
Subject: [PATCH 1/5] Add defaults to arguments --id and --name
---
scraper/arguments.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/scraper/arguments.py b/scraper/arguments.py
index 4edefe9a..36496948 100644
--- a/scraper/arguments.py
+++ b/scraper/arguments.py
@@ -57,6 +57,7 @@ def argparse_setup() -> ArgumentParser.parse_args:
nargs="*",
action="extend",
dest="id",
+ default=[],
)
parser.add_argument(
@@ -67,6 +68,7 @@ def argparse_setup() -> ArgumentParser.parse_args:
nargs="*",
action="extend",
dest="name",
+ default=[],
)
parser.add_argument(
From 6fdaa83e833934c6054e89dabfa0d6becbee38ae Mon Sep 17 00:00:00 2001
From: Crinibus <57172157+Crinibus@users.noreply.github.com>
Date: Sat, 1 Oct 2022 00:51:03 +0200
Subject: [PATCH 2/5] Make function add_scatter_plot more flexible/dynamic
Add optional parameters:
- name
- color
- hover_text
---
scraper/visualize.py | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/scraper/visualize.py b/scraper/visualize.py
index f78ed1d5..4305f05e 100644
--- a/scraper/visualize.py
+++ b/scraper/visualize.py
@@ -202,14 +202,21 @@ def add_scatter_plot(
currency: str,
dates: list,
prices: list,
+ name=None,
+ color=None,
+ hover_text=None,
) -> None:
+ scatter_name = name if name else f"{website_name.capitalize()} - {id}"
+ scatter_color = color if color else WEBSITE_COLORS[website_name]
+ scatter_hover_text = hover_text if hover_text else "Price: %{y:.0f}" + f" {currency}"
+
figure.add_trace(
go.Scatter(
- name=f"{website_name.capitalize()} - {id}",
+ name=scatter_name,
x=dates,
y=prices,
- line={"color": WEBSITE_COLORS[website_name], "width": 2},
- hovertemplate="Price: %{y:.0f}" + f" {currency}",
+ line={"color": scatter_color, "width": 2},
+ hovertemplate=scatter_hover_text,
)
)
From 2ffbf11e22df878527e7d0beb0bc1d90042ed38c Mon Sep 17 00:00:00 2001
From: Crinibus <57172157+Crinibus@users.noreply.github.com>
Date: Sat, 1 Oct 2022 00:55:46 +0200
Subject: [PATCH 3/5] Add argument --compare
---
main.py | 2 +-
scraper/arguments.py | 11 ++++++-
scraper/visualize.py | 78 +++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 88 insertions(+), 3 deletions(-)
diff --git a/main.py b/main.py
index 60ade4c5..7c0752e3 100644
--- a/main.py
+++ b/main.py
@@ -12,7 +12,7 @@ def main():
scraper.clean_records_data()
if args.visualize:
- scraper.visualize_data(args.all, args.category, args.id, args.name, args.up_to_date)
+ scraper.visualize_data(args.all, args.category, args.id, args.name, args.up_to_date, args.compare)
if args.reset:
scraper.reset()
diff --git a/scraper/arguments.py b/scraper/arguments.py
index 36496948..16c22f47 100644
--- a/scraper/arguments.py
+++ b/scraper/arguments.py
@@ -89,6 +89,13 @@ def argparse_setup() -> ArgumentParser.parse_args:
metavar="SEARCH_TERM",
)
+ parser.add_argument(
+ "--compare",
+ help="use with --visualize and --id to compare two or more products on one graph",
+ action="store_true",
+ dest="compare",
+ )
+
parser.add_argument(
"--reset",
help="delete data for each product in records.json, such as prices of each recorded day",
@@ -143,8 +150,10 @@ def validate_arguments(parser: ArgumentParser) -> None:
parser.error("Specified more urls than categories")
if args.visualize:
- if not any([args.all, args.category, args.id, args.name]):
+ if not any([args.all, args.category, args.id, args.name, args.compare]):
parser.error("When using --visualize, then one of the following is required: --all, --category, --id, --name")
+ if args.compare and not any([args.id, args.name]):
+ parser.error("When using --visualize and --compare, then one of the following is required: --id, --name")
if args.latest_datapoint:
if not args.name and not args.id:
diff --git a/scraper/visualize.py b/scraper/visualize.py
index 4305f05e..d8a737c6 100644
--- a/scraper/visualize.py
+++ b/scraper/visualize.py
@@ -5,9 +5,15 @@
from datetime import datetime
-def visualize_data(show_all: bool, categories: List[str], ids: List[str], names: List[str], only_up_to_date: bool):
+def visualize_data(
+ show_all: bool, categories: List[str], ids: List[str], names: List[str], only_up_to_date: bool, compare: bool
+) -> None:
print("Visualizing...")
+ if compare:
+ compare_products(ids, names)
+ return
+
if show_all:
show_all_products(only_up_to_date)
@@ -156,6 +162,43 @@ def show_all_products(only_up_to_date: bool) -> None:
fig.show()
+def compare_products(ids: List[str], names: List[str]) -> None:
+ products_with_ids = get_products_with_ids(ids)
+ products_with_name = get_products_with_names(names)
+
+ products = [*products_with_ids, *products_with_name]
+
+ if len(products_with_ids) < len(ids) or len(products_with_name) < len(names):
+ print("\nCouldn't find all products that have the specified id(s) or name(s), only comparing those that are found\n")
+
+ product_ids = [product["info"]["id"] for product in products]
+ product_ids_string = ", ".join(product_ids)
+
+ print(f"Comparing products with ids: {product_ids_string}")
+
+ fig = go.Figure()
+
+ for product in products:
+ product_name = product["name"]
+ product_info = product["info"]
+ product_id = product_info["id"]
+
+ add_scatter_plot(
+ fig,
+ product_info["website_name"],
+ str(product_id),
+ product_info["currency"],
+ product_info["dates"],
+ product_info["prices"],
+ name=f"{product_id} - {product_name}",
+ )
+
+ title = f"Comparing products with ids {product_ids_string}"
+
+ config_figure(fig, title)
+ fig.show()
+
+
def format_data() -> Generator[dict, None, None]:
records_data = Filemanager.get_record_data()
@@ -239,6 +282,21 @@ def get_product_with_id(id: str) -> dict:
return None
+def get_products_with_ids(ids: List[str]) -> List[dict]:
+ products = []
+ for product_info in format_data():
+ for website_info in product_info["websites"]:
+ if str(website_info["id"]) in ids:
+ products.append(
+ {
+ "name": product_info["name"],
+ "category": product_info["category"],
+ "info": website_info,
+ }
+ )
+ return products
+
+
def get_product_with_name(name: str) -> dict:
for product_info in format_data():
if product_info["name"].lower() == name.lower():
@@ -246,6 +304,24 @@ def get_product_with_name(name: str) -> dict:
return None
+def get_products_with_names(names: List[str]) -> List[str]:
+ names_lowercase = [name.lower() for name in names]
+ products = []
+ for product_info in format_data():
+ if not product_info["name"].lower() in names_lowercase:
+ continue
+
+ for website_info in product_info["websites"]:
+ products.append(
+ {
+ "name": product_info["name"],
+ "category": product_info["category"],
+ "info": website_info,
+ }
+ )
+ return products
+
+
def get_all_products() -> Generator[dict, None, None]:
for product_info in format_data():
yield product_info
From a3ebb2bccdc5aa59a4c71407652a3fc853639014 Mon Sep 17 00:00:00 2001
From: Crinibus <57172157+Crinibus@users.noreply.github.com>
Date: Sat, 1 Oct 2022 00:57:44 +0200
Subject: [PATCH 4/5] Fix spacing in visualizing example commands section
---
README.md | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 3814b7d0..cc5c5eca 100644
--- a/README.md
+++ b/README.md
@@ -233,6 +233,8 @@ To show graphs for all products, run the following command:
python3 main.py -v --all
```
+
+
**Show graph(s) for specific products**
To show a graph for only one product, run the following command where `````` is the id of the product you want a graph for:
@@ -245,6 +247,7 @@ For multiple products, just add another id, like so:
python3 main.py -v --id
```
+
**Show graphs for products in one or more categories**
@@ -258,6 +261,7 @@ For multiple categories, just add another category, like so:
python3 main.py -v -c
```
+
**Show graps for products with a specific name**
@@ -273,6 +277,7 @@ python3 main.py -v --name
If the name of a product has multiple words in it, then just add quotation marks around the name.
+
**Only show graph for products that are up to date**
@@ -282,5 +287,5 @@ python3 main.py -v --all -utd
```
The use of the flag ```-utd``` is only implemented when visualizing all products like the example above or when visualizing all products in a category:
```
-python3 main.py -v -c gpu -utd
+python3 main.py -v -c -utd
```
From 0cb9e5b42414cf5614c84b9897a4649da9de9c36 Mon Sep 17 00:00:00 2001
From: Crinibus <57172157+Crinibus@users.noreply.github.com>
Date: Sat, 1 Oct 2022 00:58:53 +0200
Subject: [PATCH 5/5] Add explanation usage of argument --compare to README
---
README.md | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/README.md b/README.md
index cc5c5eca..dbf9f74c 100644
--- a/README.md
+++ b/README.md
@@ -221,6 +221,7 @@ To visualize your data, just run main.py with the ```-v``` or ```--visualize```
- ```-c [ [ ...]]``` or ```--category [ [ ...]]``` to visualize all products in one or more categories
- ```--id [ [ ...]]``` to visualize one or more products with the specified id(s)
- ```-n [ [ ...]]``` or ```--name [ ...]]``` to visualize one or more products with the specified name(s)
+- ```--compare``` to compare two or more products with the specified id(s) and/or name(s) on one graph. Use with ```--id``` and/or ```--name```
### Example graph
![](https://user-images.githubusercontent.com/57172157/171033112-908f6420-6c7a-44ef-ba67-8a4a73bbd96e.png)
@@ -289,3 +290,20 @@ The use of the flag ```-utd``` is only implemented when visualizing all products
```
python3 main.py -v -c -utd
```
+
+
+
+**Compare two products**
+
+To compare two products on one graph, use the flag ```--compare``` with flag ```--id``` and/or ```--name```, like so:
+```
+python3 main.py -v --compare --id
+```
+```
+python3 main.py -v --compare --name
+```
+```
+python3 main.py -v --compare --id --name
+```
+
+***OBS** when using ```--name``` multiple products can be visualized*