# Jonathan Abuelouf
## Data analysis. Practical tools. Work that holds up.

I like figuring out why a process is harder than it needs to be. Sometimes the answer is in the data. Sometimes the data is scattered across systems, and getting it into one useful view is the first job.

My background is in aviation maintenance and industrial operations. That has given me a practical way of approaching analysis: understand the problem, check what the data actually means, and build something people can use. The projects here range from large public datasets to reporting dashboards, inventory workflows, and operational applications.

## Cyclistic ride-share analysis

**Google Data Analytics capstone | R, SQL, Google BigQuery, tidyverse, dplyr, ggplot2, lubridate, plotly, Tableau**

**Status:** Completed case study

### Project brief

**The problem:** The membership campaign needed a clearer picture of how casual riders and annual members used the service.

**My approach:** I combined twelve months of trips in R, compared duration and timing, and presented the patterns in Tableau.

**The result:** An analysis of 4,293,274 cleaned rides with membership ideas tied to observed behavior. The campaigns remain recommendations to test.

**My role:** I defined the comparison, prepared the data, analyzed the patterns, and connected the findings to membership ideas.

### Project context

The starting question was straightforward: how do annual members and casual riders use the same bike-share service differently? I completed this case study for the Google Data Analytics certificate, using public Divvy trip records to explore what those differences might mean for a membership campaign.

I wanted the result to explain rider behavior clearly enough to suggest a next step. That meant looking beyond a single total and comparing ride length, the weekly pattern, and the way activity changed across the year.

### A membership question, grounded in trips

The case study frames annual membership as the business opportunity. The available records describe trips, so I could investigate how the two rider groups used the service. I could not ask individual riders why they chose a casual pass or whether a particular offer would convince them to subscribe.

I used those boundaries to keep the analysis focused. Duration helps distinguish shorter trips from longer outings. Day of week provides another view of use. Month adds the seasonal context that would be lost if I treated the entire year as one average.

### One year of data, one comparison

I combined twelve monthly files from 2022 into a shared working dataset in R. After cleaning, the analysis contained 4,293,274 rides. Combining the files gave me a full-year view while retaining the member-versus-casual distinction needed for the question.

I compared members and casual riders across the same measures in R: ride duration, day of week, and month. I then brought the results into Tableau, where readers could explore those views together and compare the timing and length of trips.

I kept ride duration, weekday, and seasonal views separate rather than forcing them into one headline. A difference in ride length answers a different question from a difference in total ride volume, and either can look different once the time of year changes.

- Checked column names and data types across twelve monthly files, corrected November’s timestamp format, and combined the files in R.
- Derived date, month, weekday, and ride duration fields from trip timestamps for consistent rider comparisons.
- Removed negative-duration and incomplete records, then excluded trips shorter than one minute or longer than fifteen hours from the final comparison.
- Compared rider counts and ride-duration summaries by membership type, weekday, and month, using ggplot2 and plotly to show the patterns.
- Used SQL in Google BigQuery to support exploratory analysis alongside the R notebook.

### The groups did not ride the same way

Casual riders took longer rides than annual members. Their activity increased from May through September, and their volume was higher Friday through Sunday than Monday through Thursday. Together, those observations gave the membership question more shape than a simple count of the two groups.

The seasonal and weekly patterns suggest that a single message may not fit every potential member. They provide a reason to investigate leisure-oriented offers alongside a commute-focused campaign, while keeping those interpretations separate from what the trip records directly show.

### Ideas to test, with a reason behind each one

I proposed seasonal promotions, rewards points, and a campaign around commuting. Those ideas connect to the observed behavior: seasonal timing for the warmer-month increase, incentives for repeat use, and a clearer explanation of the value of membership for a regular trip.

Each recommendation gives the membership team a specific idea to test and a reason for testing it. A pilot would need to track repeat use, subscriptions, and whether riders remained members after an offer ended.

**From rider behavior to a campaign hypothesis**

| Observation | Proposed action | What a test would need to establish |
| --- | --- | --- |
| Casual activity increases May through September | Seasonal membership promotions | Whether seasonal offers produce subscriptions that continue beyond the promotion |
| Casual volume is higher Friday through Sunday | Rewards for repeat use | Whether the incentive changes repeat use and membership conversion |
| The groups differ in ride duration and weekly use | A campaign explaining membership value for commuting | Whether the message fits riders who make regular trips |

### What I delivered

- R notebook documenting data preparation, comparisons, and recommendations.
- A working analysis of 4,293,274 cleaned 2022 rides from twelve monthly source files.
- Tableau dashboard presenting member and casual-rider patterns.

### Where the work stands

Completed a public-data case study that connects rider behavior to specific membership ideas, with the analysis available for review.

### Scope and limitations

Completed for the Google Data Analytics certificate using public trip data.

Trip records describe observed use; they do not establish riders’ motivations or a campaign’s conversion rate.

The proposed membership campaigns have not been tested.

