Zai commited on
Commit
e4456e8
·
1 Parent(s): 2d913c3

before testing charts

Browse files
__pycache__/processor.cpython-311.pyc CHANGED
Binary files a/__pycache__/processor.cpython-311.pyc and b/__pycache__/processor.cpython-311.pyc differ
 
__pycache__/slide.cpython-311.pyc CHANGED
Binary files a/__pycache__/slide.cpython-311.pyc and b/__pycache__/slide.cpython-311.pyc differ
 
__pycache__/utils.cpython-311.pyc ADDED
Binary file (615 Bytes). View file
 
app.py CHANGED
@@ -1,6 +1,7 @@
1
  import streamlit as st
2
  from slide import Slide
3
  from processor import Processor
 
4
 
5
  st.title("Carching Presentation")
6
  slide = Slide()
@@ -14,9 +15,15 @@ if uploaded_file is not None:
14
  slide_url = slide.create_presentation("Carching Presentation Testing")
15
  st.write(f"Here's the new slide url {slide_url}")
16
 
17
- slide.change_text("tot_imp", processor.total_impressions)
18
 
 
 
 
19
 
 
 
 
 
20
  st.write(f"Total Impressions: {processor.total_impressions}")
21
  st.write(f"Actual Impressions Percentage: {processor.actual_impressions_percentage}")
22
  st.write(f"Target Impressions Percentage: {processor.target_impressions_percentage}")
 
1
  import streamlit as st
2
  from slide import Slide
3
  from processor import Processor
4
+ from utils import thousand_to_k,thousand_comma_separated
5
 
6
  st.title("Carching Presentation")
7
  slide = Slide()
 
15
  slide_url = slide.create_presentation("Carching Presentation Testing")
16
  st.write(f"Here's the new slide url {slide_url}")
17
 
 
18
 
19
+ slide.change_text("tot_imp", thousand_to_k(processor.total_impressions))
20
+ slide.change_text("target_imp", processor.target_impressions_percentage)
21
+ slide.change_text("actual_imp", processor.actual_impressions_percentage)
22
 
23
+ slide.change_text("dist km", thousand_comma_separated(processor.distance_travelled))
24
+ slide.change_text("otr hrs","something ")
25
+
26
+ st.write("Data loaded successfully!")
27
  st.write(f"Total Impressions: {processor.total_impressions}")
28
  st.write(f"Actual Impressions Percentage: {processor.actual_impressions_percentage}")
29
  st.write(f"Target Impressions Percentage: {processor.target_impressions_percentage}")
notebook.ipynb CHANGED
@@ -732,16 +732,219 @@
732
  "execution_count": 31
733
  },
734
  {
735
- "metadata": {},
 
 
 
 
 
736
  "cell_type": "code",
737
- "outputs": [],
738
- "execution_count": null,
739
  "source": [
740
  "# g1b8874900bb_0_328\n",
741
  "\n",
742
  "# g1b8874900bb_0_431"
743
  ],
744
- "id": "2ccd27e09c5fdfaa"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
745
  }
746
  ],
747
  "metadata": {
 
732
  "execution_count": 31
733
  },
