Text Generation
PEFT
Safetensors
English
pyspark
data-engineering
code-generation
qlora
lora
delta-lake
conversational
Instructions to use hoodarunner/pyspark-coding-assistant-lora with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use hoodarunner/pyspark-coding-assistant-lora with PEFT:
from peft import PeftModel from transformers import AutoModelForCausalLM base_model = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-Instruct-v0.3") model = PeftModel.from_pretrained(base_model, "hoodarunner/pyspark-coding-assistant-lora") - Notebooks
- Google Colab
- Kaggle
| """Mutation tests: prove the harness fails plausible-but-wrong code. | |
| A benchmark that only checks "the gold solution passes" is worthless -- an | |
| always-return-True comparator would satisfy that. Every task here gets a | |
| *mutant*: the specific wrong implementation a model actually tends to produce. | |
| The suite asserts the harness rejects it. | |
| If you add a task, add its mutant. CI enforces the pairing. | |
| """ | |
| from __future__ import annotations | |
| import pytest | |
| from spark_eval.harness import evaluate_candidate | |
| from spark_eval.schema import load_tasks | |
| from .conftest import TASKS_DIR | |
| # task_id -> (description of the mistake, wrong implementation) | |
| MUTANTS: dict[str, tuple[str, str]] = { | |
| "join_anti_null_key": ( | |
| "treats anti-join as set difference, dropping NULL-keyed rows", | |
| """ | |
| from pyspark.sql import functions as F | |
| def solve(spark, orders, customers): | |
| ids = [r[0] for r in customers.select("customer_id").collect()] | |
| return orders.filter(~F.col("customer_id").isin(ids)) | |
| """, | |
| ), | |
| "join_fanout_duplicate_keys": ( | |
| "dedups the right side first, so the fanout never happens", | |
| """ | |
| from pyspark.sql import functions as F | |
| def solve(spark, sales, rates): | |
| r = rates.dropDuplicates(["region"]) | |
| return (sales.join(r, on="region", how="inner") | |
| .groupBy("region") | |
| .agg(F.sum(F.col("amount") * F.col("multiplier")).alias("total"))) | |
| """, | |
| ), | |
| "window_default_frame_ties": ( | |
| "uses an explicit ROWS frame instead of the default RANGE frame", | |
| """ | |
| from pyspark.sql import functions as F | |
| from pyspark.sql.window import Window | |
| def solve(spark, events): | |
| w = Window.partitionBy("user").orderBy("ts").rowsBetween( | |
| Window.unboundedPreceding, Window.currentRow | |
| ) | |
| return events.withColumn("running", F.sum("value").over(w)) | |
| """, | |
| ), | |
| "window_rank_family_ties": ( | |
| "uses row_number() for all three columns, erasing tie behaviour", | |
| """ | |
| from pyspark.sql import functions as F | |
| from pyspark.sql.window import Window | |
| def solve(spark, scores): | |
| w = Window.partitionBy("team").orderBy(F.col("points").desc(), F.col("player").asc()) | |
| return (scores | |
| .withColumn("rnk", F.row_number().over(w)) | |
| .withColumn("dense", F.row_number().over(w)) | |
| .withColumn("rownum", F.row_number().over(w)) | |
| .orderBy(F.col("team").asc(), F.col("points").desc(), F.col("player").asc())) | |
| """, | |
| ), | |
| "agg_count_null_semantics": ( | |
| "uses count('*') everywhere, ignoring NULL and DISTINCT semantics", | |
| """ | |
| from pyspark.sql import functions as F | |
| def solve(spark, staff): | |
| return staff.groupBy("dept").agg( | |
| F.count(F.lit(1)).alias("n_rows"), | |
| F.count(F.lit(1)).alias("n_emails"), | |
| F.count(F.lit(1)).alias("n_distinct"), | |
| ) | |
| """, | |
| ), | |
| "null_sum_all_null_group": ( | |
| "plain sum(), so the all-NULL group returns NULL instead of 0", | |
| """ | |
| from pyspark.sql import functions as F | |
| def solve(spark, readings): | |
| return readings.groupBy("region").agg(F.sum("value").cast("long").alias("total")) | |
| """, | |
| ), | |
| "null_safe_equality_join": ( | |
| "plain equality, which silently drops the NULL/NULL pair", | |
| """ | |
| from pyspark.sql import functions as F | |
| def solve(spark, left_t, right_t): | |
| return (left_t.join(right_t, left_t["code"] == right_t["code"], "inner") | |
| .select(left_t["code"].alias("code"), "lval", "rval")) | |
| """, | |
| ), | |
| "nested_explode_outer_empty": ( | |
| "explode() instead of explode_outer(), dropping empty/null arrays", | |
| """ | |
| from pyspark.sql import functions as F | |
| def solve(spark, docs): | |
| return docs.select("doc_id", F.explode("tags").alias("tag")) | |
| """, | |
| ), | |
| "upsert_latest_version": ( | |
| "overwrite instead of upsert: target-only rows are lost", | |
| """ | |
| from pyspark.sql import functions as F | |
| from pyspark.sql.window import Window | |
| def solve(spark, target, updates): | |
| w = Window.partitionBy("id").orderBy(F.col("version").desc()) | |
| return (updates.withColumn("_rn", F.row_number().over(w)) | |
| .filter(F.col("_rn") == 1) | |
| .drop("_rn")) | |
| """, | |
| ), | |
| "udf_null_input_handling": ( | |
| "no None guard, so the UDF raises on the NULL row", | |
| """ | |
| from pyspark.sql import functions as F | |
| from pyspark.sql.types import IntegerType | |
| def solve(spark, notes): | |
| word_udf = F.udf(lambda s: len(s.split()), IntegerType()) | |
| return notes.withColumn("n_words", word_udf(F.col("text"))) | |
| """, | |
| ), | |
| "sql_having_to_dataframe": ( | |
| "applies HAVING as a WHERE, filtering rows instead of groups", | |
| """ | |
| from pyspark.sql import functions as F | |
| def solve(spark, txns): | |
| return (txns | |
| .filter(F.col("status") == "ok") | |
| .groupBy("store") | |
| .agg(F.sum("amount").alias("total")) | |
| .orderBy(F.col("total").desc())) | |
| """, | |
| ), | |
| "agg_pivot_fill": ( | |
| "forgets fillna, leaving NULL for absent store/quarter combinations", | |
| """ | |
| from pyspark.sql import functions as F | |
| def solve(spark, sales_long): | |
| return (sales_long.groupBy("store") | |
| .pivot("quarter", ["Q1", "Q2", "Q3"]) | |
| .agg(F.sum("amount"))) | |
| """, | |
| ), | |
| } | |
| ALL_TASKS = {t.id: t for t in load_tasks(TASKS_DIR)} | |
| def test_every_task_has_a_mutant(): | |
| """Keeps the two files honest with each other.""" | |
| missing = sorted(set(ALL_TASKS) - set(MUTANTS)) | |
| orphaned = sorted(set(MUTANTS) - set(ALL_TASKS)) | |
| assert not missing, f"tasks with no mutant test: {missing}" | |
| assert not orphaned, f"mutants for tasks that no longer exist: {orphaned}" | |
| def test_mutant_is_rejected(spark, task_id): | |
| task = ALL_TASKS[task_id] | |
| description, code = MUTANTS[task_id] | |
| result = evaluate_candidate(spark, task, code, timeout=90) | |
| assert result.status != "reference_broken", ( | |
| f"{task_id}: the reference solution itself failed -- fix the task, " | |
| f"not the mutant ({result.detail})" | |
| ) | |
| assert not result.ok, ( | |
| f"{task_id}: harness ACCEPTED a wrong answer ({description}). " | |
| f"The task cannot distinguish correct from incorrect code; " | |
| f"strengthen the fixtures." | |
| ) | |