{"id":17320825,"url":"https://github.com/andreacrotti/paint","last_synced_at":"2025-07-15T09:06:09.429Z","repository":{"id":66719717,"uuid":"92534695","full_name":"AndreaCrotti/paint","owner":"AndreaCrotti","description":"Simple text based paint program","archived":false,"fork":false,"pushed_at":"2017-06-15T21:55:47.000Z","size":39,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-27T03:15:12.616Z","etag":null,"topics":["clojure","graphics","paint","vectors"],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AndreaCrotti.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2017-05-26T17:44:01.000Z","updated_at":"2019-02-03T17:15:05.000Z","dependencies_parsed_at":"2023-03-16T07:15:53.708Z","dependency_job_id":null,"html_url":"https://github.com/AndreaCrotti/paint","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/AndreaCrotti/paint","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AndreaCrotti%2Fpaint","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AndreaCrotti%2Fpaint/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AndreaCrotti%2Fpaint/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AndreaCrotti%2Fpaint/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AndreaCrotti","download_url":"https://codeload.github.com/AndreaCrotti/paint/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AndreaCrotti%2Fpaint/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265424347,"owners_count":23762880,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["clojure","graphics","paint","vectors"],"created_at":"2024-10-15T13:34:04.157Z","updated_at":"2025-07-15T09:06:09.390Z","avatar_url":"https://github.com/AndreaCrotti.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# paint\n\n[![Build Status](https://travis-ci.org/AndreaCrotti/paint.svg?branch=master)](https://travis-ci.org/AndreaCrotti/paint)\n\nCreate an abstract image and allow to operate over it.\n\n## Usage\n\nIt's an interactive program that interprets instructions line by line.\nTo see an example usage just run:\n\n    lein run \u003c sample_input.txt\n    \n## Rationale\n\n### Implementation\n\nAn image is just represented as a vector of vector of keywords.\n\nThe library core.matrix is used for some of of the image manipulations internall, but the type\nof the matrixes passed around is still always a simple vector of vectors.\n\nOnly one function (`cli.clj:handle-line`) has side effects, because it's using an atom for storing\nwhat's the current image we are working on.\nThis was not 100% necessary, but since this program has an implicit global state for the user it\nmade sense to use an atom to store that.\n\nThe most complex part was to get the algorithm for filling in a region.\nThis was implemented in `filling.clj:fill-coordinates` as a recursive function which returns\nthe whole list of coordinates, without actually doing any mutation to the image itself.\n\nThis algorithm (inspired from the flood-fill algorithm) moves in the 4 cardinal directions recursively\nuntil every part of the image with the same colour has been discovered.\n\n### Testing\n\nTests are written with a mix of `core.test` and `clojure.test.check` generative tests.\nProperties of the system that can for example be tested like this could be for example:\n\n- a new img has all white pixels\n- clearing an existing image is the same as creating a new one withe the same dimensions\n- every operation is idempotent, so running it more than once on the same image doesn't change that image\n\nThere are many different generators composed together to accomplish that, a particularly interesting is\n`gen-image`, which allows to generate random images, which however still satisfy the general properties of the\nsystem (rectangular matrix and containing colours represented as keywords).\n\n    (gen/sample gen-image)\n    =\u003e ([[:O]] [[:G]] [[:A :E :T] [:S :A :T]] [[:J :W] [:F :X] [:T :J]] [[:C :O :B :S] [:K :B :V :R] [:P :K :O :A]])\n\n## Possible improvements\n\n- [ ] defprotocol? \n- [ ] performances with very big images\n- [ ] multi image with a map in the atom keyed by image id\n- [ ] better split between show and quit and the other manipulations\n- [ ] parse arguments could be done with regular expressions instead\n- [ ] could use swap instead of reset? \n- [ ] better prompt \n- [ ] define more colour and not just white \n- [ ] command function name? \n\n## License\n\nCopyright © 2017 Andrea Crotti\n\nDistributed under the Eclipse Public License either version 1.0 or (at\nyour option) any later version.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandreacrotti%2Fpaint","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandreacrotti%2Fpaint","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandreacrotti%2Fpaint/lists"}