From 3d2ac320e401dedc922cb3683cb91c50491723dc Mon Sep 17 00:00:00 2001
From: GUKWAT <20095319@tafe.wa.edu.au>
Date: Sun, 21 Jul 2024 13:37:49 +0800
Subject: [PATCH 01/14] set_outout_values function refactored

---
 .idea/.gitignore                              |   3 +
 .idea/cli-surf.iml                            |  12 ++
 .../inspectionProfiles/profiles_settings.xml  |   6 +
 .idea/misc.xml                                |   7 +
 .idea/modules.xml                             |   8 +
 .idea/vcs.xml                                 |   6 +
 poetry.lock                                   | 196 ++++++++++--------
 pyproject.toml                                |   4 +-
 src/helper.py                                 |  77 +++----
 9 files changed, 191 insertions(+), 128 deletions(-)
 create mode 100644 .idea/.gitignore
 create mode 100644 .idea/cli-surf.iml
 create mode 100644 .idea/inspectionProfiles/profiles_settings.xml
 create mode 100644 .idea/misc.xml
 create mode 100644 .idea/modules.xml
 create mode 100644 .idea/vcs.xml

diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/cli-surf.iml b/.idea/cli-surf.iml
new file mode 100644
index 0000000..b5ad51a
--- /dev/null
+++ b/.idea/cli-surf.iml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="PYTHON_MODULE" version="4">
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$" />
+    <orderEntry type="jdk" jdkName="Python 3.11" jdkType="Python SDK" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+  <component name="PyDocumentationSettings">
+    <option name="format" value="PLAIN" />
+    <option name="myDocStringFormat" value="Plain" />
+  </component>
+</module>
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000..105ce2d
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+<component name="InspectionProjectProfileManager">
+  <settings>
+    <option name="USE_PROJECT_PROFILE" value="false" />
+    <version value="1.0" />
+  </settings>
+</component>
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..a377feb
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.11" project-jdk-type="Python SDK" />
+  <component name="PyCharmProfessionalAdvertiser">
+    <option name="shown" value="true" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..9f0a871
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/cli-surf.iml" filepath="$PROJECT_DIR$/.idea/cli-surf.iml" />
+    </modules>
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="" vcs="Git" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/poetry.lock b/poetry.lock
index 2250fd6..0efdda5 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1,4 +1,4 @@
-# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand.
+# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand.
 
 [[package]]
 name = "aiohttp"
