diff --git a/src/electos/ballotmaker/ballots/contest_data.py b/src/electos/ballotmaker/ballots/contest_data.py
index e964d27..091a44f 100644
--- a/src/electos/ballotmaker/ballots/contest_data.py
+++ b/src/electos/ballotmaker/ballots/contest_data.py
@@ -14,11 +14,11 @@ class BallotMeasureData:
choices: list = field(default_factory=list, init=False, repr=True)
def __post_init__(self):
- self.id = "no_id_provided"
- self.title = self._b_measure_con["title"]
- self.district = self._b_measure_con["district"]
- self.text = self._b_measure_con["text"]
- self.choices = self._b_measure_con["choices"]
+ self.id = self._b_measure_con.get("id", "")
+ self.title = self._b_measure_con.get("title", "")
+ self.district = self._b_measure_con.get("district", "")
+ self.text = self._b_measure_con.get("text", "")
+ self.choices = self._b_measure_con.get("choices", [])
# for choice_data in _choices:
# self.choices.append(ChoiceData(choice_data))
@@ -45,12 +45,13 @@ class CandidateContestData:
district: str = field(init=False)
candidates: list = field(default_factory=list, init=False, repr=True)
+ # use dict.get() to assign defaults if key is missing
def __post_init__(self):
- self.id = self._can_con["id"]
- self.title = self._can_con["title"]
- self.votes_allowed = self._can_con["votes_allowed"]
- self.district = self._can_con["district"]
- _candidates = self._can_con["candidates"]
+ self.id = self._can_con.get("id", "")
+ self.title = self._can_con.get("title", "")
+ self.votes_allowed = self._can_con.get("votes_allowed", 0)
+ self.district = self._can_con.get("district", "")
+ _candidates = self._can_con.get("candidates", [])
for candidate_data in _candidates:
self.candidates.append(CandidateData(candidate_data))
@@ -58,16 +59,28 @@ def __post_init__(self):
@dataclass
class CandidateData:
_can_data: dict = field(repr=False)
- id: str = "no_id_provided"
- name: str = field(init=False)
+ id: str = field(init=False)
+ _names: list = field(init=False, repr=False, default_factory=list)
party: str = field(init=False)
party_abbr: str = field(init=False)
+ write_in: bool = field(init=False)
+ name: str = field(init=True, default="")
def __post_init__(self):
- self.name = self._can_data["name"]
- party_dict = self._can_data["party"]
- self.party = party_dict["name"]
- self.party_abbr = party_dict["abbreviation"]
+ self.id = self._can_data.get("id", "")
+ self._names = self._can_data.get("name", [])
+ _party_dict = self._can_data.get("party", {})
+ self.party = _party_dict.get("name", "")
+ self.party_abbr = _party_dict.get("abbreviation", "")
+ self.write_in = self._can_data.get("write_in")
+ if self.write_in:
+ self.name = "or write in:"
+ else:
+ for count, can_name in enumerate(self._names):
+ # append " and " only if more than one name
+ if count > 0:
+ self.name += " and "
+ self.name += can_name
if __name__ == "__main__": # pragma: no cover
diff --git a/src/electos/ballotmaker/ballots/contest_layout.py b/src/electos/ballotmaker/ballots/contest_layout.py
index 5d6dabf..0df73b8 100644
--- a/src/electos/ballotmaker/ballots/contest_layout.py
+++ b/src/electos/ballotmaker/ballots/contest_layout.py
@@ -41,7 +41,6 @@
black,
font_bold,
normal_lead,
- # sp_before=12,
sp_after=48,
keep_w_next=1,
)
@@ -54,7 +53,6 @@
font_bold,
normal_lead,
sp_before=12,
- # sp_after=32,
keep_w_next=1,
)
PageLayout.define_custom_style(
@@ -65,7 +63,6 @@
black,
font_normal,
normal_lead,
- # sp_before=12,
)
@@ -149,7 +146,8 @@ def __init__(self, width=400, height=200, *args, **kw):
self.width = oval_width + PageLayout.border_pad
self.height = oval_height + PageLayout.border_pad
oval_cx = self.width / 2
- oval_cy = self.height / 2
+ down_shift = 2
+ oval_cy = (self.height / 2) - down_shift
self._add(
self,
Ellipse(oval_cx, oval_cy, oval_width, oval_height),
@@ -157,9 +155,7 @@ def __init__(self, width=400, height=200, *args, **kw):
validate=None,
desc=None,
)
- # self.oval.fillColor = PageLayout.white
self.oval.fillColor = white
- # self.oval.strokeColor = PageLayout.black
self.oval.strokeColor = black
self.oval.strokeWidth = sm_line
@@ -183,8 +179,13 @@ def __init__(self, contest_data: CandidateContestData):
oval = SelectionOval()
for candidate in self.candidates:
# add newlines around " and "
- # if candidate.find(" and "):
- # candidate = candidate.replace(" and ", "
and
")
+ if candidate.name.find(" and "):
+ candidate.name = candidate.name.replace(
+ " and ", "
and
"
+ )
+ # add line for write ins
+ if candidate.write_in:
+ candidate.name += ("
" * 2) + ("_" * 20)
contest_line = f"{candidate.name}"
if candidate.party_abbr != "":
contest_line += f"
{candidate.party_abbr}"
diff --git a/src/electos/ballotmaker/ballots/demo_ballot.py b/src/electos/ballotmaker/ballots/demo_ballot.py
index 33711ec..62370fa 100644
--- a/src/electos/ballotmaker/ballots/demo_ballot.py
+++ b/src/electos/ballotmaker/ballots/demo_ballot.py
@@ -165,9 +165,9 @@ def build_ballot() -> str:
elements.append(NextPageTemplate("3col"))
elements.append(layout_1.contest_table)
elements.append(layout_2.contest_table)
- elements.append(layout_3.contest_table)
elements.append(CondPageBreak(c_height * inch))
elements.append(layout_4.contest_table)
+ elements.append(layout_3.contest_table)
elements.append(NextPageTemplate("1col"))
elements.append(PageBreak())
elements.append(layout_5.contest_table)
diff --git a/src/electos/ballotmaker/demo_data/spacetown_data.json b/src/electos/ballotmaker/demo_data/spacetown_data.json
index 5d3f652..e781b8b 100644
--- a/src/electos/ballotmaker/demo_data/spacetown_data.json
+++ b/src/electos/ballotmaker/demo_data/spacetown_data.json
@@ -11,22 +11,31 @@
"district": "Orbit City",
"candidates": [
{
- "name": "Cosmo Spacely",
+ "id": "recTKcXLCzRvKB9U0",
+ "name": [
+ "Cosmo Spacely"
+ ],
"party": {
"name": "The Lepton Party",
"abbreviation": "LEP"
- }
+ },
+ "write_in": false
},
{
- "name": "Spencer Cogswell",
+ "id": "recKD6dBvkNhEU4bg",
+ "name": [
+ "Spencer Cogswell"
+ ],
"party": {
"name": "The Hadron Party of Farallon",
"abbreviation": "HAD"
- }
+ },
+ "write_in": false
+ },
+ {
+ "id": "recqq21kO6HWgpJZV",
+ "write_in": true
}
- ],
- "write_ins": [
- "recqq21kO6HWgpJZV"
]
},
{
@@ -38,30 +47,46 @@
"district": "Aldrin Space Transport District",
"candidates": [
{
- "name": "Jane Jetson",
+ "id": "recvYvTb9hWH7tptb",
+ "name": [
+ "Jane Jetson"
+ ],
"party": {
"name": "",
"abbreviation": ""
- }
+ },
+ "write_in": false
},
{
- "name": "Harlan Ellis",
+ "id": "recBnJZEgCKAnfpNo",
+ "name": [
+ "Harlan Ellis"
+ ],
"party": {
"name": "",
"abbreviation": ""
- }
+ },
+ "write_in": false
},
{
- "name": "Rudy Indexer",
+ "id": "recwNuOnepWNGz67V",
+ "name": [
+ "Rudy Indexer"
+ ],
"party": {
"name": "",
"abbreviation": ""
- }
+ },
+ "write_in": false
+ },
+ {
+ "id": "rec9Eev970VhohqKi",
+ "write_in": true
+ },
+ {
+ "id": "recFiGYjGCIyk5LBe",
+ "write_in": true
}
- ],
- "write_ins": [
- "rec9Eev970VhohqKi",
- "recFiGYjGCIyk5LBe"
]
},
{
@@ -73,45 +98,72 @@
"district": "Gadget County",
"candidates": [
{
- "name": "Sally Smith",
+ "id": "recbxvhKikHJNZYbq",
+ "name": [
+ "Sally Smith"
+ ],
"party": {
"name": "",
"abbreviation": ""
- }
+ },
+ "write_in": false
},
{
- "name": "Hector Gomez",
+ "id": "recigPkqYXXDJEaCE",
+ "name": [
+ "Hector Gomez"
+ ],
"party": {
"name": "",
"abbreviation": ""
- }
+ },
+ "write_in": false
},
{
- "name": "Rosashawn Davis",
+ "id": "recJvikmG5MrUKzo1",
+ "name": [
+ "Rosashawn Davis"
+ ],
"party": {
"name": "",
"abbreviation": ""
- }
+ },
+ "write_in": false
},
{
- "name": "Oliver Tsi",
+ "id": "recvjB3rgfiicf0RP",
+ "name": [
+ "Oliver Tsi"
+ ],
"party": {
"name": "",
"abbreviation": ""
- }
+ },
+ "write_in": false
},
{
- "name": "Glavin Orotund",
+ "id": "recbN7UUMaSuOYGQ6",
+ "name": [
+ "Glavin Orotund"
+ ],
"party": {
"name": "",
"abbreviation": ""
- }
+ },
+ "write_in": false
+ },
+ {
+ "id": "recYurH2CLY3SlYS8",
+ "write_in": true
+ },
+ {
+ "id": "recI5jfcXIsbAKytC",
+ "write_in": true
+ },
+ {
+ "id": "recn9m0o1em7gLahj",
+ "write_in": true
}
- ],
- "write_ins": [
- "recYurH2CLY3SlYS8",
- "recI5jfcXIsbAKytC",
- "recn9m0o1em7gLahj"
]
},
{
@@ -123,36 +175,33 @@
"district": "United States of America",
"candidates": [
{
- "name": "Anthony Alpha",
- "party": {
- "name": "The Lepton Party",
- "abbreviation": "LEP"
- }
+ "id": "recPod2L8VhwagiDl",
+ "write_in": true
},
{
- "name": "Betty Beta",
+ "id": "recQK3J9IJq42hz2n",
+ "name": [
+ "Anthony Alpha",
+ "Betty Beta"
+ ],
"party": {
"name": "The Lepton Party",
"abbreviation": "LEP"
- }
+ },
+ "write_in": false
},
{
- "name": "Gloria Gamma",
+ "id": "reccUkUdEznfODgeL",
+ "name": [
+ "Gloria Gamma",
+ "David Delta"
+ ],
"party": {
"name": "The Hadron Party of Farallon",
"abbreviation": "HAD"
- }
- },
- {
- "name": "David Delta",
- "party": {
- "name": "The Hadron Party of Farallon",
- "abbreviation": "HAD"
- }
+ },
+ "write_in": false
}
- ],
- "write_ins": [
- "recPod2L8VhwagiDl"
]
}
],
@@ -179,4 +228,4 @@
}
]
}
-}
+}
\ No newline at end of file
diff --git a/src/electos/ballotmaker/demo_data/spacetown_data.py b/src/electos/ballotmaker/demo_data/spacetown_data.py
index 75b2dd4..66a4b7e 100644
--- a/src/electos/ballotmaker/demo_data/spacetown_data.py
+++ b/src/electos/ballotmaker/demo_data/spacetown_data.py
@@ -7,18 +7,22 @@
"district": "Orbit City",
"candidates": [
{
- "name": "Cosmo Spacely",
+ "id": "recTKcXLCzRvKB9U0",
+ "name": ["Cosmo Spacely"],
"party": {"name": "The Lepton Party", "abbreviation": "LEP"},
+ "write_in": False,
},
{
- "name": "Spencer Cogswell",
+ "id": "recKD6dBvkNhEU4bg",
+ "name": ["Spencer Cogswell"],
"party": {
"name": "The Hadron Party of Farallon",
"abbreviation": "HAD",
},
+ "write_in": False,
},
+ {"id": "recqq21kO6HWgpJZV", "write_in": True},
],
- "write_ins": ["recqq21kO6HWgpJZV"],
}
can_con_3 = {
@@ -29,11 +33,27 @@
"votes_allowed": 2,
"district": "Aldrin Space Transport District",
"candidates": [
- {"name": "Jane Jetson", "party": {"name": "", "abbreviation": ""}},
- {"name": "Harlan Ellis", "party": {"name": "", "abbreviation": ""}},
- {"name": "Rudy Indexer", "party": {"name": "", "abbreviation": ""}},
+ {
+ "id": "recvYvTb9hWH7tptb",
+ "name": ["Jane Jetson"],
+ "party": {"name": "", "abbreviation": ""},
+ "write_in": False,
+ },
+ {
+ "id": "recBnJZEgCKAnfpNo",
+ "name": ["Harlan Ellis"],
+ "party": {"name": "", "abbreviation": ""},
+ "write_in": False,
+ },
+ {
+ "id": "recwNuOnepWNGz67V",
+ "name": ["Rudy Indexer"],
+ "party": {"name": "", "abbreviation": ""},
+ "write_in": False,
+ },
+ {"id": "rec9Eev970VhohqKi", "write_in": True},
+ {"id": "recFiGYjGCIyk5LBe", "write_in": True},
],
- "write_ins": ["rec9Eev970VhohqKi", "recFiGYjGCIyk5LBe"],
}
can_con_2 = {
@@ -44,16 +64,39 @@
"votes_allowed": 4,
"district": "Gadget County",
"candidates": [
- {"name": "Sally Smith", "party": {"name": "", "abbreviation": ""}},
- {"name": "Hector Gomez", "party": {"name": "", "abbreviation": ""}},
- {"name": "Rosashawn Davis", "party": {"name": "", "abbreviation": ""}},
- {"name": "Oliver Tsi", "party": {"name": "", "abbreviation": ""}},
- {"name": "Glavin Orotund", "party": {"name": "", "abbreviation": ""}},
- ],
- "write_ins": [
- "recYurH2CLY3SlYS8",
- "recI5jfcXIsbAKytC",
- "recn9m0o1em7gLahj",
+ {
+ "id": "recbxvhKikHJNZYbq",
+ "name": ["Sally Smith"],
+ "party": {"name": "", "abbreviation": ""},
+ "write_in": False,
+ },
+ {
+ "id": "recigPkqYXXDJEaCE",
+ "name": ["Hector Gomez"],
+ "party": {"name": "", "abbreviation": ""},
+ "write_in": False,
+ },
+ {
+ "id": "recJvikmG5MrUKzo1",
+ "name": ["Rosashawn Davis"],
+ "party": {"name": "", "abbreviation": ""},
+ "write_in": False,
+ },
+ {
+ "id": "recvjB3rgfiicf0RP",
+ "name": ["Oliver Tsi"],
+ "party": {"name": "", "abbreviation": ""},
+ "write_in": False,
+ },
+ {
+ "id": "recbN7UUMaSuOYGQ6",
+ "name": ["Glavin Orotund"],
+ "party": {"name": "", "abbreviation": ""},
+ "write_in": False,
+ },
+ {"id": "recYurH2CLY3SlYS8", "write_in": True},
+ {"id": "recI5jfcXIsbAKytC", "write_in": True},
+ {"id": "recn9m0o1em7gLahj", "write_in": True},
],
}
@@ -66,29 +109,22 @@
"district": "United States of America",
"candidates": [
{
- "name": "Anthony Alpha",
- "party": {"name": "The Lepton Party", "abbreviation": "LEP"},
- },
- {
- "name": "Betty Beta",
+ "id": "recQK3J9IJq42hz2n",
+ "name": ["Anthony Alpha", "Betty Beta"],
"party": {"name": "The Lepton Party", "abbreviation": "LEP"},
+ "write_in": False,
},
{
- "name": "Gloria Gamma",
- "party": {
- "name": "The Hadron Party of Farallon",
- "abbreviation": "HAD",
- },
- },
- {
- "name": "David Delta",
+ "id": "reccUkUdEznfODgeL",
+ "name": ["Gloria Gamma", "David Delta"],
"party": {
"name": "The Hadron Party of Farallon",
"abbreviation": "HAD",
},
+ "write_in": False,
},
+ {"id": "recPod2L8VhwagiDl", "write_in": True},
],
- "write_ins": ["recPod2L8VhwagiDl"],
}
ballot_measure_1 = {