Skip to content

Commit

Permalink
Merge pull request #178 from Crinibus/add-argument-to-compare-product…
Browse files Browse the repository at this point in the history
…s-visualize

Add argument --compare
  • Loading branch information
Crinibus authored Sep 30, 2022
2 parents 873a311 + 0cb9e5b commit 73d1b32
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 7 deletions.
25 changes: 24 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ To visualize your data, just run main.py with the ```-v``` or ```--visualize```
- ```-c [<category> [<category> ...]]``` or ```--category [<category> [<category> ...]]``` to visualize all products in one or more categories
- ```--id [<id> [<id> ...]]``` to visualize one or more products with the specified id(s)
- ```-n [<name> [<name> ...]]``` or ```--name [<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)
Expand All @@ -253,6 +254,8 @@ To show graphs for all products, run the following command:
python3 main.py -v --all
```

<br/>

**Show graph(s) for specific products**

To show a graph for only one product, run the following command where ```<id>``` is the id of the product you want a graph for:
Expand All @@ -265,6 +268,7 @@ For multiple products, just add another id, like so:
python3 main.py -v --id <id> <id>
```

<br/>

**Show graphs for products in one or more categories**

Expand All @@ -278,6 +282,7 @@ For multiple categories, just add another category, like so:
python3 main.py -v -c <category> <category>
```

<br/>

**Show graps for products with a specific name**

Expand All @@ -293,6 +298,7 @@ python3 main.py -v --name <name> <name2>

If the name of a product has multiple words in it, then just add quotation marks around the name.

<br/>

**Only show graph for products that are up to date**

Expand All @@ -302,5 +308,22 @@ 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 <category> -utd
```

<br/>

**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 <id>
```
```
python3 main.py -v --compare --name <name>
```
```
python3 main.py -v --compare --id <id> --name <name>
```

***OBS** when using ```--name``` multiple products can be visualized*
2 changes: 1 addition & 1 deletion main.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
13 changes: 12 additions & 1 deletion scraper/arguments.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ def argparse_setup() -> ArgumentParser.parse_args:
nargs="*",
action="extend",
dest="id",
default=[],
)

parser.add_argument(
Expand All @@ -67,6 +68,7 @@ def argparse_setup() -> ArgumentParser.parse_args:
nargs="*",
action="extend",
dest="name",
default=[],
)

parser.add_argument(
Expand All @@ -87,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",
Expand Down Expand Up @@ -141,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:
Expand Down
91 changes: 87 additions & 4 deletions scraper/visualize.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -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()

Expand Down Expand Up @@ -202,14 +245,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,
)
)

Expand All @@ -232,13 +282,46 @@ 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():
return product_info
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
Expand Down

0 comments on commit 73d1b32

Please sign in to comment.