@@ -1267,9 +1267,9 @@ files = [
 
 [package.dependencies]
 numpy = [
+    {version = ">=1.26.0", markers = "python_version >= \"3.12\""},
     {version = ">=1.22.4", markers = "python_version < \"3.11\""},
     {version = ">=1.23.2", markers = "python_version == \"3.11\""},
-    {version = ">=1.26.0", markers = "python_version >= \"3.12\""},
 ]
 python-dateutil = ">=2.8.2"
 pytz = ">=2020.1"
@@ -1392,109 +1392,123 @@ files = [
 
 [[package]]
 name = "pydantic"
-version = "2.7.2"
+version = "2.8.2"
 description = "Data validation using Python type hints"
 optional = false
 python-versions = ">=3.8"
 files = [
-    {file = "pydantic-2.7.2-py3-none-any.whl", hash = "sha256:834ab954175f94e6e68258537dc49402c4a5e9d0409b9f1b86b7e934a8372de7"},
-    {file = "pydantic-2.7.2.tar.gz", hash = "sha256:71b2945998f9c9b7919a45bde9a50397b289937d215ae141c1d0903ba7149fd7"},
+    {file = "pydantic-2.8.2-py3-none-any.whl", hash = "sha256:73ee9fddd406dc318b885c7a2eab8a6472b68b8fb5ba8150949fc3db939f23c8"},
+    {file = "pydantic-2.8.2.tar.gz", hash = "sha256:6f62c13d067b0755ad1c21a34bdd06c0c12625a22b0fc09c6b149816604f7c2a"},
 ]
 
 [package.dependencies]
 annotated-types = ">=0.4.0"
-pydantic-core = "2.18.3"
-typing-extensions = ">=4.6.1"
+email-validator = {version = ">=2.0.0", optional = true, markers = "extra == \"email\""}
+pydantic-core = "2.20.1"
+typing-extensions = [
+    {version = ">=4.12.2", markers = "python_version >= \"3.13\""},
+    {version = ">=4.6.1", markers = "python_version < \"3.13\""},
+]
 
 [package.extras]
 email = ["email-validator (>=2.0.0)"]
 
 [[package]]
 name = "pydantic-core"
-version = "2.18.3"
+version = "2.20.1"
 description = "Core functionality for Pydantic validation and serialization"
 optional = false
 python-versions = ">=3.8"
 files = [
-    {file = "pydantic_core-2.18.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:744697428fcdec6be5670460b578161d1ffe34743a5c15656be7ea82b008197c"},
-    {file = "pydantic_core-2.18.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:37b40c05ced1ba4218b14986fe6f283d22e1ae2ff4c8e28881a70fb81fbfcda7"},
-    {file = "pydantic_core-2.18.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:544a9a75622357076efb6b311983ff190fbfb3c12fc3a853122b34d3d358126c"},
-    {file = "pydantic_core-2.18.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e2e253af04ceaebde8eb201eb3f3e3e7e390f2d275a88300d6a1959d710539e2"},
-    {file = "pydantic_core-2.18.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:855ec66589c68aa367d989da5c4755bb74ee92ccad4fdb6af942c3612c067e34"},
-    {file = "pydantic_core-2.18.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d3e42bb54e7e9d72c13ce112e02eb1b3b55681ee948d748842171201a03a98a"},
-    {file = "pydantic_core-2.18.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c6ac9ffccc9d2e69d9fba841441d4259cb668ac180e51b30d3632cd7abca2b9b"},
-    {file = "pydantic_core-2.18.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c56eca1686539fa0c9bda992e7bd6a37583f20083c37590413381acfc5f192d6"},
-    {file = "pydantic_core-2.18.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:17954d784bf8abfc0ec2a633108207ebc4fa2df1a0e4c0c3ccbaa9bb01d2c426"},
-    {file = "pydantic_core-2.18.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:98ed737567d8f2ecd54f7c8d4f8572ca7c7921ede93a2e52939416170d357812"},
-    {file = "pydantic_core-2.18.3-cp310-none-win32.whl", hash = "sha256:9f9e04afebd3ed8c15d67a564ed0a34b54e52136c6d40d14c5547b238390e779"},
-    {file = "pydantic_core-2.18.3-cp310-none-win_amd64.whl", hash = "sha256:45e4ffbae34f7ae30d0047697e724e534a7ec0a82ef9994b7913a412c21462a0"},
-    {file = "pydantic_core-2.18.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:b9ebe8231726c49518b16b237b9fe0d7d361dd221302af511a83d4ada01183ab"},
-    {file = "pydantic_core-2.18.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b8e20e15d18bf7dbb453be78a2d858f946f5cdf06c5072453dace00ab652e2b2"},
-    {file = "pydantic_core-2.18.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c0d9ff283cd3459fa0bf9b0256a2b6f01ac1ff9ffb034e24457b9035f75587cb"},
-    {file = "pydantic_core-2.18.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2f7ef5f0ebb77ba24c9970da18b771711edc5feaf00c10b18461e0f5f5949231"},
-    {file = "pydantic_core-2.18.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73038d66614d2e5cde30435b5afdced2b473b4c77d4ca3a8624dd3e41a9c19be"},
-    {file = "pydantic_core-2.18.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6afd5c867a74c4d314c557b5ea9520183fadfbd1df4c2d6e09fd0d990ce412cd"},
-    {file = "pydantic_core-2.18.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd7df92f28d351bb9f12470f4c533cf03d1b52ec5a6e5c58c65b183055a60106"},
-    {file = "pydantic_core-2.18.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:80aea0ffeb1049336043d07799eace1c9602519fb3192916ff525b0287b2b1e4"},
-    {file = "pydantic_core-2.18.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:aaee40f25bba38132e655ffa3d1998a6d576ba7cf81deff8bfa189fb43fd2bbe"},
-    {file = "pydantic_core-2.18.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9128089da8f4fe73f7a91973895ebf2502539d627891a14034e45fb9e707e26d"},
-    {file = "pydantic_core-2.18.3-cp311-none-win32.whl", hash = "sha256:fec02527e1e03257aa25b1a4dcbe697b40a22f1229f5d026503e8b7ff6d2eda7"},
-    {file = "pydantic_core-2.18.3-cp311-none-win_amd64.whl", hash = "sha256:58ff8631dbab6c7c982e6425da8347108449321f61fe427c52ddfadd66642af7"},
-    {file = "pydantic_core-2.18.3-cp311-none-win_arm64.whl", hash = "sha256:3fc1c7f67f34c6c2ef9c213e0f2a351797cda98249d9ca56a70ce4ebcaba45f4"},
-    {file = "pydantic_core-2.18.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f0928cde2ae416a2d1ebe6dee324709c6f73e93494d8c7aea92df99aab1fc40f"},
-    {file = "pydantic_core-2.18.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0bee9bb305a562f8b9271855afb6ce00223f545de3d68560b3c1649c7c5295e9"},
-    {file = "pydantic_core-2.18.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e862823be114387257dacbfa7d78547165a85d7add33b446ca4f4fae92c7ff5c"},
-    {file = "pydantic_core-2.18.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6a36f78674cbddc165abab0df961b5f96b14461d05feec5e1f78da58808b97e7"},
-    {file = "pydantic_core-2.18.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba905d184f62e7ddbb7a5a751d8a5c805463511c7b08d1aca4a3e8c11f2e5048"},
-    {file = "pydantic_core-2.18.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7fdd362f6a586e681ff86550b2379e532fee63c52def1c666887956748eaa326"},
-    {file = "pydantic_core-2.18.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24b214b7ee3bd3b865e963dbed0f8bc5375f49449d70e8d407b567af3222aae4"},
-    {file = "pydantic_core-2.18.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:691018785779766127f531674fa82bb368df5b36b461622b12e176c18e119022"},
-    {file = "pydantic_core-2.18.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:60e4c625e6f7155d7d0dcac151edf5858102bc61bf959d04469ca6ee4e8381bd"},
-    {file = "pydantic_core-2.18.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a4e651e47d981c1b701dcc74ab8fec5a60a5b004650416b4abbef13db23bc7be"},
-    {file = "pydantic_core-2.18.3-cp312-none-win32.whl", hash = "sha256:ffecbb5edb7f5ffae13599aec33b735e9e4c7676ca1633c60f2c606beb17efc5"},
-    {file = "pydantic_core-2.18.3-cp312-none-win_amd64.whl", hash = "sha256:2c8333f6e934733483c7eddffdb094c143b9463d2af7e6bd85ebcb2d4a1b82c6"},
-    {file = "pydantic_core-2.18.3-cp312-none-win_arm64.whl", hash = "sha256:7a20dded653e516a4655f4c98e97ccafb13753987434fe7cf044aa25f5b7d417"},
-    {file = "pydantic_core-2.18.3-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:eecf63195be644b0396f972c82598cd15693550f0ff236dcf7ab92e2eb6d3522"},
-    {file = "pydantic_core-2.18.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2c44efdd3b6125419c28821590d7ec891c9cb0dff33a7a78d9d5c8b6f66b9702"},
-    {file = "pydantic_core-2.18.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e59fca51ffbdd1638b3856779342ed69bcecb8484c1d4b8bdb237d0eb5a45e2"},
-    {file = "pydantic_core-2.18.3-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:70cf099197d6b98953468461d753563b28e73cf1eade2ffe069675d2657ed1d5"},
-    {file = "pydantic_core-2.18.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:63081a49dddc6124754b32a3774331467bfc3d2bd5ff8f10df36a95602560361"},
-    {file = "pydantic_core-2.18.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:370059b7883485c9edb9655355ff46d912f4b03b009d929220d9294c7fd9fd60"},
-    {file = "pydantic_core-2.18.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a64faeedfd8254f05f5cf6fc755023a7e1606af3959cfc1a9285744cc711044"},
-    {file = "pydantic_core-2.18.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:19d2e725de0f90d8671f89e420d36c3dd97639b98145e42fcc0e1f6d492a46dc"},
-    {file = "pydantic_core-2.18.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:67bc078025d70ec5aefe6200ef094576c9d86bd36982df1301c758a9fff7d7f4"},
-    {file = "pydantic_core-2.18.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:adf952c3f4100e203cbaf8e0c907c835d3e28f9041474e52b651761dc248a3c0"},
-    {file = "pydantic_core-2.18.3-cp38-none-win32.whl", hash = "sha256:9a46795b1f3beb167eaee91736d5d17ac3a994bf2215a996aed825a45f897558"},
-    {file = "pydantic_core-2.18.3-cp38-none-win_amd64.whl", hash = "sha256:200ad4e3133cb99ed82342a101a5abf3d924722e71cd581cc113fe828f727fbc"},
-    {file = "pydantic_core-2.18.3-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:304378b7bf92206036c8ddd83a2ba7b7d1a5b425acafff637172a3aa72ad7083"},
-    {file = "pydantic_core-2.18.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c826870b277143e701c9ccf34ebc33ddb4d072612683a044e7cce2d52f6c3fef"},
-    {file = "pydantic_core-2.18.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e201935d282707394f3668380e41ccf25b5794d1b131cdd96b07f615a33ca4b1"},
-    {file = "pydantic_core-2.18.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5560dda746c44b48bf82b3d191d74fe8efc5686a9ef18e69bdabccbbb9ad9442"},
-    {file = "pydantic_core-2.18.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6b32c2a1f8032570842257e4c19288eba9a2bba4712af542327de9a1204faff8"},
-    {file = "pydantic_core-2.18.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:929c24e9dea3990bc8bcd27c5f2d3916c0c86f5511d2caa69e0d5290115344a9"},
-    {file = "pydantic_core-2.18.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1a8376fef60790152564b0eab376b3e23dd6e54f29d84aad46f7b264ecca943"},
-    {file = "pydantic_core-2.18.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dccf3ef1400390ddd1fb55bf0632209d39140552d068ee5ac45553b556780e06"},
-    {file = "pydantic_core-2.18.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:41dbdcb0c7252b58fa931fec47937edb422c9cb22528f41cb8963665c372caf6"},
-    {file = "pydantic_core-2.18.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:666e45cf071669fde468886654742fa10b0e74cd0fa0430a46ba6056b24fb0af"},
-    {file = "pydantic_core-2.18.3-cp39-none-win32.whl", hash = "sha256:f9c08cabff68704a1b4667d33f534d544b8a07b8e5d039c37067fceb18789e78"},
-    {file = "pydantic_core-2.18.3-cp39-none-win_amd64.whl", hash = "sha256:4afa5f5973e8572b5c0dcb4e2d4fda7890e7cd63329bd5cc3263a25c92ef0026"},
-    {file = "pydantic_core-2.18.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:77319771a026f7c7d29c6ebc623de889e9563b7087911b46fd06c044a12aa5e9"},
-    {file = "pydantic_core-2.18.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:df11fa992e9f576473038510d66dd305bcd51d7dd508c163a8c8fe148454e059"},
-    {file = "pydantic_core-2.18.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d531076bdfb65af593326ffd567e6ab3da145020dafb9187a1d131064a55f97c"},
-    {file = "pydantic_core-2.18.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d33ce258e4e6e6038f2b9e8b8a631d17d017567db43483314993b3ca345dcbbb"},
-    {file = "pydantic_core-2.18.3-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1f9cd7f5635b719939019be9bda47ecb56e165e51dd26c9a217a433e3d0d59a9"},
-    {file = "pydantic_core-2.18.3-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:cd4a032bb65cc132cae1fe3e52877daecc2097965cd3914e44fbd12b00dae7c5"},
-    {file = "pydantic_core-2.18.3-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:82f2718430098bcdf60402136c845e4126a189959d103900ebabb6774a5d9fdb"},
-    {file = "pydantic_core-2.18.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:c0037a92cf0c580ed14e10953cdd26528e8796307bb8bb312dc65f71547df04d"},
-    {file = "pydantic_core-2.18.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b95a0972fac2b1ff3c94629fc9081b16371dad870959f1408cc33b2f78ad347a"},
-    {file = "pydantic_core-2.18.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:a62e437d687cc148381bdd5f51e3e81f5b20a735c55f690c5be94e05da2b0d5c"},
-    {file = "pydantic_core-2.18.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b367a73a414bbb08507da102dc2cde0fa7afe57d09b3240ce82a16d608a7679c"},
-    {file = "pydantic_core-2.18.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ecce4b2360aa3f008da3327d652e74a0e743908eac306198b47e1c58b03dd2b"},
-    {file = "pydantic_core-2.18.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bd4435b8d83f0c9561a2a9585b1de78f1abb17cb0cef5f39bf6a4b47d19bafe3"},
-    {file = "pydantic_core-2.18.3-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:616221a6d473c5b9aa83fa8982745441f6a4a62a66436be9445c65f241b86c94"},
-    {file = "pydantic_core-2.18.3-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:7e6382ce89a92bc1d0c0c5edd51e931432202b9080dc921d8d003e616402efd1"},
-    {file = "pydantic_core-2.18.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:ff58f379345603d940e461eae474b6bbb6dab66ed9a851ecd3cb3709bf4dcf6a"},
-    {file = "pydantic_core-2.18.3.tar.gz", hash = "sha256:432e999088d85c8f36b9a3f769a8e2b57aabd817bbb729a90d1fe7f18f6f1f39"},
+    {file = "pydantic_core-2.20.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3acae97ffd19bf091c72df4d726d552c473f3576409b2a7ca36b2f535ffff4a3"},
+    {file = "pydantic_core-2.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:41f4c96227a67a013e7de5ff8f20fb496ce573893b7f4f2707d065907bffdbd6"},
+    {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f239eb799a2081495ea659d8d4a43a8f42cd1fe9ff2e7e436295c38a10c286a"},
+    {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53e431da3fc53360db73eedf6f7124d1076e1b4ee4276b36fb25514544ceb4a3"},
+    {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1f62b2413c3a0e846c3b838b2ecd6c7a19ec6793b2a522745b0869e37ab5bc1"},
+    {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d41e6daee2813ecceea8eda38062d69e280b39df793f5a942fa515b8ed67953"},
+    {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d482efec8b7dc6bfaedc0f166b2ce349df0011f5d2f1f25537ced4cfc34fd98"},
+    {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e93e1a4b4b33daed65d781a57a522ff153dcf748dee70b40c7258c5861e1768a"},
+    {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e7c4ea22b6739b162c9ecaaa41d718dfad48a244909fe7ef4b54c0b530effc5a"},
+    {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4f2790949cf385d985a31984907fecb3896999329103df4e4983a4a41e13e840"},
+    {file = "pydantic_core-2.20.1-cp310-none-win32.whl", hash = "sha256:5e999ba8dd90e93d57410c5e67ebb67ffcaadcea0ad973240fdfd3a135506250"},
+    {file = "pydantic_core-2.20.1-cp310-none-win_amd64.whl", hash = "sha256:512ecfbefef6dac7bc5eaaf46177b2de58cdf7acac8793fe033b24ece0b9566c"},
+    {file = "pydantic_core-2.20.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d2a8fa9d6d6f891f3deec72f5cc668e6f66b188ab14bb1ab52422fe8e644f312"},
+    {file = "pydantic_core-2.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:175873691124f3d0da55aeea1d90660a6ea7a3cfea137c38afa0a5ffabe37b88"},
+    {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37eee5b638f0e0dcd18d21f59b679686bbd18917b87db0193ae36f9c23c355fc"},
+    {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25e9185e2d06c16ee438ed39bf62935ec436474a6ac4f9358524220f1b236e43"},
+    {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:150906b40ff188a3260cbee25380e7494ee85048584998c1e66df0c7a11c17a6"},
+    {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ad4aeb3e9a97286573c03df758fc7627aecdd02f1da04516a86dc159bf70121"},
+    {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3f3ed29cd9f978c604708511a1f9c2fdcb6c38b9aae36a51905b8811ee5cbf1"},
+    {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0dae11d8f5ded51699c74d9548dcc5938e0804cc8298ec0aa0da95c21fff57b"},
+    {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:faa6b09ee09433b87992fb5a2859efd1c264ddc37280d2dd5db502126d0e7f27"},
+    {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9dc1b507c12eb0481d071f3c1808f0529ad41dc415d0ca11f7ebfc666e66a18b"},
+    {file = "pydantic_core-2.20.1-cp311-none-win32.whl", hash = "sha256:fa2fddcb7107e0d1808086ca306dcade7df60a13a6c347a7acf1ec139aa6789a"},
+    {file = "pydantic_core-2.20.1-cp311-none-win_amd64.whl", hash = "sha256:40a783fb7ee353c50bd3853e626f15677ea527ae556429453685ae32280c19c2"},
+    {file = "pydantic_core-2.20.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:595ba5be69b35777474fa07f80fc260ea71255656191adb22a8c53aba4479231"},
+    {file = "pydantic_core-2.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a4f55095ad087474999ee28d3398bae183a66be4823f753cd7d67dd0153427c9"},
+    {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9aa05d09ecf4c75157197f27cdc9cfaeb7c5f15021c6373932bf3e124af029f"},
+    {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e97fdf088d4b31ff4ba35db26d9cc472ac7ef4a2ff2badeabf8d727b3377fc52"},
+    {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc633a9fe1eb87e250b5c57d389cf28998e4292336926b0b6cdaee353f89a237"},
+    {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d573faf8eb7e6b1cbbcb4f5b247c60ca8be39fe2c674495df0eb4318303137fe"},
+    {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26dc97754b57d2fd00ac2b24dfa341abffc380b823211994c4efac7f13b9e90e"},
+    {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:33499e85e739a4b60c9dac710c20a08dc73cb3240c9a0e22325e671b27b70d24"},
+    {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bebb4d6715c814597f85297c332297c6ce81e29436125ca59d1159b07f423eb1"},
+    {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:516d9227919612425c8ef1c9b869bbbee249bc91912c8aaffb66116c0b447ebd"},
+    {file = "pydantic_core-2.20.1-cp312-none-win32.whl", hash = "sha256:469f29f9093c9d834432034d33f5fe45699e664f12a13bf38c04967ce233d688"},
+    {file = "pydantic_core-2.20.1-cp312-none-win_amd64.whl", hash = "sha256:035ede2e16da7281041f0e626459bcae33ed998cca6a0a007a5ebb73414ac72d"},
+    {file = "pydantic_core-2.20.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0827505a5c87e8aa285dc31e9ec7f4a17c81a813d45f70b1d9164e03a813a686"},
+    {file = "pydantic_core-2.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:19c0fa39fa154e7e0b7f82f88ef85faa2a4c23cc65aae2f5aea625e3c13c735a"},
+    {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa223cd1e36b642092c326d694d8bf59b71ddddc94cdb752bbbb1c5c91d833b"},
+    {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c336a6d235522a62fef872c6295a42ecb0c4e1d0f1a3e500fe949415761b8a19"},
+    {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7eb6a0587eded33aeefea9f916899d42b1799b7b14b8f8ff2753c0ac1741edac"},
+    {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70c8daf4faca8da5a6d655f9af86faf6ec2e1768f4b8b9d0226c02f3d6209703"},
+    {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9fa4c9bf273ca41f940bceb86922a7667cd5bf90e95dbb157cbb8441008482c"},
+    {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:11b71d67b4725e7e2a9f6e9c0ac1239bbc0c48cce3dc59f98635efc57d6dac83"},
+    {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:270755f15174fb983890c49881e93f8f1b80f0b5e3a3cc1394a255706cabd203"},
+    {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c81131869240e3e568916ef4c307f8b99583efaa60a8112ef27a366eefba8ef0"},
+    {file = "pydantic_core-2.20.1-cp313-none-win32.whl", hash = "sha256:b91ced227c41aa29c672814f50dbb05ec93536abf8f43cd14ec9521ea09afe4e"},
+    {file = "pydantic_core-2.20.1-cp313-none-win_amd64.whl", hash = "sha256:65db0f2eefcaad1a3950f498aabb4875c8890438bc80b19362cf633b87a8ab20"},
+    {file = "pydantic_core-2.20.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:4745f4ac52cc6686390c40eaa01d48b18997cb130833154801a442323cc78f91"},
+    {file = "pydantic_core-2.20.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a8ad4c766d3f33ba8fd692f9aa297c9058970530a32c728a2c4bfd2616d3358b"},
+    {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41e81317dd6a0127cabce83c0c9c3fbecceae981c8391e6f1dec88a77c8a569a"},
+    {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:04024d270cf63f586ad41fff13fde4311c4fc13ea74676962c876d9577bcc78f"},
+    {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eaad4ff2de1c3823fddf82f41121bdf453d922e9a238642b1dedb33c4e4f98ad"},
+    {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:26ab812fa0c845df815e506be30337e2df27e88399b985d0bb4e3ecfe72df31c"},
+    {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c5ebac750d9d5f2706654c638c041635c385596caf68f81342011ddfa1e5598"},
+    {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2aafc5a503855ea5885559eae883978c9b6d8c8993d67766ee73d82e841300dd"},
+    {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4868f6bd7c9d98904b748a2653031fc9c2f85b6237009d475b1008bfaeb0a5aa"},
+    {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aa2f457b4af386254372dfa78a2eda2563680d982422641a85f271c859df1987"},
+    {file = "pydantic_core-2.20.1-cp38-none-win32.whl", hash = "sha256:225b67a1f6d602de0ce7f6c1c3ae89a4aa25d3de9be857999e9124f15dab486a"},
+    {file = "pydantic_core-2.20.1-cp38-none-win_amd64.whl", hash = "sha256:6b507132dcfc0dea440cce23ee2182c0ce7aba7054576efc65634f080dbe9434"},
+    {file = "pydantic_core-2.20.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:b03f7941783b4c4a26051846dea594628b38f6940a2fdc0df00b221aed39314c"},
+    {file = "pydantic_core-2.20.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1eedfeb6089ed3fad42e81a67755846ad4dcc14d73698c120a82e4ccf0f1f9f6"},
+    {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:635fee4e041ab9c479e31edda27fcf966ea9614fff1317e280d99eb3e5ab6fe2"},
+    {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:77bf3ac639c1ff567ae3b47f8d4cc3dc20f9966a2a6dd2311dcc055d3d04fb8a"},
+    {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ed1b0132f24beeec5a78b67d9388656d03e6a7c837394f99257e2d55b461611"},
+    {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6514f963b023aeee506678a1cf821fe31159b925c4b76fe2afa94cc70b3222b"},
+    {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10d4204d8ca33146e761c79f83cc861df20e7ae9f6487ca290a97702daf56006"},
+    {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2d036c7187b9422ae5b262badb87a20a49eb6c5238b2004e96d4da1231badef1"},
+    {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9ebfef07dbe1d93efb94b4700f2d278494e9162565a54f124c404a5656d7ff09"},
+    {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6b9d9bb600328a1ce523ab4f454859e9d439150abb0906c5a1983c146580ebab"},
+    {file = "pydantic_core-2.20.1-cp39-none-win32.whl", hash = "sha256:784c1214cb6dd1e3b15dd8b91b9a53852aed16671cc3fbe4786f4f1db07089e2"},
+    {file = "pydantic_core-2.20.1-cp39-none-win_amd64.whl", hash = "sha256:d2fe69c5434391727efa54b47a1e7986bb0186e72a41b203df8f5b0a19a4f669"},
+    {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a45f84b09ac9c3d35dfcf6a27fd0634d30d183205230a0ebe8373a0e8cfa0906"},
+    {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d02a72df14dfdbaf228424573a07af10637bd490f0901cee872c4f434a735b94"},
+    {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2b27e6af28f07e2f195552b37d7d66b150adbaa39a6d327766ffd695799780f"},
+    {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084659fac3c83fd674596612aeff6041a18402f1e1bc19ca39e417d554468482"},
+    {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:242b8feb3c493ab78be289c034a1f659e8826e2233786e36f2893a950a719bb6"},
+    {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:38cf1c40a921d05c5edc61a785c0ddb4bed67827069f535d794ce6bcded919fc"},
+    {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e0bbdd76ce9aa5d4209d65f2b27fc6e5ef1312ae6c5333c26db3f5ade53a1e99"},
+    {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:254ec27fdb5b1ee60684f91683be95e5133c994cc54e86a0b0963afa25c8f8a6"},
+    {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:407653af5617f0757261ae249d3fba09504d7a71ab36ac057c938572d1bc9331"},
+    {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:c693e916709c2465b02ca0ad7b387c4f8423d1db7b4649c551f27a529181c5ad"},
+    {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b5ff4911aea936a47d9376fd3ab17e970cc543d1b68921886e7f64bd28308d1"},
+    {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:177f55a886d74f1808763976ac4efd29b7ed15c69f4d838bbd74d9d09cf6fa86"},
+    {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:964faa8a861d2664f0c7ab0c181af0bea66098b1919439815ca8803ef136fc4e"},
+    {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:4dd484681c15e6b9a977c785a345d3e378d72678fd5f1f3c0509608da24f2ac0"},
+    {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f6d6cff3538391e8486a431569b77921adfcdef14eb18fbf19b7c0a5294d4e6a"},
+    {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a6d511cc297ff0883bc3708b465ff82d7560193169a8b93260f74ecb0a5e08a7"},
+    {file = "pydantic_core-2.20.1.tar.gz", hash = "sha256:26ca695eeee5f9f1aeeb211ffc12f10bcb6f71e2989988fda61dabd65db878d4"},
 ]
 
 [package.dependencies]
@@ -1808,13 +1822,13 @@ telegram = ["requests"]
 
 [[package]]
 name = "typing-extensions"
-version = "4.12.0"
+version = "4.12.2"
 description = "Backported and Experimental Type Hints for Python 3.8+"
 optional = false
 python-versions = ">=3.8"
 files = [
-    {file = "typing_extensions-4.12.0-py3-none-any.whl", hash = "sha256:b349c66bea9016ac22978d800cfff206d5f9816951f12a7d0ec5578b0a819594"},
-    {file = "typing_extensions-4.12.0.tar.gz", hash = "sha256:8cbcdc8606ebcb0d95453ad7dc5065e6237b6aa230a31e81d0f440c30fed5fd8"},
+    {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"},
+    {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"},
 ]
 
 [[package]]
@@ -2017,4 +2031,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more
 [metadata]
 lock-version = "2.0"
 python-versions = "^3.9"
-content-hash = "45947f34e5309ce6a1aabb948da30f3a514bccffb6c28ffcaf0266c3190b0a57"
+content-hash = "68c182df5330d36985e088d6d87c5048c753dfdd3f23788cb76b6373ddb511b3"
diff --git a/pyproject.toml b/pyproject.toml
index df3596d..18ee5d5 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -2,7 +2,7 @@
 name = "cli-surf"
 version = "0.1.0"
 description = ""
-authors = ["ryansurf <your@email.com>"] # TODO: email
+authors = ["tadi <tadiguks@gmail.com>"] # TODO: email
 readme = "README.md"
 packages = [{ include = "src" }]
 
@@ -15,7 +15,7 @@ g4f = "0.3.1.9"
 geopy = "2.4.1"
 openmeteo-requests = "1.2.0"
 pandas = "2.2.2"
-pydantic = "2.7.2"
+pydantic = {extras = ["email"], version = "^2.8.2"}
 pydantic-settings = "2.2.1"
 python-dotenv = "1.0.1"
 requests = "2.32.3"
diff --git a/src/helper.py b/src/helper.py
index 01d1f77..daaf5b1 100644
--- a/src/helper.py
+++ b/src/helper.py
@@ -42,41 +42,48 @@ def arguments_dictionary(lat, long, city, args):
     return arguments
 
 
-def set_output_values(args, arguments):  # noqa
-    """
-    Takes a list of command line arguments(args)
-    and sets the appropritate values
-    in the arguments dictionary(show_wave = 1, etc).
-    Returns the arguments dict with the updated CLI args
-    """
-    if "hide_wave" in args or "hw" in args:
-        arguments["show_wave"] = 0
-    if "show_large_wave" in args or "slw" in args:
-        arguments["show_large_wave"] = 1
-    if "hide_uv" in args or "huv" in args:
-        arguments["show_uv"] = 0
-    if "hide_height" in args or "hh" in args:
-        arguments["show_height"] = 0
-    if "hide_direction" in args or "hdir" in args:
-        arguments["show_direction"] = 0
-    if "hide_period" in args or "hp" in args:
-        arguments["show_period"] = 0
-    if "hide_location" in args or "hl" in args:
-        arguments["show_city"] = 0
-    if "hide_date" in args or "hdate" in args:
-        arguments["show_date"] = 0
-    if "metric" in args or "m" in args:
-        arguments["unit"] = "metric"
-    if "json" in args or "j" in args:
-        arguments["json_output"] = 1
-    if "gpt" in args or "g" in args:
-        arguments["gpt"] = 1
-    if "show_air_temp" in args or "sat" in args:
-        arguments["show_air_temp"] = 1
-    if "show_wind_speed" in args or "sws" in args:
-        arguments["show_wind_speed"] = 1
-    if "show_wind_direction" in args or "swd" in args:
-        arguments["show_wind_direction"] = 1
+def set_output_values(args, arguments):
+    """
+    Takes a list of command line arguments (args)
+    and sets the appropriate values
+    in the arguments dictionary (show_wave = 1, etc).
+    Returns the arguments dict with the updated CLI args.
+    """
+    actions = {
+        "hide_wave": ("show_wave", 0),
+        "hw": ("show_wave", 0),
+        "show_large_wave": ("show_large_wave", 1),
+        "slw": ("show_large_wave", 1),
+        "hide_uv": ("show_uv", 0),
+        "huv": ("show_uv", 0),
+        "hide_height": ("show_height", 0),
+        "hh": ("show_height", 0),
+        "hide_direction": ("show_direction", 0),
+        "hdir": ("show_direction", 0),
+        "hide_period": ("show_period", 0),
+        "hp": ("show_period", 0),
+        "hide_location": ("show_city", 0),
+        "hl": ("show_city", 0),
+        "hide_date": ("show_date", 0),
+        "hdate": ("show_date", 0),
+        "metric": ("unit", "metric"),
+        "m": ("unit", "metric"),
+        "json": ("json_output", 1),
+        "j": ("json_output", 1),
+        "gpt": ("gpt", 1),
+        "g": ("gpt", 1),
+        "show_air_temp": ("show_air_temp", 1),
+        "sat": ("show_air_temp", 1),
+        "show_wind_speed": ("show_wind_speed", 1),
+        "sws": ("show_wind_speed", 1),
+        "show_wind_direction": ("show_wind_direction", 1),
+        "swd": ("show_wind_direction", 1),
+    }
+
+    for arg in args:
+        if arg in actions:
+            key, value = actions[arg]
+            arguments[key] = value
 
     return arguments
 

From 8c1851b06fc879b8c0773633b6445a10b0df009a Mon Sep 17 00:00:00 2001
From: GUKWAT <20095319@tafe.wa.edu.au>
Date: Sun, 21 Jul 2024 19:46:18 +0800
Subject: [PATCH 02/14] print_forecast function refactored

---
 src/helper.py | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/src/helper.py b/src/helper.py
index daaf5b1..113f874 100644
--- a/src/helper.py
+++ b/src/helper.py
@@ -148,15 +148,18 @@ def print_forecast(ocean, forecast):
     Takes in list of forecast data and prints
     """
     transposed = list(zip(*forecast))
+
     for day in transposed:
-        if ocean["show_date"] == 1:
-            print("Date: ", day[3])
-        if int(ocean["show_height"]) == 1:
-            print("Wave Height: ", day[0])
-        if int(ocean["show_direction"]) == 1:
-            print("Wave Direction: ", day[1])
-        if int(ocean["show_period"]) == 1:
-            print("Wave Period: ", day[2])
+        actions = {
+            "show_date": (3, "Date: "),
+            "show_height": (0, "Wave Height: "),
+            "show_direction": (1, "Wave Direction: "),
+            "show_period": (2, "Wave Period: ")
+        }
+
+        for key, (index, forecast_data) in actions.items():
+            if int(ocean.get(key, 0)) == 1:
+                print(forecast_data, day[index])
         print("\n")
 
 

From b38375a9bd27f9e2f47dbc73ff95d228a0998153 Mon Sep 17 00:00:00 2001
From: GUKWAT <20095319@tafe.wa.edu.au>
Date: Sun, 21 Jul 2024 20:13:45 +0800
Subject: [PATCH 03/14] fixed typo function seperate_args to separate_args

---
 src/cli.py    | 4 ++--
 src/helper.py | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/cli.py b/src/cli.py
index 191fb91..d8940ba 100644
--- a/src/cli.py
+++ b/src/cli.py
@@ -19,8 +19,8 @@ def run(lat=0, long=0):
     """
     Main function
     """
-    # Seperates the cli args into a list
-    args = helper.seperate_args(sys.argv)
+    # Separates the cli args into a list
+    args = helper.separate_args(sys.argv)
 
     #  return coordinates, lat, long, city
     location = api.seperate_args_and_get_location(args)
diff --git a/src/helper.py b/src/helper.py
index 113f874..6089657 100644
--- a/src/helper.py
+++ b/src/helper.py
@@ -88,9 +88,9 @@ def set_output_values(args, arguments):
     return arguments
 
 
-def seperate_args(args):
+def separate_args(args):
     """
-    Args are seperated by commas in input. Sereperat them and return list
+    Args are separated by commas in input. Separate them and return list
     """
     if len(args) > 1:
         new_args = args[1].split(",")

From 2ce2e6becaddb7fef697b28dc30143fe33f4f975 Mon Sep 17 00:00:00 2001
From: GUKWAT <20095319@tafe.wa.edu.au>
Date: Tue, 23 Jul 2024 15:05:35 +0800
Subject: [PATCH 04/14] print_ocean_data method refactored

---
 src/helper.py | 35 +++++++++++++++++++----------------
 1 file changed, 19 insertions(+), 16 deletions(-)

diff --git a/src/helper.py b/src/helper.py
index 6089657..81abde8 100644
--- a/src/helper.py
+++ b/src/helper.py
@@ -125,22 +125,25 @@ def print_location(city, show_city):
 
 def print_ocean_data(arguments_dict, ocean_data_dict):
     """
-    Prints ocean data(height, wave direction, period, etc)
-    """
-    if int(arguments_dict["show_uv"]) == 1:
-        print("UV index: ", ocean_data_dict["UV Index"])
-    if int(arguments_dict["show_height"]) == 1:
-        print("Wave Height: ", ocean_data_dict["Height"])
-    if int(arguments_dict["show_direction"]) == 1:
-        print("Wave Direction: ", ocean_data_dict["Swell Direction"])
-    if int(arguments_dict["show_period"]) == 1:
-        print("Wave Period: ", ocean_data_dict["Period"])
-    if int(arguments_dict["show_air_temp"]) == 1:
-        print("Air Temp: ", ocean_data_dict["Air Temperature"])
-    if int(arguments_dict["show_wind_speed"]) == 1:
-        print("Wind Speed: ", ocean_data_dict["Wind Speed"])
-    if int(arguments_dict["show_wind_direction"]) == 1:
-        print("Wind Direction: ", ocean_data_dict["Wind Direction"])
+    Prints ocean data (height, wave direction, period, etc.)
+    """
+    display_mapping = {
+        "show_uv": ("UV Index", "UV index: "),
+        "show_height": ("Height", "Wave Height: "),
+        "show_direction": ("Swell Direction", "Wave Direction: "),
+        "show_period": ("Period", "Wave Period: "),
+        "show_air_temp": ("Air Temperature", "Air Temp: "),
+        "show_wind_speed": ("Wind Speed", "Wind Speed: "),
+        "show_wind_direction": ("Wind Direction", "Wind Direction: ")
+    }
+
+    for key, (data_key, label) in display_mapping.items():
+        if int(arguments_dict.get(key, 0)) == 1:
+            value = ocean_data_dict.get(data_key)
+            if value is not None:
+                print(f"{label} {value}")
+            else:
+                print(f"{label} None")
 
 
 def print_forecast(ocean, forecast):

From 5105fd627d1eca7abdd5294d59cae36803c42a3f Mon Sep 17 00:00:00 2001
From: GUKWAT <20095319@tafe.wa.edu.au>
Date: Sat, 27 Jul 2024 09:36:44 +0800
Subject: [PATCH 05/14] test added for print location

---
 src/helper.py        |  4 ++--
 tests/test_helper.py | 14 +++++++++++++-
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/src/helper.py b/src/helper.py
index 81abde8..4a04edb 100644
--- a/src/helper.py
+++ b/src/helper.py
@@ -123,7 +123,7 @@ def print_location(city, show_city):
         print("\n")
 
 
-def print_ocean_data(arguments_dict, ocean_data_dict):
+def print_ocean_data(arguments_dict, ocean_data):
     """
     Prints ocean data (height, wave direction, period, etc.)
     """
@@ -139,7 +139,7 @@ def print_ocean_data(arguments_dict, ocean_data_dict):
 
     for key, (data_key, label) in display_mapping.items():
         if int(arguments_dict.get(key, 0)) == 1:
-            value = ocean_data_dict.get(data_key)
+            value = ocean_data.get(data_key)
             if value is not None:
                 print(f"{label} {value}")
             else:
diff --git a/tests/test_helper.py b/tests/test_helper.py
index db4acf6..bd8c326 100644
--- a/tests/test_helper.py
+++ b/tests/test_helper.py
@@ -5,9 +5,10 @@
 """
 
 import io
+import sys
 from unittest.mock import patch
 
-from src.helper import extract_decimal
+from src.helper import extract_decimal, print_location
 
 
 def test_invalid_input():
@@ -27,3 +28,14 @@ def test_default_input():
     """
     decimal = extract_decimal([])
     assert 1 == decimal
+
+
+def test_print_location():
+    city = "Perth"
+    show_city = 1
+    captured_output = io.StringIO()
+    sys.stdout = captured_output
+    print_location(city, show_city)
+    sys.stdout = sys.__stdout__
+    expected_output = "Location: Perth"
+    assert captured_output.getvalue().strip() == expected_output.strip()

From 2f8ecc739dedf4f56d27f1bc6f844bec4a947c50 Mon Sep 17 00:00:00 2001
From: GUKWAT <20095319@tafe.wa.edu.au>
Date: Sat, 27 Jul 2024 09:45:51 +0800
Subject: [PATCH 06/14] changes made to the print_location function for the
 unit test to pass

---
 src/helper.py | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/helper.py b/src/helper.py
index 4a04edb..42b8ea4 100644
--- a/src/helper.py
+++ b/src/helper.py
@@ -119,8 +119,9 @@ def print_location(city, show_city):
     Prints location
     """
     if int(show_city) == 1:
-        print("Location: ", city)
-        print("\n")
+        print("Location:", city)
+    else:
+        print("Location unknown")
 
 
 def print_ocean_data(arguments_dict, ocean_data):

From 0066ff3fb5c8d6f5e3b04162c2113a5a42a096e9 Mon Sep 17 00:00:00 2001
From: GUKWAT <20095319@tafe.wa.edu.au>
Date: Sun, 28 Jul 2024 11:58:49 +0800
Subject: [PATCH 07/14] test for set output values created

---
 tests/test_helper.py | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/tests/test_helper.py b/tests/test_helper.py
index bd8c326..f7548c8 100644
--- a/tests/test_helper.py
+++ b/tests/test_helper.py
@@ -8,7 +8,7 @@
 import sys
 from unittest.mock import patch
 
-from src.helper import extract_decimal, print_location
+from src.helper import extract_decimal, print_location, set_output_values
 
 
 def test_invalid_input():
@@ -39,3 +39,10 @@ def test_print_location():
     sys.stdout = sys.__stdout__
     expected_output = "Location: Perth"
     assert captured_output.getvalue().strip() == expected_output.strip()
+
+
+def test_set_output_values():
+    args = ['hw', 'show_large_wave', 'huv']
+    arguments = {}
+    expected = {"show_wave": 0, "show_large_wave": 1, "show_uv": 0}
+    assert set_output_values(args, arguments) == expected

From 111aab03644e8b23a288037b4534fe586adee346 Mon Sep 17 00:00:00 2001
From: GUKWAT <20095319@tafe.wa.edu.au>
Date: Mon, 29 Jul 2024 08:55:32 +0800
Subject: [PATCH 08/14] print_ocean_data test created

---
 tests/test_helper.py | 37 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/tests/test_helper.py b/tests/test_helper.py
index f7548c8..720087e 100644
--- a/tests/test_helper.py
+++ b/tests/test_helper.py
@@ -6,9 +6,10 @@
 
 import io
 import sys
+from io import StringIO
 from unittest.mock import patch
 
-from src.helper import extract_decimal, print_location, set_output_values
+from src.helper import extract_decimal, print_location, set_output_values, print_ocean_data
 
 
 def test_invalid_input():
@@ -46,3 +47,37 @@ def test_set_output_values():
     arguments = {}
     expected = {"show_wave": 0, "show_large_wave": 1, "show_uv": 0}
     assert set_output_values(args, arguments) == expected
+
+
+def test_print_ocean_data():
+    arguments_dict = {
+        "show_uv": "1",
+        "show_height": "1",
+        "show_direction": "1",
+        "show_period": "0",
+        "show_air_temp": "1",
+        "show_wind_speed": "1",
+        "show_wind_direction": "0"
+    }
+
+    ocean_data = {
+        "UV Index": 5,
+        "Height": 2.5,
+        "Swell Direction": "NE",
+        "Air Temperature": 25,
+        "Wind Speed": 15
+    }
+
+    expected_output = (
+        "UV index: 5\n"
+        "Wave Height: 2.5\n"
+        "Wave Direction: NE\n"
+        "Air Temp: 25\n"
+        "Wind Speed: 15\n"
+    )
+
+    captured_output = StringIO()
+    sys.stdout = captured_output
+    print_ocean_data(arguments_dict, ocean_data)
+    sys.stdout = sys.__stdout__
+    assert captured_output.getvalue() == expected_output

From bf310f688b1ad5005857226ea6b2aacb49280b76 Mon Sep 17 00:00:00 2001
From: GUKWAT <20095319@tafe.wa.edu.au>
Date: Mon, 29 Jul 2024 09:00:07 +0800
Subject: [PATCH 09/14] print ocean data function modified

---
 src/helper.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/helper.py b/src/helper.py
index 42b8ea4..c2277bc 100644
--- a/src/helper.py
+++ b/src/helper.py
@@ -142,7 +142,7 @@ def print_ocean_data(arguments_dict, ocean_data):
         if int(arguments_dict.get(key, 0)) == 1:
             value = ocean_data.get(data_key)
             if value is not None:
-                print(f"{label} {value}")
+                print(f"{label}{value}")
             else:
                 print(f"{label} None")
 

From acec7954654b8316d504f3fc349f85c2e38f863a Mon Sep 17 00:00:00 2001
From: GUKWAT <20095319@tafe.wa.edu.au>
Date: Mon, 29 Jul 2024 14:04:02 +0800
Subject: [PATCH 10/14] helper file formatted

---
 src/helper.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/helper.py b/src/helper.py
index c2277bc..497bb7b 100644
--- a/src/helper.py
+++ b/src/helper.py
@@ -135,7 +135,7 @@ def print_ocean_data(arguments_dict, ocean_data):
         "show_period": ("Period", "Wave Period: "),
         "show_air_temp": ("Air Temperature", "Air Temp: "),
         "show_wind_speed": ("Wind Speed", "Wind Speed: "),
-        "show_wind_direction": ("Wind Direction", "Wind Direction: ")
+        "show_wind_direction": ("Wind Direction", "Wind Direction: "),
     }
 
     for key, (data_key, label) in display_mapping.items():
@@ -158,7 +158,7 @@ def print_forecast(ocean, forecast):
             "show_date": (3, "Date: "),
             "show_height": (0, "Wave Height: "),
             "show_direction": (1, "Wave Direction: "),
-            "show_period": (2, "Wave Period: ")
+            "show_period": (2, "Wave Period: "),
         }
 
         for key, (index, forecast_data) in actions.items():

From 02c421ac6107f21334b4531b7a3274ec929e0262 Mon Sep 17 00:00:00 2001
From: GUKWAT <20095319@tafe.wa.edu.au>
Date: Mon, 29 Jul 2024 14:29:35 +0800
Subject: [PATCH 11/14] formatted helper.py

---
 tests/test_helper.py | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/tests/test_helper.py b/tests/test_helper.py
index 720087e..75a5e72 100644
--- a/tests/test_helper.py
+++ b/tests/test_helper.py
@@ -9,7 +9,13 @@
 from io import StringIO
 from unittest.mock import patch
 
-from src.helper import extract_decimal, print_location, set_output_values, print_ocean_data
+from src.helper import (
+    extract_decimal,
+    print_forecast,
+    print_location,
+    print_ocean_data,
+    set_output_values,
+)
 
 
 def test_invalid_input():
@@ -32,6 +38,7 @@ def test_default_input():
 
 
 def test_print_location():
+
     city = "Perth"
     show_city = 1
     captured_output = io.StringIO()
@@ -43,7 +50,7 @@ def test_print_location():
 
 
 def test_set_output_values():
-    args = ['hw', 'show_large_wave', 'huv']
+    args = ["hw", "show_large_wave", "huv"]
     arguments = {}
     expected = {"show_wave": 0, "show_large_wave": 1, "show_uv": 0}
     assert set_output_values(args, arguments) == expected
@@ -57,7 +64,7 @@ def test_print_ocean_data():
         "show_period": "0",
         "show_air_temp": "1",
         "show_wind_speed": "1",
-        "show_wind_direction": "0"
+        "show_wind_direction": "0",
     }
 
     ocean_data = {
@@ -65,7 +72,7 @@ def test_print_ocean_data():
         "Height": 2.5,
         "Swell Direction": "NE",
         "Air Temperature": 25,
-        "Wind Speed": 15
+        "Wind Speed": 15,
     }
 
     expected_output = (

From e3f694674f4933eb18c0ab7852d89a77e85fe154 Mon Sep 17 00:00:00 2001
From: GUKWAT <20095319@tafe.wa.edu.au>
Date: Fri, 2 Aug 2024 00:37:34 +0800
Subject: [PATCH 12/14] docstrings modified for helper.py and test_helper.py

---
 src/helper.py        | 41 +++++++++++++++++++++++++++++++++++++----
 tests/test_helper.py | 14 +++++++++++++-
 2 files changed, 50 insertions(+), 5 deletions(-)

diff --git a/src/helper.py b/src/helper.py
index 497bb7b..3570c43 100644
--- a/src/helper.py
+++ b/src/helper.py
@@ -116,7 +116,16 @@ def get_forecast_days(args):
 
 def print_location(city, show_city):
     """
-    Prints location
+    Prints the location only if `show_city` is equal to 1.
+    Prints "Location unknown" if the value is not 1.
+
+    Args:
+        city (str): The name of the city to be printed.
+        show_city (int): An integer that determines whether the city
+                         should be printed (1) or not (any other value).
+
+    Returns:
+        None
     """
     if int(show_city) == 1:
         print("Location:", city)
@@ -127,6 +136,20 @@ def print_location(city, show_city):
 def print_ocean_data(arguments_dict, ocean_data):
     """
     Prints ocean data (height, wave direction, period, etc.)
+
+    Args:
+        arguments_dict (dict): Dictionary with keys such as "show_uv", "show_height",
+                               "show_direction", "show_period", "show_air_temp",
+                               "show_wind_speed", and "show_wind_direction". Values
+                               should be 1 to display the corresponding data; If the value
+                               is not equal to 1 data will not be displayed.
+
+        ocean_data (dict): Dictionary containing ocean data. Keys include
+                           "UV Index", "Height", "Swell Direction", "Period",
+                           "Air Temperature", "Wind Speed", and "Wind Direction".
+
+    Returns:
+        None
     """
     display_mapping = {
         "show_uv": ("UV Index", "UV index: "),
@@ -144,12 +167,23 @@ def print_ocean_data(arguments_dict, ocean_data):
             if value is not None:
                 print(f"{label}{value}")
             else:
-                print(f"{label} None")
+                print(f"{label} Not available")
 
 
 def print_forecast(ocean, forecast):
     """
-    Takes in list of forecast data and prints
+    Prints forecast data based on flags in the ocean dictionary.
+
+    Args:
+        ocean: Dictionary with keys like "show_date", "show_height",
+               "show_direction", and "show_period" indicating which data
+               to display (1 to show, otherwise hide).
+
+        forecast: List of tuples where each tuple contains
+                  (date, wave height, wave direction, wave period).
+
+    Returns:
+        None
     """
     transposed = list(zip(*forecast))
 
@@ -166,7 +200,6 @@ def print_forecast(ocean, forecast):
                 print(forecast_data, day[index])
         print("\n")
 
-
 def extract_decimal(args):
     """
     Function to extract decimal value from command-line arguments
diff --git a/tests/test_helper.py b/tests/test_helper.py
index 75a5e72..8fa19c7 100644
--- a/tests/test_helper.py
+++ b/tests/test_helper.py
@@ -11,7 +11,6 @@
 
 from src.helper import (
     extract_decimal,
-    print_forecast,
     print_location,
     print_ocean_data,
     set_output_values,
@@ -38,6 +37,10 @@ def test_default_input():
 
 
 def test_print_location():
+    """
+    Test the print_location function to check if the city name is printed
+    when the show_city parameter is 1
+    """
 
     city = "Perth"
     show_city = 1
@@ -50,6 +53,11 @@ def test_print_location():
 
 
 def test_set_output_values():
+    """
+    Tests the set_output_values function to verify that it correctly
+    sets values in the output dictionary based on the provided list of
+    input arguments (args)
+    """
     args = ["hw", "show_large_wave", "huv"]
     arguments = {}
     expected = {"show_wave": 0, "show_large_wave": 1, "show_uv": 0}
@@ -57,6 +65,10 @@ def test_set_output_values():
 
 
 def test_print_ocean_data():
+    """
+    Test that checks if the print_ocean_data function prints all
+    the ocean data
+    """
     arguments_dict = {
         "show_uv": "1",
         "show_height": "1",

From 8fbb0c2d6d2fb7540d1c1322cfe38d7c63d2f9d8 Mon Sep 17 00:00:00 2001
From: GUKWAT <20095319@tafe.wa.edu.au>
Date: Fri, 2 Aug 2024 00:54:49 +0800
Subject: [PATCH 13/14] test created for print_location when show city is 0

---
 tests/test_helper.py | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/tests/test_helper.py b/tests/test_helper.py
index 8fa19c7..7b9bc0d 100644
--- a/tests/test_helper.py
+++ b/tests/test_helper.py
@@ -51,6 +51,20 @@ def test_print_location():
     expected_output = "Location: Perth"
     assert captured_output.getvalue().strip() == expected_output.strip()
 
+def test_print_location_show_city_0():
+    """
+    Test the print_location function to check if the city name prints
+    location not available when the show_city parameter is 0
+    """
+    city = "Perth"
+    show_city = 0
+    captured_output = io.StringIO()
+    sys.stdout = captured_output
+    print_location(city, show_city)
+    sys.stdout = sys.__stdout__
+    expected_output = "Not Available"
+    assert captured_output.getvalue().strip() == expected_output.strip()
+
 
 def test_set_output_values():
     """

From b6bcce9077b770616bb2a5ccfb21c65f6ad582ec Mon Sep 17 00:00:00 2001
From: GUKWAT <20095319@tafe.wa.edu.au>
Date: Fri, 2 Aug 2024 00:56:59 +0800
Subject: [PATCH 14/14] print location function condition enhanced

---
 src/helper.py | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/src/helper.py b/src/helper.py
index 3570c43..9a2996e 100644
--- a/src/helper.py
+++ b/src/helper.py
@@ -44,9 +44,7 @@ def arguments_dictionary(lat, long, city, args):
 
 def set_output_values(args, arguments):
     """
-    Takes a list of command line arguments (args)
-    and sets the appropriate values
-    in the arguments dictionary (show_wave = 1, etc).
+    Takes a list of command line (show_wave = 1, etc).
     Returns the arguments dict with the updated CLI args.
     """
     actions = {
@@ -130,7 +128,7 @@ def print_location(city, show_city):
     if int(show_city) == 1:
         print("Location:", city)
     else:
-        print("Location unknown")
+        print("Not Available")
 
 
 def print_ocean_data(arguments_dict, ocean_data):