[Notebook](https://www.kaggle.com/code/jonathanabuelouf/cyclistic-ride-share-analysis) · [Dashboard](https://public.tableau.com/app/profile/jonathan8167/viz/2022CyclisticData/Cyclistic2022)

## US traffic accident analysis

**Flatiron capstone | Python, pandas, SciPy, Tableau**

**Status:** Completed case study

### Project brief

**The problem:** Millions of incident records needed to become a focused planning discussion about timing, weather, and location.

**My approach:** I prepared the data in Python, compared counts with disruption proportions, and evaluated associations using statistical tests and effect sizes.

**The result:** A notebook, dashboard, and presentation with three response priorities. The findings describe reported incidents, without establishing causes or intervention results.

**My role:** I organized the analytical questions, prepared and analyzed the dataset, and developed the dashboard and recommendations.

### Project context

For my Flatiron capstone, I investigated 7.7 million reported US traffic accidents from February 2016 through March 2023. I organized the work around three questions: when incidents cluster, how weather relates to traffic disruption, and where reported incidents are concentrated.

The challenge was to turn a large dataset into a useful planning discussion without treating every strong-looking pattern as a proven cause. I built the notebook, charts, and presentation around that distinction.

### Choose the questions before loading everything

The source contains records collected through traffic-event APIs covering 49 states. I loaded the subset of fields needed for the analysis, including incident times, location, weather, and the traffic-impact score, rather than bringing every available column into memory.

I checked the meaning of the outcome before using it. The dataset’s Severity field measures traffic disruption on a one-to-four scale. It is not an injury scale. I grouped levels three and four for comparisons of higher disruption and kept that definition attached to the findings.

### Make the comparisons consistent

I checked missingness and required start-time, severity, and state fields for the analysis. I converted timestamps and derived hour, weekday, month, season, and time-of-day categories. A city-and-state label helped keep cities with the same name from being treated as one place.

Weather descriptions needed grouping before they could support a readable comparison. I mapped variants into categories such as Fair, Cloudy, Rain, and Snow/Ice, while retaining an Unknown category for missing values. Unknown was excluded from weather-association tests rather than presented as an actual condition.

I used the same time and weather categories across the charts and statistical comparisons. That kept a change in grouping from being mistaken for a change in the underlying pattern.

### Separate volume from the disruption share

The notebook’s selected commute windows, 7–9 a.m. and 3–6 p.m., contained 33.5% of reported incidents across all days. That calculation includes records starting in hours 7, 8, 15, 16, and 17. Five states contained 50.9%. Those are concentrations within the records, useful for identifying where to investigate further, rather than rates per vehicle or mile traveled.

For weather, I compared both incident counts and the share with higher disruption. Rain’s higher-disruption share was 23.5%, compared with 16.9% for Fair weather. A category can have a large total without the largest disruption share, so the two charts answer different questions.

I used chi-square tests and Cramer’s V to examine categorical associations and their strength. The tests were statistically significant, but the associations were weak: Cramer’s V was 0.0972 for time of day and 0.0645 for weather. With millions of records, that distinction mattered when interpreting the patterns. I also compared adverse and fair-weather proportions, with a sensitivity check excluding Fog/Haze from the adverse group.

### Turn patterns into response priorities

I proposed time-based staffing and safety messaging, weather-responsive warnings, and further investigation of geographic hotspots. The presentation connects each proposal to a finding and a metric that could be monitored if the idea were piloted.

A pilot would need local traffic-volume data, a baseline, and consistent reporting to evaluate whether a response improved conditions. The patterns identify places and times for further investigation; the next step is to test the proposed response in that local context.

**Findings and the planning decisions they support**

| Finding | Response priority | Interpretation |
| --- | --- | --- |
| 33.5% start in hours 7, 8, 15, 16, and 17 across all days | Evaluate time-based staffing and safety messaging | Share of reported incidents, not risk per trip |
| Higher-disruption share: Rain 23.5%; Fair 16.9% | Evaluate weather-responsive warnings | Severity levels 3 and 4 describe traffic disruption, not injuries |
| Five states account for 50.9% of records | Investigate geographic hotspots | Counts need travel-exposure and reporting context before comparing risk |
| Cramer's V: time of day 0.0972; weather 0.0645 | Keep response priorities proportional to the evidence | Statistically significant associations are weak, not predictive rules |

### What I delivered

- Python analysis notebook with preparation steps, visual exploration, statistical comparisons, and limitations.
- Exported analysis data for Tableau and a set of temporal, weather, and geographic charts.
- Interactive dashboard and presentation with three response priorities.

### Where the work stands

Completed a notebook, Tableau dashboard, and presentation connecting temporal, weather, and geographic patterns to three response priorities.

### Scope and limitations

Completed as a Flatiron School capstone using public traffic-event data.

Severity measures traffic disruption, not injuries.

Counts are not normalized by vehicle miles traveled; reporting coverage and collection methods vary.

The analysis identifies associations; the proposed interventions have not been evaluated.

[GitHub](https://github.com/Jabuelouf/us_traffic_cap) · [Dashboard](https://public.tableau.com/app/profile/jonathan8167/viz/US_Traffic_Cap/USTrafficAccidentAnalysis)

## Overtime requests, without the back-and-forth

**OvertimeRequester | Python, Slack, AWS Lambda, API Gateway, DynamoDB, CloudWatch**

**Status:** Deployed application

### Project brief

**The problem:** Requests, approvals, and shift capacity were separate decisions that needed a consistent record and workflow.

**My approach:** I built a Slack application with role-aware actions, configurable quotas, FIFO borrowing, persistent records, and reviewer notifications.

**The result:** A deployed request workflow with AWS storage and processing, operating guides, and tested approval rules.

**My role:** I translated operational rules into requirements, coordinated feature development and validation, and produced the deployment and user handoff.

### Project context

An overtime request is a small transaction with several decisions behind it. Who is requesting the hours? Which shift owns the capacity? Who can approve the request? What happens when that shift has used its allocation? Handling those questions in separate messages makes it harder to keep the record and the decision together.

I built OvertimeRequester around the workflow the maintenance team already used: Slack. The goal was a consistent path from a technician submitting a request to a manager making a decision, with the availability rules and request history handled by the application.

### Make the operating rules explicit

I separated technician, manager, and administrator responsibilities so each role had the controls it needed. Technicians need to submit and review their requests. Managers need to see the queue, check availability, and approve or reject. Administrators need to manage users, settings, and technician records. Those differences appear in the Home views and in permission checks around the actions.

Availability is calculated across six shift types. The default configuration assigns 120 weekly hours overall and a preferred allocation of 20 per shift. When a shift runs out, the borrowing workflow checks other shifts rather than ignoring the limit. Administrators can adjust those allocations to fit the operation.

Bulk approval made that calculation more involved. Requests needing borrowed hours are presented in submission order. As a manager selects a lending shift for each request, the interface subtracts the hours already assigned in that same batch. That keeps the next selection from showing capacity already committed by an earlier selection.

**Who makes each decision**

| Role or step | Action | Rule that keeps the workflow coherent |
| --- | --- | --- |
| Technician | Submit a request or edit their own pending request | Validate date, hours, notes, and duplicate requests |
| Manager | Approve, reject, or arrange borrowed hours | Check available capacity before committing the decision |
| Bulk borrowing | Allocate lending-shift hours in submission order | Subtract allocations already selected in the same batch |
| Administrator | Manage users, technicians, and configuration | Keep account and linked technician participation aligned |

### Keep the record connected to the decision

The request model includes the technician, date, hours, status, notes, and borrowing information. A technician submits through a modal; managers and administrators receive a direct message with decision buttons. The stored request moves through pending, approved, or rejected states, so the conversation is tied to a record. Validation rejects duplicate requests for the same technician and date and checks hours, dates, and required notes.

I treated the list a manager sees as part of the workflow too. Edit and borrowing dialogs retain the parent list’s view identifier, allowing the list to refresh after a decision. Refreshed checkbox controls clear earlier selections instead of carrying them into the next action. Bulk changes are saved before status notifications are sent, keeping the message aligned with the stored decision.

User registration and technician records also need to stay aligned. Deactivating an account without updating its linked technician would leave the two parts of the workflow disagreeing about who can participate. The administrative lifecycle updates those linked records, while technicians are limited to editing their own pending requests.

### Build for deployment and support

The application uses Python and Slack Bolt, with AWS Lambda handling the deployed workflow and DynamoDB retaining the data. API Gateway provides the HTTP entry path. A storage adapter separates persistence from application behavior, with local development options. Bulk actions batch record changes and explicitly flush them, avoiding a separate storage round trip for every selected request.

Slack’s short interaction window shaped the deployment. Manager notification broadcasts run through a separate asynchronous Lambda invocation, rather than making a technician wait while the application messages every reviewer. Warm-start application reuse, scheduled warmup, and CloudWatch monitoring address cold-start behavior and make failures easier to investigate. The handler checks Slack retry headers to reduce repeated processing.

### Work through the less obvious paths

Testing covered the request lifecycle, roles, quota handling, and management actions. I also coordinated a change to how the application reads profiles, removing a broader Slack permission requirement and updating the initial administrator setup. That kept user identification working with more limited access to Slack data.

I managed requirements and development through versioned tasks, review notes, and handoffs. I coordinated changes across the interface, storage, and notifications, checked the workflow against its operating rules, and documented how administrators could configure and support it.

### What I delivered

- Slack submission, review, availability, and FIFO borrowing interfaces
- Linked user and technician lifecycle with role-aware request actions
- Persistent storage, batched updates, and asynchronous reviewer notifications
- AWS deployment configuration, operating guides, and recorded test reports

### Where the work stands

The application was deployed and validated for technician requests, manager approvals, and shift-capacity checks. It keeps those decisions and the request history in one operational workflow.

### Scope and limitations

The workflow has not been evaluated in a before-and-after time study.

Shift quotas must be configured for the operation. Retry checks reduce duplicate processing but do not guarantee that every request is processed exactly once.

## Aircraft maintenance reporting that helps people act

**Viasat | SQL, Spotfire, Excel**

**Status:** Working reporting workflow

### Project brief

**The problem:** Morning aircraft maintenance reviews and scheduled technician dispatches changed as flight plans shifted through the day. An open deferral alone did not reveal a useful dispatch opportunity.

**My approach:** I matched the supported fleet to maintenance records, added flight routing, and displayed ground-time windows in linked Spotfire views.

**The result:** A working planning dashboard with three-minute updates and two-hour email snapshots.

**My role:** I designed the reporting logic, cleaned identifiers, built the visualizations, and documented the reporting workflow.

### Project context

At Viasat, the morning work-order review involved looking through roughly 30 to 80 aircraft with open WiFi maintenance deferrals, figuring out which belonged to the supported fleet, and creating the corresponding work orders. That manual review was missing aircraft.

I built a Spotfire reporting workflow to bring fleet eligibility, open discrepancies, and routing information together. The goal was to make it easier for coordination staff to identify an aircraft that needed attention and a realistic opportunity for a technician to work it.

### Find the right data and reduce the noise

I worked directly with the airline’s data engineer to arrange database access for a dashboard serving the airline and Viasat. The airline already had a maintenance-deferral dashboard, and the engineer copied its SQL-backed information link into our reporting repository. I reduced the SQL selection to the fields needed for WiFi maintenance and filtered the relevant maintenance groups before matching the results to our supported fleet.

The second source was our supported-fleet list from Salesforce. That list had to define eligibility: an aircraft appearing in the airline’s deferral report did not automatically mean Viasat was responsible for the work. I used the fleet list as the master and matched maintenance records to it.

### A missing zero could become a missed aircraft

The identifier comparison was a concrete data-quality problem. Some Salesforce exports omitted the leading zero from a four-digit aircraft nose identifier, and Spotfire read different source columns as strings or integers. I standardized the identifiers and their types before building the match.

The first join retained the supported aircraft even where no open deferral matched. That was useful during preparation, but those blank maintenance rows did not belong in the action list. I filtered out rows without a logpage so the final view focused on aircraft with an actual open record.

### Open work was only half the answer

The maintenance report’s flight fields described the station scheduled against a particular discrepancy. They were not a dependable picture of where the aircraft would be next. After searching for another source, I found a flight-information link and worked with the data engineer to add it.

I joined the routing information to the supported aircraft with open work and built linked views. Selecting an aircraft filtered its flights, and another view showed arrivals at our maintenance stations. Ground-time colors distinguished windows of at least ten, five, and two hours from shorter visits.

Those colors supported scanning; they did not automatically decide whether a job could be completed. The user still needed to consider the discrepancy and available technician. I also retained a broader routing view so the supported-station filter did not remove the context of the aircraft’s other flights.

### Put the information where the team would read it

The live dashboard updated every three minutes, but reaching Spotfire required navigating the airline network and login process. I built a reporting view limited to the next two days and scheduled a server-side task to send updated dashboard images every two hours.

The email gave coordination staff a recurring reference for checking whether work orders and dispatches were addressed. I documented the SQL selections, identifiers, joins, filters, color rules, and schedule so the workflow could be followed beyond the finished screen.

The supported-fleet list still required a manual Salesforce export. The workflow automated the maintenance views and their delivery while keeping that source update as a separate step.

**The information behind a maintenance opportunity**

| Input or view | Decision it supports | Important dependency |
| --- | --- | --- |
| Salesforce supported-fleet list | Is this aircraft eligible for our maintenance support? | Manual export; aircraft identifiers and types must match |
| SQL-backed deferrals | Does the supported aircraft have open WiFi work? | A matching logpage is required for the action list |
| Linked flight routing and station views | Where might a technician reach the aircraft? | Ground-time colors guide review; job scope and staffing still matter |
| Two-day email snapshot | Which upcoming opportunities need follow-up? | Images are sent every two hours; the live dashboard refreshes every three minutes |

**From aircraft records to a planning view**

1. **Define the supported fleet:** A manual Salesforce export identifies aircraft eligible for Viasat maintenance.
2. **Match open WiFi work:** Normalized aircraft identifiers connect the fleet to SQL-backed deferrals with a matching logpage.
3. **Add flight routing:** Linked station and ground-time views show where a technician might reach the aircraft.
4. **Share the view:** The live dashboard refreshes every three minutes; two-day image snapshots arrive by email every two hours.

The fleet export remained manual. Staff still reviewed the job scope and available technician before dispatch.

*Reporting path and source dependency in the Spotfire workflow*

### What I delivered

- Spotfire dashboard joining supported aircraft, open maintenance deferrals, and flight information.
- Linked aircraft-routing views with station filtering and ground-time indicators.
- Two-day reporting snapshot delivered through a scheduled two-hour email task.
- Documentation covering source fields, identifier formatting, transformations, and reporting setup.

### Where the work stands

Built a working reporting workflow that surfaces maintenance opportunities from multiple operational sources in one view and distributes recurring snapshots.

### Scope and limitations

The supported-fleet export remained manual.

The dashboard was designed around approximately 190 supported aircraft, with planned growth to 600 informing the workflow.

## Six station inventories, one usable process

**Viasat | Excel, SharePoint, Power Automate, Power Apps, Power BI**

**Status:** Built application and reporting workflow

### Project brief

**The problem:** Six station workbooks lacked a consistent shared view, while receiving and installation required repeated record entry.

**My approach:** I standardized the records, synchronized by serial number, and built a Power Apps interface around the part lifecycle.

**The result:** Shared SharePoint inventory, twice-daily synchronization, stock views, and documented receiving, editing, installation, and archive workflows.

**My role:** I standardized the data, built the formulas and record-matching flow, developed the interface, and wrote user instructions.

### Project context

Each Viasat station maintained an inventory workbook while a single employee handled receiving, inspections, recordkeeping, and maintenance responsibilities. A typical intake involved inspecting a part, completing the receiving form, entering its identifiers and location in the workbook, and filling out two green tags. Repeated entry added work, and the wider team lacked a consistent view across stations.

I started by standardizing six station workbooks, then built a shared SharePoint inventory and a Power Apps interface. The project grew from consolidating data into handling the everyday decisions around receiving, editing, installing, and archiving a part.

### Start with a record people could maintain

The initial records included part number, serial, location, equipment type, status, revision, customer, and notes. I built a common workbook template and populated classifications from the selected part number so people did not have to retype the same information on every intake.

Serial number became the stable identifier for synchronization. I documented that it could not be blank or casually changed. Status and physical location also needed to remain separate: a part could be out of one station’s stock while being sent to another location.

I wrote workbook instructions explaining the fields and their dependencies. Standardizing the sheet mattered as much as the later automation because inconsistent source records would simply become inconsistent records in a larger shared list.

### Update the existing part instead of adding another copy

I initially considered keeping the consolidated inventory in Excel, but refresh behavior varied with user permissions. Moving the shared records to SharePoint gave the automation a common destination.

I used Power Automate to collect each station’s workbook rows and compare them with the master SharePoint list twice daily. When a serial already existed, the flow updated its record; when it did not, the flow created one.

That distinction addressed an immediate failure mode. If every status change created a new row, an installed part could appear both in stock and out of stock. Matching the existing record was the foundation for making the shared inventory useful.

The shared list could be filtered across locations and equipment types, but it did not remove much of the station employee’s intake effort. That was why I continued into an application rather than treating consolidation as the finished solution.

### Make the common actions visible

The Power Apps screen combined a searchable item list with the selected part’s detail form. Filters covered location, equipment type, variation, and status. The overview used Power BI stock charts with minimum and maximum indicators, while counts on the main screen followed the selected location.

Receiving, editing, and installation were separate actions. Edit mode exposed save and cancel controls. Switching between the in-stock and installed lists reset the filters, and selecting another item reset editing and installation flags so an abandoned action did not carry into the next record.

I spent months refining behavior after the initial working version. I documented how the selected record, form state, and background flow interact so the application could be maintained as the workflow developed.

### Handle the interrupted path as well as the successful one

Before installation could continue, the user had to verify the selected part. The confirmation button remained disabled until that check was complete. Canceling the action reset the selection flags and verification checkbox.

Installation required a status change, creation of an OUT/RMA record, preservation of attachments, and an archive record. During testing, I found a condition that repeatedly triggered the flow. I added a processed-state check to address that loop.

I also disabled the confirmation action while background work ran and used the flow’s returned record identifier to continue the application. If the response was blank, the interface notified the user and reset the relevant flags instead of navigating as though the operation had succeeded.

These controls kept the selected part, its status, and the background record changes aligned when an action was canceled or a response failed.

**Record changes and the controls around them**

| Action | Record behavior | Control or recovery path |
| --- | --- | --- |
| Synchronize a station workbook | Update an existing serial or create a new record | Keep serial numbers stable and distinguish status from location |
| Edit or select a different part | Save or cancel changes to the selected record | Reset edit and installation flags when the selection changes |
| Install a part | Change status, create OUT/RMA and archive records, preserve attachments | Processed-state check prevents the repeated flow trigger found during testing |
| Wait for the background flow | Use the returned record identifier to continue | Disable confirmation during processing; notify and reset flags if the response is blank |

**Follow a part through the shared record**

1. **Receive and identify:** Station workbooks use common fields, with serial number as the stable record identifier.
2. **Match or create:** Twice-daily synchronization updates an existing SharePoint serial or creates a new record.
3. **Edit or install:** The app separates save and cancel from verified installation; changing selection clears unfinished action flags.
4. **Complete the record:** Installation changes status and creates OUT/RMA and archive records while preserving attachments.

A processed-state check addresses a repeated flow trigger. A blank flow response notifies the user and resets the relevant flags instead of continuing as if the action succeeded.

*Inventory record path and the controls around interrupted actions*

### What I delivered

- Standardized workbooks and field instructions for six stations.
- Twice-daily workbook-to-SharePoint synchronization using serial-number matching.
- Power Apps inventory interface with intake, editing, installation, and archive workflows.
- Power BI stock overview and documentation of interface state, record movement, and failure handling.

### Where the work stands

Built a shared inventory and an application that connects stock review to the receiving and installation workflow, with the logic documented for continued refinement.

### Scope and limitations

Receiving inspections and required station records remain part of the workflow alongside the application.

## Putting a cost around a workforce bottleneck

**Retention and cost analysis | Python, pandas, Excel, Public-source research**

**Status:** Proposal and financial model

### Project brief

**The problem:** A fixed number of senior technician positions constrained advancement and left tactical work with managers.

**My approach:** I compared recurring promotion costs with replacement-cost scenarios and the value of transferable management time.

**The result:** A phased proposal with a first-year combined net range of $95,960 to $200,960. The model includes valued capacity and conditional benefits, not achieved cash savings.

**My role:** I structured the business question, gathered sources, built the scenario model, and developed the stakeholder presentation.

### Project context

A fixed number of senior technician positions created an advancement bottleneck. Taking on more responsibility did not necessarily create a path to the next role. I wanted to put a cost around that structure and connect the staffing discussion to retention, workload, and the work managers were holding.

I built a financial model that compared the cost of expanding the senior role with two potential benefits: fewer employee replacements and more management time available for other work. The analysis became a business case for a phased change, with the assumptions and tradeoffs made explicit.

### Define the advancement problem

I started with two questions. What does it cost when an employee leaves because the advancement path is blocked? And how much tactical work could move from managers to a senior technician role with a higher responsibility threshold? Looking at both kept the analysis tied to the operation rather than treating the issue only as a pay increase.

The staffing scenario uses 42 technician positions: 30 Tech 2s and 12 Tech 3s. Promoting seven technicians changes that mix to 23 Tech 2s and 19 Tech 3s without adding headcount. The proposal replaces the fixed-position gate with readiness criteria and a clearer definition of the work expected at the senior level.

### Compare compensation in context

I compared job postings, public filings, salary references, and workforce information to understand the compensation context. Colorado postings were useful because their disclosed pay ranges made comparisons possible where other advertisements provided little detail. I separated base pay from stock compensation and considered geography, experience, and role responsibilities.

For the model, I used $37 per hour for Tech 2 and $43 per hour for Tech 3. Those rates define the $6 increase used throughout the calculation. Keeping one consistent baseline matters: substituting a regional pay range or a different proposed role halfway through would change the investment without changing the rest of the scenario.

### Calculate the first-year wage cost

Seven promotions, a $6 hourly increase, and 2,080 annual hours produce $87,360 in additional annual base wages: 7 × $6 × 2,080. Each promotion adds $12,480 per year. I kept that recurring expenditure separate from the potential benefits so the comparison starts with a clear cost.

The wage difference is only one part of a staffing decision. The expanded role also needs defined responsibilities, training, and agreement on which tasks can move. A promotion that changes the title and pay without changing the work would not create the management capacity included in the model.

### Separate replacement cost from management capacity

I modeled three to five avoided replacements at $15,000 to $30,000 each, producing a $45,000 to $150,000 range. I also estimated 38 weekly management hours across eight task groups that could move into the expanded senior role. At $70 per hour over 52 weeks, that time has an annual value of $138,320.

Those benefits have different meanings. Avoided replacement costs depend on retention improving. Management capacity depends on work actually moving and the released time being used productively. The manager's salary remains in the budget, so the capacity figure is a value assigned to available time, not a reduction in payroll.

- Shift scheduling: 6 hours per week
- Preventive-maintenance tracking: 4 hours
- Work-order prioritization: 5 hours
- Spare-parts inventory management: 3 hours
- Breakdown-response coordination: 8 hours
- Technician-training coordination: 4 hours
- Equipment-downtime reporting: 3 hours
- Root-cause documentation: 5 hours

**First-year cost and benefit comparison**

| Component | Lower scenario | Upper scenario |
| --- | --- | --- |
| Avoided replacements | $45,000 | $150,000 |
| Management capacity value | $138,320 | $138,320 |
| Combined gross benefit | $183,320 | $288,320 |
| Additional base wages | $87,360 | $87,360 |
| Combined net benefit | $95,960 | $200,960 |
| Net excluding capacity value | −$42,360 | $62,640 |

### Carry the wage cost into later years

I extended the model with seven new promotions in year one, five in year two, and three in year three. Earlier wage increases continue, so annual wage costs rise with the total promoted cohort. I held the annual replacement and capacity benefits constant to see how the proposal behaves without assuming that each expansion automatically produces more value.

The three-year combined net range is $125,640 to $440,640. The lower annual result falls below zero in year three as recurring wages grow. A positive first year supports evaluating an initial step, but it does not justify expanding indefinitely under the same benefit assumptions.

**Three-year projection with recurring wage increases**

| Year | New / total promotions | Annual added wages | Annual net, lower | Annual net, upper |
| --- | --- | --- | --- | --- |
| 1 | 7 / 7 | $87,360 | $95,960 | $200,960 |
| 2 | 5 / 12 | $149,760 | $33,560 | $138,560 |
| 3 | 3 / 15 | $187,200 | −$3,880 | $101,120 |
| Three-year total | 15 total | $424,320 | $125,640 | $440,640 |

### Turn the model into a decision

I connected the financial comparison to a phased recommendation in an executive summary and stakeholder presentation. The first step is to define readiness criteria, agree on task ownership, and evaluate the seven-promotion scenario. The model makes it possible to discuss which assumptions are reasonable before committing to a broader change.

I proposed tracking departures, replacement spending, task transfers, and management hours released during a pilot. Those measures would show whether the expected benefits are materializing and provide better inputs for the next decision. My contribution was to turn an operational concern into a structured business case that leadership could evaluate, revise, and measure.

### What I delivered

- Compensation and role research comparing public pay disclosures and responsibilities
- Python model covering first-year costs, benefit scenarios, and recurring three-year wages
- Task-hour breakdown separating management capacity from replacement costs
- Executive summary and stakeholder recommendation for a phased change

### Where the work stands

The analysis connected advancement, retention, and management workload in one business case. It showed where the first-year proposal could create value and how additional promotions change the longer-term balance. The resulting recommendation is a proposal for evaluation; the projected benefits are not implemented savings.

### Scope and limitations

The model uses estimated task hours, replacement costs, and wage assumptions. Its results depend on retention and task transfer.

Management capacity represents time available for other work, not cash savings.

The comparison excludes employer payroll costs, benefits, stock compensation, overtime, training, and rollout expenses. The three-year totals are undiscounted.

## Bringing a fragmented workstation together

**ICWinUI3 | C#, .NET 8, WinUI 3, SQL Server, D3D11**

**Status:** Paused pending engineering review

### Project brief

**The problem:** Troubleshooting required switching among equipment views, alarms, reports, and parts references while retaining the same asset context.

**My approach:** I built a WinUI 3 workspace with native docking, live equipment views, SQL-backed reporting, and process-isolated legacy communication.

**The result:** A substantial working prototype with tested components and documented migration gaps. Development is paused pending engineering review and production approval.

**My role:** I defined the project scope, coordinated rendering, data access, and panel migration, and documented implementation decisions and tests.

### Project context

Maintenance troubleshooting can begin with an alarm and quickly turn into a search across several tools. The equipment view, report history, control panels, and parts reference all provide pieces of the answer, but switching between them adds work when the situation is already time-sensitive.

ICWinUI3 is a modernization project built around that fragmentation. I developed a WinUI 3 workspace that connects asset context with alarms, SQL-backed panels, reporting, and parts lookup.

### Start with the question at the equipment

The interface centers the work on the asset. A technician looking at an alarm should be able to navigate to the relevant equipment, run a report, and reach the parts reference without reconstructing the context in another application. That workflow shaped the reporting and navigation decisions.

I added a Layout Manager rather than reproducing the original arrangement unchanged. A custom native docking engine supports workspaces and panel zones, with layout save and restore. The point is to keep the views needed for a particular task together. Some catalog entries still require migration into the native workspace.

The parts integration makes a reference of 104,362 records across 3,654 equipment numbers available within the troubleshooting workflow. A technician can use the equipment context to reach the relevant lookup without starting a separate search.

### Connect graphics, alarms, and records

The application uses C#, .NET 8, WinUI 3, SQL Server, and a D3D11 renderer. The 3D view handles 5,740 conveyor segments with live equipment color updates, alarm overlays, device markers, and hover information. Native alarm triage and SQL-backed panels provide other views of the same operation.

Reporting work brings a searchable catalog, time-range parameters, area and device filters, results, and export controls into the workspace. The reports use the operational schema for events, downtime, alarms, devices, and sorter statistics. The reporting view places the catalog and filters alongside populated downtime rows.

### Respect the legacy dependencies

A modern interface does not make the legacy communication layer disappear. The architecture uses a separate host process for legacy remoting because initializing it inside the WinUI process could disrupt the compositor. The host passes equipment and sorter data to the native interface while keeping that dependency separate from rendering. Transitional legacy-panel hosting remains distinct from the native WinUI implementation.

Each panel also needs the correct data path. A SQL-backed display or an online-status check cannot replace a live control function simply because the screens look similar. I compared panel behavior with the original system and tracked the remaining data and control dependencies as part of the migration.

**Workstreams and their implementation boundaries**

| Workstream | What I built | Integration requirement |
| --- | --- | --- |
| Workspace | Custom native Layout Manager with docking, save, and restore | Complete migration of the required panels into the native workspace |
| Equipment rendering | D3D11 view of 5,740 conveyor segments with live colors and overlays | Align live equipment updates with the rendering lifecycle |
| Reporting and parts | Parameterized SQL-backed reports and contextual lookup across 104,362 reference records | Connect report parameters and asset context to the operational schema |
| Legacy communication | Separate host process to protect the WinUI rendering process | Maintain process isolation and verify the required live control behavior |

**What the prototype demonstrates, and what remains**

- **Implemented in the prototype:** Native docking and saved layouts, D3D11 equipment rendering, alarm triage, SQL-backed reporting, parts lookup, and process-isolated legacy communication.
- **Still to migrate or validate:** Required native panels and their live data and control paths need further integration and testing before production approval.

Development is paused while the required panels and live control paths await engineering review.

*ICWinUI3 implementation and review boundary*

### Manage the work as dependent workstreams

I coordinated phased work across rendering, data access, reports, and panel migration. I kept task ownership, architecture decisions, test records, and handoffs in version control so changes in one area could be checked against the others. That coordination mattered because a report, an equipment view, and a control panel needed to retain the same asset context.

Validation included reporting integration tests and runtime checks of key components. Reviews also covered event cleanup, theme resources, accessibility, and asynchronous view lifecycles. I tracked the remaining issues alongside the implementation work to keep integration requirements visible before production review.

### What I delivered

- Modern workstation prototype with custom workspaces and Layout Manager
- 3D equipment view, alarm triage, and process-isolated legacy communication
- Reporting interface and contextual parts integration
- Architecture decisions, feature audits, test records, and handoffs

### Where the work stands

The working components demonstrate an integrated approach to maintenance troubleshooting. Development remains paused pending engineering review and production approval.

### Scope and limitations

The application does not yet reproduce all legacy features.

Remaining panels need validation against their required live data and control behavior.

Estimated efficiency gains are conditional on approval and adoption.

## A clearer path for facility changes

**Intake and approval process | Process design, Intake forms, Approval matrix**

**Status:** Process and documentation package

### Project brief

**The problem:** One shift could request a facility modification that another later wanted reversed, creating avoidable maintenance work.

**My approach:** I designed a request package with Safety review, four shift Operations decisions, Maintenance review, and documented closure.

**The result:** An editable form and policy package connecting the request, cross-shift decisions, and completed work order.

**My role:** I mapped the rework pattern and designed the intake, approval matrix, and policy documents.

### Project context

A facility modification could begin as a reasonable request from one shift and become a reversal request from another. Changes to bollards, fans, separators, or netting could leave Maintenance installing something, then spending more time taking it back out. The missing piece was a shared decision before the labor began.

I designed a request and approval package that puts safety, operational need, and maintenance feasibility into the same process. It includes an editable HTML request form, a matching Markdown version, and policy guidance. The goal is practical: give people a consistent way to explain a change, review it across shifts, and preserve the decision.

### Ask for the information that changes the decision

The intake form records the requester, area, location, proposed change, and reason for the request. It separates the expected benefit from potential risks and allows supporting photos, sketches, and cost estimates. That makes it easier to evaluate a request than receiving only an instruction to move or install something.

I included safety, productivity, ergonomics, and other reasons without assuming the category alone proves the request should proceed. A proposed benefit still needs an explanation. A photo or sketch can also expose details about the location that are difficult to communicate in a short message.

### Give each reviewer a distinct job

The first tier is Safety, which checks whether the change introduces a hazard or conflicts with safety requirements. The second tier has separate approval rows for four shift Operations managers, giving each a place to record a decision and date. The Maintenance Manager is the third tier, reviewing feasibility, cost, available resources, and long-term maintenance implications.

Each group brings a different constraint. Cross-shift review is particularly important when one group requests a change that another later disputes. The guidelines also ask reviewers to consider whether a change is permanent or reversible, alongside safety, productivity, and cost-effectiveness. That puts the impact of undoing the work into the initial decision.

**From request to documented completion**

| Stage | Review question | Record |
| --- | --- | --- |
| Intake | What changes, where, and why? | Proposed benefit, risks, photos or sketches, and cost information |
| Tier 1: Safety | Does the change create a hazard or conflict with requirements? | Safety decision and date |
| Tier 2: Operations | Does the change work across shifts? | Separate decisions for four shift managers |
| Tier 3: Maintenance | Is the change feasible, supportable, and appropriately resourced? | Maintenance Manager decision |
| Decision and closure | Was it approved, and was the work completed? | Decision rationale, denial reason where applicable, and completion/work-order fields |

### Keep denied requests in the history too

The documentation package records rationale and supporting material for the decision. Denied requests also remain documented, with a reason. Otherwise the same idea can return later without anyone knowing why it was declined or which concern needs to be addressed.

The form includes a final decision and a maintenance completion area for the work order, date, and notes. Approved changes are communicated to affected departments; the policy also allows a monthly approval summary. These details connect the request to execution and make it possible to distinguish an approved idea from work that was actually completed.

### Put a cost around avoidable rework

The supporting cost analysis describes reversals requiring roughly two to thirteen technician-hours before materials, lift use, or operational disruption. It gives event-level examples ranging from about $70 to $300 for smaller reversals and $500 or more for larger work. Those examples explain why reviewing a request first can be worthwhile.

I used those examples to explain the value of reviewing a change before assigning the work. The package gives each group a place to raise concerns, records the decision, and connects an approved request to its work order. Its intended value is preventing avoidable work and making changes less surprising across shifts.

### What I delivered

- Editable HTML facility-modification intake form and matching Markdown version
- Three-tier approval matrix with separate rows for four shift Operations managers
- Decision, denial-reason, and maintenance-completion fields
- Policy, evaluation criteria, and communication guidance

### Where the work stands

The package gives facility changes a consistent path from request to review and documented execution. It addresses the conditions behind install-and-reverse work.

### Scope and limitations

Event-level rework examples are estimates, not a measured annual saving.

The effect on reversal frequency has not been measured.

## Making noisy radio traffic searchable

**Operational transcription pipeline | Python, SoX, faster-whisper**

**Status:** Built transcription pipeline

### Project brief

**The problem:** Noisy radio recordings were difficult to search, and general transcription models struggled with operational vocabulary.

**My approach:** I preserved the audio, segmented the stream, compared preprocessing profiles, and selected transcripts using confidence and plausibility signals.

**The result:** A configurable audio-to-text pipeline with daily logs, debugging artifacts, labeling, and a training path.

**My role:** I designed the surrounding audio and quality-selection workflow and integrated the transcription model.

### Project context

Radio traffic is useful operational information, but it is difficult to search after the conversation has passed. Warehouse recordings add another problem: noisy audio and terms that a general transcription model does not reliably recognize.

I built a Python pipeline around audio capture, segmentation, preprocessing, transcription, and result selection. The model supplies the transcription capability; the project work is in making that capability usable with a noisy, domain-specific input and retaining enough context to investigate mistakes.

### Keep the input stable

The capture path uses one persistent SoX process to stream raw PCM audio into Python. Python handles level detection and splitting the stream into recordings. The design avoids repeatedly opening the capture device and avoids relying on a SoX silence effect that the project notes identify as problematic with virtual audio devices.

The recorder checks the environment and supports a continuous-monitor mode as well as an interactive shell. Configuration controls capture settings, output locations, and the transcription model. I kept those choices outside the main processing logic so the capture setup can change without rewriting the whole pipeline.

### Compare alternatives for the same recording

The original audio is preserved. The pipeline processes copies with configured SoX profiles, then runs faster-whisper on each version. The documented configuration includes baseline, denasal, and narrowband approaches. Different preprocessing choices can help or hurt a recording, so selection happens after transcription rather than assuming one filter always wins.

The implementation records preprocessing and transcription failures alongside successful attempts. When debugging is enabled, it saves the processed audio, transcripts, and JSON metrics. That makes it possible to compare what the model heard across profiles rather than judge only the final text. Multiple attempts also add processing cost, so this is a quality-oriented design tradeoff.

### Treat confidence as a signal, not proof

The scoring function combines average log probability, no-speech probability, compression ratio, and text plausibility checks. It penalizes repeated phrases, known unwanted output patterns, and implausible word rates. The highest-scoring attempt is selected, with a minimum-score check for heavily penalized results.

Domain corrections address common warehouse vocabulary and number formatting before the result is appended to the daily log. These rules can make the text more useful, but they are still heuristics. A confident model can be wrong, and a vocabulary substitution can also be wrong. The retained source and debug artifacts support review when the output needs to be checked.

**How a recording becomes a reviewable transcript**

| Stage | Processing decision | What remains available for review |
| --- | --- | --- |
| Capture | Keep one SoX stream open and segment it in Python | Original audio recordings |
| Preprocess | Run configured profiles on copies of the same recording | Processed audio and failures when debugging is enabled |
| Transcribe and score | Apply number and domain corrections, then compare model signals, repetition, and plausible word rates | Alternative transcripts and JSON metrics when debugging is enabled |
| Select and log | Choose the highest-scoring attempt, check its minimum score, and append accepted text | Daily log plus source audio for checking uncertain results |

### Keep a path for learning from labeled examples

The recorder includes a guided labeling mode, and a companion training script reads labeled audio-text pairs for LoRA fine-tuning. The training path is designed for a constrained GPU and includes conversion for the inference runtime. That creates a way to adapt the model if enough good examples are available.

I connected capture, model integration, domain handling, and result selection into one workflow. Preserving the audio and alternative attempts makes it possible to investigate a missed term or incorrect number and identify examples that could improve later training.

### What I delivered

- Continuous audio capture and segmentation pipeline
- Configurable preprocessing and transcription attempts
- Confidence and unwanted-output screening with daily logs
- Debug artifacts, labeling mode, and a LoRA training path

### Where the work stands

The pipeline produced searchable text from radio recordings with configurable preprocessing and domain handling. It provides a way to inspect alternative attempts when transcription quality is uncertain.

### Scope and limitations

Transcription accuracy and the effect of fine-tuning have not been measured against a labeled evaluation set.

Confidence and heuristic checks cannot guarantee a correct transcript.

## Earlier experience

### Connecting flight-test data to engineering decisions
**Mitsubishi Aircraft Corporation America | SpaceJet M90 Flight Test Sub-Lead Mechanic / Data Collection and Analysis | December 2018 - June 2020**

I recorded flight-test instrumentation data, used Excel and Tableau to investigate trends, and reported results to engineering. As a sub-lead mechanic, I also set daily goals, assigned work, and checked maintenance and quality-control sign-offs. The analysis had to connect to the practical work needed to carry out the test.

### Automating maintenance documentation
**FEAM | On call A&P/Avionics / Data Collection | January 2022 - October 2022**

I built automated maintenance-tracking forms with AcroScript and JavaScript while supporting on-call aircraft maintenance. This was an early opportunity to apply software to the documentation around a technical operation, using my understanding of the work to shape the tool.

### Business and web experience
**Fast Fix | Computer and Smartphone Technician / Marketing Data Collection and Analysis | December 2010 - May 2014**

Alongside computer and smartphone repair, I managed AdWords campaigns, search-engine optimization, website content, and advertising graphics. That experience gave me another perspective on a practical solution: how a business explains its services and connects with customers.

## How I approach the work

I start with the person who needs the answer. Then I work backward to the data, the rules, and the steps required to produce it reliably. I document the parts that still depend on a manual action, keep estimates separate from measured results, and build enough context for the next person to understand the work.

The combination I bring is analytical training and experience with the operational details that determine whether a solution gets used.