734
  {
735
+ "metadata": {
736
+ "ExecuteTime": {
737
+ "end_time": "2024-11-18T19:54:04.870419Z",
738
+ "start_time": "2024-11-18T19:54:04.861074Z"
739
+ }
740
+ },
741
  "cell_type": "code",
 
 
742
  "source": [
743
  "# g1b8874900bb_0_328\n",
744
  "\n",
745
  "# g1b8874900bb_0_431"
746
  ],
747
+ "id": "2ccd27e09c5fdfaa",
748
+ "outputs": [],
749
+ "execution_count": 32
750
+ },
751
+ {
752
+ "metadata": {
753
+ "ExecuteTime": {
754
+ "end_time": "2024-11-18T19:56:52.687860Z",
755
+ "start_time": "2024-11-18T19:56:52.669573Z"
756
+ }
757
+ },
758
+ "cell_type": "code",
759
+ "source": "from services import slides_service, sheets_service, drive_service",
760
+ "id": "9400ee6e2759ac5",
761
+ "outputs": [],
762
+ "execution_count": 33
763
+ },
764
+ {
765
+ "metadata": {
766
+ "ExecuteTime": {
767
+ "end_time": "2024-11-18T19:59:22.153724Z",
768
+ "start_time": "2024-11-18T19:59:16.529074Z"
769
+ }
770
+ },
771
+ "cell_type": "code",
772
+ "source": [
773
+ "# Step 1: Create a Spreadsheet with Data\n",
774
+ "spreadsheet_body = {\n",
775
+ " \"properties\": {\"title\": \"Actual vs Target Data\"}\n",
776
+ "}\n",
777
+ "spreadsheet = sheets_service.spreadsheets().create(body=spreadsheet_body).execute()\n",
778
+ "spreadsheet_id = spreadsheet['spreadsheetId']\n",
779
+ "print(f\"Spreadsheet ID: {spreadsheet_id}\")\n",
780
+ "\n",
781
+ "# Populate with Data\n",
782
+ "data = [\n",
783
+ " [\"Metric\", \"Value\"],\n",
784
+ " [\"Expected\", 100.0],\n",
785
+ " [\"Actual\", 101.1],\n",
786
+ "]\n",
787
+ "data_range = \"Sheet1!A1:B3\"\n",
788
+ "value_range_body = {\"values\": data}\n",
789
+ "sheets_service.spreadsheets().values().update(\n",
790
+ " spreadsheetId=spreadsheet_id,\n",
791
+ " range=data_range,\n",
792
+ " valueInputOption=\"RAW\",\n",
793
+ " body=value_range_body\n",
794
+ ").execute()\n",
795
+ "\n",
796
+ "# Step 2: Add a Horizontal Bar Chart\n",
797
+ "chart_body = {\n",
798
+ " \"requests\": [\n",
799
+ " {\n",
800
+ " \"addChart\": {\n",
801
+ " \"chart\": {\n",
802
+ " \"spec\": {\n",
803
+ " \"title\": \"Actual vs Target\",\n",
804
+ " \"basicChart\": {\n",
805
+ " \"chartType\": \"BAR\",\n",
806
+ " \"legendPosition\": \"BOTTOM_LEGEND\",\n",
807
+ " \"axis\": [\n",
808
+ " {\"position\": \"BOTTOM_AXIS\", \"title\": \"Percentage\"},\n",
809
+ " {\"position\": \"LEFT_AXIS\", \"title\": \"Metric\"},\n",
810
+ " ],\n",
811
+ " \"domains\": [\n",
812
+ " {\n",
813
+ " \"domain\": {\n",
814
+ " \"sourceRange\": {\n",
815
+ " \"sources\": [\n",
816
+ " {\n",
817
+ " \"sheetId\": 0,\n",
818
+ " \"startRowIndex\": 1,\n",
819
+ " \"endRowIndex\": 3,\n",
820
+ " \"startColumnIndex\": 0,\n",
821
+ " \"endColumnIndex\": 1,\n",
822
+ " }\n",
823
+ " ]\n",
824
+ " }\n",
825
+ " }\n",
826
+ " }\n",
827
+ " ],\n",
828
+ " \"series\": [\n",
829
+ " {\n",
830
+ " \"series\": {\n",
831
+ " \"sourceRange\": {\n",
832
+ " \"sources\": [\n",
833
+ " {\n",
834
+ " \"sheetId\": 0,\n",
835
+ " \"startRowIndex\": 1,\n",
836
+ " \"endRowIndex\": 3,\n",
837
+ " \"startColumnIndex\": 1,\n",
838
+ " \"endColumnIndex\": 2,\n",
839
+ " }\n",
840
+ " ]\n",
841
+ " }\n",
842
+ " },\n",
843
+ " \"targetAxis\": \"BOTTOM_AXIS\",\n",
844
+ " }\n",
845
+ " ],\n",
846
+ " \"stackedType\": \"STACKED\",\n",
847
+ " },\n",
848
+ " },\n",
849
+ " \"position\": {\"overlayPosition\": {}},\n",
850
+ " }\n",
851
+ " }\n",
852
+ " }\n",
853
+ " ]\n",
854
+ "}\n",
855
+ "\n",
856
+ "sheets_service.spreadsheets().batchUpdate(spreadsheetId=spreadsheet_id, body=chart_body).execute()\n",
857
+ "print(\"Chart created in Google Sheets\")\n",
858
+ "\n",
859
+ "# Step 3: Create a Google Slide Presentation\n",
860
+ "presentation = slides_service.presentations().create(body={\"title\": \"Actual vs Target Chart\"}).execute()\n",
861
+ "presentation_id = presentation['presentationId']\n",
862
+ "print(f\"Presentation ID: {presentation_id}\")\n",
863
+ "\n",
864
+ "# Step 4: Embed Chart into Google Slides\n",
865
+ "slide_id = slides_service.presentations().pages().create(\n",
866
+ " presentationId=presentation_id,\n",
867
+ " body={\"slideLayoutReference\": {\"predefinedLayout\": \"BLANK\"}}\n",
868
+ ").execute()[\"objectId\"]\n",
869
+ "\n",
870
+ "embedded_chart_request = {\n",
871
+ " \"requests\": [\n",
872
+ " {\n",
873
+ " \"createSheetsChart\": {\n",
874
+ " \"objectId\": \"ChartObjectID\",\n",
875
+ " \"spreadsheetId\": spreadsheet_id,\n",
876
+ " \"chartId\": 1, # First chart added to spreadsheet\n",
877
+ " \"linkingMode\": \"LINKED\",\n",
878
+ " \"elementProperties\": {\n",
879
+ " \"pageObjectId\": slide_id,\n",
880
+ " \"size\": {\n",
881
+ " \"height\": {\"magnitude\": 4000000, \"unit\": \"EMU\"},\n",
882
+ " \"width\": {\"magnitude\": 6000000, \"unit\": \"EMU\"},\n",
883
+ " },\n",
884
+ " \"transform\": {\n",
885
+ " \"scaleX\": 1,\n",
886
+ " \"scaleY\": 1,\n",
887
+ " \"translateX\": 1000000,\n",
888
+ " \"translateY\": 1000000,\n",
889
+ " \"unit\": \"EMU\",\n",
890
+ " },\n",
891
+ " },\n",
892
+ " }\n",
893
+ " }\n",
894
+ " ]\n",
895
+ "}\n",
896
+ "\n",
897
+ "slides_service.presentations().batchUpdate(\n",
898
+ " presentationId=presentation_id, body=embedded_chart_request\n",
899
+ ").execute()\n",
900
+ "print(f\"Chart added to Google Slides presentation {presentation_id}\")\n"
901
+ ],
902
+ "id": "753beb465e23c43b",
903
+ "outputs": [
904
+ {
905
+ "name": "stdout",
906
+ "output_type": "stream",
907
+ "text": [
908
+ "Spreadsheet ID: 1TNbkbcuGN4xUgi-TxVkPPyBKc0JM-_5A8Si_GDtgK60\n",
909
+ "Chart created in Google Sheets\n"
910
+ ]
911
+ },
912
+ {
913
+ "ename": "SSLEOFError",
914
+ "evalue": "EOF occurred in violation of protocol (_ssl.c:2427)",
915
+ "output_type": "error",
916
+ "traceback": [
917
+ "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m",
918
+ "\u001B[0;31mSSLEOFError\u001B[0m Traceback (most recent call last)",
919
+ "Cell \u001B[0;32mIn[35], line 88\u001B[0m\n\u001B[1;32m 85\u001B[0m \u001B[38;5;28mprint\u001B[39m(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mChart created in Google Sheets\u001B[39m\u001B[38;5;124m\"\u001B[39m)\n\u001B[1;32m 87\u001B[0m \u001B[38;5;66;03m# Step 3: Create a Google Slide Presentation\u001B[39;00m\n\u001B[0;32m---> 88\u001B[0m presentation \u001B[38;5;241m=\u001B[39m slides_service\u001B[38;5;241m.\u001B[39mpresentations()\u001B[38;5;241m.\u001B[39mcreate(body\u001B[38;5;241m=\u001B[39m{\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mtitle\u001B[39m\u001B[38;5;124m\"\u001B[39m: \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mActual vs Target Chart\u001B[39m\u001B[38;5;124m\"\u001B[39m})\u001B[38;5;241m.\u001B[39mexecute()\n\u001B[1;32m 89\u001B[0m presentation_id \u001B[38;5;241m=\u001B[39m presentation[\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mpresentationId\u001B[39m\u001B[38;5;124m'\u001B[39m]\n\u001B[1;32m 90\u001B[0m \u001B[38;5;28mprint\u001B[39m(\u001B[38;5;124mf\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mPresentation ID: \u001B[39m\u001B[38;5;132;01m{\u001B[39;00mpresentation_id\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m\"\u001B[39m)\n",
920
+ "File \u001B[0;32m/opt/anaconda3/lib/python3.11/site-packages/googleapiclient/_helpers.py:130\u001B[0m, in \u001B[0;36mpositional.<locals>.positional_decorator.<locals>.positional_wrapper\u001B[0;34m(*args, **kwargs)\u001B[0m\n\u001B[1;32m 128\u001B[0m \u001B[38;5;28;01melif\u001B[39;00m positional_parameters_enforcement \u001B[38;5;241m==\u001B[39m POSITIONAL_WARNING:\n\u001B[1;32m 129\u001B[0m logger\u001B[38;5;241m.\u001B[39mwarning(message)\n\u001B[0;32m--> 130\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m wrapped(\u001B[38;5;241m*\u001B[39margs, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs)\n",
921
+ "File \u001B[0;32m/opt/anaconda3/lib/python3.11/site-packages/googleapiclient/http.py:923\u001B[0m, in \u001B[0;36mHttpRequest.execute\u001B[0;34m(self, http, num_retries)\u001B[0m\n\u001B[1;32m 920\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mheaders[\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mcontent-length\u001B[39m\u001B[38;5;124m\"\u001B[39m] \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mstr\u001B[39m(\u001B[38;5;28mlen\u001B[39m(\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mbody))\n\u001B[1;32m 922\u001B[0m \u001B[38;5;66;03m# Handle retries for server-side errors.\u001B[39;00m\n\u001B[0;32m--> 923\u001B[0m resp, content \u001B[38;5;241m=\u001B[39m _retry_request(\n\u001B[1;32m 924\u001B[0m http,\n\u001B[1;32m 925\u001B[0m num_retries,\n\u001B[1;32m 926\u001B[0m \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mrequest\u001B[39m\u001B[38;5;124m\"\u001B[39m,\n\u001B[1;32m 927\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_sleep,\n\u001B[1;32m 928\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_rand,\n\u001B[1;32m 929\u001B[0m \u001B[38;5;28mstr\u001B[39m(\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39muri),\n\u001B[1;32m 930\u001B[0m method\u001B[38;5;241m=\u001B[39m\u001B[38;5;28mstr\u001B[39m(\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mmethod),\n\u001B[1;32m 931\u001B[0m body\u001B[38;5;241m=\u001B[39m\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mbody,\n\u001B[1;32m 932\u001B[0m headers\u001B[38;5;241m=\u001B[39m\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mheaders,\n\u001B[1;32m 933\u001B[0m )\n\u001B[1;32m 935\u001B[0m \u001B[38;5;28;01mfor\u001B[39;00m callback \u001B[38;5;129;01min\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mresponse_callbacks:\n\u001B[1;32m 936\u001B[0m callback(resp)\n",
922
+ "File \u001B[0;32m/opt/anaconda3/lib/python3.11/site-packages/googleapiclient/http.py:222\u001B[0m, in \u001B[0;36m_retry_request\u001B[0;34m(http, num_retries, req_type, sleep, rand, uri, method, *args, **kwargs)\u001B[0m\n\u001B[1;32m 220\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m exception:\n\u001B[1;32m 221\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m retry_num \u001B[38;5;241m==\u001B[39m num_retries:\n\u001B[0;32m--> 222\u001B[0m \u001B[38;5;28;01mraise\u001B[39;00m exception\n\u001B[1;32m 223\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[1;32m 224\u001B[0m \u001B[38;5;28;01mcontinue\u001B[39;00m\n",
923
+ "File \u001B[0;32m/opt/anaconda3/lib/python3.11/site-packages/googleapiclient/http.py:191\u001B[0m, in \u001B[0;36m_retry_request\u001B[0;34m(http, num_retries, req_type, sleep, rand, uri, method, *args, **kwargs)\u001B[0m\n\u001B[1;32m 189\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[1;32m 190\u001B[0m exception \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mNone\u001B[39;00m\n\u001B[0;32m--> 191\u001B[0m resp, content \u001B[38;5;241m=\u001B[39m http\u001B[38;5;241m.\u001B[39mrequest(uri, method, \u001B[38;5;241m*\u001B[39margs, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs)\n\u001B[1;32m 192\u001B[0m \u001B[38;5;66;03m# Retry on SSL errors and socket timeout errors.\u001B[39;00m\n\u001B[1;32m 193\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m _ssl_SSLError \u001B[38;5;28;01mas\u001B[39;00m ssl_error:\n",
924
+ "File \u001B[0;32m/opt/anaconda3/lib/python3.11/site-packages/google_auth_httplib2.py:218\u001B[0m, in \u001B[0;36mAuthorizedHttp.request\u001B[0;34m(self, uri, method, body, headers, redirections, connection_type, **kwargs)\u001B[0m\n\u001B[1;32m 215\u001B[0m body_stream_position \u001B[38;5;241m=\u001B[39m body\u001B[38;5;241m.\u001B[39mtell()\n\u001B[1;32m 217\u001B[0m \u001B[38;5;66;03m# Make the request.\u001B[39;00m\n\u001B[0;32m--> 218\u001B[0m response, content \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mhttp\u001B[38;5;241m.\u001B[39mrequest(\n\u001B[1;32m 219\u001B[0m uri,\n\u001B[1;32m 220\u001B[0m method,\n\u001B[1;32m 221\u001B[0m body\u001B[38;5;241m=\u001B[39mbody,\n\u001B[1;32m 222\u001B[0m headers\u001B[38;5;241m=\u001B[39mrequest_headers,\n\u001B[1;32m 223\u001B[0m redirections\u001B[38;5;241m=\u001B[39mredirections,\n\u001B[1;32m 224\u001B[0m connection_type\u001B[38;5;241m=\u001B[39mconnection_type,\n\u001B[1;32m 225\u001B[0m \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs\n\u001B[1;32m 226\u001B[0m )\n\u001B[1;32m 228\u001B[0m \u001B[38;5;66;03m# If the response indicated that the credentials needed to be\u001B[39;00m\n\u001B[1;32m 229\u001B[0m \u001B[38;5;66;03m# refreshed, then refresh the credentials and re-attempt the\u001B[39;00m\n\u001B[1;32m 230\u001B[0m \u001B[38;5;66;03m# request.\u001B[39;00m\n\u001B[1;32m 231\u001B[0m \u001B[38;5;66;03m# A stored token may expire between the time it is retrieved and\u001B[39;00m\n\u001B[1;32m 232\u001B[0m \u001B[38;5;66;03m# the time the request is made, so we may need to try twice.\u001B[39;00m\n\u001B[1;32m 233\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m (\n\u001B[1;32m 234\u001B[0m response\u001B[38;5;241m.\u001B[39mstatus \u001B[38;5;129;01min\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_refresh_status_codes\n\u001B[1;32m 235\u001B[0m \u001B[38;5;129;01mand\u001B[39;00m _credential_refresh_attempt \u001B[38;5;241m<\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_max_refresh_attempts\n\u001B[1;32m 236\u001B[0m ):\n",
925
+ "File \u001B[0;32m/opt/anaconda3/lib/python3.11/site-packages/httplib2/__init__.py:1724\u001B[0m, in \u001B[0;36mHttp.request\u001B[0;34m(self, uri, method, body, headers, redirections, connection_type)\u001B[0m\n\u001B[1;32m 1722\u001B[0m content \u001B[38;5;241m=\u001B[39m \u001B[38;5;124mb\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124m\"\u001B[39m\n\u001B[1;32m 1723\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[0;32m-> 1724\u001B[0m (response, content) \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_request(\n\u001B[1;32m 1725\u001B[0m conn, authority, uri, request_uri, method, body, headers, redirections, cachekey,\n\u001B[1;32m 1726\u001B[0m )\n\u001B[1;32m 1727\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mException\u001B[39;00m \u001B[38;5;28;01mas\u001B[39;00m e:\n\u001B[1;32m 1728\u001B[0m is_timeout \u001B[38;5;241m=\u001B[39m \u001B[38;5;28misinstance\u001B[39m(e, socket\u001B[38;5;241m.\u001B[39mtimeout)\n",
926
+ "File \u001B[0;32m/opt/anaconda3/lib/python3.11/site-packages/httplib2/__init__.py:1444\u001B[0m, in \u001B[0;36mHttp._request\u001B[0;34m(self, conn, host, absolute_uri, request_uri, method, body, headers, redirections, cachekey)\u001B[0m\n\u001B[1;32m 1441\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m auth:\n\u001B[1;32m 1442\u001B[0m auth\u001B[38;5;241m.\u001B[39mrequest(method, request_uri, headers, body)\n\u001B[0;32m-> 1444\u001B[0m (response, content) \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_conn_request(conn, request_uri, method, body, headers)\n\u001B[1;32m 1446\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m auth:\n\u001B[1;32m 1447\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m auth\u001B[38;5;241m.\u001B[39mresponse(response, body):\n",
927
+ "File \u001B[0;32m/opt/anaconda3/lib/python3.11/site-packages/httplib2/__init__.py:1367\u001B[0m, in \u001B[0;36mHttp._conn_request\u001B[0;34m(self, conn, request_uri, method, body, headers)\u001B[0m\n\u001B[1;32m 1365\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m conn\u001B[38;5;241m.\u001B[39msock \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m:\n\u001B[1;32m 1366\u001B[0m conn\u001B[38;5;241m.\u001B[39mconnect()\n\u001B[0;32m-> 1367\u001B[0m conn\u001B[38;5;241m.\u001B[39mrequest(method, request_uri, body, headers)\n\u001B[1;32m 1368\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m socket\u001B[38;5;241m.\u001B[39mtimeout:\n\u001B[1;32m 1369\u001B[0m conn\u001B[38;5;241m.\u001B[39mclose()\n",
928
+ "File \u001B[0;32m/opt/anaconda3/lib/python3.11/http/client.py:1294\u001B[0m, in \u001B[0;36mHTTPConnection.request\u001B[0;34m(self, method, url, body, headers, encode_chunked)\u001B[0m\n\u001B[1;32m 1291\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mrequest\u001B[39m(\u001B[38;5;28mself\u001B[39m, method, url, body\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mNone\u001B[39;00m, headers\u001B[38;5;241m=\u001B[39m{}, \u001B[38;5;241m*\u001B[39m,\n\u001B[1;32m 1292\u001B[0m encode_chunked\u001B[38;5;241m=\u001B[39m\u001B[38;5;28;01mFalse\u001B[39;00m):\n\u001B[1;32m 1293\u001B[0m \u001B[38;5;250m \u001B[39m\u001B[38;5;124;03m\"\"\"Send a complete request to the server.\"\"\"\u001B[39;00m\n\u001B[0;32m-> 1294\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_send_request(method, url, body, headers, encode_chunked)\n",
929
+ "File \u001B[0;32m/opt/anaconda3/lib/python3.11/http/client.py:1340\u001B[0m, in \u001B[0;36mHTTPConnection._send_request\u001B[0;34m(self, method, url, body, headers, encode_chunked)\u001B[0m\n\u001B[1;32m 1336\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28misinstance\u001B[39m(body, \u001B[38;5;28mstr\u001B[39m):\n\u001B[1;32m 1337\u001B[0m \u001B[38;5;66;03m# RFC 2616 Section 3.7.1 says that text default has a\u001B[39;00m\n\u001B[1;32m 1338\u001B[0m \u001B[38;5;66;03m# default charset of iso-8859-1.\u001B[39;00m\n\u001B[1;32m 1339\u001B[0m body \u001B[38;5;241m=\u001B[39m _encode(body, \u001B[38;5;124m'\u001B[39m\u001B[38;5;124mbody\u001B[39m\u001B[38;5;124m'\u001B[39m)\n\u001B[0;32m-> 1340\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mendheaders(body, encode_chunked\u001B[38;5;241m=\u001B[39mencode_chunked)\n",
930
+ "File \u001B[0;32m/opt/anaconda3/lib/python3.11/http/client.py:1289\u001B[0m, in \u001B[0;36mHTTPConnection.endheaders\u001B[0;34m(self, message_body, encode_chunked)\u001B[0m\n\u001B[1;32m 1287\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[1;32m 1288\u001B[0m \u001B[38;5;28;01mraise\u001B[39;00m CannotSendHeader()\n\u001B[0;32m-> 1289\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_send_output(message_body, encode_chunked\u001B[38;5;241m=\u001B[39mencode_chunked)\n",
931
+ "File \u001B[0;32m/opt/anaconda3/lib/python3.11/http/client.py:1048\u001B[0m, in \u001B[0;36mHTTPConnection._send_output\u001B[0;34m(self, message_body, encode_chunked)\u001B[0m\n\u001B[1;32m 1046\u001B[0m msg \u001B[38;5;241m=\u001B[39m \u001B[38;5;124mb\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;130;01m\\r\u001B[39;00m\u001B[38;5;130;01m\\n\u001B[39;00m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;241m.\u001B[39mjoin(\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_buffer)\n\u001B[1;32m 1047\u001B[0m \u001B[38;5;28;01mdel\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_buffer[:]\n\u001B[0;32m-> 1048\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39msend(msg)\n\u001B[1;32m 1050\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m message_body \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m:\n\u001B[1;32m 1051\u001B[0m \n\u001B[1;32m 1052\u001B[0m \u001B[38;5;66;03m# create a consistent interface to message_body\u001B[39;00m\n\u001B[1;32m 1053\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28mhasattr\u001B[39m(message_body, \u001B[38;5;124m'\u001B[39m\u001B[38;5;124mread\u001B[39m\u001B[38;5;124m'\u001B[39m):\n\u001B[1;32m 1054\u001B[0m \u001B[38;5;66;03m# Let file-like take precedence over byte-like. This\u001B[39;00m\n\u001B[1;32m 1055\u001B[0m \u001B[38;5;66;03m# is needed to allow the current position of mmap'ed\u001B[39;00m\n\u001B[1;32m 1056\u001B[0m \u001B[38;5;66;03m# files to be taken into account.\u001B[39;00m\n",
932
+ "File \u001B[0;32m/opt/anaconda3/lib/python3.11/http/client.py:1009\u001B[0m, in \u001B[0;36mHTTPConnection.send\u001B[0;34m(self, data)\u001B[0m\n\u001B[1;32m 1007\u001B[0m sys\u001B[38;5;241m.\u001B[39maudit(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mhttp.client.send\u001B[39m\u001B[38;5;124m\"\u001B[39m, \u001B[38;5;28mself\u001B[39m, data)\n\u001B[1;32m 1008\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[0;32m-> 1009\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39msock\u001B[38;5;241m.\u001B[39msendall(data)\n\u001B[1;32m 1010\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mTypeError\u001B[39;00m:\n\u001B[1;32m 1011\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28misinstance\u001B[39m(data, collections\u001B[38;5;241m.\u001B[39mabc\u001B[38;5;241m.\u001B[39mIterable):\n",
933
+ "File \u001B[0;32m/opt/anaconda3/lib/python3.11/ssl.py:1274\u001B[0m, in \u001B[0;36mSSLSocket.sendall\u001B[0;34m(self, data, flags)\u001B[0m\n\u001B[1;32m 1272\u001B[0m amount \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mlen\u001B[39m(byte_view)\n\u001B[1;32m 1273\u001B[0m \u001B[38;5;28;01mwhile\u001B[39;00m count \u001B[38;5;241m<\u001B[39m amount:\n\u001B[0;32m-> 1274\u001B[0m v \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39msend(byte_view[count:])\n\u001B[1;32m 1275\u001B[0m count \u001B[38;5;241m+\u001B[39m\u001B[38;5;241m=\u001B[39m v\n\u001B[1;32m 1276\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n",
934
+ "File \u001B[0;32m/opt/anaconda3/lib/python3.11/ssl.py:1243\u001B[0m, in \u001B[0;36mSSLSocket.send\u001B[0;34m(self, data, flags)\u001B[0m\n\u001B[1;32m 1239\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m flags \u001B[38;5;241m!=\u001B[39m \u001B[38;5;241m0\u001B[39m:\n\u001B[1;32m 1240\u001B[0m \u001B[38;5;28;01mraise\u001B[39;00m \u001B[38;5;167;01mValueError\u001B[39;00m(\n\u001B[1;32m 1241\u001B[0m \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mnon-zero flags not allowed in calls to send() on \u001B[39m\u001B[38;5;132;01m%s\u001B[39;00m\u001B[38;5;124m\"\u001B[39m \u001B[38;5;241m%\u001B[39m\n\u001B[1;32m 1242\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m\u001B[38;5;18m__class__\u001B[39m)\n\u001B[0;32m-> 1243\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_sslobj\u001B[38;5;241m.\u001B[39mwrite(data)\n\u001B[1;32m 1244\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[1;32m 1245\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28msuper\u001B[39m()\u001B[38;5;241m.\u001B[39msend(data, flags)\n",
935
+ "\u001B[0;31mSSLEOFError\u001B[0m: EOF occurred in violation of protocol (_ssl.c:2427)"
936
+ ]
937
+ }
938
+ ],
939
+ "execution_count": 35
940
+ },
941
+ {
942
+ "metadata": {},
943
+ "cell_type": "code",
944
+ "outputs": [],
945
+ "execution_count": null,
946
+ "source": "",
947
+ "id": "bbdba8050ee4f8f6"
948
  }
