Repository: data-for-change/anyway

Issue:
Widget: motorcycle_accidents_vs_all_accidents
**Name**
Query for severe and fatal motorcycle accidents VS other accidents in a specific road vs all of the interurban roads 

**Title**
תאונות אופנועים קשות וקטלניות בכביש __ בהשוואה לכל הארץ
(שם הכותרת משתנה כתלות במספר כביש)

**Visualization**
@MichalOren please attach :) 

**Visualization explanation**
Visualization contains 2 bar graphs (for the specific road and for all of Israel interurban roads)
Each bar is a stacked bar completing to 100% containing the the percentage of severe and fatal accidents with motorcycles and the rest - all other severe and fatal accidents.

**Use case**
When the percentage of motorcycle accidents in the specific road is greater than 1.5 times the percentage of the motorcycle accidents in all of the roads (for example, if all interurban roads have a 20% of motorcycle severe and fatal accidents, infographics will be presented if the specific road has at least 30% of motorcycle accidents)

**SQL query**
See [query here](https://app.redash.io/hasadna/queries/511391/source)
Road number changes - according to the newsflash road1 field. Also title changes accordingly.

**Additional context**
- Definition will be used by BE team to generate a Json response to FE
- Mock Json already exists in code (look for motorcycle_accidents_vs_all_accidents in [infographics_utils.py](https://github.com/hasadna/anyway/blob/dev/anyway/infographics_utils.py))
- Definition will be provided by Data team, after internal review
- Definition will be written in English and should use language agnostic definitions and data structures 
(e.g. SQL columns) as much as possible.



Discussion:
![Moto4](https://user-images.githubusercontent.com/61007501/99146929-39f81e80-2685-11eb-9839-e85aed4cdd24.PNG)

@atalyaalon 
Usually the analysis have specific time frame. I wonder if we should include constatnt 'time reference' in infographic slides and jsons ? 
as part of standartization...
i cant find reference to the time frame of the analysis it in the website slides
@MichalOren you are absolutely right - we'll already asked from the FE to add the dates in the bottom of each infographics.
@MichalOren infographic looks really good. Thank you! 

Resolving patch:
diff --git a/anyway/backend_constants.py b/anyway/backend_constants.py
--- a/anyway/backend_constants.py
+++ b/anyway/backend_constants.py
@@ -30,10 +30,13 @@ class BackEndConstants(object):
 
     # This is a type for the 'accident_severity' table field name
     ACCIDENT_SEVERITY_DEADLY = 1
+    ACCIDENT_SEVERITY_SEVERE = 2
+    ACCIDENT_SEVERITY_LIGHT = 3
 
     # This is a type for the 'road_type' table field name
     ROAD_TYPE_NOT_IN_CITY_IN_INTERSECTION = 3
     ROAD_TYPE_NOT_IN_CITY_NOT_IN_INTERSECTION = 4
+    NON_CITY_ROAD_TYPES = [ROAD_TYPE_NOT_IN_CITY_IN_INTERSECTION, ROAD_TYPE_NOT_IN_CITY_NOT_IN_INTERSECTION]
 
     # other global constants (python only)
     DEFAULT_NUMBER_OF_YEARS_AGO = 5
diff --git a/anyway/infographics_utils.py b/anyway/infographics_utils.py
--- a/anyway/infographics_utils.py
+++ b/anyway/infographics_utils.py
@@ -10,7 +10,7 @@
 
 import pandas as pd
 from collections import defaultdict
-from sqlalchemy import func
+from sqlalchemy import func, distinct, literal_column, case
 from sqlalchemy import cast, Numeric
 from sqlalchemy import desc
 from flask_babel import _
@@ -964,7 +964,8 @@ class MotorcycleAccidentsVsAllAccidentsWidget(Widget):
     def __init__(self, request_params: RequestParams):
         super().__init__(request_params, type(self).name)
         self.rank = 20
-        self.text = {"title": "תאונות אופנועים קשות וקטלניות בכביש 20 בהשוואה לכל הארץ"}
+        self.road_number = request_params.location_info["road1"]
+        self.text = {"title": f"תאונות אופנועים קשות וקטלניות בכביש {int(self.road_number)} בהשוואה לכל הארץ"}
 
     # noinspection PyMethodMayBeStatic
     def is_in_cache(self) -> bool:
@@ -972,17 +973,80 @@ def is_in_cache(self) -> bool:
 
     def generate_items(self) -> None:
         self.items = (
-            MotorcycleAccidentsVsAllAccidentsWidget.motorcycle_accidents_vs_all_accidents_mock_data()
+            MotorcycleAccidentsVsAllAccidentsWidget.motorcycle_accidents_vs_all_accidents(
+                self.request_params.start_time, self.request_params.end_time, self.road_number)
         )
 
     @staticmethod
-    def motorcycle_accidents_vs_all_accidents_mock_data():  # Temporary for Frontend
+    def motorcycle_accidents_vs_all_accidents(start_time, end_time, road_number):
+        location_label = "location"
+        location_other = "שאר הארץ"
+        location_road = f'כביש {int(road_number)}'
+        case_location = case([
+            ((InvolvedMarkerView.road1 == road_number) | (InvolvedMarkerView.road2 == road_number),
+             location_road)
+        ],
+            else_=literal_column(f"'{location_other}'")
+        ).label(location_label)
+
+        vehicle_label = "vehicle"
+        vehicle_other = "אחר"
+        vehicle_motorcycle = "אופנוע"
+        case_vehicle = case([(
+            InvolvedMarkerView.involve_vehicle_type.in_(BE_CONST.MOTORCYCLE_VEHICLE_TYPES),
+            literal_column(f"'{vehicle_motorcycle}'")
+        )],
+            else_=literal_column(f"'{vehicle_other}'")
+        ).label(vehicle_label)
+
+        query = get_query(table_obj=InvolvedMarkerView, filters={}, start_time=start_time,
+                          end_time=end_time)
+
+        num_accidents_label = "num_of_accidents"
+        query = (query.with_entities(case_location, case_vehicle,
+                                     func.count(distinct(InvolvedMarkerView.provider_and_id))
+                                     .label(num_accidents_label))
+                 .filter(InvolvedMarkerView.road_type.in_(BE_CONST.NON_CITY_ROAD_TYPES))
+                 .filter(InvolvedMarkerView.accident_severity.in_([BE_CONST.ACCIDENT_SEVERITY_DEADLY,
+                                                                   BE_CONST.ACCIDENT_SEVERITY_SEVERE]))
+                 .group_by(location_label, vehicle_label)
+                 .order_by(desc(num_accidents_label))
+                 )
+        results = pd.read_sql_query(query.statement, query.session.bind)\
+            .to_dict(orient="records")  # pylint: disable=no-member
+
+        counter_road_motorcycle = 0
+        counter_other_motorcycle = 0
+        counter_road_other = 0
+        counter_other_other = 0
+        for record in results:
+            if record[location_label] == location_other:
+                if record[vehicle_label] == vehicle_other:
+                    counter_other_other = record[num_accidents_label]
+                else:
+                    counter_other_motorcycle = record[num_accidents_label]
+            else:
+                if record[vehicle_label] == vehicle_other:
+                    counter_road_other = record[num_accidents_label]
+                else:
+                    counter_road_motorcycle = record[num_accidents_label]
+        sum_road = counter_road_other + counter_road_motorcycle
+        if sum_road == 0:
+            sum_road = 1  # prevent division by zero
+        sum_all = counter_other_other + counter_other_motorcycle + sum_road
+        percentage_label = "percentage"
+        location_all_label = "כל הארץ"
+
         return [
-            {"location": "כביש 20", "vehicle": "אופנוע", "percentage": 0.50},
-            {"location": "כביש 20", "vehicle": "אחר", "percentage": 0.50},
-            {"location": "כל הארץ", "vehicle": "אחר", "percentage": 0.80},
-            {"location": "כל הארץ", "vehicle": "אופנוע", "percentage": 0.20},
-        ]
+            {location_label: location_road, vehicle_label: vehicle_motorcycle,
+             percentage_label: counter_road_motorcycle / sum_road},
+            {location_label: location_road, vehicle_label: vehicle_other,
+             percentage_label: counter_road_other / sum_road},
+            {location_label: location_all_label, vehicle_label: vehicle_motorcycle,
+             percentage_label: (counter_other_motorcycle + counter_road_motorcycle) / sum_all},
+            {location_label: location_all_label, vehicle_label: vehicle_other,
+             percentage_label: (counter_other_other + counter_road_other) / sum_all},
+            ]
 
 
 @register


Test patch: