diff --git a/MyWork/LambdaFunctionTutorial.ipynb b/MyWork/LambdaFunctionTutorial.ipynb
new file mode 100644
index 0000000..3e6bad9
--- /dev/null
+++ b/MyWork/LambdaFunctionTutorial.ipynb
@@ -0,0 +1,141 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "4cd33944-a665-4b67-abf1-de228d9c99e9",
+ "metadata": {},
+ "source": [
+ "This code has been prouced as a teaching resource for the UKSA space software, data and AI course run by the Space South Central Universities.\n",
+ "\n",
+ "Contributors to this code includes: M. Chandar"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "75e5aa33-5261-4e5d-b894-309031fea1b6",
+ "metadata": {},
+ "source": [
+ "## Learning Outcome"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "e4d50917-7bff-4dac-8a44-19ab5a36c127",
+ "metadata": {},
+ "source": [
+ "\n",
+ "
NOTE \n",
+ "This notebook aims to explain what the lambda function is in Python through examples. \n",
+ "
\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "dbc81d61-fa78-49ae-a014-8b3fe5a507c8",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# A lambda function is known as an anonymous function as it is not bound to an identifier,\n",
+ "# A regular function (defined with def) can be reused many times. A lambda function are single-use functions that can be inlined. \n",
+ "# Since you only use them once, \n",
+ "# they don't need an identifier\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "0e86f85e-40cc-4acd-8d4f-ef62ff661eaf",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "10\n"
+ ]
+ }
+ ],
+ "source": [
+ "# If we wanted to write a reusable function to double a number:\n",
+ "\n",
+ "def doubleNum(num):\n",
+ " return 2 * num\n",
+ "\n",
+ "# As a single use lambda expression\n",
+ "\n",
+ "# This is known as an antipattern as lambda functions are not supposed to be assigned to an identifier - it defeats the point of an anonymous function!\n",
+ "doubleNum = lambda num : 2 * num # This takes the identifier doubleNum from the namespace which is also bad practice with lambda functions.\n",
+ "\n",
+ "\n",
+ "print(doubleNum(5))\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "6b5cb119-7d2d-41ee-8c95-0ab6f29d74de",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "With a function: [['Daniel', 12], ['Beth', 15], ['Aaron', 56], ['Carrie', 80]]\n",
+ "With a lambda function [['Daniel', 12], ['Beth', 15], ['Aaron', 56], ['Carrie', 80]]\n"
+ ]
+ }
+ ],
+ "source": [
+ "# You can create custom sorts\n",
+ "# With a selection sort function\n",
+ "def sortByGrade(studentGradeList):\n",
+ " for i in range(len(studentGradeList)):\n",
+ " smallestGradeStudent = i\n",
+ " for j in range(i,len(studentGradeList)):\n",
+ " if studentGradeList[j][1] < studentGradeList[smallestGradeStudent][1]:\n",
+ " smallestGradeStudent = j\n",
+ " studentGradeList[smallestGradeStudent], studentGradeList[i] = studentGradeList[i], studentGradeList[smallestGradeStudent]\n",
+ " \n",
+ " return studentGradeList \n",
+ " \n",
+ "studentGradeList = [[\"Aaron\",56],[\"Beth\",15],[\"Carrie\",80], [\"Daniel\",12]]\n",
+ "\n",
+ "print(f\"With a function: {sortByGrade(studentGradeList)}\")\n",
+ "print(f\"With a lambda function {sorted(studentGradeList, key=lambda grade: grade[1])}\")\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "af3b3085-6de4-4d6a-a28d-24c60e9158fe",
+ "metadata": {},
+ "source": [
+ "As we can see, using the lamda function to make this custom sort was much easier, quicker, and it will be more efficient. "
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3 (ipykernel)",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.9.21"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/MyWork/Space_Track_API.ipynb b/MyWork/Space_Track_API.ipynb
new file mode 100644
index 0000000..eb98696
--- /dev/null
+++ b/MyWork/Space_Track_API.ipynb
@@ -0,0 +1,288 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "ec9eed2a-ae9e-4949-8d3f-3df297b09423",
+ "metadata": {},
+ "source": [
+ "This code has been produced as a teaching resource for the UKSA space software, data and AI course run by the Space South Central Universities.\n",
+ "\n",
+ "Contributors to this code includes: M. Chandar"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "a2682037-5554-48c3-b93c-152c1c64212f",
+ "metadata": {
+ "editable": true,
+ "slideshow": {
+ "slide_type": ""
+ },
+ "tags": []
+ },
+ "source": [
+ " What is an API?\n",
+ "\n",
+ "API stands for Application Programming Interface, it's a sort of messenger between a server holding some data in a database and a client requesting that data (us). It usually does not matter how things work under the hood of an API so what it does, and how it does it, is no concern of ours! (At least for this tutorial.) The image below shows what we aim to do - create a program that will send API requests to the Space-Track API endpoint, and then receive the information that we have requested. \n",
+ "
\n"
+ ]
+ },
+ {
+ "attachments": {
+ "0e6b6151-5d12-4fde-a8e7-35a620c83cf0.png": {
+ "image/png": "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"
+ }
+ },
+ "cell_type": "markdown",
+ "id": "475df677-fede-4f4e-b386-c3a7f6377376",
+ "metadata": {
+ "editable": true,
+ "slideshow": {
+ "slide_type": ""
+ },
+ "tags": []
+ },
+ "source": [
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "b3ced9de-eee9-4dc2-b525-9419c4e3130b",
+ "metadata": {},
+ "source": [
+ "## Learning Outcome"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "b229481c-8f1d-4baf-9178-4d9a2428a37c",
+ "metadata": {},
+ "source": [
+ "\n",
+ " NOTE \n",
+ "Before starting this notebook, it is important to create an account on https://www.space-track.org/ as your username and password will be used for the API authentication. In this notebook we will learn: \n",
+ "
\n",
+ " - How to access and query the Space Track API
\n",
+ " - How to break down a Map datastructure.
\n",
+ " - How to write data to a CSV file
\n",
+ "
\n",
+ "
\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "5c2494b4-61ad-41ae-bbaf-ac9e55572b74",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# The general code structure is taken from https://www.space-track.org/documentation#howto-api_python\n",
+ "# Import the necessary libaries for this\n",
+ "import requests\n",
+ "import json\n",
+ "import time\n",
+ "import configparser\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "2c23637f-04ba-420d-9326-eed782fb0b53",
+ "metadata": {
+ "editable": true,
+ "slideshow": {
+ "slide_type": ""
+ },
+ "tags": []
+ },
+ "outputs": [],
+ "source": [
+ "\n",
+ "\n",
+ "baseURL = \"https://www.space-track.org\"\n",
+ "authPath = \"/ajaxauth/login\"\n",
+ "\n",
+ "config = configparser.ConfigParser()\n",
+ "\n",
+ "# Open the config.ini folder that is within the directory of this notebook.\n",
+ "# This is where you need to put the login information for Space-Track.org\n",
+ "config.read(\"./config.ini\")\n",
+ "username = config.get(\"configuration\",\"username\")\n",
+ "password = config.get(\"configuration\",\"password\")\n",
+ "\n",
+ "\n",
+ "\n",
+ "query = \"/basicspacedata/query/class/gp/COUNTRY_CODE/UK/orderby/COUNTRY_CODE%20asc/limit/100/emptyresult/show\";\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "b850e3b3-6ac3-44b0-8a1a-25f4ee8e216b",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "\n",
+ "# This is how we will access the Space-Track API. \n",
+ "def api_access():\n",
+ " with requests.Session() as session: # This provides cookie persistance so our login credentials are remembered for the whole session. \n",
+ " \n",
+ " # Send the username and password data to the website.\n",
+ " response = session.post(baseURL + authPath, data = {\"identity\":username, \"password\":password}) # When \"adding\" two or more strings, they concatenate.\n",
+ " \n",
+ " # Check whether the website got the data, a status_code of 200 means it did. \n",
+ " if response.status_code != 200:\n",
+ " print(f\"Could not POST for login: {response}\") # f-strings are incredibly convieniant!\n",
+ " \n",
+ " response = session.get(baseURL + query) # Let's get the data.\n",
+ " \n",
+ " # Check whether this GET request is valid. \n",
+ " if response.status_code != 200:\n",
+ " print(f\"Could not GET data: {response}\")\n",
+ " \n",
+ " response = json.loads(response.text)\n",
+ " # print(response.keys())\n",
+ " \n",
+ " \n",
+ " \n",
+ " session.close()\n",
+ " \n",
+ " return response"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "id": "d7f1dd59-9152-4d38-bcd1-837e256e5635",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "{'CCSDS_OMM_VERS': '3.0', 'COMMENT': 'GENERATED VIA SPACE-TRACK.ORG API', 'CREATION_DATE': '2025-03-24T02:21:51', 'ORIGINATOR': '18 SPCS', 'OBJECT_NAME': 'ELEVATION-1', 'OBJECT_ID': '2025-009BW', 'CENTER_NAME': 'EARTH', 'REF_FRAME': 'TEME', 'TIME_SYSTEM': 'UTC', 'MEAN_ELEMENT_THEORY': 'SGP4', 'EPOCH': '2025-03-23T18:58:52.857120', 'MEAN_MOTION': '15.20111431', 'ECCENTRICITY': '0.00063870', 'INCLINATION': '97.4273', 'RA_OF_ASC_NODE': '164.3248', 'ARG_OF_PERICENTER': '118.6319', 'MEAN_ANOMALY': '241.5559', 'EPHEMERIS_TYPE': '0', 'CLASSIFICATION_TYPE': 'U', 'NORAD_CAT_ID': '62677', 'ELEMENT_SET_NO': '999', 'REV_AT_EPOCH': '6795', 'BSTAR': '0.00143940000000', 'MEAN_MOTION_DOT': '0.00031157', 'MEAN_MOTION_DDOT': '0.0000000000000', 'SEMIMAJOR_AXIS': '6883.641', 'PERIOD': '94.730', 'APOAPSIS': '509.903', 'PERIAPSIS': '501.110', 'OBJECT_TYPE': 'PAYLOAD', 'RCS_SIZE': 'MEDIUM', 'COUNTRY_CODE': 'UK', 'LAUNCH_DATE': '2025-01-14', 'SITE': 'AFWTR', 'DECAY_DATE': None, 'FILE': '4678815', 'GP_ID': '283892638', 'TLE_LINE0': '0 ELEVATION-1', 'TLE_LINE1': '1 62677U 25009BW 25082.79088955 .00031157 00000-0 14394-2 0 9992', 'TLE_LINE2': '2 62677 97.4273 164.3248 0006387 118.6319 241.5559 15.20111431 67950'}\n"
+ ]
+ }
+ ],
+ "source": [
+ "response = api_access()\n",
+ "print(response[0]) # Just print the first satellite's information from the list."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "id": "d4616732-2a1b-4273-8b1b-de3732dcd94b",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "['2025-009BW', 0.0006387, 97.4273, 164.3248, 118.6319, 15.20111431, 241.5559, '2025-03-23T18:58:52.857120', '2025-03-23', '18:58:52.857120']\n"
+ ]
+ }
+ ],
+ "source": [
+ "satellite_info = []\n",
+ "for satellite in response:\n",
+ " \n",
+ " objectID = satellite[\"OBJECT_ID\"]\n",
+ "\n",
+ " # We convert the following to floats for later tutorials, where we use the values for neural nets. \n",
+ " ecc = float(satellite[\"ECCENTRICITY\"])\n",
+ " inc = float(satellite[\"INCLINATION\"])\n",
+ " raan = float(satellite[\"RA_OF_ASC_NODE\"])\n",
+ " argP = float(satellite[\"ARG_OF_PERICENTER\"])\n",
+ "\n",
+ " meanM = float(satellite[\"MEAN_MOTION\"])\n",
+ " meanA = float(satellite[\"MEAN_ANOMALY\"])\n",
+ " \n",
+ " epochDate = satellite[\"EPOCH\"].split('T')[0]\n",
+ " epochTime = satellite[\"EPOCH\"].split('T')[1]\n",
+ " \n",
+ " \n",
+ " epoch = satellite[\"EPOCH\"]\n",
+ " \n",
+ " \n",
+ " satellite_info.append([objectID, ecc, inc, raan, argP, meanM, meanA, epoch, epochDate, epochTime])\n",
+ "\n",
+ "print(satellite_info[0])\n",
+ "\n",
+ " "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "id": "44e28604-4f5f-4721-9a68-444a98c77c15",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "100\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(len(satellite_info))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "id": "9e008ce4-1da9-44d7-82d7-b16ede5d1292",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import csv # We will use a CSV file as it is easier to parse data this way"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "id": "6076d884-8606-46c3-b2aa-60bddf64d3d0",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Creates a csv file with some satellite information\n",
+ "with open('Satellite.csv', 'w', newline='') as f:\n",
+ " \n",
+ " writer = csv.writer(f)\n",
+ " x = [\"OBJECT ID\", \"ECCENTRICITY\",\"INCLINATION\",\"RA_OF_ASCENDING_NODE\", \"ARG OF PERICENTRE\", \"MEAN MOTION\", \"MEAN ANOMALY\", \"EPOCH\", \"EPOCH DATE\", \"EPOCH TIME\" ]\n",
+ " writer.writerow(x)\n",
+ " writer.writerows(satellite_info)\n",
+ " "
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 13.2 (Pytorch)",
+ "language": "python",
+ "name": "python-13.2"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.13.2"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/MyWork/Space_Track_API_Image.png b/MyWork/Space_Track_API_Image.png
new file mode 100644
index 0000000..ba6822c
Binary files /dev/null and b/MyWork/Space_Track_API_Image.png differ
diff --git a/MyWork/config.ini b/MyWork/config.ini
new file mode 100644
index 0000000..a589914
--- /dev/null
+++ b/MyWork/config.ini
@@ -0,0 +1,3 @@
+[configuration]
+username=ENTER-USERNAME-HERE
+password=ENTER-PASSWORD-HERE
diff --git a/Tutorials/IdentifyingSatellitesGivenTime.ipynb b/Tutorials/IdentifyingSatellitesGivenTime.ipynb
new file mode 100644
index 0000000..507f004
--- /dev/null
+++ b/Tutorials/IdentifyingSatellitesGivenTime.ipynb
@@ -0,0 +1,273 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "7969caea-8913-467f-871d-965c2ce5febe",
+ "metadata": {},
+ "source": [
+ "This code has been produced as a teaching resource for the UKSA space software, data and AI course run by the Space South Central Universities.\n",
+ "\n",
+ "Contributors to this code includes: M. Chandar"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "963a0eb9-4bb2-4511-8e8e-038608dfbfc7",
+ "metadata": {},
+ "source": [
+ "## Learning Outcome\n",
+ " NOTE This notebook builds on the Space_Track_API notebook so it is required to complete that first. \n",
+ "In this notebook, we aim to:\n",
+ "
- Learn what a Pandas dataframe is and can do for us.
\n",
+ "- Access specific data from a dataframe.
\n",
+ "- Calculate the mean anomaly of a satellite after a period of time.
\n",
+ "
\n",
+ "
\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "1fe45d90-d0d3-4259-b7a5-0b1639057a88",
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ " OBJECT ID ECCENTRICITY INCLINATION RA_OF_ASCENDING_NODE \\\n",
+ "0 2025-009BW 0.000639 97.4273 164.3248 \n",
+ "1 2024-252D 0.619028 4.7404 343.0654 \n",
+ "2 2024-252C 0.648293 5.6139 343.0543 \n",
+ "3 2024-252B 0.664626 6.2401 344.0201 \n",
+ "4 2024-252A 0.746990 8.6998 349.3559 \n",
+ ".. ... ... ... ... \n",
+ "95 2023-029AP 0.000240 87.9082 19.0956 \n",
+ "96 2023-029AN 0.000199 87.9229 34.3020 \n",
+ "97 2023-029AM 0.000152 87.9338 3.9442 \n",
+ "98 2023-029AL 0.000223 87.9230 34.3329 \n",
+ "99 2023-029AK 0.000231 87.9090 19.0529 \n",
+ "\n",
+ " ARG OF PERICENTRE MEAN MOTION MEAN ANOMALY EPOCH \\\n",
+ "0 118.6319 15.201114 241.5559 2025-03-23T18:58:52.857120 \n",
+ "1 203.4793 0.900445 106.9887 2025-03-24T10:48:25.194240 \n",
+ "2 203.3242 0.909780 103.2405 2025-03-24T09:07:45.251904 \n",
+ "3 202.2377 0.924584 103.8226 2025-03-24T11:39:24.978528 \n",
+ "4 198.9588 1.017776 100.3081 2025-03-23T14:49:26.078880 \n",
+ ".. ... ... ... ... \n",
+ "95 85.8644 13.145047 274.2759 2025-03-24T18:44:54.377952 \n",
+ "96 72.5325 13.197268 287.6025 2025-03-24T14:20:55.834080 \n",
+ "97 84.0894 13.207741 276.0413 2025-03-24T11:26:57.553728 \n",
+ "98 82.7774 13.197274 277.3612 2025-03-24T14:55:02.663040 \n",
+ "99 83.4671 13.145040 276.6722 2025-03-25T00:59:24.410400 \n",
+ "\n",
+ " EPOCH DATE EPOCH TIME \n",
+ "0 2025-03-23 18:58:52.857120 \n",
+ "1 2025-03-24 10:48:25.194240 \n",
+ "2 2025-03-24 09:07:45.251904 \n",
+ "3 2025-03-24 11:39:24.978528 \n",
+ "4 2025-03-23 14:49:26.078880 \n",
+ ".. ... ... \n",
+ "95 2025-03-24 18:44:54.377952 \n",
+ "96 2025-03-24 14:20:55.834080 \n",
+ "97 2025-03-24 11:26:57.553728 \n",
+ "98 2025-03-24 14:55:02.663040 \n",
+ "99 2025-03-25 00:59:24.410400 \n",
+ "\n",
+ "[100 rows x 10 columns]\n"
+ ]
+ }
+ ],
+ "source": [
+ "import pandas as pd # Pandas is useful to handle datasets\n",
+ "\n",
+ "df = pd.read_csv(\"Satellite.csv\") # df is short for Dataframe, a datastructure similar to an Excel spreadsheet\n",
+ "print(df) # See what the dataframe looks like"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 36,
+ "id": "9e0ca01b-d8a2-4938-bed5-362f83a0a3be",
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "name": "stdin",
+ "output_type": "stream",
+ "text": [
+ "Input start date: 2025-03-12\n",
+ "Input end date: 2025-03-14\n"
+ ]
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ " OBJECT ID MEAN MOTION MEAN ANOMALY EPOCH DATE EPOCH TIME\n",
+ "0 2025-009BW 15.193892 209.8770 2025-03-13 04:33:47.608704\n",
+ "8 2024-188S 13.103745 252.1050 2025-03-13 04:20:02.484384\n",
+ "10 2024-188Q 13.767497 253.3387 2025-03-13 06:00:02.000160\n",
+ "11 2024-188P 13.103765 285.3898 2025-03-13 04:29:38.612544\n",
+ "14 2024-188L 13.737165 343.9318 2025-03-13 06:00:02.000160\n",
+ "15 2024-188K 13.705825 29.9547 2025-03-13 06:00:02.000160\n",
+ "16 2024-188J 13.731674 177.4994 2025-03-13 06:00:02.000160\n",
+ "18 2024-188G 13.741105 319.0862 2025-03-13 06:00:02.000160\n",
+ "19 2024-188F 13.759159 173.9416 2025-03-13 02:00:01.999872\n",
+ "20 2024-188E 13.971749 170.8949 2025-03-13 06:00:02.000160\n",
+ "21 2024-188D 13.707831 302.2357 2025-03-13 06:00:02.000160\n",
+ "23 2024-188B 14.838404 276.8280 2025-03-13 03:40:42.949632\n",
+ "24 2024-188A 13.636899 266.6821 2025-03-13 06:00:02.000160\n",
+ "27 2023-174DJ 14.799127 316.2160 2025-03-13 04:06:49.296960\n",
+ "31 2023-174C 15.286561 327.5375 2025-03-13 03:49:55.778304\n",
+ "32 2023-174B 15.422362 340.9037 2025-03-13 05:13:00.953760\n",
+ "34 2023-084BY 14.813040 207.2466 2025-03-13 05:47:48.275808\n",
+ "35 2023-084BX 15.156130 19.3462 2025-03-13 05:47:57.879168\n",
+ "37 2023-084Y 15.236255 207.4210 2025-03-13 05:15:12.819168\n",
+ "44 2023-068K 13.155505 285.3032 2025-03-13 05:22:38.289792\n",
+ "54 2023-054AZ 15.095786 82.6598 2025-03-13 05:56:55.508352\n",
+ "56 2023-054B 15.488425 34.4856 2025-03-13 05:27:59.912064\n",
+ "61 2023-043AH 13.155471 272.9853 2025-03-13 05:29:28.792608\n",
+ "63 2023-043AF 13.155475 293.6001 2025-03-13 05:47:43.871136\n",
+ "86 2023-043G 13.218258 276.9143 2025-03-13 05:41:20.814144\n",
+ "88 2023-043E 13.165967 264.6639 2025-03-13 04:52:50.219328\n",
+ "91 2023-043B 13.165953 290.5776 2025-03-13 04:34:36.901632\n",
+ "92 2023-043A 13.165963 285.1796 2025-03-13 04:43:43.603680\n"
+ ]
+ }
+ ],
+ "source": [
+ "start_date = input(\"Input start date: \")\n",
+ "end_date = input(\"Input end date: \")\n",
+ "\n",
+ "mask = (df[\"EPOCH DATE\"] > start_date) & (df[\"EPOCH DATE\"] < end_date) # This is just a filter, or \"mask\", that we will apply to the df. \n",
+ "output = df.loc[mask][[\"OBJECT ID\",\"MEAN MOTION\", \"MEAN ANOMALY\", \"EPOCH DATE\", \"EPOCH TIME\"]] # Use the filter and output only the desired columns\n",
+ "\n",
+ "print(output)\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "id": "bd13e981-a9ea-439a-ac26-0a862187b3f8",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "There are 28 satellites between 2025-03-12 to 2025-03-15\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(f\"There are {len(output)} satellites between {start_date} to {end_date}\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "3797316f-efe1-4a72-96be-3d5e0abcad0b",
+ "metadata": {},
+ "source": [
+ "## Exercise: \n",
+ "### Create a new \"mask\" that can filter the epoch time. Uncomment the code, then fill the gaps in the code with **** and run."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "fa034f30-17a1-4be2-b196-4723a897dd42",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ " \n",
+ "# start_date = input(\"Input start time: \")\n",
+ "# end_date = input(\"Input end time: \")\n",
+ "\n",
+ "# mask = (df[****] > ****) & (df[****] < ****) # This is just a filter, or \"mask\", that we will apply to the df. \n",
+ "# output = df.loc[mask][[\"OBJECT ID\",\"MEAN MOTION\", \"MEAN ANOMALY\", \"EPOCH DATE\", \"EPOCH TIME\"]] # Use the filter and output only the desired columns\n",
+ "\n",
+ "# print(output)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "e04160c8-c6d1-44aa-b3dc-e4fa31315e90",
+ "metadata": {},
+ "source": [
+ "## Where would a satellite be 20 seconds after the epoch time?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 38,
+ "id": "8ebc3f31-514c-4bef-9919-e3394c90b631",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Satellite 2025-009BW has a mean_motion of 15.19389189 and a mean_anomaly of 209.877 degrees\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Setup\n",
+ "object_id = \"2025-009BW\"\n",
+ "dt = 20 # delta time is 20 seconds\n",
+ "mean_motion = df.loc[df[\"OBJECT ID\"] == object_id][\"MEAN MOTION\"][0]\n",
+ "mean_anomaly = df.loc[df[\"OBJECT ID\"] == object_id][\"MEAN ANOMALY\"][0]\n",
+ "epoch_time = df.loc[df[\"OBJECT ID\"] == object_id][\"EPOCH TIME\"][0]\n",
+ "\n",
+ "print(f\"Satellite {object_id} has a mean_motion of {mean_motion} and a mean_anomaly of {mean_anomaly} degrees\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 42,
+ "id": "356f7a2f-87b8-4dd0-a68e-72380afd55bd",
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "The satellite 2025-009BW, 20 seconds after 04:33:47.608704 and with a mean anomaly of 209.877 degrees, will be at 153.755 degrees\n"
+ ]
+ }
+ ],
+ "source": [
+ "# Calculate the new mean anomaly\n",
+ "new_mean_anomaly = round((mean_motion * dt + mean_anomaly) % 360,3)\n",
+ "\n",
+ "# Output the result!\n",
+ "print(f\"The satellite {object_id}, {dt} seconds after {epoch_time} and with a mean anomaly of {mean_anomaly} degrees, will be at {new_mean_anomaly} degrees\")"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 13.2 (Pytorch)",
+ "language": "python",
+ "name": "python-13.2"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.13.2"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}