<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[The Flight Tech Labs]]></title><description><![CDATA[Exploring AI, automation, full stack development, and real-world engineering projects. Sharing insights, tutorials, project breakdowns, and lessons learned whil]]></description><link>https://theflighttechlabs.hashnode.dev</link><image><url>https://cdn.hashnode.com/uploads/logos/6a4e29ad81613f0f68eaddb6/c1e6989e-aacc-42b0-bd64-aacf2fbf7dfc.png</url><title>The Flight Tech Labs</title><link>https://theflighttechlabs.hashnode.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Fri, 11 Sep 2026 21:19:45 GMT</lastBuildDate><atom:link href="https://theflighttechlabs.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How I Automated 3–4 Days of Manual Work at L&T Using Python]]></title><description><![CDATA[When I joined Larsen & Toubro Construction's Analytics Department as a second-year undergrad intern, I expected to spend two months learning from the sidelines. What I didn't expect was to build produ]]></description><link>https://theflighttechlabs.hashnode.dev/how-i-automated-3-4-days-of-manual-work-at-l-t-using-python</link><guid isPermaLink="true">https://theflighttechlabs.hashnode.dev/how-i-automated-3-4-days-of-manual-work-at-l-t-using-python</guid><category><![CDATA[Python]]></category><category><![CDATA[faiss]]></category><category><![CDATA[bm25]]></category><category><![CDATA[RAG ]]></category><category><![CDATA[automation]]></category><category><![CDATA[Data Science]]></category><category><![CDATA[Machine Learning]]></category><dc:creator><![CDATA[Varun Vaibhav.S]]></dc:creator><pubDate>Wed, 08 Jul 2026 11:27:13 GMT</pubDate><content:encoded><![CDATA[<p>When I joined Larsen &amp; Toubro Construction's Analytics Department as a second-year undergrad intern, I expected to spend two months learning from the sidelines. What I didn't expect was to build production level tools.</p>
<p>This is the story of one of them — a PDF-to-Excel data extraction pipeline that turned a 3–4 day manual process into something that runs in minutes.</p>
<p>The Problem</p>
<p>Companies deals with enormous volumes of technical documentation. Project specifications, measurement sheets, bills of quantities, material schedules — all of it arrives as dense, multi-page PDFs. Some documents run hundreds of pages. Some run over a thousand.</p>
<p>Before this tool existed, an engineer would open the PDF, scan through pages manually, identify the relevant data, and copy it cell by cell into a pre-formatted Excel sheet. For a 1,200-page document, that could take an entire working week for one person.</p>
<p>The data existed. The Excel template existed. The problem was purely the gap between them.</p>
<p>My job was to close that gap.</p>
<p>Why This Is Harder Than It Sounds</p>
<p>If you've never worked with real-world engineering PDFs, you might think this is straightforward — just extract the text and parse it. It isn't.</p>
<p>Here's what makes it genuinely difficult:</p>
<ol>
<li><p>PDFs are not structured data. A PDF is essentially a rendering instruction set. Text that looks like a table to your eyes is often a flat list of strings with no inherent row/column relationship. Spatial positioning has to be inferred.</p>
</li>
<li><p>Document formats vary. No two specification documents are identical. Column headers appear in different positions, section titles use different phrasing, and sometimes the same data point is described three different ways across different sheets.</p>
</li>
<li><p>Accuracy vs. recall tradeoff. Extracting everything aggressively means flooding the output with noise. Being too conservative means missing critical data. Finding the right balance for engineering specifications is non-trivial.</p>
</li>
<li><p>Scale. A tool that works on 10 pages needs to work reliably on 1,200. Memory management, processing time, and error handling all become real concerns.</p>
</li>
</ol>
<p>The Architecture</p>
<p>After a week of experimentation, I settled on a hybrid retrieval pipeline with a 3-pass verification architecture.</p>
<p>Step 1 — PDF Text Extraction</p>
<p>I used two libraries in combination:</p>
<p>pythonimport fitz # PyMuPDF import pdfplumber</p>
<p>def extract_text_blocks(pdf_path): doc = fitz.open(pdf_path) blocks = [] for page_num in range(len(doc)): page = doc[page_num] # Extract with positional metadata block_data = page.get_text("blocks") for block in block_data: blocks.append({ "page": page_num + 1, "text": block[4], "bbox": block[:4] # x0, y0, x1, y1 }) return blocks</p>
<p>PyMuPDF handles positional metadata well. pdfplumber handles table detection. Together they cover most document structures I encountered.</p>
<p>Step 2 — Hybrid Retrieval</p>
<p>This is the core of the pipeline. For each target field in the Excel template, I needed to find the most relevant text block in the document.</p>
<p>I combined two retrieval methods:</p>
<p>BM25 — a classical information retrieval algorithm that scores text blocks based on keyword overlap with the target field name. Fast, interpretable, and surprisingly effective for domain-specific terminology.</p>
<p>FAISS — Facebook's vector similarity search library. I embedded both the query (field name) and all text blocks using SentenceTransformers, then retrieved the most semantically similar blocks.</p>
<p>Neither method alone was reliable enough. BM25 misses semantic similarity. FAISS misses exact keyword matches. The solution was Reciprocal Rank Fusion — combining the ranked results from both systems:</p>
<p>pythondef reciprocal_rank_fusion(bm25_results, faiss_results, k=60): scores = {} for rank, doc_id in enumerate(bm25_results): scores[doc_id] = scores.get(doc_id, 0) + 1 / (k + rank + 1) for rank, doc_id in enumerate(faiss_results): scores[doc_id] = scores.get(doc_id, 0) + 1 / (k + rank + 1) return sorted(scores.items(), key=lambda x: x[1], reverse=True)</p>
<p>This consistently outperformed either method alone.</p>
<p>Step 3 — 3-Pass Verification</p>
<p>A single extraction pass isn't reliable enough for production. I implemented a 3-pass system:</p>
<p>Pass 1: Extract candidate values for each field Pass 2: Cross-reference candidates against known domain patterns and synonyms Pass 3: Flag low-confidence extractions for human review rather than silently inserting wrong data</p>
<p>This last point matters. A tool that confidently outputs wrong data is worse than a tool that admits uncertainty. The flagging system meant engineers knew exactly which cells to double-check.</p>
<p>Step 4 — Parallel Processing</p>
<p>Processing 1,200 pages sequentially is slow. I used Python's ThreadPoolExecutor to process multiple page ranges concurrently:</p>
<p>pythonfrom concurrent.futures import ThreadPoolExecutor</p>
<p>def process_document(pdf_path, sheet_configs): with ThreadPoolExecutor(max_workers=4) as executor: futures = { executor.submit(extract_sheet_data, pdf_path, config): config for config in sheet_configs } results = {} for future in futures: config = futures[future] results[config['sheet_name']] = future.result() return results</p>
<p>This reduced processing time significantly compared to sequential execution.</p>
<p>The Results</p>
<p>Pages processed per run: 1,200+ Extraction accuracy: ~65–70% across all defined sheet formats Time saved: 3–4 days of manual work reduced to minutes Deployment: Production useable within L&amp;T Constructions.</p>
<p>65–70% accuracy sounds modest until you consider what the alternative was — 0% automation. Engineers now spend their time reviewing and correcting a structured output rather than starting from a blank sheet. The cognitive load reduction is enormous.</p>
<p>What I Learned</p>
<p>Domain knowledge matters more than algorithm sophistication. The biggest accuracy improvements didn't come from better models — they came from understanding what "compressive strength" means in a civil engineering context versus a materials context, and encoding that knowledge into the retrieval system.</p>
<p>Fail loudly, not silently. Early versions of the tool would fill in a best guess even when confidence was low. This caused more problems than it solved. Flagging uncertain outputs and leaving them blank for human review was the right call.</p>
<p>Production is different from prototypes. A Jupyter notebook that works on a sample PDF is not a production tool. Error handling, logging, memory management, and graceful degradation under unexpected input formats all had to be built explicitly.</p>
<p>The problem definition is the hardest part. It took two weeks just to fully understand what the tool needed to do — what "correct" meant, what edge cases existed, what the engineers actually needed versus what they said they needed.</p>
<p>What's Next...</p>
<p>This tool handles text-based PDFs. A second tool I built at L&amp;T handles a different problem entirely — AutoCAD-exported electrical single-line diagrams with zero embedded text, where all data exists only as visual labels. That required a completely different approach using Tesseract OCR/GPT vision and custom image pre-processing.</p>
<p>That's a story for another post.</p>
<p>The Bigger Picture</p>
<p>I'm a third-year undergraduate student. Six months ago I didn't know what FAISS was. I built this tool by reading documentation, failing repeatedly, and being honest with myself about what wasn't working.</p>
<p>If you're a student reading this — the gap between classroom ML and production data engineering is real, but it's crossable. Find a problem that actually exists, build something that actually works, and write down what you learned.</p>
<p>That's what I did. And somehow it ended up being a useful tool at one of India's largest infrastructure companies.</p>
<p>S. Varun Vaibhav is a B.Tech CSE (AI &amp; Data Analytics) student at SRIHER Chennai and a former Data Analyst Intern at Larsen &amp; Toubro Construction. Find me on GitHub and LinkedIn.</p>
<p>Tags: Python, Data Engineering, PDF Extraction, Machine Learning, Internship, FAISS, BM25, PyMuPDF, NLP, Real World ML</p>
]]></content:encoded></item></channel></rss>