Spaces:
Sleeping
Sleeping
File size: 17,346 Bytes
bf75d52 3603153 bf75d52 a425fa9 895a686 3603153 895a686 a9fe74f a425fa9 7b358db a425fa9 2eb4cf2 7b358db a425fa9 d919aa0 919be7b fb39ca3 2eb4cf2 fb39ca3 c40bc82 09ff2ee 7b358db a9fe74f d460b8a 7b358db 22f31fd 919be7b d460b8a 711dc9d d919aa0 bf75d52 a9fe74f 711dc9d d919aa0 22f31fd 560782b d919aa0 919be7b d919aa0 5053d22 d919aa0 028b757 31d31bd 8f41051 80eb545 f408e8c d919aa0 f4facc1 aa10998 f2c0ef6 80eb545 c40bc82 80eb545 c40bc82 80eb545 c40bc82 80eb545 85f3be6 5053d22 f4facc1 8ac2e2e dc4c04d fb39ca3 dc4c04d fb39ca3 dc4c04d fb39ca3 dc4c04d f4facc1 d460b8a d201c51 796ea23 22f31fd 796ea23 260fa64 7c3fd9a e7103e4 2b0e5c7 e7103e4 796ea23 e7103e4 d201c51 796ea23 d201c51 796ea23 d201c51 d460b8a 260fa64 22f31fd 260fa64 d460b8a 260fa64 22f31fd 260fa64 22f31fd 260fa64 7493d62 2787b29 260fa64 6c36dd2 260fa64 7493d62 2787b29 6c36dd2 22f31fd 2787b29 260fa64 22f31fd 260fa64 22f31fd 2787b29 260fa64 5338729 d201c51 7493d62 d919aa0 8ac2e2e 5338729 95cc5b2 22f31fd 95cc5b2 0d8264c 95cc5b2 8ac2e2e 22f31fd 7493d62 8ac2e2e 0d8264c dc4c04d 8ac2e2e d919aa0 89443f0 a9fe74f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 |
import gradio as gr
import os
# PERSISTENT DATA STORAGE: these are used to upload user responses to a dataset
import json
from datetime import datetime
from pathlib import Path
from uuid import uuid4
from huggingface_hub import CommitScheduler
JSON_DATASET_DIR = Path("json_dataset")
JSON_DATASET_DIR.mkdir(parents=True, exist_ok=True)
JSON_DATASET_PATH = JSON_DATASET_DIR / f"train-{uuid4()}.json"
scheduler = CommitScheduler(
repo_id="ebrowne/test-data",
repo_type="dataset",
folder_path=JSON_DATASET_DIR,
path_in_repo="data",
token = os.getenv("HF_TOKEN")
)
def save_json(score1, score2):
with scheduler.lock:
with JSON_DATASET_PATH.open("a") as f:
json.dump({"relevance": score1, "novelty": score2, "datetime": datetime.now().isoformat()}, f)
f.write("\n")
# READING EXISTING DATA: this is used to read questions
"""
from datasets import load_dataset
qa_data = load_dataset("ebrowne/test-data", data_files = "test.json")
q = qa_data["train"][0] # loaded question data
"""
# VARIABLES: will eventually be loaded with JSON from a dataset
"""
question_text = q["prompt"] + " " + q["question"]
answers_text = [q["a"], q["b"], q["c"], q["d"]]
"""
question_text = "An act of Congress provides that \"no federal court shall order the implementation of a public school desegregation plan that would require the transportation of any student to a school other than the school closest or next closest to his place of residence.\" Which of the following is the strongest argument for the constitutionality of the act?"
answers_text = ["The Fourteenth Amendment authorizes Congress to define governmental conduct which violates the equal protection clause.", "Under Article III, Congress may restrict the jurisdiction of the federal courts.", "Transportation of students is subject to regulation by Congress because commerce is involved.", "Congress provides partial support for public education and is therefore entitled to establish conditions upon the expenditure of federal grants."]
answer_id = 1
passage_texts = ["The IDEA also requires states receiving federal funds to educate disabled children in the \"[l]east restrictive environment\" appropriate for each child. 20 U.S.C. § 1412(a)(5). The statute mandates at § 1412(a)(5)(A):",
"Under the current iteration of Arkansas' school choice law-the 2017 Act-a school that claims a conflict with participating in school choice must show that it is subject to an active and enforceable desegregation court order or plan that \"explicitly limits the transfer of students between school districts.\" Ark. Code Ann. § 6-18-1906(a)(2). Accordingly, for Junction City to receive an exemption from participating in school choice under the 2017 Act, it must show that it is subject to a desegregation order that explicitly bars \"inter-district\" student transfers.",
"This is not to say that a school may unilaterally reject or revise a child's stay-put IEP-that would defang the stay-put requirement entirely. To the contrary, the Supreme Court has made clear that the IDEA \"strip[s] schools of the unilateral authority they had traditionally employed to exclude disabled students.\" Honig , 484 U.S. at 323, 108 S.Ct. 592 (emphasis omitted); see also Sch. Comm. of the Town of Burlington v. Dep't of Educ. , 471 U.S. 359, 373, 105 S.Ct. 1996, 85 L.Ed.2d 385 (1985). Courts should therefore view deviations from the IEP \"with a critical eye to ensure that motivations other than those compatible with the statute, such as bureaucratic inertia, are not driving the decision.\" John M. , 502 F.3d at 715. But context matters; for example, as a child moves \"from elementary school to middle school or from middle school to high school,\" not every change necessitated by a new educational environment will necessarily violate the IDEA. See id. at 714-15.",
"Under § 79-209(2), all schools are required to have a policy that states the number of absences after which the school shall render services to address a student's barriers to attendance. Such services shall include, but not be limited to:",
"To assure that children attending public schools obtain a high quality education, the legislature shall make adequate provision to ensure that ... there are a sufficient number of classrooms ....",
"courts should not disturb a state's denial of IDEA reimbursement where the chief benefits of the chosen school are the kind of advantages that might be preferred by parents of any child, disabled or not. Rather, the unilateral private placement is only appropriate if it provides education instruction [specially ] designed to meet the unique needs of a handicapped child.",
"It is also likely that residents of the States will attend out-of-state schools that invoke the Exemptions, and that such students will seek contraceptive services through programs in their home states, also giving rise to fiscal injuries to the States that only a nationwide injunction can remedy.",
"Although state classifications based on alienage are generally suspect, a state may reserve a government position for citizens if it is related to self-governance, involves policymaking, or requires exercise of important discretionary power over citizens. In these cases, only a rationality test is used. A public school teacher at the primary and secondary school level performs an important governmental function (e.g., he influences students' attitudes about government, the political process, citizenship, etc.), and therefore the exclusion of aliens is rationally related to the state's interest in furthering educational goals. [Ambach v. Norwick (1979)]",
"Passage 9",
"Passage 10"]
generation = "The strongest argument for the constitutionality of the act is that it represents a reasonable balance between achieving school desegregation and respecting local control. It limits federal court orders to prevent overly burdensome transportation requirements for students, aiming to achieve desegregation while minimizing disruption for families. The act is seen as a legitimate exercise of Congress's authority to shape the implementation of federal laws, acknowledging local concerns and practicalities without entirely undermining the desegregation goals."
gold_passage = "Unlike its original jurisdiction, the appellate jurisdiction of the Supreme Court is subject to “exceptions and regulations” prescribed by Congress, and the jurisdiction of the inferior federal courts is subject to congressional prescription. Additionally, Congress has power to regulate modes and practices of proceeding on the part of the inferior federal courts. Whether there are limitations to the exercise of these congressional powers, and what the limitations may be, are matters that have vexed scholarly and judicial interpretation over the years, inasmuch as congressional displeasure with judicial decisions has sometimes led to successful efforts to “curb” the courts and more frequently to proposed but unsuccessful curbs."
gold_passage_generation = "The strongest argument for the constitutionality of the Congressional act is that Congress has the constitutional authority to regulate federal court jurisdiction and procedures. This includes setting limits on judicial orders. By restricting desegregation plans to only require transportation to the nearest or next nearest school, Congress is exercising its power to define and control how federal courts address such issues, ensuring judicial actions align with legislative priorities and practical concerns."
step = 0
mode = 0
sample_dict = {
"question": question_text,
"answers": answers_text,
"correct_answer_index": answer_id,
"top10": passage_texts,
"generation": generation,
"top10_contains_gold_passage": False,
"gold_passage": gold_passage,
"gold_passage_generation": gold_passage_generation
}
# THEMING: colors and styles (Gradio native)
theme = gr.themes.Soft(
primary_hue="sky",
secondary_hue="sky",
neutral_hue="slate",
font=[gr.themes.GoogleFont('Inter'), 'ui-sans-serif', 'system-ui', 'sans-serif'],
)
# BLOCKS: main user interface
user_id = "NO_ID"
with gr.Blocks(theme = theme) as user_eval:
# Title text introducing study
forward_btn = gr.Textbox("unchanged", visible = False, elem_id = "togglebutton") # used for toggling windows
gr.HTML("""
<h1> Legal Retriever Evaluation Study </h1>
<p> Score the passages based on the question and provided answer choices. Detailed instructions are found <a href="https://docs.google.com/document/d/1ReODJ0hlXz_M3kE2UG1cwSRVoyDLQo88OvG71Gt8lUQ/edit?usp=sharing" target="_blank">here</a>. </p>
""")
# Passages and user evaluations thereof
with gr.Row(equal_height = False, visible = False) as evals:
# Passage text
with gr.Column(scale = 2) as passages:
selection = gr.HTML("""
<h2> Retrieved Passage </h2>
<p> """ + passage_texts[0] + "</p>")
line = gr.Markdown("---")
# New answers is able to render the Q and A with formatting. It doesn't change the contents of the answers.
new_answers = answers_text.copy()
new_answers[answer_id] = "**" + answers_text[answer_id] + "** ✅"
passage_display = gr.Markdown("""
## Question and Answer
*""" + question_text +
"""* \n
+ """ + new_answers[0] +
""" \n
+ """ + new_answers[1] +
""" \n
+ """ + new_answers[2] +
""" \n
+ """ + new_answers[3])
# Scoring box
with gr.Column(scale = 1) as scores_p:
desc_0 = gr.Markdown("Does the passage describe **a legal rule?**")
eval_0 = gr.Radio(["Yes", "No"], label = "Legal Rule?")
desc_1 = gr.Markdown("How **relevant** is this passage to the question?")
eval_1 = gr.Slider(1, 5, step = 0.5, label = "Relevance")
desc_2 = gr.Markdown("How would you rate the passage's **quality** in terms of detail, clarity, and focus?")
eval_2 = gr.Slider(1, 5, step = 0.5, label = "Quality")
desc_3 = gr.Markdown("How effectively does the passage **lead you to the correct answer?**")
eval_3 = gr.Slider(1, 5, step = 0.5, label = "Helpfulness")
btn_p = gr.Button("Next")
with gr.Column(scale = 1, visible = False) as scores_g:
helps = gr.Markdown("Does this information **help answer** the question?")
eval_helps = gr.Slider(1, 5, step = 0.5, label = "Helpfulness")
satisfied = gr.Markdown("How **satisfied** are you by this answer?")
eval_satisfied = gr.Slider(1, 5, step = 0.5, label = "User Satisfaction")
btn_g = gr.Button("Next")
def next_p(eval_1, eval_2, eval_3):
global step
global mode
step += 1
print(eval_1 + eval_2 + eval_3)
if step == len(passage_texts):
# Step 10: all sources
collapsible_string = ""
for i, passage in enumerate(passage_texts):
collapsible_string += """
<strong>Passage """ + str(i + 1) + """</strong>
<p> """ + passage + """ </p>
"""
return {
selection: gr.HTML(collapsible_string),
scores_p: gr.Column(visible = False),
scores_g: gr.Column(visible = True)
}
else:
return {
selection: gr.HTML("""
<h2> Retrieved Passage </h2> <br />
""" + passage_texts[step])
}
def next_g(eval_helps, eval_satisfied):
global step
global mode
step += 1
print(eval_helps + eval_satisfied)
if step == 11:
# Step 11: guaranteed to be generation
return {
selection: gr.HTML("""
<h2> Autogenerated Response </h2> <br />
""" + generation)
}
# Steps 12 and 13 are gold passage + gold passage generation IF it is applicable
if step > 11 and not sample_dict["top10_contains_gold_passage"]:
# When mode is 0 -> reset with mode = 1
if mode == 0:
return {
selection: gr.HTML("<p> Loading second set... </p>") ,
forward_btn: gr.Textbox("load new data")
}
# When mode is 1 -> display GP and GP generation, then switch
if step == 12:
return {
selection: gr.HTML("""
<h2> Retrieved Passage </h2> <br />
""" + gold_passage),
forward_btn: gr.Textbox()
}
elif step == 13:
return {
selection: gr.HTML("""
<h2> Autogenerated Response </h2> <br />
""" + gold_passage_generation),
forward_btn: gr.Textbox()
}
else:
return {
selection: gr.Markdown("Advancing to the next question..."),
forward_btn: gr.Textbox("changed")
}
else:
# When mode is 0 -> reset with mode = 1
if mode == 0:
return {
selection: gr.HTML("<p> Loading second set... </p>") ,
forward_btn: gr.Textbox("load new data")
}
# When mode is 1 -> change question
return {
selection: gr.Markdown("Advancing to the next question..."),
forward_btn: gr.Textbox("changed")
}
btn_p.click(fn = next_p, inputs = [eval_1, eval_2, eval_3], outputs = [selection, scores_p, scores_g])
btn_g.click(fn = next_g, inputs = [eval_helps, eval_satisfied], outputs = [selection, forward_btn])
# Question and answering dynamics
with gr.Row(equal_height = False, visible = False) as question:
with gr.Column():
gr.Markdown("---")
gr.Markdown("**Question**")
gr.Markdown(question_text)
a = gr.Button(answers_text[0])
b = gr.Button(answers_text[1])
c = gr.Button(answers_text[2])
d = gr.Button(answers_text[3])
def answer():
return {
question: gr.Row(visible = False),
evals: gr.Row(visible = True)
}
a.click(fn = answer, outputs = [question, evals])
b.click(fn = answer, outputs = [question, evals])
c.click(fn = answer, outputs = [question, evals])
d.click(fn = answer, outputs = [question, evals])
def toggle():
global step
global mode
step = 0
if mode == 0:
mode = 1 # update mode to 1, will restart with same Q, next set of Ps
print("Next set of passages for same question")
return {
scores_p: gr.Column(visible = True),
scores_g: gr.Column(visible = False),
evals: gr.Row(visible = True),
question: gr.Row(visible = False),
}
else:
mode = 0 # reset mode to 0, will restart with new Q, first set of Ps
print("New question")
return {
scores_p: gr.Column(visible = True),
scores_g: gr.Column(visible = False),
evals: gr.Row(visible = False),
question: gr.Row(visible = True),
}
forward_btn.change(fn = toggle, inputs = None, outputs = [scores_p, scores_g, evals, question])
with gr.Row() as login:
with gr.Column():
gr.Markdown("---")
gr.Markdown("# Enter email to start")
gr.Markdown("Thank you so much for your participation in our study! We're using emails to keep track of which questions you've answered and which you haven't seen. Use the same email every time to keep your progress saved. :)")
email = gr.Textbox(label = "Email", placeholder = "[email protected]")
s = gr.Button("Start!")
def submit_email(email):
global user_id
user_id = email
print(user_id)
return {
question: gr.Row(visible = True),
login: gr.Row(visible = False)
}
s.click(fn = submit_email, inputs = [email], outputs = [question, login])
# Starts on question, switches to evaluation after the user answers
user_eval.launch()
# https://github.com/gradio-app/gradio/issues/5791 |