.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "_examples\ukvi-trips\plot_main05.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note Click :ref:`here ` to download the full example code .. rst-class:: sphx-glr-example-title .. _sphx_glr__examples_ukvi-trips_plot_main05.py: UKVI Travel History Calculator ============================== This Python script is designed to calculate the total number of days spent outside the UK from a flight history log, which is particularly useful for UK Visa and Immigration (UKVI) applications like Indefinite Leave to Remain (ILR) that have limits on absences. .. note:: Generated with Google Gemini .. GENERATED FROM PYTHON SOURCE LINES 14-134 .. rst-class:: sphx-glr-script-out Out: .. code-block:: none --- Processing Flight Log --- ⚠️ Warning: Ignoring Inbound flight on 2019-12-02 06:15:00 as there was no preceding Outbound flight. ⚠️ Warning: Consecutive Outbound flight on 2022-08-06 05:50:00. Using this as the new departure. ⚠️ Warning: Consecutive Outbound flight on 2023-09-04 08:50:00. Using this as the new departure. ⚠️ Warning: Consecutive Outbound flight on 2024-04-24 16:30:00. Using this as the new departure. ⚠️ Note: Log ends while abroad. The last trip starting 2024-07-20 19:15:00 is not included. --- Final Summary --- ✅ Total time spent abroad: 543 days (exact duration) ✅ Total time spent abroad: 535 days (full days only) --- Valid Round Trips --- Outbound Date Inbound Date Duration (days) Route 0 2019-12-04 20:05:00 2020-01-13 00:20:00 39 Out: STN → MAD | In: SGN → LHR 1 2020-09-15 10:00:00 2021-02-08 15:35:00 146 Out: STN → RMI | In: MAD → LHR 2 2021-06-17 08:25:00 2021-10-05 07:05:00 109 Out: STN → MAD | In: MAD → STN 3 2021-11-19 08:05:00 2021-12-02 20:45:00 13 Out: STN → BLO | In: RMU → LGW 4 2022-01-20 17:20:00 2022-02-15 12:35:00 25 Out: LGW → MAD | In: MAD → STN 5 2022-03-24 09:50:00 2022-03-30 14:50:00 6 Out: STN → TFS | In: TFS → LGW 6 2022-04-22 11:40:00 2022-04-27 15:10:00 5 Out: STN → LIS | In: LIS → STN 7 2022-06-03 12:55:00 2022-06-14 15:35:00 11 Out: STN → MAD | In: MAD → STN 8 2022-08-06 05:50:00 2022-09-21 06:45:00 46 Out: LTN → CDT | In: MAD → STN 9 2022-10-26 13:05:00 2022-11-15 15:50:00 20 Out: STN → MAD | In: MAD → LHR 10 2022-11-16 21:25:00 2022-12-26 09:05:00 39 Out: LHR → KUL | In: KUL → LHR 11 2023-02-04 06:45:00 2023-02-06 14:10:00 2 Out: LTN → ATH | In: ATH → LGW 12 2023-02-21 16:05:00 2023-03-01 10:15:00 7 Out: LTN → BLQ | In: PEG → STN 13 2023-04-28 14:45:00 2023-05-09 12:20:00 10 Out: STN → LPA | In: LPA → STN 14 2023-09-04 08:50:00 2023-09-11 07:10:00 6 Out: LGW → MXP | In: MXP → LGW 15 2023-10-04 18:15:00 2023-10-17 15:35:00 12 Out: STN → MAD | In: MAD → STN 16 2023-12-15 06:15:00 2024-01-10 10:45:00 26 Out: STN → PEG | In: MAD → STN 17 2024-04-24 16:30:00 2024-05-02 20:50:00 8 Out: LHR → MAD | In: MAD → LHR 18 2024-06-26 15:50:00 2024-07-01 18:40:00 5 Out: LHR → MAD | In: MAD → LGW | .. code-block:: default :lineno-start: 14 # Libraries import pandas as pd def calculate_time_abroad_from_df( df: pd.DataFrame, date_col: str, status_col: str, dep_port_col: str, arr_port_col: str ) -> tuple[pd.Timedelta, pd.DataFrame]: """ Calculates total time spent abroad from a flight log in a pandas DataFrame, handling multi-airport routes. Args: df: The DataFrame containing the flight log. date_col: The name of the column with the flight timestamps. status_col: The name of the column with the 'Inbound'/'Outbound' status. dep_port_col: The name of the departure port column. arr_port_col: The name of the arrival port column. Returns: A tuple containing: - The total duration abroad (pandas.Timedelta). - A new DataFrame with details of the valid round trips, including routes. """ # --- 1. Prepare the DataFrame --- df_processed = df.copy() df_processed[date_col] = pd.to_datetime( df_processed[date_col], dayfirst=True, errors='coerce') df_processed = df_processed.dropna(subset=[date_col]) \ .sort_values(by=date_col).reset_index(drop=True) # --- 2. Calculate Time Abroad with State Machine Logic --- total_duration_abroad = pd.Timedelta(0) last_outbound_leg = None # Stores the entire row of the last outbound flight valid_trips = [] print("--- Processing Flight Log ---") for index, row in df_processed.iterrows(): if row[status_col] == 'Outbound': if last_outbound_leg is not None: print(f"⚠️ Warning: Consecutive Outbound flight on {row[date_col]}. Using this as the new departure.") last_outbound_leg = row elif row[status_col] == 'Inbound': if last_outbound_leg is not None: # A valid return trip is found duration = row[date_col] - last_outbound_leg[date_col] total_duration_abroad += duration # Capture the outbound and inbound journeys separately outbound_route = f"{last_outbound_leg[dep_port_col]} → {last_outbound_leg[arr_port_col]}" inbound_route = f"{row[dep_port_col]} → {row[arr_port_col]}" # Combine them for a full description full_route_str = f"Out: {outbound_route} | In: {inbound_route}" valid_trips.append({ 'Outbound Date': last_outbound_leg[date_col], 'Inbound Date': row[date_col], 'Duration (days)': duration.days, 'Route': full_route_str }) # Reset state to "Home" last_outbound_leg = None else: print( f"⚠️ Warning: Ignoring Inbound flight on {row[date_col]} as there was no preceding Outbound flight.") if last_outbound_leg is not None: print( f"\n⚠️ Note: Log ends while abroad. The last trip starting {last_outbound_leg[date_col]} is not included.") trips_df = pd.DataFrame(valid_trips) return total_duration_abroad, trips_df # ------------------------------------------ # Main # ------------------------------------------ # Libraries from pathlib import Path # Configuration id = '775243' id = '1085721' out_path = Path(f'./outputs/{id}') # Load data flight_df = pd.read_json(out_path / 'flights.json') # 2. Call the function with all the required column names total_time, valid_trips_df = calculate_time_abroad_from_df( df=flight_df, date_col='Departure Date/Time', status_col='In/Out', dep_port_col='Dep Port', arr_port_col='Arrival Port' ) # 3. Print the final results print("\n--- Final Summary ---") print(f"✅ Total time spent abroad: {total_time.days} days (exact duration)") print(f"✅ Total time spent abroad: %s days (full days only)" % \ valid_trips_df['Duration (days)'].sum()) print("\n--- Valid Round Trips ---") print(valid_trips_df) .. rst-class:: sphx-glr-timing **Total running time of the script:** ( 0 minutes 0.015 seconds) .. _sphx_glr_download__examples_ukvi-trips_plot_main05.py: .. only :: html .. container:: sphx-glr-footer :class: sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_main05.py ` .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_main05.ipynb ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_