-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add a command to set up some minimal example data
- Loading branch information
Showing
3 changed files
with
259 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
number,section,question,criteria,clarifications,type,option_1,option_2,option_3,option_4 | ||
1,First Section,Is the council transitioning their vehicle fleet to electric?,"Two-tier criteria | ||
|
||
First tier criteria met if 10% or more of the council's fleet are electric vehicles. | ||
|
||
Second tier criteria met if 50% or more of the council's fleet are electric vehicles","A council's fleet includes council owned or leased vehicles, and may include street cleaners and waste collection vehicles. | ||
|
||
Usually the breakdown of the council fleet by vehicle type is not published, therefore we will just take the stated total fleet number and number of electric vehicles.",multiple_choice,No evidence found,Evidence doesn't meet criteria,10% or over,50% or over | ||
2,First Section,Has the council set up or supported a shared transport scheme that can be used across their whole area?,"Criteria met for each type of scheme where a member of the public can hire a vehicle (e.g. car/scooter/bike/mobility device) within the local authorities area. | ||
|
||
The following schemes will be awarded points: | ||
- Car share scheme of any size in the area. Including: | ||
- Community car clubs. | ||
- Car clubs provided by private companies | ||
- Hiring of council vehicles when not in use | ||
- Bike share scheme | ||
- E-bike or cargo bike share scheme | ||
- E-scooter scheme | ||
- Mobility Devices | ||
- Wheels 2 Work scheme | ||
|
||
Trial schemes that are active at the time of marking will be accepted.",Marked initially using Coordinated Mobility's publicly available data on shared transport schemes.,select_one,No evidence found,Car share,Bike share,E-bike or cargo bike share | ||
1,Second Section,Does the council's corporate plan include a net zero target and make tackling the climate emergency one of its main priorities?,"Criteria met if climate action (alternatively called sustainability or environment) is listed as one of the council's core priorities or equivalent. It must have its own heading or section and a net zero target date must be referenced. | ||
|
||
The net zero target date must be an area-wide target, either the UK Government's national target, the devolved nation's target or the council's area-wide net zero target. | ||
|
||
",,yes_no,,,, | ||
2,Second Section,"Does the council's medium term financial plan include the council's net zero target and make tackling the climate emergency one of its main priorities? | ||
","Criteria met if climate action (alternatively called sustainability or environment) is listed as one of the council's core priorities or equivalent. It must have its own heading or section and a net zero target date must be referenced. | ||
|
||
The net zero target date must be an area-wide target, either the UK Government's national target, the devolved nation's target or the council's area-wide net zero target. ",,yes_no,,,, |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
section,session,number,stage,authority,answer,public_notes,page_number,evidence,private_notes,agree_with_response | ||
First Section,Session One,1,First Mark,Test Council,10% or over,Section One Q1 2023 notes,1,http://example.com,First Section Q1 2023 private notes, | ||
First Section,Session One,2,First Mark,Test Council,Car share,Section One Q2 2023 notes,2,http://example.com,Section One Q2 2023 private notes, | ||
Second Section,Session One,1,First Mark,Test Council,Yes,Section Two Q1 2023 notes,34,http://example.com,Section Two Q1 2023 private notes, | ||
Second Section,Session One,2,First Mark,Test Council,No,Section Two Q2 2023 notes,,http://example.com,Section Two Q2 2023 private notes, | ||
First Section,Session One,1,Right of Reply,Test Council,,,,http://example.com,Section One Q1 2023 council private notes,Yes | ||
First Section,Session One,2,Right of Reply,Test Council,,,,http://example.com,Section One Q1 2023 council private notes,No | ||
Second Section,Session One,1,Right of Reply,Test Council,,,,http://example.com,Section One Q1 2023 council private notes,Yes | ||
Second Section,Session One,2,Right of Reply,Test Council,,,,http://example.com,Section One Q1 2023 council private notes,No | ||
First Section,Session Two,1,First Mark,Test Council,10% or over,Section One Q1 2025 notes,1,http://example.com,Section One Q1 2025 private notes, | ||
First Section,Session Two,2,First Mark,Test Council,Car share,Section One Q2 2025 notes,2,http://example.com,Section One Q2 2025 private notes, | ||
Second Section,Session Two,1,First Mark,Test Council,Yes,Section Two Q1 2025 notes,34,http://example.com,Section Two Q1 2025 private notes, | ||
Second Section,Session Two,2,First Mark,Test Council,No,Section Two Q2 2025 notes,,http://example.com,Section Two Q2 2025 private notes, |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,215 @@ | ||
from django.conf import settings | ||
from django.contrib.auth.models import User | ||
from django.core.management.base import BaseCommand | ||
|
||
import pandas as pd | ||
|
||
from crowdsourcer.models import ( | ||
MarkingSession, | ||
Option, | ||
PublicAuthority, | ||
Question, | ||
QuestionGroup, | ||
Response, | ||
ResponseType, | ||
Section, | ||
) | ||
|
||
|
||
class Command(BaseCommand): | ||
help = "set up some helpful data for testing" | ||
|
||
question_list = ( | ||
settings.BASE_DIR / "crowdsourcer" / "fixtures" / "test_data_questions.csv" | ||
) | ||
responses_list = ( | ||
settings.BASE_DIR / "crowdsourcer" / "fixtures" / "test_data_responses.csv" | ||
) | ||
|
||
marking_sessions = ["Session One", "Session Two"] | ||
groups = ["Single Tier", "District", "County", "Northern Ireland"] | ||
|
||
sections = [ | ||
"First Section", | ||
"Second Section", | ||
] | ||
|
||
areas = [ | ||
{ | ||
"name": "Test Council", | ||
"type": "CTY", | ||
"gss": "E100001", | ||
}, | ||
{ | ||
"name": "Example Council", | ||
"type": "CTY", | ||
"gss": "E100002", | ||
}, | ||
] | ||
|
||
response_types = ["First Mark", "Right of Reply", "Audit"] | ||
|
||
def add_arguments(self, parser): | ||
parser.add_argument( | ||
"-q", "--quiet", action="store_true", help="Silence progress bars." | ||
) | ||
|
||
def get_group(self, props): | ||
group = "District" | ||
|
||
print(props["name"], props["type"]) | ||
if props["type"] == "LGD": | ||
group = "Northern Ireland" | ||
elif props["type"] in ["CC", "MTD", "LBO", "UTA"]: | ||
group = "Single Tier" | ||
elif props["type"] in ["CTY"]: | ||
group = "County" | ||
|
||
g = QuestionGroup.objects.get(description=group) | ||
return g | ||
|
||
def add_questions(self): | ||
df = pd.read_csv(self.question_list) | ||
for _, question in df.iterrows(): | ||
sections = Section.objects.filter(title=question["section"]).all() | ||
defaults = { | ||
"description": question["question"], | ||
"criteria": question["criteria"], | ||
"question_type": question["type"], | ||
"clarifications": question["clarifications"], | ||
} | ||
|
||
for section in sections: | ||
q, c = Question.objects.update_or_create( | ||
number=int(question["number"]), | ||
section=section, | ||
defaults=defaults, | ||
) | ||
|
||
if q.question_type in ["select_one", "tiered", "multiple_choice"]: | ||
o, c = Option.objects.update_or_create( | ||
question=q, | ||
description="None", | ||
defaults={"score": 0, "ordering": 100}, | ||
) | ||
|
||
for i in range(1, 4): | ||
desc = question[f"option_{i}"] | ||
score = 1 | ||
ordering = i | ||
|
||
o, c = Option.objects.update_or_create( | ||
question=q, | ||
description=desc, | ||
defaults={"score": score, "ordering": ordering}, | ||
) | ||
elif q.question_type == "yes_no": | ||
for desc in ["Yes", "No"]: | ||
ordering = 1 | ||
score = 1 | ||
if desc == "No": | ||
score = 0 | ||
ordering = 2 | ||
o, c = Option.objects.update_or_create( | ||
question=q, | ||
description=desc, | ||
defaults={"score": score, "ordering": ordering}, | ||
) | ||
|
||
for group in QuestionGroup.objects.all(): | ||
q.questiongroup.add(group) | ||
|
||
for section in Section.objects.filter(marking_session__label="Session Two"): | ||
prev_section = Section.objects.get( | ||
title=section.title, marking_session__label="Session One" | ||
) | ||
for question in Question.objects.filter(section=section): | ||
prev_question = Question.objects.get( | ||
number=question.number, section=prev_section | ||
) | ||
question.previous_question = prev_question | ||
question.save() | ||
|
||
def add_responses(self): | ||
df = pd.read_csv(self.responses_list) | ||
for _, response in df.iterrows(): | ||
question = Question.objects.get( | ||
number=response["number"], | ||
section=Section.objects.get( | ||
title=response["section"], | ||
marking_session__label=response["session"], | ||
), | ||
) | ||
|
||
stage = ResponseType.objects.get(type=response["stage"]) | ||
authority = PublicAuthority.objects.get(name=response["authority"]) | ||
defaults = { | ||
"public_notes": response["public_notes"], | ||
"page_number": response["page_number"], | ||
"evidence": response["evidence"], | ||
"private_notes": response["private_notes"], | ||
"user": self.user, | ||
} | ||
|
||
if stage.type != "Right of Reply": | ||
option = Option.objects.get( | ||
question=question, description=response["answer"] | ||
) | ||
|
||
defaults["option"] = option | ||
else: | ||
defaults["agree_with_response"] = False | ||
if response["agree_with_response"] == "Yes": | ||
defaults["agree_with_response"] = True | ||
|
||
_, r = Response.objects.update_or_create( | ||
question=question, | ||
authority=authority, | ||
response_type=stage, | ||
defaults=defaults, | ||
) | ||
|
||
def handle(self, quiet: bool = False, *args, **options): | ||
|
||
for r_type in self.response_types: | ||
r, c = ResponseType.objects.update_or_create(type=r_type, priority=1) | ||
|
||
stage = ResponseType.objects.get(type="First Mark") | ||
|
||
for session in self.marking_sessions: | ||
m, c = MarkingSession.objects.update_or_create( | ||
label=session, | ||
defaults={"active": True, "stage": stage, "start_date": "2024-10-01"}, | ||
) | ||
|
||
for section in self.sections: | ||
s, c = Section.objects.update_or_create( | ||
title=section, marking_session=m | ||
) | ||
|
||
for group in QuestionGroup.objects.all(): | ||
group.marking_session.add(m) | ||
|
||
m.default = True | ||
m.save() | ||
|
||
for area in self.areas: | ||
defaults = { | ||
"name": area["name"], | ||
"questiongroup": self.get_group(area), | ||
"do_not_mark": False, | ||
"type": area["type"], | ||
} | ||
|
||
a, created = PublicAuthority.objects.update_or_create( | ||
unique_id=area["gss"], | ||
defaults=defaults, | ||
) | ||
|
||
for session in MarkingSession.objects.all(): | ||
a.marking_session.add(session) | ||
|
||
self.user, _ = User.objects.get_or_create(username="test_data_user@example.com") | ||
|
||
self.add_questions() | ||
self.add_responses() |