From 8a388ada5c0fd7eeb8f4df88548d96b469830b34 Mon Sep 17 00:00:00 2001 From: Fernando Ruiz Diaz <88462636+ferdlestier@users.noreply.github.com> Date: Tue, 23 Jul 2024 15:23:33 -0400 Subject: [PATCH] Add PDF report generation for dataframes --- parser.py | 31 +++++++++++++++++++++++++++++++ requirements.txt | 2 ++ tests/test_parser.py | 28 +++++++++++++++++++++++++++- 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/parser.py b/parser.py index e9b2344..968e067 100644 --- a/parser.py +++ b/parser.py @@ -3,6 +3,8 @@ import pandas as pd import logging # Import logging module +import matplotlib.pyplot as plt +from fpdf import FPDF # Configure logging logging.basicConfig(filename='parser.log', level=logging.DEBUG, format='%(asctime)s:%(levelname)s:%(message)s') @@ -132,6 +134,35 @@ logging.info(f"Fundamental data compared across industry group: {grupo}") logging.info(f"Number of records processed for industry group {grupo}: {len(industria)}") + # Generate PDF report + pdf = FPDF() + pdf.add_page() + pdf.set_font("Arial", size=12) + + def add_dataframe_to_pdf(pdf, df, title): + pdf.set_font("Arial", 'B', 14) + pdf.cell(200, 10, txt=title, ln=True, align='C') + pdf.set_font("Arial", size=10) + pdf.ln(10) + for i in range(len(df)): + row = df.iloc[i] + for item in row: + pdf.cell(40, 10, txt=str(item), border=1) + pdf.ln(10) + pdf.ln(10) + + add_dataframe_to_pdf(pdf, dailymovers.head(20), "Top 20 Daily Movers") + add_dataframe_to_pdf(pdf, dailymovers.tail(20), "Top 20 Daily Losers") + add_dataframe_to_pdf(pdf, pricetracker, "Top 20 Medium Term Price Change (Growth)") + add_dataframe_to_pdf(pdf, pricetrackerloss, "Top 20 Medium Term Price Change (Loss)") + add_dataframe_to_pdf(pdf, p_e, "Growth Potential Based on Analyst Recommendations") + add_dataframe_to_pdf(pdf, exposure.head(20), "Top 20 Financial Exposure") + add_dataframe_to_pdf(pdf, cap_return.head(20), "Top 20 Return on Invested Capital") + add_dataframe_to_pdf(pdf, fund_data.head(20), "Top 20 Fundamental Data") + + pdf.output("report.pdf") + logging.info("PDF report generated successfully") + logging.info("Script completed successfully") except Exception as e: diff --git a/requirements.txt b/requirements.txt index 939997c..6cc8e86 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,3 +6,5 @@ pytz>=2022.7.1 jupyter; python_version >= '3.0' notebook>=4.4.1; python_version >'3.0' pandas>=2.0.3 +matplotlib>=3.5.1 +fpdf>=1.7.2 diff --git a/tests/test_parser.py b/tests/test_parser.py index 55d4ef8..d00f577 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -2,6 +2,8 @@ import logging import pandas as pd from parser import main +from fpdf import FPDF +import os class TestParser(unittest.TestCase): @@ -10,10 +12,12 @@ def setUp(self): self.log_file = 'parser.log' self.csv_file = 'minhaReq2.20220126.csv' self.df = pd.read_csv(self.csv_file) + self.pdf_file = 'report.pdf' def tearDown(self): # Clean up after tests - pass + if os.path.exists(self.pdf_file): + os.remove(self.pdf_file) def test_script_execution(self): # Test the execution of the parser script @@ -49,5 +53,27 @@ def test_data_analysis(self): self.assertEqual(len(dailymovers), 20) self.assertIn('ticker', dailymovers.columns) + def test_pdf_generation(self): + # Test the PDF report generation + main() + self.assertTrue(os.path.exists(self.pdf_file)) + + # Check if the PDF contains expected data + pdf = FPDF() + pdf.add_page() + pdf.set_font("Arial", size=12) + pdf.output(self.pdf_file) + + with open(self.pdf_file, 'rb') as pdf_file: + content = pdf_file.read() + self.assertIn(b'Top 20 Daily Movers', content) + self.assertIn(b'Top 20 Daily Losers', content) + self.assertIn(b'Top 20 Medium Term Price Change (Growth)', content) + self.assertIn(b'Top 20 Medium Term Price Change (Loss)', content) + self.assertIn(b'Growth Potential Based on Analyst Recommendations', content) + self.assertIn(b'Top 20 Financial Exposure', content) + self.assertIn(b'Top 20 Return on Invested Capital', content) + self.assertIn(b'Top 20 Fundamental Data', content) + if __name__ == '__main__': unittest.main()