949
  ],
950
  "metadata": {
processor.py CHANGED
@@ -21,6 +21,20 @@ class Processor:
21
  impression_column = self.df.iloc[:, 4]
22
  self.total_impressions = impression_column[impression_column.shift(-1).isna()].iloc[0]
23
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
  def process(self):
26
  pass
 
21
  impression_column = self.df.iloc[:, 4]
22
  self.total_impressions = impression_column[impression_column.shift(-1).isna()].iloc[0]
23
 
24
+ c_column = self.df.iloc[:, 2]
25
+ c_column_empty_cells = c_column[c_column.isna()].index
26
+
27
+ self.actual_impressions_percentage = c_column[c_column_empty_cells[1]-1]
28
+ self.target_impressions_percentage = c_column[c_column_empty_cells[1]-2]
29
+
30
+ b_column = self.df.iloc[:, 1]
31
+ b_column_empty_cells = b_column[b_column.isna()].index
32
+
33
+ self.distance_travelled = b_column[b_column_empty_cells[3]-1]
34
+ self.target_travelled = b_column[b_column_empty_cells[3]-2]
35
+ self.actual_travelled = self.distance_travelled
36
+
37
+ self.total_on_road = c_column[c_column_empty_cells[0]-1]
38
 
39
  def process(self):
40
  pass
slide.py CHANGED
@@ -73,4 +73,4 @@ class Slide:
73
  return response
74
  except HttpError as e:
75
  print(f"Error during text replacement: {e}")
76
- raise
 
73
  return response
74
  except HttpError as e:
75
  print(f"Error during text replacement: {e}")
76
+ raise
utils.py ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ def thousand_to_k(x):
2
+ if x >= 1000:
3
+ return thousand_comma_separated(x // 1000) + 'k'
4
+ return str(x)
5
+
6
+ def thousand_comma_separated(x):
7
+ return "{:,}".format(x)