From c5e03ee28aa70726aa304bae5a81d80f91b35ceb Mon Sep 17 00:00:00 2001 From: Renan Costa <105220100+RenanCosta2@users.noreply.github.com> Date: Thu, 25 Jun 2026 15:11:19 -0300 Subject: [PATCH] =?UTF-8?q?feat:=20implementa=C3=A7=C3=A3o=20das=20solu?= =?UTF-8?q?=C3=A7=C3=B5es=20do=20desafio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 + cases/01/queries/get_product.sql | 11 + cases/01/retrieve_products.py | 63 ++++ cases/02/queries/data_store_cad.sql | 8 + cases/02/queries/data_store_sales.sql | 7 + cases/02/store_tm.py | 71 +++++ cases/03/data_viz.py | 49 +++ cases/03/queries/IMDB_movies.sql | 12 + cases/sql_test/01.sql | 14 + cases/sql_test/02.sql | 8 + cases/sql_test/03.sql | 13 + imdb_scatter_plot.png | Bin 0 -> 67054 bytes respostas_desafio.md | 437 ++++++++++++++++++++++++++ 13 files changed, 695 insertions(+) create mode 100644 .gitignore create mode 100644 cases/01/queries/get_product.sql create mode 100644 cases/01/retrieve_products.py create mode 100644 cases/02/queries/data_store_cad.sql create mode 100644 cases/02/queries/data_store_sales.sql create mode 100644 cases/02/store_tm.py create mode 100644 cases/03/data_viz.py create mode 100644 cases/03/queries/IMDB_movies.sql create mode 100644 cases/sql_test/01.sql create mode 100644 cases/sql_test/02.sql create mode 100644 cases/sql_test/03.sql create mode 100644 imdb_scatter_plot.png create mode 100644 respostas_desafio.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c2eabec --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.venv +.env \ No newline at end of file diff --git a/cases/01/queries/get_product.sql b/cases/01/queries/get_product.sql new file mode 100644 index 0000000..9b48b2b --- /dev/null +++ b/cases/01/queries/get_product.sql @@ -0,0 +1,11 @@ +SELECT + * +FROM + `looqbox-challenge`.data_product_sales +WHERE + PRODUCT_CODE = {product_code} AND + STORE_CODE = {store_code} AND + ( + DATE >= '{start_date}' AND + DATE <= '{end_date}' + ) \ No newline at end of file diff --git a/cases/01/retrieve_products.py b/cases/01/retrieve_products.py new file mode 100644 index 0000000..fbde3d1 --- /dev/null +++ b/cases/01/retrieve_products.py @@ -0,0 +1,63 @@ +import os +from sqlalchemy import create_engine +from dotenv import load_dotenv +import pandas as pd + + +def retrieve_data(product_code: int, store_code: int, date: list[str]) -> pd.DataFrame: + """ + Recupera os dados de vendas de produtos para um produto e uma loja específicos, em um período de tempo especificado. + + Args: + product_code (int): Código do produto filtrado. + store_code (int): Código da loja filtrada. + date (list[str]): Lista contendo a data inicial e a data final. + + Returns: + pd.DataFrame: Um DataFrame contendo as vendas dos produtos para o produto e a loja especificados, no período passado. + """ + + + # Carrega as variáveis de ambiente + load_dotenv() + user = os.getenv("USER") + password = os.getenv("PASSWORD") + host = os.getenv("HOST") + port = os.getenv("PORT") + database = os.getenv("DATABASE") + + # Forma a string de conexão + connection_string = f"mysql+pymysql://{user}:{password}@{host}:{port}/{database}" + + # Cria o motor de conexão + engine = create_engine(connection_string) + + # Leitura dos arquivos SQL e aplicação das variáveis + query_path = os.path.join(os.path.dirname(__file__), "queries", "get_product.sql") + try: + with open(query_path, "r", encoding="utf-8") as f: + sql_template = f.read() + + sql_query = sql_template.format( + product_code=product_code, + store_code=store_code, + start_date=date[0], + end_date=date[1] + ) + + except Exception as e: + print(f'Error: {e}') + + df = pd.read_sql(sql_query, con=engine) + + return df + + +def main(): + + # Exemplo de execução da função + df = retrieve_data(18, 1, ['2019-01-01', '2019-01-31']) + print(df) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/cases/02/queries/data_store_cad.sql b/cases/02/queries/data_store_cad.sql new file mode 100644 index 0000000..a9d092b --- /dev/null +++ b/cases/02/queries/data_store_cad.sql @@ -0,0 +1,8 @@ +SELECT + STORE_CODE, + STORE_NAME, + START_DATE, + END_DATE, + BUSINESS_NAME, + BUSINESS_CODE +FROM data_store_cad \ No newline at end of file diff --git a/cases/02/queries/data_store_sales.sql b/cases/02/queries/data_store_sales.sql new file mode 100644 index 0000000..99399c3 --- /dev/null +++ b/cases/02/queries/data_store_sales.sql @@ -0,0 +1,7 @@ +SELECT + STORE_CODE, + DATE, + SALES_VALUE, + SALES_QTY +FROM data_store_sales +WHERE DATE BETWEEN '2019-01-01' AND '2019-12-31' \ No newline at end of file diff --git a/cases/02/store_tm.py b/cases/02/store_tm.py new file mode 100644 index 0000000..205e458 --- /dev/null +++ b/cases/02/store_tm.py @@ -0,0 +1,71 @@ +import os +from sqlalchemy import create_engine +from dotenv import load_dotenv +import pandas as pd + +def get_sql_data() -> pd.DataFrame: + # Carrega as variáveis de ambiente + load_dotenv() + user = os.getenv("USER") + password = os.getenv("PASSWORD") + host = os.getenv("HOST") + port = os.getenv("PORT") + database = os.getenv("DATABASE") + + # Forma a string de conexão + connection_string = f"mysql+pymysql://{user}:{password}@{host}:{port}/{database}" + + # Cria o motor de conexão + engine = create_engine(connection_string) + + # Carrega os caminhos dos arquivos SQL + store_cad_path = os.path.join(os.path.dirname(__file__), "queries", "data_store_cad.sql") + store_sales_path = os.path.join(os.path.dirname(__file__), "queries", "data_store_sales.sql") + + # Lê as queries de dentro dos arquivos SQL + with open(store_cad_path, "r", encoding="utf-8") as f: + store_cad_query = f.read() + with open(store_sales_path, "r", encoding="utf-8") as f: + store_sales_query = f.read() + + # Carrega os dados + store_cad = pd.read_sql(store_cad_query, con=engine) + store_sales = pd.read_sql(store_sales_query, con=engine, parse_dates=['DATE']) + + return store_cad, store_sales + +def main(): + + # Exemplo de execução da função + store_cad, store_sales = get_sql_data() + + # Filtrando para o período especificado + store_sales = store_sales[(store_sales['DATE'] >= '2019-10-01') & (store_sales['DATE'] <= '2019-12-31')] + + # Junção dos DataFrames a partir do STORE_CODE + df_merged = store_cad.merge(store_sales, on='STORE_CODE', how='inner') + + # Agrupando a soma de venda e quantidade pela loja e categoria + df_grouped = df_merged.groupby([ + 'STORE_NAME', + 'BUSINESS_NAME' + ]).agg({ + 'SALES_VALUE': ['sum'], + 'SALES_QTY': ['sum'] + }).reset_index() + + # Cálculo do Ticket Médio + df_grouped['TM'] = (df_grouped['SALES_VALUE'] / df_grouped['SALES_QTY']).round(2) + + # Mantendo e renomeando apenas as colunas necessárias + df_result = df_grouped[['STORE_NAME', 'BUSINESS_NAME', 'TM']].rename( + columns={ + 'STORE_NAME': 'Loja', + 'BUSINESS_NAME': 'Categoria' + } + ) + + print(df_result) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/cases/03/data_viz.py b/cases/03/data_viz.py new file mode 100644 index 0000000..b3d1620 --- /dev/null +++ b/cases/03/data_viz.py @@ -0,0 +1,49 @@ +import os +from sqlalchemy import create_engine +from dotenv import load_dotenv +import pandas as pd +import matplotlib.pyplot as plt + +def get_imdb_data(): + # Carrega as variáveis de ambiente + load_dotenv() + user = os.getenv("USER") + password = os.getenv("PASSWORD") + host = os.getenv("HOST") + port = os.getenv("PORT") + database = os.getenv("DATABASE") + + # Forma a string de conexão + connection_string = f"mysql+pymysql://{user}:{password}@{host}:{port}/{database}" + + # Cria o motor de conexão + engine = create_engine(connection_string) + + # Carrega os caminhos dos arquivos SQL + imdb_path = os.path.join(os.path.dirname(__file__), "queries", "IMDB_movies.sql") + + # Lê as queries de dentro dos arquivos SQL + with open(imdb_path, "r", encoding="utf-8") as f: + imdb_query = f.read() + + # Carrega os dados + imdb = pd.read_sql(imdb_query, con=engine) + + return imdb + +def main(): + df = get_imdb_data() + + plt.figure(figsize=(10, 6)) + plt.scatter(df['RevenueMillions'], df['Metascore'], alpha=0.5, color='darkblue') + + plt.title('Relação entre Receita e Avaliação dos Filmes (IMDB)') + plt.xlabel('Receita (em Milhões)') + plt.ylabel('Avaliação (Metascore)') + plt.grid(True, linestyle='--', alpha=0.7) + + # Exibe o gráfico interativo na tela + plt.show() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/cases/03/queries/IMDB_movies.sql b/cases/03/queries/IMDB_movies.sql new file mode 100644 index 0000000..d7f60bd --- /dev/null +++ b/cases/03/queries/IMDB_movies.sql @@ -0,0 +1,12 @@ +SELECT + * +FROM + `looqbox-challenge`.IMDB_movies +WHERE + RevenueMillions IS NOT NULL AND + Votes > ( + SELECT + AVG(Votes) + FROM + `looqbox-challenge`.IMDB_movies + ) \ No newline at end of file diff --git a/cases/sql_test/01.sql b/cases/sql_test/01.sql new file mode 100644 index 0000000..76f3ca5 --- /dev/null +++ b/cases/sql_test/01.sql @@ -0,0 +1,14 @@ +WITH ranked_products_by_value AS ( + SELECT + *, + RANK() OVER (ORDER BY PRODUCT_VAL DESC) AS rank_value + FROM + `looqbox-challenge`.data_product +) + +SELECT + * +FROM + ranked_products_by_value +WHERE + rank_value <= 10 \ No newline at end of file diff --git a/cases/sql_test/02.sql b/cases/sql_test/02.sql new file mode 100644 index 0000000..1084bbe --- /dev/null +++ b/cases/sql_test/02.sql @@ -0,0 +1,8 @@ +SELECT DISTINCT + DEP_NAME, SECTION_NAME +FROM + `looqbox-challenge`.data_product +WHERE + DEP_NAME IN ('BEBIDAS', 'PADARIA') +ORDER BY + DEP_NAME \ No newline at end of file diff --git a/cases/sql_test/03.sql b/cases/sql_test/03.sql new file mode 100644 index 0000000..8dd521e --- /dev/null +++ b/cases/sql_test/03.sql @@ -0,0 +1,13 @@ +SELECT + BUSINESS_NAME, + SUM(SALES_VALUE) AS TOTAL_SALES +FROM + `looqbox-challenge`.data_store_cad AS store +JOIN + `looqbox-challenge`.data_product_sales AS sales + USING(STORE_CODE) +WHERE + sales.DATE >= '2019-01-01' AND + sales.DATE < '2019-04-01' +GROUP BY + BUSINESS_NAME \ No newline at end of file diff --git a/imdb_scatter_plot.png b/imdb_scatter_plot.png new file mode 100644 index 0000000000000000000000000000000000000000..abbde3b11203f22510cb8c93b0d1e345030b2556 GIT binary patch literal 67054 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 Lh9dFW?@#_8Zh*P$ literal 0 HcmV?d00001 diff --git a/respostas_desafio.md b/respostas_desafio.md new file mode 100644 index 0000000..cc1d641 --- /dev/null +++ b/respostas_desafio.md @@ -0,0 +1,437 @@ +# Desafio Técnico - Looqbox Data Challenge + +**Candidato:** Francisco Renan Leite da Costa +**Data:** 25/06/2026 +**Contato:** renanleitedacosta@gmail.com + +--- + +## 1. Teste SQL (SQL Test) + +Abaixo estão as consultas SQL criadas para responder às perguntas com base no schema `looqbox-challenge`. + +### Questão 1 +> **Pergunta:** Quais são os 10 produtos mais caros da empresa? + +#### Query SQL +```sql +WITH ranked_products_by_value AS ( + SELECT + *, + RANK() OVER (ORDER BY PRODUCT_VAL DESC) AS rank_value + FROM + `looqbox-challenge`.data_product +) + +SELECT + * +FROM + ranked_products_by_value +WHERE + rank_value <= 10 +``` + +#### Resultado +| PRODUCT_COD | PRODUCT_NAME | PRODUCT_VAL | DEP_NAME | DEP_COD | SECTION_NAME | SECTION_COD | rank_value | +|-------------|--------------|-------------|----------|---------|--------------|-------------|------------| +| 301409 | Whisky Escoces THE MACALLAN Ruby Garrafa 700ml com Caixa | 741.99 | BEBIDAS | 2 | BEBIDAS | 4 | 1 | +| 176185 | Whisky Escoces JOHNNIE WALKER Blue Label Garrafa 750ml | 735.90 | BEBIDAS | 2 | BEBIDAS | 4 | 2 | +| 315481 | Cafeteira Expresso 3 CORACOES Tres Modo Vermelho | 499.00 | BEBIDAS | 2 | BEBIDAS | 4 | 3 | +| 100280 | Vinho Portugues Tinto Vintage QUINTA DO CRASTO Garrafa 750ml | 445.90 | BEBIDAS | 2 | VINHOS | 30 | 4 | +| 320046 | Escova Dental Eletrica ORAL B D34 Professional Care 5000 110v | 399.90 | PERFUMARIA | 8 | HIGIENE BUCAL | 39 | 5 | +| 190817 | Champagne Rose VEUVE CLICQUOT PONSARDIM Garrafa 750ml | 366.90 | MERCEARIA | 6 | ARTIGOS-PARA-O-LAR | 2 | 6 | +| 153795 | Champagne Frances Brut Imperial MOET Rose Garrafa 750ml | 359.90 | MERCEARIA | 6 | ARTIGOS-PARA-O-LAR | 2 | 7 | +| 311397 | Conjunto de Panelas Allegra em Inox TRAMONTINA 5 Pecas Gratis Utensilios 5 Pecas | 359.00 | MERCEARIA | 6 | ARTIGOS-PARA-O-LAR | 2 | 8 | +| 147706 | Whisky Escoces CHIVAS REGAL 18 Anos Garrafa 750ml | 329.90 | BEBIDAS | 2 | BEBIDAS | 4 | 9 | +| 154431 | Champagne Frances Brut Imperial MOET & CHANDON Garrafa 750ml | 315.90 | MERCEARIA | 6 | ARTIGOS-PARA-O-LAR | 2 | 10 | +| 44311 | Champagne Frances Demi Sec Nectar Imperial MOET & CHANDON Garrafa 750ml | 315.90 | MERCEARIA | 6 | ARTIGOS-PARA-O-LAR | 2 | 10 | + + + +--- + +### Questão 2 +> **Pergunta:** Quais seções os departamentos de 'BEBIDAS' e 'PADARIA' possuem? + +#### Query SQL +```sql +SELECT DISTINCT + DEP_NAME, SECTION_NAME +FROM + `looqbox-challenge`.data_product +WHERE + DEP_NAME IN ('BEBIDAS', 'PADARIA') +ORDER BY + DEP_NAME +``` + +#### Resultado +| DEP_NAME | SECTION_NAME | +|--------------|-------| +| BEBIDAS | BEBIDAS | +| BEBIDAS | CERVEJAS | +| BEBIDAS | REFRESCOS | +| BEBIDAS | VINHOS | +| PADARIA | DOCES-E-SOBREMESAS | +| PADARIA | GESTANTE | +| PADARIA | PADARIA | +| PADARIA | QUEIJOS-E-FRIOS | + + +--- + +### Questão 3 +> **Pergunta:** Qual foi o total de vendas de produtos (em $) de cada Área de Negócio no primeiro trimestre de 2019? + +#### Query SQL +```sql +SELECT + BUSINESS_NAME, + SUM(SALES_VALUE) AS TOTAL_SALES +FROM + `looqbox-challenge`.data_store_cad AS store +JOIN + `looqbox-challenge`.data_product_sales AS sales + USING(STORE_CODE) +WHERE + sales.DATE >= '2019-01-01' AND + sales.DATE < '2019-04-01' +GROUP BY + BUSINESS_NAME +``` +**Observação:** Não ficou claro pra mim se deveria multiplicar o valor por algo para ser em $, então mantive como estava. + +#### Resultado +| BUSINESS_NAME | TOTAL_SALES | +|---------------------------------|---------------------| +| Varejo | 81032347.65 | +| Farma | 81776691.73 | +| Atacado | 80384884.60 | +| Posto | 32072326.40 | +| Proximidade | 80171122.80 | + + +--- +--- + +## 2. Casos Práticos (Cases) + +### Caso 1: Função Dinâmica de Recuperação de Dados +**Objetivo:** Criar uma função em Python (`retrieve_data`) flexível para gerar consultas e retornar um DataFrame com base em três parâmetros dinâmicos: `product_code`, `store_code` e `date`. + +#### Solução em Python +```python +import os +from sqlalchemy import create_engine +from dotenv import load_dotenv +import pandas as pd + + +def retrieve_data(product_code: int, store_code: int, date: list[str]) -> pd.DataFrame: + """ + Recupera os dados de vendas de produtos para um produto e uma loja específicos, em um período de tempo especificado. + + Args: + product_code (int): Código do produto filtrado. + store_code (int): Código da loja filtrada. + date (list[str]): Lista contendo a data inicial e a data final. + + Returns: + pd.DataFrame: Um DataFrame contendo as vendas dos produtos para o produto e a loja especificados, no período passado. + """ + + + # Carrega as variáveis de ambiente + load_dotenv() + user = os.getenv("USER") + password = os.getenv("PASSWORD") + host = os.getenv("HOST") + port = os.getenv("PORT") + database = os.getenv("DATABASE") + + # Forma a string de conexão + connection_string = f"mysql+pymysql://{user}:{password}@{host}:{port}/{database}" + + # Cria o motor de conexão + engine = create_engine(connection_string) + + # Leitura dos arquivos SQL e aplicação das variáveis + query_path = os.path.join(os.path.dirname(__file__), "queries", "get_product.sql") + try: + with open(query_path, "r", encoding="utf-8") as f: + sql_template = f.read() + + sql_query = sql_template.format( + product_code=product_code, + store_code=store_code, + start_date=date[0], + end_date=date[1] + ) + + except Exception as e: + print(f'Error: {e}') + + df = pd.read_sql(sql_query, con=engine) + + return df + + +def main(): + + # Exemplo de execução da função + df = retrieve_data(18, 1, ['2019-01-01', '2019-01-31']) + print(df) + +if __name__ == "__main__": + main() +``` + +**Apoio de IA:** Solicitei a IA para apresentar o formato da string de conexão com um banco MySQL. + +##### Arquivo `get_product.sql` +```sql +SELECT + * +FROM + `looqbox-challenge`.data_product_sales +WHERE + PRODUCT_CODE = {product_code} AND + STORE_CODE = {store_code} AND + ( + DATE >= '{start_date}' AND + DATE <= '{end_date}' + ) +``` + +#### Retorno do Exemplo +```cli + STORE_CODE PRODUCT_CODE DATE SALES_VALUE SALES_QTY +0 1 18 2019-01-01 708.5 65.0 +1 1 18 2019-01-02 1297.1 119.0 +2 1 18 2019-01-03 1144.5 105.0 +3 1 18 2019-01-04 1090.0 100.0 +4 1 18 2019-01-05 893.8 82.0 +5 1 18 2019-01-06 741.2 68.0 +6 1 18 2019-01-07 654.0 60.0 +7 1 18 2019-01-08 741.2 68.0 +8 1 18 2019-01-09 1373.4 126.0 +9 1 18 2019-01-10 1068.2 98.0 +10 1 18 2019-01-11 1057.3 97.0 +11 1 18 2019-01-12 806.6 74.0 +12 1 18 2019-01-13 686.7 63.0 +13 1 18 2019-01-14 697.6 64.0 +14 1 18 2019-01-15 763.0 70.0 +15 1 18 2019-01-16 1199.0 110.0 +16 1 18 2019-01-17 1068.2 98.0 +17 1 18 2019-01-18 1057.3 97.0 +18 1 18 2019-01-19 795.7 73.0 +19 1 18 2019-01-20 697.6 64.0 +20 1 18 2019-01-21 675.8 62.0 +21 1 18 2019-01-22 806.6 74.0 +22 1 18 2019-01-23 1395.2 128.0 +23 1 18 2019-01-24 1035.5 95.0 +24 1 18 2019-01-25 1057.3 97.0 +25 1 18 2019-01-26 850.2 78.0 +26 1 18 2019-01-27 763.0 70.0 +27 1 18 2019-01-28 708.5 65.0 +28 1 18 2019-01-29 730.3 67.0 +29 1 18 2019-01-30 1384.3 127.0 +30 1 18 2019-01-31 1177.2 108.0 +``` + +--- + +### Caso 2: Visualização de Ticket Médio por Loja +**Objetivo:** Calcular o Ticket Médio (TM) por Loja e por Categoria de Negócio no período entre `2019-10-01` e `2019-12-31`. + +#### Solução em Python +```python +import os +from sqlalchemy import create_engine +from dotenv import load_dotenv +import pandas as pd + +def get_sql_data() -> pd.DataFrame: + # Carrega as variáveis de ambiente + load_dotenv() + user = os.getenv("USER") + password = os.getenv("PASSWORD") + host = os.getenv("HOST") + port = os.getenv("PORT") + database = os.getenv("DATABASE") + + # Forma a string de conexão + connection_string = f"mysql+pymysql://{user}:{password}@{host}:{port}/{database}" + + # Cria o motor de conexão + engine = create_engine(connection_string) + + # Carrega os caminhos dos arquivos SQL + store_cad_path = os.path.join(os.path.dirname(__file__), "queries", "data_store_cad.sql") + store_sales_path = os.path.join(os.path.dirname(__file__), "queries", "data_store_sales.sql") + + # Lê as queries de dentro dos arquivos SQL + with open(store_cad_path, "r", encoding="utf-8") as f: + store_cad_query = f.read() + with open(store_sales_path, "r", encoding="utf-8") as f: + store_sales_query = f.read() + + # Carrega os dados + store_cad = pd.read_sql(store_cad_query, con=engine) + store_sales = pd.read_sql(store_sales_query, con=engine, parse_dates=['DATE']) + + return store_cad, store_sales + +def main(): + + # Exemplo de execução da função + store_cad, store_sales = get_sql_data() + + # Filtrando para o período especificado + store_sales = store_sales[(store_sales['DATE'] >= '2019-10-01') & (store_sales['DATE'] <= '2019-12-31')] + + # Junção dos DataFrames a partir do STORE_CODE + df_merged = store_cad.merge(store_sales, on='STORE_CODE', how='inner') + + # Agrupando a soma de venda e quantidade pela loja e categoria + df_grouped = df_merged.groupby([ + 'STORE_NAME', + 'BUSINESS_NAME' + ]).agg({ + 'SALES_VALUE': ['sum'], + 'SALES_QTY': ['sum'] + }).reset_index() + + # Cálculo do Ticket Médio + df_grouped['TM'] = (df_grouped['SALES_VALUE'] / df_grouped['SALES_QTY']).round(2) + + # Mantendo e renomeando apenas as colunas necessárias + df_result = df_grouped[['STORE_NAME', 'BUSINESS_NAME', 'TM']].rename( + columns={ + 'STORE_NAME': 'Loja', + 'BUSINESS_NAME': 'Categoria' + } + ) + + print(df_result) + +if __name__ == "__main__": + main() +``` + +#### Tabela de Resultados Gerada +```cli + Loja Categoria TM + +0 Bahia Atacado 15.39 +1 Bangkok Posto 13.67 +2 Belem Proximidade 15.37 +3 Berlin Proximidade 15.39 +4 Buenos Aires Atacado 15.39 +5 Chicago Varejo 15.53 +6 Dubai Atacado 15.39 +7 Hong Kong Farma 26.35 +8 London Farma 28.99 +9 Madri Farma 29.03 +10 Miami Posto 13.67 +11 New York Proximidade 15.39 +12 Paris Proximidade 15.39 +13 Rio de Janeiro Farma 29.59 +14 Roma Varejo 15.39 +15 Salvador Atacado 15.39 +16 Sao Paulo Varejo 15.39 +17 Sidney Posto 13.67 +18 Tokio Varejo 15.39 +19 Vancouver Posto 13.67 +``` +--- + +### Caso 3: Visualização com Base no IMDB +**Objetivo:** Criar um gráfico explicativo a partir da tabela `IMDB_movies` e justificar a escolha da visualização. + +#### Gráfico Gerado +![Relação entre Receita e Metascore](imdb_scatter_plot.png) + +#### Justificativa da Visualização + +A escolha do gráfico de Scatter Plot teve como objetivo analisar a ocorrência e correlação entre as variáveis correspondentes à receita e à avaliação dos críticos (Metascore). + +Com o objetivo de realizar uma análise rebusta e com uma boa confiabilidade dos dados, filtrei a base para os registros em que: + +- A receita não é nula (`NULL`). +- O volume de votos do filme é superior à média geral. + +Essa filtragem permite analisar apenas os filmes com os dados de receita válidos e com nível de popularidade expressivo. + +A partir da correlação entre essas variáveis é possível observar uma sutil tendência de alta (filmes com avaliação superior tendem a ter maior receita). No entanto, não se trata de uma correlação linear forte que garanta alta bilheteria em caso de uma boa nota. + +#### Script de Geração do Gráfico (Python) +```python +import os +from sqlalchemy import create_engine +from dotenv import load_dotenv +import pandas as pd +import matplotlib.pyplot as plt + +def get_imdb_data(): + # Carrega as variáveis de ambiente + load_dotenv() + user = os.getenv("USER") + password = os.getenv("PASSWORD") + host = os.getenv("HOST") + port = os.getenv("PORT") + database = os.getenv("DATABASE") + + # Forma a string de conexão + connection_string = f"mysql+pymysql://{user}:{password}@{host}:{port}/{database}" + + # Cria o motor de conexão + engine = create_engine(connection_string) + + # Carrega os caminhos dos arquivos SQL + imdb_path = os.path.join(os.path.dirname(__file__), "queries", "IMDB_movies.sql") + + # Lê as queries de dentro dos arquivos SQL + with open(imdb_path, "r", encoding="utf-8") as f: + imdb_query = f.read() + + # Carrega os dados + imdb = pd.read_sql(imdb_query, con=engine) + + return imdb + +def main(): + df = get_imdb_data() + + plt.figure(figsize=(10, 6)) + plt.scatter(df['RevenueMillions'], df['Metascore'], alpha=0.5, color='darkblue') + + plt.title('Relação entre Receita e Avaliação dos Filmes (IMDB)') + plt.xlabel('Receita (em Milhões)') + plt.ylabel('Avaliação (Metascore)') + plt.grid(True, linestyle='--', alpha=0.7) + + # Exibe o gráfico interativo na tela + plt.show() + +if __name__ == "__main__": + main() +``` + +##### Arquivo `IMDB_movies.sql` +```sql +SELECT + * +FROM + `looqbox-challenge`.IMDB_movies +WHERE + RevenueMillions IS NOT NULL AND + Votes > ( + SELECT + AVG(Votes) + FROM + `looqbox-challenge`.IMDB_movies + ) +``` + +---