[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M7BTCSWV2GKXCME7P0BXP425":3,"skill-same:01M7BTCSWV2GKXCME7P0BXP425":45},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":19,"linkOnly":20,"markdownContent":21,"markdownBody":22,"frontMatter":23,"refName":24,"commitSha":25,"skillDirectory":26,"forksCount":27,"repositoryHtmlUrl":28,"repositoryHomepageUrl":6,"ownerHtmlUrl":29,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":30,"install":31,"resources":44},"01M7BTCSWV2GKXCME7P0BXP425","python-scala-libraries",null,"Guide for mapping common Python libraries and idioms to Scala equivalents. Use when converting Python code that uses standard library modules (json, datetime, os, re, logging) or needs equivalent Scala libraries for HTTP, testing, or async operations.","linyouxue\u002Fskill-repair-benchmark","linyouxue","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F216151464?v=4","01M7BJEVCXKD74KH6FG9CBVSQB","林宥学","01M7BJEVE02NP217V93BKZFC0J",0,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Flinyouxue\u002Fskill-repair-benchmark\u002Fblob\u002Fmain\u002Fevaluation\u002Fresults\u002FMMG2Skill-GPT52-Gold31-20260923\u002Fruns\u002Fmmg2skill-gpt52-gold31-20260923\u002Fpython-scala-translation-mmg2skill-gpt52-r001\u002Finputs\u002Fskills\u002Fpython-scala-libraries\u002FSKILL.md",[],[],"2026-11-15 14:19:17",false,"---\nname: python-scala-libraries\ndescription: Guide for mapping common Python libraries and idioms to Scala equivalents. Use when converting Python code that uses standard library modules (json, datetime, os, re, logging) or needs equivalent Scala libraries for HTTP, testing, or async operations.\n---\n\n# Python to Scala Library Mappings\n## JSON Handling\n```python\n# Python\nimport json\ndata = {\"name\": \"Alice\", \"age\": 30}\njson_str = json.dumps(data)\nparsed = json.loads(json_str)\n# With dataclass\nfrom dataclasses import dataclass, asdict\n@dataclass\nclass Person:\n    name: str\n    age: int\nperson = Person(\"Alice\", 30)\njson.dumps(asdict(person))\n```\n```scala\n\u002F\u002F Scala - circe (most popular)\nimport io.circe._\nimport io.circe.generic.auto._\nimport io.circe.syntax._\nimport io.circe.parser._\ncase class Person(name: String, age: Int)\nval person = Person(\"Alice\", 30)\nval jsonStr: String = person.asJson.noSpaces\nval parsed: Either[Error, Person] = decode[Person](jsonStr)\n\u002F\u002F Scala - play-json\nimport play.api.libs.json._\ncase class Person(name: String, age: Int)\nimplicit val personFormat: Format[Person] = Json.format[Person]\nval json = Json.toJson(person)\nval parsed = json.as[Person]\n```\n## Date and Time\n```python\n# Python\nfrom datetime import datetime, date, timedelta\nimport pytz\nnow = datetime.now()\ntoday = date.today()\nspecific = datetime(2024, 1, 15, 10, 30)\nformatted = now.strftime(\"%Y-%m-%d %H:%M:%S\")\nparsed = datetime.strptime(\"2024-01-15\", \"%Y-%m-%d\")\ntomorrow = now + timedelta(days=1)\n# Timezone\nutc_now = datetime.now(pytz.UTC)\n```\n```scala\n\u002F\u002F Scala - java.time (recommended)\nimport java.time._\nimport java.time.format.DateTimeFormatter\nval now = LocalDateTime.now()\nval today = LocalDate.now()\nval specific = LocalDateTime.of(2024, 1, 15, 10, 30)\nval formatted = now.format(DateTimeFormatter.ofPattern(\"yyyy-MM-dd HH:mm:ss\"))\nval parsed = LocalDate.parse(\"2024-01-15\")\nval tomorrow = now.plusDays(1)\n\u002F\u002F Timezone\nval utcNow = ZonedDateTime.now(ZoneOffset.UTC)\nval instant = Instant.now()\n```\n## File Operations\n```python\n# Python\nfrom pathlib import Path\nimport os\n# Reading\nwith open(\"file.txt\", \"r\") as f:\n    content = f.read()\n    lines = f.readlines()\n# Writing\nwith open(\"file.txt\", \"w\") as f:\n    f.write(\"Hello\")\n# Path operations\npath = Path(\"dir\u002Ffile.txt\")\npath.exists()\npath.parent\npath.name\npath.suffix\nlist(Path(\".\").glob(\"*.txt\"))\nos.makedirs(\"new\u002Fdir\", exist_ok=True)\n```\n```scala\n\u002F\u002F Scala - java.nio.file (standard) + scala.io\nimport java.nio.file.{Files, Path, Paths}\nimport scala.io.Source\nimport scala.util.Using\n\u002F\u002F Reading\nval content = Source.fromFile(\"file.txt\").mkString\nUsing(Source.fromFile(\"file.txt\")) { source =>\n  source.getLines().toList\n}\n\u002F\u002F Writing\nFiles.writeString(Paths.get(\"file.txt\"), \"Hello\")\n\u002F\u002F Path operations\nval path = Paths.get(\"dir\u002Ffile.txt\")\nFiles.exists(path)\npath.getParent\npath.getFileName\n\u002F\u002F Extension: path.toString.split('.').lastOption\nFiles.createDirectories(Paths.get(\"new\u002Fdir\"))\n\u002F\u002F os-lib (better alternative)\n\u002F\u002F import os._\n\u002F\u002F os.read(os.pwd \u002F \"file.txt\")\n\u002F\u002F os.write(os.pwd \u002F \"file.txt\", \"Hello\")\n```\n## Regular Expressions\n```python\n# Python\nimport re\npattern = r\"\\d+\"\ntext = \"abc123def456\"\n# Search\nmatch = re.search(pattern, text)\nif match:\n    print(match.group())\n# Find all\nmatches = re.findall(pattern, text)\n# Replace\nresult = re.sub(pattern, \"X\", text)\n# Split\nparts = re.split(r\"\\s+\", \"a b  c\")\n```\n```scala\n\u002F\u002F Scala\nval pattern = \"\"\"\\d+\"\"\".r\nval text = \"abc123def456\"\n\u002F\u002F Search\npattern.findFirstIn(text) match {\n  case Some(m) => println(m)\n  case None => ()\n}\n\u002F\u002F Find all\nval matches = pattern.findAllIn(text).toList\n\u002F\u002F Replace\nval result = pattern.replaceAllIn(text, \"X\")\n\u002F\u002F Split\nval parts = \"\"\"\\s+\"\"\".r.split(\"a b  c\").toList\n\u002F\u002F Pattern matching with regex\nval datePattern = \"\"\"(\\d{4})-(\\d{2})-(\\d{2})\"\"\".r\n\"2024-01-15\" match {\n  case datePattern(year, month, day) => s\"$year\u002F$month\u002F$day\"\n  case _ => \"no match\"\n}\n```\n## HTTP Requests\n```python\n# Python\nimport requests\nresponse = requests.get(\"https:\u002F\u002Fapi.example.com\u002Fdata\")\ndata = response.json()\nresponse = requests.post(\n    \"https:\u002F\u002Fapi.example.com\u002Fdata\",\n    json={\"key\": \"value\"},\n    headers={\"Authorization\": \"Bearer token\"}\n)\n```\n```scala\n\u002F\u002F Scala - sttp (recommended)\nimport sttp.client3._\nimport sttp.client3.circe._\nimport io.circe.generic.auto._\nval backend = HttpURLConnectionBackend()\nval response = basicRequest\n  .get(uri\"https:\u002F\u002Fapi.example.com\u002Fdata\")\n  .send(backend)\nval postResponse = basicRequest\n  .post(uri\"https:\u002F\u002Fapi.example.com\u002Fdata\")\n  .body(\"\"\"{\"key\": \"value\"}\"\"\")\n  .header(\"Authorization\", \"Bearer token\")\n  .send(backend)\n```\n## Logging\n```python\n# Python\nimport logging\nlogging.basicConfig(level=logging.INFO)\nlogger = logging.getLogger(__name__)\nlogger.debug(\"Debug message\")\nlogger.info(\"Info message\")\nlogger.warning(\"Warning message\")\nlogger.error(\"Error message\", exc_info=True)\n```\n```scala\n\u002F\u002F Scala - scala-logging with logback\nimport com.typesafe.scalalogging.LazyLogging\nclass MyClass extends LazyLogging {\n  logger.debug(\"Debug message\")\n  logger.info(\"Info message\")\n  logger.warn(\"Warning message\")\n  logger.error(\"Error message\", exception)\n}\n\u002F\u002F Alternative: slf4j directly\nimport org.slf4j.LoggerFactory\nval logger = LoggerFactory.getLogger(getClass)\n```\n## Testing\n```python\n# Python - pytest\nimport pytest\ndef test_addition():\n    assert 1 + 1 == 2\n@pytest.fixture\ndef sample_data():\n    return {\"key\": \"value\"}\ndef test_with_fixture(sample_data):\n    assert sample_data[\"key\"] == \"value\"\n@pytest.mark.parametrize(\"input,expected\", [\n    (1, 2),\n    (2, 4),\n])\ndef test_double(input, expected):\n    assert input * 2 == expected\n```\n```scala\n\u002F\u002F Scala - ScalaTest\nimport org.scalatest.flatspec.AnyFlatSpec\nimport org.scalatest.matchers.should.Matchers\nclass MySpec extends AnyFlatSpec with Matchers {\n  \"Addition\" should \"work\" in {\n    1 + 1 shouldEqual 2\n  }\n  it should \"handle negative numbers\" in {\n    -1 + 1 shouldEqual 0\n  }\n}\n\u002F\u002F Table-driven tests\nimport org.scalatest.prop.TableDrivenPropertyChecks._\nval examples = Table(\n  (\"input\", \"expected\"),\n  (1, 2),\n  (2, 4)\n)\nforAll(examples) { (input, expected) =>\n  input * 2 shouldEqual expected\n}\n\u002F\u002F Scala - munit (simpler alternative)\nclass MySuite extends munit.FunSuite {\n  test(\"addition\") {\n    assertEquals(1 + 1, 2)\n  }\n}\n```\n## Async\u002FConcurrent Operations\n```python\n# Python\nimport asyncio\nasync def fetch_data(url: str) -> str:\n    # async HTTP call\n    await asyncio.sleep(1)\n    return \"data\"\nasync def main():\n    results = await asyncio.gather(\n        fetch_data(\"url1\"),\n        fetch_data(\"url2\"),\n    )\n```\n```scala\n\u002F\u002F Scala - Future (standard)\nimport scala.concurrent.{Future, ExecutionContext}\nimport scala.concurrent.ExecutionContext.Implicits.global\ndef fetchData(url: String): Future[String] = Future {\n  Thread.sleep(1000)\n  \"data\"\n}\nval results: Future[List[String]] = Future.sequence(List(\n  fetchData(\"url1\"),\n  fetchData(\"url2\")\n))\n\u002F\u002F Scala - cats-effect IO (preferred for FP)\nimport cats.effect.IO\nimport cats.syntax.parallel._\ndef fetchData(url: String): IO[String] = IO.sleep(1.second) *> IO.pure(\"data\")\nval results: IO[List[String]] = List(\n  fetchData(\"url1\"),\n  fetchData(\"url2\")\n).parSequence\n```\n## Configuration\n```python\n# Python\nimport os\nfrom dataclasses import dataclass\n@dataclass\nclass Config:\n    db_host: str = os.getenv(\"DB_HOST\", \"localhost\")\n    db_port: int = int(os.getenv(\"DB_PORT\", \"5432\"))\n```\n```scala\n\u002F\u002F Scala - pureconfig\nimport pureconfig._\nimport pureconfig.generic.auto._\ncase class Config(dbHost: String, dbPort: Int)\nval config = ConfigSource.default.loadOrThrow[Config]\n\u002F\u002F application.conf (HOCON format)\n\u002F\u002F db-host = \"localhost\"\n\u002F\u002F db-host = ${?DB_HOST}\n\u002F\u002F db-port = 5432\n```\n## Command Line Arguments\n```python\n# Python\nimport argparse\nparser = argparse.ArgumentParser()\nparser.add_argument(\"--name\", required=True)\nparser.add_argument(\"--count\", type=int, default=1)\nargs = parser.parse_args()\n```\n```scala\n\u002F\u002F Scala - scopt\nimport scopt.OParser\ncase class Config(name: String = \"\", count: Int = 1)\nval builder = OParser.builder[Config]\nval parser = {\n  import builder._\n  OParser.sequence(\n    opt[String](\"name\").required().action((x, c) => c.copy(name = x)),\n    opt[Int](\"count\").action((x, c) => c.copy(count = x))\n  )\n}\nOParser.parse(parser, args, Config()) match {\n  case Some(config) => \u002F\u002F use config\n  case None => \u002F\u002F arguments are bad\n}\n\u002F\u002F Scala - decline (FP style)\nimport com.monovore.decline._\nval nameOpt = Opts.option[String](\"name\", \"Name\")\nval countOpt = Opts.option[Int](\"count\", \"Count\").withDefault(1)\nval command = Command(\"app\", \"Description\") {\n  (nameOpt, countOpt).tupled\n}\n```\n## Build Tools Comparison\n| Python | Scala |\n|--------|-------|\n| pip\u002Fpoetry | sbt\u002Fmill |\n| requirements.txt | build.sbt |\n| pyproject.toml | build.sbt |\n| setup.py | build.sbt |\n| virtualenv | Project-local dependencies (automatic) |\n","# Python to Scala Library Mappings\n## JSON Handling\n```python\n# Python\nimport json\ndata = {\"name\": \"Alice\", \"age\": 30}\njson_str = json.dumps(data)\nparsed = json.loads(json_str)\n# With dataclass\nfrom dataclasses import dataclass, asdict\n@dataclass\nclass Person:\n    name: str\n    age: int\nperson = Person(\"Alice\", 30)\njson.dumps(asdict(person))\n```\n```scala\n\u002F\u002F Scala - circe (most popular)\nimport io.circe._\nimport io.circe.generic.auto._\nimport io.circe.syntax._\nimport io.circe.parser._\ncase class Person(name: String, age: Int)\nval person = Person(\"Alice\", 30)\nval jsonStr: String = person.asJson.noSpaces\nval parsed: Either[Error, Person] = decode[Person](jsonStr)\n\u002F\u002F Scala - play-json\nimport play.api.libs.json._\ncase class Person(name: String, age: Int)\nimplicit val personFormat: Format[Person] = Json.format[Person]\nval json = Json.toJson(person)\nval parsed = json.as[Person]\n```\n## Date and Time\n```python\n# Python\nfrom datetime import datetime, date, timedelta\nimport pytz\nnow = datetime.now()\ntoday = date.today()\nspecific = datetime(2024, 1, 15, 10, 30)\nformatted = now.strftime(\"%Y-%m-%d %H:%M:%S\")\nparsed = datetime.strptime(\"2024-01-15\", \"%Y-%m-%d\")\ntomorrow = now + timedelta(days=1)\n# Timezone\nutc_now = datetime.now(pytz.UTC)\n```\n```scala\n\u002F\u002F Scala - java.time (recommended)\nimport java.time._\nimport java.time.format.DateTimeFormatter\nval now = LocalDateTime.now()\nval today = LocalDate.now()\nval specific = LocalDateTime.of(2024, 1, 15, 10, 30)\nval formatted = now.format(DateTimeFormatter.ofPattern(\"yyyy-MM-dd HH:mm:ss\"))\nval parsed = LocalDate.parse(\"2024-01-15\")\nval tomorrow = now.plusDays(1)\n\u002F\u002F Timezone\nval utcNow = ZonedDateTime.now(ZoneOffset.UTC)\nval instant = Instant.now()\n```\n## File Operations\n```python\n# Python\nfrom pathlib import Path\nimport os\n# Reading\nwith open(\"file.txt\", \"r\") as f:\n    content = f.read()\n    lines = f.readlines()\n# Writing\nwith open(\"file.txt\", \"w\") as f:\n    f.write(\"Hello\")\n# Path operations\npath = Path(\"dir\u002Ffile.txt\")\npath.exists()\npath.parent\npath.name\npath.suffix\nlist(Path(\".\").glob(\"*.txt\"))\nos.makedirs(\"new\u002Fdir\", exist_ok=True)\n```\n```scala\n\u002F\u002F Scala - java.nio.file (standard) + scala.io\nimport java.nio.file.{Files, Path, Paths}\nimport scala.io.Source\nimport scala.util.Using\n\u002F\u002F Reading\nval content = Source.fromFile(\"file.txt\").mkString\nUsing(Source.fromFile(\"file.txt\")) { source =>\n  source.getLines().toList\n}\n\u002F\u002F Writing\nFiles.writeString(Paths.get(\"file.txt\"), \"Hello\")\n\u002F\u002F Path operations\nval path = Paths.get(\"dir\u002Ffile.txt\")\nFiles.exists(path)\npath.getParent\npath.getFileName\n\u002F\u002F Extension: path.toString.split('.').lastOption\nFiles.createDirectories(Paths.get(\"new\u002Fdir\"))\n\u002F\u002F os-lib (better alternative)\n\u002F\u002F import os._\n\u002F\u002F os.read(os.pwd \u002F \"file.txt\")\n\u002F\u002F os.write(os.pwd \u002F \"file.txt\", \"Hello\")\n```\n## Regular Expressions\n```python\n# Python\nimport re\npattern = r\"\\d+\"\ntext = \"abc123def456\"\n# Search\nmatch = re.search(pattern, text)\nif match:\n    print(match.group())\n# Find all\nmatches = re.findall(pattern, text)\n# Replace\nresult = re.sub(pattern, \"X\", text)\n# Split\nparts = re.split(r\"\\s+\", \"a b  c\")\n```\n```scala\n\u002F\u002F Scala\nval pattern = \"\"\"\\d+\"\"\".r\nval text = \"abc123def456\"\n\u002F\u002F Search\npattern.findFirstIn(text) match {\n  case Some(m) => println(m)\n  case None => ()\n}\n\u002F\u002F Find all\nval matches = pattern.findAllIn(text).toList\n\u002F\u002F Replace\nval result = pattern.replaceAllIn(text, \"X\")\n\u002F\u002F Split\nval parts = \"\"\"\\s+\"\"\".r.split(\"a b  c\").toList\n\u002F\u002F Pattern matching with regex\nval datePattern = \"\"\"(\\d{4})-(\\d{2})-(\\d{2})\"\"\".r\n\"2024-01-15\" match {\n  case datePattern(year, month, day) => s\"$year\u002F$month\u002F$day\"\n  case _ => \"no match\"\n}\n```\n## HTTP Requests\n```python\n# Python\nimport requests\nresponse = requests.get(\"https:\u002F\u002Fapi.example.com\u002Fdata\")\ndata = response.json()\nresponse = requests.post(\n    \"https:\u002F\u002Fapi.example.com\u002Fdata\",\n    json={\"key\": \"value\"},\n    headers={\"Authorization\": \"Bearer token\"}\n)\n```\n```scala\n\u002F\u002F Scala - sttp (recommended)\nimport sttp.client3._\nimport sttp.client3.circe._\nimport io.circe.generic.auto._\nval backend = HttpURLConnectionBackend()\nval response = basicRequest\n  .get(uri\"https:\u002F\u002Fapi.example.com\u002Fdata\")\n  .send(backend)\nval postResponse = basicRequest\n  .post(uri\"https:\u002F\u002Fapi.example.com\u002Fdata\")\n  .body(\"\"\"{\"key\": \"value\"}\"\"\")\n  .header(\"Authorization\", \"Bearer token\")\n  .send(backend)\n```\n## Logging\n```python\n# Python\nimport logging\nlogging.basicConfig(level=logging.INFO)\nlogger = logging.getLogger(__name__)\nlogger.debug(\"Debug message\")\nlogger.info(\"Info message\")\nlogger.warning(\"Warning message\")\nlogger.error(\"Error message\", exc_info=True)\n```\n```scala\n\u002F\u002F Scala - scala-logging with logback\nimport com.typesafe.scalalogging.LazyLogging\nclass MyClass extends LazyLogging {\n  logger.debug(\"Debug message\")\n  logger.info(\"Info message\")\n  logger.warn(\"Warning message\")\n  logger.error(\"Error message\", exception)\n}\n\u002F\u002F Alternative: slf4j directly\nimport org.slf4j.LoggerFactory\nval logger = LoggerFactory.getLogger(getClass)\n```\n## Testing\n```python\n# Python - pytest\nimport pytest\ndef test_addition():\n    assert 1 + 1 == 2\n@pytest.fixture\ndef sample_data():\n    return {\"key\": \"value\"}\ndef test_with_fixture(sample_data):\n    assert sample_data[\"key\"] == \"value\"\n@pytest.mark.parametrize(\"input,expected\", [\n    (1, 2),\n    (2, 4),\n])\ndef test_double(input, expected):\n    assert input * 2 == expected\n```\n```scala\n\u002F\u002F Scala - ScalaTest\nimport org.scalatest.flatspec.AnyFlatSpec\nimport org.scalatest.matchers.should.Matchers\nclass MySpec extends AnyFlatSpec with Matchers {\n  \"Addition\" should \"work\" in {\n    1 + 1 shouldEqual 2\n  }\n  it should \"handle negative numbers\" in {\n    -1 + 1 shouldEqual 0\n  }\n}\n\u002F\u002F Table-driven tests\nimport org.scalatest.prop.TableDrivenPropertyChecks._\nval examples = Table(\n  (\"input\", \"expected\"),\n  (1, 2),\n  (2, 4)\n)\nforAll(examples) { (input, expected) =>\n  input * 2 shouldEqual expected\n}\n\u002F\u002F Scala - munit (simpler alternative)\nclass MySuite extends munit.FunSuite {\n  test(\"addition\") {\n    assertEquals(1 + 1, 2)\n  }\n}\n```\n## Async\u002FConcurrent Operations\n```python\n# Python\nimport asyncio\nasync def fetch_data(url: str) -> str:\n    # async HTTP call\n    await asyncio.sleep(1)\n    return \"data\"\nasync def main():\n    results = await asyncio.gather(\n        fetch_data(\"url1\"),\n        fetch_data(\"url2\"),\n    )\n```\n```scala\n\u002F\u002F Scala - Future (standard)\nimport scala.concurrent.{Future, ExecutionContext}\nimport scala.concurrent.ExecutionContext.Implicits.global\ndef fetchData(url: String): Future[String] = Future {\n  Thread.sleep(1000)\n  \"data\"\n}\nval results: Future[List[String]] = Future.sequence(List(\n  fetchData(\"url1\"),\n  fetchData(\"url2\")\n))\n\u002F\u002F Scala - cats-effect IO (preferred for FP)\nimport cats.effect.IO\nimport cats.syntax.parallel._\ndef fetchData(url: String): IO[String] = IO.sleep(1.second) *> IO.pure(\"data\")\nval results: IO[List[String]] = List(\n  fetchData(\"url1\"),\n  fetchData(\"url2\")\n).parSequence\n```\n## Configuration\n```python\n# Python\nimport os\nfrom dataclasses import dataclass\n@dataclass\nclass Config:\n    db_host: str = os.getenv(\"DB_HOST\", \"localhost\")\n    db_port: int = int(os.getenv(\"DB_PORT\", \"5432\"))\n```\n```scala\n\u002F\u002F Scala - pureconfig\nimport pureconfig._\nimport pureconfig.generic.auto._\ncase class Config(dbHost: String, dbPort: Int)\nval config = ConfigSource.default.loadOrThrow[Config]\n\u002F\u002F application.conf (HOCON format)\n\u002F\u002F db-host = \"localhost\"\n\u002F\u002F db-host = ${?DB_HOST}\n\u002F\u002F db-port = 5432\n```\n## Command Line Arguments\n```python\n# Python\nimport argparse\nparser = argparse.ArgumentParser()\nparser.add_argument(\"--name\", required=True)\nparser.add_argument(\"--count\", type=int, default=1)\nargs = parser.parse_args()\n```\n```scala\n\u002F\u002F Scala - scopt\nimport scopt.OParser\ncase class Config(name: String = \"\", count: Int = 1)\nval builder = OParser.builder[Config]\nval parser = {\n  import builder._\n  OParser.sequence(\n    opt[String](\"name\").required().action((x, c) => c.copy(name = x)),\n    opt[Int](\"count\").action((x, c) => c.copy(count = x))\n  )\n}\nOParser.parse(parser, args, Config()) match {\n  case Some(config) => \u002F\u002F use config\n  case None => \u002F\u002F arguments are bad\n}\n\u002F\u002F Scala - decline (FP style)\nimport com.monovore.decline._\nval nameOpt = Opts.option[String](\"name\", \"Name\")\nval countOpt = Opts.option[Int](\"count\", \"Count\").withDefault(1)\nval command = Command(\"app\", \"Description\") {\n  (nameOpt, countOpt).tupled\n}\n```\n## Build Tools Comparison\n| Python | Scala |\n|--------|-------|\n| pip\u002Fpoetry | sbt\u002Fmill |\n| requirements.txt | build.sbt |\n| pyproject.toml | build.sbt |\n| setup.py | build.sbt |\n| virtualenv | Project-local dependencies (automatic) |\n",{"name":5,"description":7},"main","cdcb6d230f3b15c3c33f8a2bdd16439f43602cbe","evaluation\u002Fresults\u002FMMG2Skill-GPT52-Gold31-20260923\u002Fruns\u002Fmmg2skill-gpt52-gold31-20260923\u002Fpython-scala-translation-mmg2skill-gpt52-r001\u002Finputs\u002Fskills\u002Fpython-scala-libraries",1,"https:\u002F\u002Fgithub.com\u002Flinyouxue\u002Fskill-repair-benchmark","https:\u002F\u002Fgithub.com\u002Flinyouxue","2026-11-14 20:28:35",{"source":8,"skillName":5,"commands":32,"prompt":42,"zipAvailable":43},[33,36,39],{"tool":34,"command":35},"npx","npx skills add linyouxue\u002Fskill-repair-benchmark --skill python-scala-libraries",{"tool":37,"command":38},"bunx","bunx skills add linyouxue\u002Fskill-repair-benchmark --skill python-scala-libraries",{"tool":40,"command":41},"pnpm","pnpm dlx skills add linyouxue\u002Fskill-repair-benchmark --skill python-scala-libraries","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Flinyouxue\u002Fskill-repair-benchmark\u002Fblob\u002Fmain\u002Fevaluation\u002Fresults\u002FMMG2Skill-GPT52-Gold31-20260923\u002Fruns\u002Fmmg2skill-gpt52-gold31-20260923\u002Fpython-scala-translation-mmg2skill-gpt52-r001\u002Finputs\u002Fskills\u002Fpython-scala-libraries\u002FSKILL.md",true,[],[46,53,60,67,72,77],{"skillNo":47,"name":48,"nameZh":6,"description":49,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":50,"categories":51,"keywords":52,"publishedAt":19},"01M7E1HGVRY73NBJ022CJG13X6","video-frame-extraction","Extract frames from video files and save them as images using OpenCV","https:\u002F\u002Fgithub.com\u002Flinyouxue\u002Fskill-repair-benchmark\u002Fblob\u002Fmain\u002Fjpg-ocr-stat\u002Fresult\u002Fskilltta-claude4.7\u002Fgroup_03\u002Frun_03\u002Finputs\u002Fskills\u002Fvideo-frame-extraction\u002FSKILL.md",[],[],{"skillNo":54,"name":55,"nameZh":6,"description":56,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":57,"categories":58,"keywords":59,"publishedAt":19},"01M7E1HAG5R7CJ9C8NYJS771MB","openai-vision","Analyze images and multi-frame sequences using OpenAI GPT vision models","https:\u002F\u002Fgithub.com\u002Flinyouxue\u002Fskill-repair-benchmark\u002Fblob\u002Fmain\u002Fjpg-ocr-stat\u002Fresult\u002Fskilltta-claude4.7\u002Fgroup_03\u002Frun_03\u002Finputs\u002Fskills\u002Fopenai-vision\u002FSKILL.md",[],[],{"skillNo":61,"name":62,"nameZh":6,"description":63,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":64,"categories":65,"keywords":66,"publishedAt":19},"01M7E1H7DADKB6QBWKC2KQ63SZ","image-ocr","Extract text content from images using Tesseract OCR via Python, including structured field extraction from receipts and forms","https:\u002F\u002Fgithub.com\u002Flinyouxue\u002Fskill-repair-benchmark\u002Fblob\u002Fmain\u002Fjpg-ocr-stat\u002Fresult\u002Fskilltta-claude4.7\u002Fgroup_03\u002Frun_03\u002Finputs\u002Fskills\u002Fimage-ocr\u002FSKILL.md",[],[],{"skillNo":68,"name":48,"nameZh":6,"description":49,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":69,"categories":70,"keywords":71,"publishedAt":19},"01M7E1H0WBNT43TENGQY7AVZHD","https:\u002F\u002Fgithub.com\u002Flinyouxue\u002Fskill-repair-benchmark\u002Fblob\u002Fmain\u002Fjpg-ocr-stat\u002Fresult\u002Fskilltta-claude4.7\u002Fgroup_03\u002Frun_02\u002Finputs\u002Fskills\u002Fvideo-frame-extraction\u002FSKILL.md",[],[],{"skillNo":73,"name":55,"nameZh":6,"description":56,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":74,"categories":75,"keywords":76,"publishedAt":19},"01M7E1GTC7D4N4Q2EF03875J9E","https:\u002F\u002Fgithub.com\u002Flinyouxue\u002Fskill-repair-benchmark\u002Fblob\u002Fmain\u002Fjpg-ocr-stat\u002Fresult\u002Fskilltta-claude4.7\u002Fgroup_03\u002Frun_02\u002Finputs\u002Fskills\u002Fopenai-vision\u002FSKILL.md",[],[],{"skillNo":78,"name":62,"nameZh":6,"description":63,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":79,"categories":80,"keywords":81,"publishedAt":19},"01M7E1GQ92CWFMGH53KSSE4WER","https:\u002F\u002Fgithub.com\u002Flinyouxue\u002Fskill-repair-benchmark\u002Fblob\u002Fmain\u002Fjpg-ocr-stat\u002Fresult\u002Fskilltta-claude4.7\u002Fgroup_03\u002Frun_02\u002Finputs\u002Fskills\u002Fimage-ocr\u002FSKILL.md",[],[]]