car info: function that sorts all car info into tiers (#24498)

* base function that returns all car info sorted by make model

* don't need to pass it in quite yet
pull/24501/head
Shane Smiskol 3 years ago committed by GitHub
parent d2d3b7b823
commit dabcfd266e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      scripts/count_cars.py
  2. 23
      selfdrive/car/docs.py
  3. 1
      selfdrive/car/docs_definitions.py
  4. 23
      selfdrive/car/tests/test_docs.py

@ -2,12 +2,10 @@
from collections import Counter from collections import Counter
from pprint import pprint from pprint import pprint
from selfdrive.car.docs import get_tier_car_info from selfdrive.car.docs import get_all_car_info
if __name__ == "__main__": if __name__ == "__main__":
tiers = get_tier_car_info() cars = get_all_car_info()
cars = [car for tier_cars in tiers.values() for car in tier_cars]
make_count = Counter(l.make for l in cars) make_count = Counter(l.make for l in cars)
print("\n", "*" * 20, len(cars), "total", "*" * 20, "\n") print("\n", "*" * 20, len(cars), "total", "*" * 20, "\n")
pprint(make_count) pprint(make_count)

@ -26,9 +26,8 @@ CARS_MD_OUT = os.path.join(BASEDIR, "docs", "CARS.md")
CARS_MD_TEMPLATE = os.path.join(BASEDIR, "selfdrive", "car", "CARS_template.md") CARS_MD_TEMPLATE = os.path.join(BASEDIR, "selfdrive", "car", "CARS_template.md")
def get_tier_car_info() -> Dict[Tier, List[CarInfo]]: def get_all_car_info() -> List[CarInfo]:
tier_car_info: Dict[Tier, List[CarInfo]] = {tier: [] for tier in Tier} all_car_info: List[CarInfo] = []
for models in get_interface_attr("CAR_INFO").values(): for models in get_interface_attr("CAR_INFO").values():
for model, car_info in models.items(): for model, car_info in models.items():
# Hyundai exception: those with radar have openpilot longitudinal # Hyundai exception: those with radar have openpilot longitudinal
@ -43,8 +42,16 @@ def get_tier_car_info() -> Dict[Tier, List[CarInfo]]:
car_info = (car_info,) car_info = (car_info,)
for _car_info in car_info: for _car_info in car_info:
_car_info.init(CP, non_tested_cars, ALL_FOOTNOTES) all_car_info.append(_car_info.init(CP, non_tested_cars, ALL_FOOTNOTES))
tier_car_info[_car_info.tier].append(_car_info)
# Sort cars by make and model + year
return natsorted(all_car_info, key=lambda car: (car.make + car.model).lower())
def sort_by_tier(all_car_info: List[CarInfo]) -> Dict[Tier, List[CarInfo]]:
tier_car_info: Dict[Tier, List[CarInfo]] = {tier: [] for tier in Tier}
for car_info in all_car_info:
tier_car_info[car_info.tier].append(car_info)
# Sort cars by make and model + year # Sort cars by make and model + year
for tier, cars in tier_car_info.items(): for tier, cars in tier_car_info.items():
@ -53,12 +60,12 @@ def get_tier_car_info() -> Dict[Tier, List[CarInfo]]:
return tier_car_info return tier_car_info
def generate_cars_md(tier_car_info: Dict[Tier, List[CarInfo]], template_fn: str) -> str: def generate_cars_md(all_car_info: List[CarInfo], template_fn: str) -> str:
with open(template_fn, "r") as f: with open(template_fn, "r") as f:
template = jinja2.Template(f.read(), trim_blocks=True, lstrip_blocks=True) template = jinja2.Template(f.read(), trim_blocks=True, lstrip_blocks=True)
footnotes = [fn.value.text for fn in ALL_FOOTNOTES] footnotes = [fn.value.text for fn in ALL_FOOTNOTES]
return template.render(tiers=tier_car_info, footnotes=footnotes, Star=Star, Column=Column) return template.render(tiers=sort_by_tier(all_car_info), footnotes=footnotes, Star=Star, Column=Column)
if __name__ == "__main__": if __name__ == "__main__":
@ -70,5 +77,5 @@ if __name__ == "__main__":
args = parser.parse_args() args = parser.parse_args()
with open(args.out, 'w') as f: with open(args.out, 'w') as f:
f.write(generate_cars_md(get_tier_car_info(), args.template)) f.write(generate_cars_md(get_all_car_info(), args.template))
print(f"Generated and written to {args.out}") print(f"Generated and written to {args.out}")

@ -91,6 +91,7 @@ class CarInfo:
self.row[column] = footnote.value.star self.row[column] = footnote.value.star
self.tier = {5: Tier.GOLD, 4: Tier.SILVER}.get(list(self.row.values()).count(Star.FULL), Tier.BRONZE) self.tier = {5: Tier.GOLD, 4: Tier.SILVER}.get(list(self.row.values()).count(Star.FULL), Tier.BRONZE)
return self
@no_type_check @no_type_check
def get_column(self, column: Column, star_icon: str, footnote_tag: str) -> str: def get_column(self, column: Column, star_icon: str, footnote_tag: str) -> str:

@ -1,15 +1,15 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import unittest import unittest
from selfdrive.car.docs import CARS_MD_OUT, CARS_MD_TEMPLATE, generate_cars_md, get_tier_car_info from selfdrive.car.docs import CARS_MD_OUT, CARS_MD_TEMPLATE, generate_cars_md, get_all_car_info
class TestCarDocs(unittest.TestCase): class TestCarDocs(unittest.TestCase):
def setUp(self): def setUp(self):
self.tier_cars = get_tier_car_info() self.all_cars = get_all_car_info()
def test_generator(self): def test_generator(self):
generated_cars_md = generate_cars_md(self.tier_cars, CARS_MD_TEMPLATE) generated_cars_md = generate_cars_md(self.all_cars, CARS_MD_TEMPLATE)
with open(CARS_MD_OUT, "r") as f: with open(CARS_MD_OUT, "r") as f:
current_cars_md = f.read() current_cars_md = f.read()
@ -18,15 +18,14 @@ class TestCarDocs(unittest.TestCase):
def test_naming_conventions(self): def test_naming_conventions(self):
# Asserts market-standard car naming conventions by make # Asserts market-standard car naming conventions by make
for cars in self.tier_cars.values(): for car in self.all_cars:
for car in cars: if car.car_name == "hyundai":
if car.car_name == "hyundai": tokens = car.model.lower().split(" ")
tokens = car.model.lower().split(" ") self.assertNotIn("phev", tokens, "Use `Plug-in Hybrid`")
self.assertNotIn("phev", tokens, "Use `Plug-in Hybrid`") self.assertNotIn("hev", tokens, "Use `Hybrid`")
self.assertNotIn("hev", tokens, "Use `Hybrid`") self.assertNotIn("ev", tokens, "Use `Electric`")
self.assertNotIn("ev", tokens, "Use `Electric`") if "plug-in hybrid" in car.model.lower():
if "plug-in hybrid" in car.model.lower(): self.assertIn("Plug-in Hybrid", car.model, "Use correct capitalization")
self.assertIn("Plug-in Hybrid", car.model, "Use correct capitalization")
if __name__ == "__main__": if __name__ == "__main__":

Loading…
Cancel
Save