{"id":50545609,"url":"https://github.com/raphaelramosds/cs50s-python","last_synced_at":"2026-06-03T23:02:11.004Z","repository":{"id":355238663,"uuid":"1227324232","full_name":"raphaelramosds/cs50s-python","owner":"raphaelramosds","description":"Problem sets of \"CS50’s Introduction to Programming with Python\" solved with Go and Python","archived":false,"fork":false,"pushed_at":"2026-05-10T13:42:23.000Z","size":47,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-10T15:28:44.014Z","etag":null,"topics":["golang","problem-sets","python"],"latest_commit_sha":null,"homepage":"https://cs50.harvard.edu/python","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/raphaelramosds.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-02T14:24:35.000Z","updated_at":"2026-05-10T13:42:27.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/raphaelramosds/cs50s-python","commit_stats":null,"previous_names":["raphaelramosds/cs50s-introduction-to-programming-with-python","raphaelramosds/cs50s-python"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/raphaelramosds/cs50s-python","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raphaelramosds%2Fcs50s-python","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raphaelramosds%2Fcs50s-python/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raphaelramosds%2Fcs50s-python/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raphaelramosds%2Fcs50s-python/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/raphaelramosds","download_url":"https://codeload.github.com/raphaelramosds/cs50s-python/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/raphaelramosds%2Fcs50s-python/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33883102,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-03T02:00:06.370Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["golang","problem-sets","python"],"created_at":"2026-06-03T23:02:10.140Z","updated_at":"2026-06-03T23:02:10.998Z","avatar_url":"https://github.com/raphaelramosds.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CS50's Introduction to Programming with Python\n\nEach problem set is implemented in **Python** and/or **Go** as a way to review Python and learn Go side-by-side.\n\n- Python tests use [pytest](https://docs.pytest.org/)\n- Go tests use the standard `go test` toolchain\n\n---\n\n## Language Features by Problem Set\n\n### Week 0 — Functions\n\n| Problem | Python | Go |\n|---|---|---|\n| `0_indoor` | `str.lower()`, type hints, `if __name__ == \"__main__\"` | `strings.ToLower`, exported functions (capitalized), package layout |\n| `1_playback` | `str.replace()`, type hints | `strings.Replace` with `-1` (replace all) |\n| `2_making_faces` | Chained method calls, return type annotations, Unicode literals | `strings.ReplaceAll`, intermediate variables, Unicode literals |\n| `3_einstein` | Module-level constants, numeric underscores (`90_000_000_000_000_000`), `int` type hints | `const` declaration, explicit unsigned types (`uint`, `uint64`), type casting |\n| `4_tip_calculator` | Custom exceptions via class inheritance, `re.fullmatch`, f-string with precision (`:.2f`), string slicing | Custom error types via `Error() string` interface, `regexp.MustCompile`, multiple return values `(T, error)`, `strconv` for type conversion |\n\n### Week 1 — Conditionals\n\n| Problem | Python | Go |\n|---|---|---|\n| `0_deep_thought` | — | `if`/`else`, logical OR (`\\|\\|`), string equality |\n| `1_bank` | — | `strings.HasPrefix`, `strings.ToLower`, byte indexing (`s[0]`), `if`/`else if`, `strconv.Itoa` |\n| `2_extensions` | — | `switch`/`case`/`default`, `regexp.MustCompile`, `FindStringSubmatch`, regex capture groups, `strings.TrimSpace` |\n| `3_math_interpreter` | `re.match` with capture groups (`.group()`), `str.strip/lower/replace`, `float()`, floor division (`//`), `ZeroDivisionError`, `ValueError` | — |\n| `4_meal_time` | `str.split(\":\")`, `float()`, numeric range checks (`\u003e=`/`\u003c=`), helper function for unit conversion | — |\n\n### Week 2 — Loops\n\n| Problem | Python | Go |\n|---|---|---|\n| `0_camel_case` | Character-by-character iteration, `str.isupper()`, conditional expression, string concatenation | — |\n| `1_coke_machine` | Module-level list constant (`VALID_COINS`), `str.isnumeric()`, `dict` as mutable accumulator (pass-by-reference semantics), generator expression inside `str.join()`, `while` loop on dict value, testable wrapper (`_static` variant) separating I/O from logic | — |\n| `2_just_setting_up_my_twttr` | `re.sub` for pattern-based deletion, character class `[aeiouAEIOU]` in regex | — |\n| `3_vanity_plates` | `len()` for length bounds checks, `re.fullmatch` with quantifiers (`{2,}`, `+`) and negated character class `[^\\s0]` | — |\n| `4_nutrition` | Module-level `dict` constant, `dict.get()` for safe key lookup (returns `None` on miss), `str.lower()` for case-insensitive matching | — |\n\n---\n\n## Python Features Overview\n\n- **Type hints** — parameter and return annotations on all functions:\n  ```python\n  def indoor(txt: str) -\u003e str:\n  ```\n- **String methods** — `.lower()`, `.replace()`, `.strip()`, chained:\n  ```python\n  exp.strip().lower().replace(' ', '')\n  ```\n- **Numeric literals** — underscores for readability:\n  ```python\n  C2 = 90_000_000_000_000_000\n  ```\n- **f-strings** — with format specifiers:\n  ```python\n  f\"Leave ${tip:.2f}\"\n  ```\n- **Regular expressions** — `re.fullmatch` for strict matching, `re.match` with capture groups, `re.sub` for pattern-based replacement:\n  ```python\n  re.fullmatch(r\"\\$\\d{1,3}(\\.\\d{1,2})?\", dollars)\n  exp_operands.group(1)\n  re.sub(r'[aeiouAEIOU]', '', input)  # delete all vowels\n  ```\n- **Floor division** — `//` operator for integer-valued results:\n  ```python\n  return x // y\n  ```\n- **Built-in exceptions** — raising directly with a message:\n  ```python\n  raise ZeroDivisionError()\n  ```\n- **Custom exceptions** — subclassing `ValueError`, calling `super().__init__`:\n  ```python\n  class InvalidDollarStr(ValueError):\n      def __init__(self, txt: str):\n          super().__init__(f\"dollar: {txt} should be formatted as $##.##\")\n  ```\n- **String splitting** — to unpack structured tokens:\n  ```python\n  hh, mm = time_str.strip().split(\":\")\n  ```\n- **Module guard** — entry point pattern:\n  ```python\n  if __name__ == \"__main__\":\n  ```\n- **String slicing** — strip a leading character:\n  ```python\n  float(dollars[1:])\n  ```\n- **`str.isupper()`** — character classification for camelCase → snake_case:\n  ```python\n  c = '_' + char.lower() if char.isupper() else char\n  ```\n- **`str.isnumeric()`** — input validation before `int()` conversion:\n  ```python\n  if not coin.isnumeric():\n      return False\n  ```\n- **`dict` as mutable accumulator** — mutations inside a function are visible to the caller:\n  ```python\n  invoice[\"total_inserted\"] = invoice[\"total_inserted\"] + coin\n  ```\n- **Generator expressions** — inline inside `str.join()` to avoid an intermediate list:\n  ```python\n  \", \".join(str(i) for i in VALID_COINS)\n  ```\n- **`while` loop** — condition checked against a dict value each iteration:\n  ```python\n  while invoice[\"total_inserted\"] \u003c COKE_PRICE:\n  ```\n- **Testability pattern** — `_static` variant accepts a list instead of reading from stdin:\n  ```python\n  def coke_machine_static(inputs: list) -\u003e dict:  # testable\n  def coke_machine() -\u003e None:                     # interactive\n  ```\n- **`len()`** — string length bounds check:\n  ```python\n  if len(s) \u003e 6 or len(s) \u003c 2:\n  ```\n- **Regex quantifiers** — `{n,}` for \"at least n\", `+` for \"one or more\", negated class `[^...]`:\n  ```python\n  re.fullmatch(r'^[A-Z]{2,}[^\\s0]\\d+$', s)\n  ```\n- **`dict.get()`** — safe key lookup returning `None` when the key is absent:\n  ```python\n  FRUITS_CAL.get(item)  # None if item not in dict\n  ```\n\n## Go Features Overview\n\n- **Package organization** — each problem in its own package with exported (capitalized) functions:\n  ```go\n  package tip\n  func DollarsToFloat(dollars string) (float32, error)\n  ```\n- **Multiple return values** — `(T, error)` pattern for fallible operations:\n  ```go\n  func DollarsToFloat(dollars string) (float32, error) { ... }\n  dollarsFloat, err := DollarsToFloat(dollars)\n  ```\n- **Custom error types** — named types implementing the `error` interface via `Error() string`:\n  ```go\n  type InvalidDollarStr string\n  func (txt InvalidDollarStr) Error() string {\n      return fmt.Sprintf(\"dollar: %s should be formatted as $##.##\", string(txt))\n  }\n  ```\n- **`strings` package** — `ToLower`, `HasPrefix`, `TrimSpace`, `ReplaceAll`:\n  ```go\n  strings.ToLower(greeting)\n  strings.HasPrefix(greeting, \"hello\")\n  strings.ReplaceAll(dollars, \"$\", \"\")\n  ```\n- **`regexp` package** — `MustCompile`, `MatchString`, `FindStringSubmatch` with capture groups:\n  ```go\n  re := regexp.MustCompile(`.*\\.(\\w+)$`)\n  match := re.FindStringSubmatch(filename)  // match[1] = captured extension\n  ```\n- **`strconv` package** — `ParseFloat`, `Itoa`, `FormatFloat` for string↔numeric conversion:\n  ```go\n  strconv.ParseFloat(dollarsStrParsed, 32)\n  strconv.Itoa(amount)\n  strconv.FormatFloat(float64(tip), 'f', 2, 32)\n  ```\n- **`const`** — typed and untyped constant declarations:\n  ```go\n  const C2 = 90000000000000000\n  ```\n- **Explicit numeric types** — `uint`, `uint64`, `float32`, `float64` with explicit casts:\n  ```go\n  func Einstein(mass uint) uint64 {\n      return uint64(mass) * C2\n  }\n  ```\n- **`switch`/`case`** — multi-branch dispatch with a `default` fallback:\n  ```go\n  switch match[1] {\n  case \"jpg\", \"jpeg\": return \"image/jpeg\"\n  case \"png\":         return \"image/png\"\n  default:            return \"application/octet-stream\"\n  }\n  ```\n- **Byte indexing** — `s[0]` to inspect the first byte of a string:\n  ```go\n  greeting[0] == 'h'\n  ```\n- **Testing** — table-driven style using `*testing.T` and `t.Errorf`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fraphaelramosds%2Fcs50s-python","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fraphaelramosds%2Fcs50s-python","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fraphaelramosds%2Fcs50s-python/lists"}