diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml new file mode 100644 index 0000000..cf4f6eb --- /dev/null +++ b/.github/workflows/build.yaml @@ -0,0 +1,23 @@ +name: CI +on: [pull_request] +jobs: + build: + runs-on: ubuntu-latest + timeout-minutes: 5 + strategy: + matrix: + python-version: ["3.9", "3.11"] + steps: + - uses: actions/checkout@v4 + - name: Install Python, pipenv and Pipfile packages + uses: kojoru/prepare-pipenv@v1 + with: + python-version: ${{ matrix.python-version }} + - name: Turn on 'editable' mode + run: | + pipenv install -e . + - name: Test with pytest + run: | + pipenv install pytest + pipenv --venv + pipenv run python -m pytest \ No newline at end of file diff --git a/.github/workflows/deliver.yaml b/.github/workflows/deliver.yaml new file mode 100644 index 0000000..ed6b5c9 --- /dev/null +++ b/.github/workflows/deliver.yaml @@ -0,0 +1,28 @@ +name: CD +on: + push: + branches: + - main +jobs: + deliver: + # needs: [build] + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - uses: actions/checkout@v4 + - name: Install Python, pipenv and Pipfile packages + uses: kojoru/prepare-pipenv@v1 + # you gotta do it manually bud, im not making it commit the new version number + # - name: Install bumpver and bump + # run: | + # pipenv install bumpver + # pipenv run bumpver update -p + - name: Build package + run: | + pipenv install build + pipenv run python -m build . + - name: Publish to PyPI test server + uses: pypa/gh-action-pypi-publish@release/v1 + with: + password: ${{ secrets.TEST_PYPI_API_TOKEN }} + repository-url: https://test.pypi.org/legacy/ \ No newline at end of file diff --git a/Pipfile b/Pipfile new file mode 100644 index 0000000..c93a64c --- /dev/null +++ b/Pipfile @@ -0,0 +1,23 @@ +[[source]] +name = "pypi" +url = "https://pypi.org/simple" +verify_ssl = true + +[[source]] +url = "https://test.pypi.org/simple/" +verify_ssl = true +name = "testpypi" + +[packages] +twine = "*" +build = "*" +pytest = "*" +coverage = "*" +pytest-cov = "*" +emojiguessr = {file = ".", editable = true} +bumpver = "*" + +[dev-packages] + +[requires] +python_version = "3" diff --git a/Pipfile.lock b/Pipfile.lock new file mode 100644 index 0000000..20ebe8a --- /dev/null +++ b/Pipfile.lock @@ -0,0 +1,536 @@ +{ + "_meta": { + "hash": { + "sha256": "5887ae81f28eb165ed0eed1712a48fe41582cabd99dc09dbdacc3a6575083249" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + }, + { + "name": "testpypi", + "url": "https://test.pypi.org/simple/", + "verify_ssl": true + } + ] + }, + "default": { + "build": { + "hashes": [ + "sha256:698edd0ea270bde950f53aed21f3a0135672206f3911e0176261a31e0e07b397", + "sha256:7145f0b5061ba90a1500d60bd1b13ca0a8a4cebdd0cc16ed8adf1c0e739f43b4" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==1.3.0" + }, + "bumpver": { + "hashes": [ + "sha256:a35fd2d43a5f65f014035c094866bd3bd6c739606f29fd41246d6ec6e839d3f9", + "sha256:c02527f6ed7887afbc06c07630047b24a9f9d02d544a65639e99bf8b92aaa674" + ], + "index": "pypi", + "markers": "python_version >= '2.7'", + "version": "==2025.1131" + }, + "certifi": { + "hashes": [ + "sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de", + "sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43" + ], + "markers": "python_version >= '3.7'", + "version": "==2025.10.5" + }, + "charset-normalizer": { + "hashes": [ + "sha256:027f6de494925c0ab2a55eab46ae5129951638a49a34d87f4c3eda90f696b4ad", + "sha256:077fbb858e903c73f6c9db43374fd213b0b6a778106bc7032446a8e8b5b38b93", + "sha256:0a98e6759f854bd25a58a73fa88833fba3b7c491169f86ce1180c948ab3fd394", + "sha256:0d3d8f15c07f86e9ff82319b3d9ef6f4bf907608f53fe9d92b28ea9ae3d1fd89", + "sha256:0f04b14ffe5fdc8c4933862d8306109a2c51e0704acfa35d51598eb45a1e89fc", + "sha256:11d694519d7f29d6cd09f6ac70028dba10f92f6cdd059096db198c283794ac86", + "sha256:194f08cbb32dc406d6e1aea671a68be0823673db2832b38405deba2fb0d88f63", + "sha256:1bee1e43c28aa63cb16e5c14e582580546b08e535299b8b6158a7c9c768a1f3d", + "sha256:21d142cc6c0ec30d2efee5068ca36c128a30b0f2c53c1c07bd78cb6bc1d3be5f", + "sha256:2437418e20515acec67d86e12bf70056a33abdacb5cb1655042f6538d6b085a8", + "sha256:244bfb999c71b35de57821b8ea746b24e863398194a4014e4c76adc2bbdfeff0", + "sha256:2677acec1a2f8ef614c6888b5b4ae4060cc184174a938ed4e8ef690e15d3e505", + "sha256:277e970e750505ed74c832b4bf75dac7476262ee2a013f5574dd49075879e161", + "sha256:2aaba3b0819274cc41757a1da876f810a3e4d7b6eb25699253a4effef9e8e4af", + "sha256:2b7d8f6c26245217bd2ad053761201e9f9680f8ce52f0fcd8d0755aeae5b2152", + "sha256:2c9d3c380143a1fedbff95a312aa798578371eb29da42106a29019368a475318", + "sha256:3162d5d8ce1bb98dd51af660f2121c55d0fa541b46dff7bb9b9f86ea1d87de72", + "sha256:31fd66405eaf47bb62e8cd575dc621c56c668f27d46a61d975a249930dd5e2a4", + "sha256:362d61fd13843997c1c446760ef36f240cf81d3ebf74ac62652aebaf7838561e", + "sha256:376bec83a63b8021bb5c8ea75e21c4ccb86e7e45ca4eb81146091b56599b80c3", + "sha256:44c2a8734b333e0578090c4cd6b16f275e07aa6614ca8715e6c038e865e70576", + "sha256:47cc91b2f4dd2833fddaedd2893006b0106129d4b94fdb6af1f4ce5a9965577c", + "sha256:4902828217069c3c5c71094537a8e623f5d097858ac6ca8252f7b4d10b7560f1", + "sha256:4bd5d4137d500351a30687c2d3971758aac9a19208fc110ccb9d7188fbe709e8", + "sha256:4fe7859a4e3e8457458e2ff592f15ccb02f3da787fcd31e0183879c3ad4692a1", + "sha256:542d2cee80be6f80247095cc36c418f7bddd14f4a6de45af91dfad36d817bba2", + "sha256:554af85e960429cf30784dd47447d5125aaa3b99a6f0683589dbd27e2f45da44", + "sha256:5833d2c39d8896e4e19b689ffc198f08ea58116bee26dea51e362ecc7cd3ed26", + "sha256:5947809c8a2417be3267efc979c47d76a079758166f7d43ef5ae8e9f92751f88", + "sha256:5ae497466c7901d54b639cf42d5b8c1b6a4fead55215500d2f486d34db48d016", + "sha256:5bd2293095d766545ec1a8f612559f6b40abc0eb18bb2f5d1171872d34036ede", + "sha256:5bfbb1b9acf3334612667b61bd3002196fe2a1eb4dd74d247e0f2a4d50ec9bbf", + "sha256:5cb4d72eea50c8868f5288b7f7f33ed276118325c1dfd3957089f6b519e1382a", + "sha256:5dbe56a36425d26d6cfb40ce79c314a2e4dd6211d51d6d2191c00bed34f354cc", + "sha256:5f819d5fe9234f9f82d75bdfa9aef3a3d72c4d24a6e57aeaebba32a704553aa0", + "sha256:64b55f9dce520635f018f907ff1b0df1fdc31f2795a922fb49dd14fbcdf48c84", + "sha256:6515f3182dbe4ea06ced2d9e8666d97b46ef4c75e326b79bb624110f122551db", + "sha256:65e2befcd84bc6f37095f5961e68a6f077bf44946771354a28ad434c2cce0ae1", + "sha256:6aee717dcfead04c6eb1ce3bd29ac1e22663cdea57f943c87d1eab9a025438d7", + "sha256:6b39f987ae8ccdf0d2642338faf2abb1862340facc796048b604ef14919e55ed", + "sha256:6e1fcf0720908f200cd21aa4e6750a48ff6ce4afe7ff5a79a90d5ed8a08296f8", + "sha256:74018750915ee7ad843a774364e13a3db91682f26142baddf775342c3f5b1133", + "sha256:74664978bb272435107de04e36db5a9735e78232b85b77d45cfb38f758efd33e", + "sha256:74bb723680f9f7a6234dcf67aea57e708ec1fbdf5699fb91dfd6f511b0a320ef", + "sha256:752944c7ffbfdd10c074dc58ec2d5a8a4cd9493b314d367c14d24c17684ddd14", + "sha256:778d2e08eda00f4256d7f672ca9fef386071c9202f5e4607920b86d7803387f2", + "sha256:780236ac706e66881f3b7f2f32dfe90507a09e67d1d454c762cf642e6e1586e0", + "sha256:798d75d81754988d2565bff1b97ba5a44411867c0cf32b77a7e8f8d84796b10d", + "sha256:799a7a5e4fb2d5898c60b640fd4981d6a25f1c11790935a44ce38c54e985f828", + "sha256:7a32c560861a02ff789ad905a2fe94e3f840803362c84fecf1851cb4cf3dc37f", + "sha256:7c308f7e26e4363d79df40ca5b2be1c6ba9f02bdbccfed5abddb7859a6ce72cf", + "sha256:7fa17817dc5625de8a027cb8b26d9fefa3ea28c8253929b8d6649e705d2835b6", + "sha256:81d5eb2a312700f4ecaa977a8235b634ce853200e828fbadf3a9c50bab278328", + "sha256:82004af6c302b5d3ab2cfc4cc5f29db16123b1a8417f2e25f9066f91d4411090", + "sha256:837c2ce8c5a65a2035be9b3569c684358dfbf109fd3b6969630a87535495ceaa", + "sha256:840c25fb618a231545cbab0564a799f101b63b9901f2569faecd6b222ac72381", + "sha256:8a6562c3700cce886c5be75ade4a5db4214fda19fede41d9792d100288d8f94c", + "sha256:8af65f14dc14a79b924524b1e7fffe304517b2bff5a58bf64f30b98bbc5079eb", + "sha256:8ef3c867360f88ac904fd3f5e1f902f13307af9052646963ee08ff4f131adafc", + "sha256:94537985111c35f28720e43603b8e7b43a6ecfb2ce1d3058bbe955b73404e21a", + "sha256:99ae2cffebb06e6c22bdc25801d7b30f503cc87dbd283479e7b606f70aff57ec", + "sha256:9a26f18905b8dd5d685d6d07b0cdf98a79f3c7a918906af7cc143ea2e164c8bc", + "sha256:9b35f4c90079ff2e2edc5b26c0c77925e5d2d255c42c74fdb70fb49b172726ac", + "sha256:9cd98cdc06614a2f768d2b7286d66805f94c48cde050acdbbb7db2600ab3197e", + "sha256:9d1bb833febdff5c8927f922386db610b49db6e0d4f4ee29601d71e7c2694313", + "sha256:9f7fcd74d410a36883701fafa2482a6af2ff5ba96b9a620e9e0721e28ead5569", + "sha256:a59cb51917aa591b1c4e6a43c132f0cdc3c76dbad6155df4e28ee626cc77a0a3", + "sha256:a61900df84c667873b292c3de315a786dd8dac506704dea57bc957bd31e22c7d", + "sha256:a79cfe37875f822425b89a82333404539ae63dbdddf97f84dcbc3d339aae9525", + "sha256:a8a8b89589086a25749f471e6a900d3f662d1d3b6e2e59dcecf787b1cc3a1894", + "sha256:a8bf8d0f749c5757af2142fe7903a9df1d2e8aa3841559b2bad34b08d0e2bcf3", + "sha256:a9768c477b9d7bd54bc0c86dbaebdec6f03306675526c9927c0e8a04e8f94af9", + "sha256:ac1c4a689edcc530fc9d9aa11f5774b9e2f33f9a0c6a57864e90908f5208d30a", + "sha256:af2d8c67d8e573d6de5bc30cdb27e9b95e49115cd9baad5ddbd1a6207aaa82a9", + "sha256:b435cba5f4f750aa6c0a0d92c541fb79f69a387c91e61f1795227e4ed9cece14", + "sha256:b5b290ccc2a263e8d185130284f8501e3e36c5e02750fc6b6bdeb2e9e96f1e25", + "sha256:b5d84d37db046c5ca74ee7bb47dd6cbc13f80665fdde3e8040bdd3fb015ecb50", + "sha256:b7cf1017d601aa35e6bb650b6ad28652c9cd78ee6caff19f3c28d03e1c80acbf", + "sha256:bc7637e2f80d8530ee4a78e878bce464f70087ce73cf7c1caf142416923b98f1", + "sha256:c0463276121fdee9c49b98908b3a89c39be45d86d1dbaa22957e38f6321d4ce3", + "sha256:c4ef880e27901b6cc782f1b95f82da9313c0eb95c3af699103088fa0ac3ce9ac", + "sha256:c8ae8a0f02f57a6e61203a31428fa1d677cbe50c93622b4149d5c0f319c1d19e", + "sha256:ca5862d5b3928c4940729dacc329aa9102900382fea192fc5e52eb69d6093815", + "sha256:cb01158d8b88ee68f15949894ccc6712278243d95f344770fa7593fa2d94410c", + "sha256:cb6254dc36b47a990e59e1068afacdcd02958bdcce30bb50cc1700a8b9d624a6", + "sha256:cc00f04ed596e9dc0da42ed17ac5e596c6ccba999ba6bd92b0e0aef2f170f2d6", + "sha256:cd09d08005f958f370f539f186d10aec3377d55b9eeb0d796025d4886119d76e", + "sha256:cd4b7ca9984e5e7985c12bc60a6f173f3c958eae74f3ef6624bb6b26e2abbae4", + "sha256:ce8a0633f41a967713a59c4139d29110c07e826d131a316b50ce11b1d79b4f84", + "sha256:cead0978fc57397645f12578bfd2d5ea9138ea0fac82b2f63f7f7c6877986a69", + "sha256:d055ec1e26e441f6187acf818b73564e6e6282709e9bcb5b63f5b23068356a15", + "sha256:d1f13550535ad8cff21b8d757a3257963e951d96e20ec82ab44bc64aeb62a191", + "sha256:d9c7f57c3d666a53421049053eaacdd14bbd0a528e2186fcb2e672effd053bb0", + "sha256:d9e45d7faa48ee908174d8fe84854479ef838fc6a705c9315372eacbc2f02897", + "sha256:da3326d9e65ef63a817ecbcc0df6e94463713b754fe293eaa03da99befb9a5bd", + "sha256:de00632ca48df9daf77a2c65a484531649261ec9f25489917f09e455cb09ddb2", + "sha256:e1f185f86a6f3403aa2420e815904c67b2f9ebc443f045edd0de921108345794", + "sha256:e824f1492727fa856dd6eda4f7cee25f8518a12f3c4a56a74e8095695089cf6d", + "sha256:e912091979546adf63357d7e2ccff9b44f026c075aeaf25a52d0e95ad2281074", + "sha256:eaabd426fe94daf8fd157c32e571c85cb12e66692f15516a83a03264b08d06c3", + "sha256:ebf3e58c7ec8a8bed6d66a75d7fb37b55e5015b03ceae72a8e7c74495551e224", + "sha256:ecaae4149d99b1c9e7b88bb03e3221956f68fd6d50be2ef061b2381b61d20838", + "sha256:eecbc200c7fd5ddb9a7f16c7decb07b566c29fa2161a16cf67b8d068bd21690a", + "sha256:f155a433c2ec037d4e8df17d18922c3a0d9b3232a396690f17175d2946f0218d", + "sha256:f1e34719c6ed0b92f418c7c780480b26b5d9c50349e9a9af7d76bf757530350d", + "sha256:f34be2938726fc13801220747472850852fe6b1ea75869a048d6f896838c896f", + "sha256:f820802628d2694cb7e56db99213f930856014862f3fd943d290ea8438d07ca8", + "sha256:f8bf04158c6b607d747e93949aa60618b61312fe647a6369f88ce2ff16043490", + "sha256:f8e160feb2aed042cd657a72acc0b481212ed28b1b9a95c0cee1621b524e1966", + "sha256:f9d332f8c2a2fcbffe1378594431458ddbef721c1769d78e2cbc06280d8155f9", + "sha256:fa09f53c465e532f4d3db095e0c55b615f010ad81803d383195b6b5ca6cbf5f3", + "sha256:faa3a41b2b66b6e50f84ae4a68c64fcd0c44355741c6374813a800cd6695db9e", + "sha256:fd44c878ea55ba351104cb93cc85e74916eb8fa440ca7903e57575e97394f608" + ], + "markers": "python_version >= '3.7'", + "version": "==3.4.4" + }, + "click": { + "hashes": [ + "sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc", + "sha256:e7b8232224eba16f4ebe410c25ced9f7875cb5f3263ffc93cc3e8da705e229c4" + ], + "markers": "python_version >= '3.10'", + "version": "==8.3.0" + }, + "colorama": { + "hashes": [ + "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", + "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6'", + "version": "==0.4.6" + }, + "coverage": { + "extras": [ + "toml" + ], + "hashes": [ + "sha256:037b2d064c2f8cc8716fe4d39cb705779af3fbf1ba318dc96a1af858888c7bb5", + "sha256:05791e528a18f7072bf5998ba772fe29db4da1234c45c2087866b5ba4dea710e", + "sha256:0d7f0616c557cbc3d1c2090334eddcbb70e1ae3a40b07222d62b3aa47f608fab", + "sha256:0efa742f431529699712b92ecdf22de8ff198df41e43aeaaadf69973eb93f17a", + "sha256:10ad04ac3a122048688387828b4537bc9cf60c0bf4869c1e9989c46e45690b82", + "sha256:167bd504ac1ca2af7ff3b81d245dfea0292c5032ebef9d66cc08a7d28c1b8050", + "sha256:16ce17ceb5d211f320b62df002fa7016b7442ea0fd260c11cec8ce7730954893", + "sha256:214b622259dd0cf435f10241f1333d32caa64dbc27f8790ab693428a141723de", + "sha256:24d6f3128f1b2d20d84b24f4074475457faedc3d4613a7e66b5e769939c7d969", + "sha256:258d9967520cca899695d4eb7ea38be03f06951d6ca2f21fb48b1235f791e601", + "sha256:269bfe913b7d5be12ab13a95f3a76da23cf147be7fa043933320ba5625f0a8de", + "sha256:2727d47fce3ee2bac648528e41455d1b0c46395a087a229deac75e9f88ba5a05", + "sha256:314c24e700d7027ae3ab0d95fbf8d53544fca1f20345fd30cd219b737c6e58d3", + "sha256:3d4ba9a449e9364a936a27322b20d32d8b166553bfe63059bd21527e681e2fad", + "sha256:3d4ed4de17e692ba6415b0587bc7f12bc80915031fc9db46a23ce70fc88c9841", + "sha256:3d58ecaa865c5b9fa56e35efc51d1014d4c0d22838815b9fce57a27dd9576847", + "sha256:4036cc9c7983a2b1f2556d574d2eb2154ac6ed55114761685657e38782b23f52", + "sha256:424538266794db2861db4922b05d729ade0940ee69dcf0591ce8f69784db0e11", + "sha256:4b7589765348d78fb4e5fb6ea35d07564e387da2fc5efff62e0222971f155f68", + "sha256:4c1eeb3fb8eb9e0190bebafd0462936f75717687117339f708f395fe455acc73", + "sha256:4d3ffa07a08657306cd2215b0da53761c4d73cb54d9143b9303a6481ec0cd415", + "sha256:5693e57a065760dcbeb292d60cc4d0231a6d4b6b6f6a3191561e1d5e8820b745", + "sha256:587c38849b853b157706407e9ebdca8fd12f45869edb56defbef2daa5fb0812b", + "sha256:596763d2f9a0ee7eec6e643e29660def2eef297e1de0d334c78c08706f1cb785", + "sha256:59a6e5a265f7cfc05f76e3bb53eca2e0dfe90f05e07e849930fecd6abb8f40b4", + "sha256:5a03eaf7ec24078ad64a07f02e30060aaf22b91dedf31a6b24d0d98d2bba7f48", + "sha256:5ef83b107f50db3f9ae40f69e34b3bd9337456c5a7fe3461c7abf8b75dd666a2", + "sha256:630d0bd7a293ad2fc8b4b94e5758c8b2536fdf36c05f1681270203e463cbfa9b", + "sha256:695340f698a5f56f795b2836abe6fb576e7c53d48cd155ad2f80fd24bc63a040", + "sha256:6fbcee1a8f056af07ecd344482f711f563a9eb1c2cad192e87df00338ec3cdb0", + "sha256:7161edd3426c8d19bdccde7d49e6f27f748f3c31cc350c5de7c633fea445d866", + "sha256:73feb83bb41c32811973b8565f3705caf01d928d972b72042b44e97c71fd70d1", + "sha256:765c0bc8fe46f48e341ef737c91c715bd2a53a12792592296a095f0c237e09cf", + "sha256:7ab934dd13b1c5e94b692b1e01bd87e4488cb746e3a50f798cb9464fd128374b", + "sha256:7db53b5cdd2917b6eaadd0b1251cf4e7d96f4a8d24e174bdbdf2f65b5ea7994d", + "sha256:80027673e9d0bd6aef86134b0771845e2da85755cf686e7c7c59566cf5a89115", + "sha256:81b335f03ba67309a95210caf3eb43bd6fe75a4e22ba653ef97b4696c56c7ec2", + "sha256:865965bf955d92790f1facd64fe7ff73551bd2c1e7e6b26443934e9701ba30b9", + "sha256:8badf70446042553a773547a61fecaa734b55dc738cacf20c56ab04b77425e43", + "sha256:8c934bd088eed6174210942761e38ee81d28c46de0132ebb1801dbe36a390dcc", + "sha256:9516add7256b6713ec08359b7b05aeff8850c98d357784c7205b2e60aa2513fa", + "sha256:9c49e77811cf9d024b95faf86c3f059b11c0c9be0b0d61bc598f453703bd6fd1", + "sha256:9cbabd8f4d0d3dc571d77ae5bdbfa6afe5061e679a9d74b6797c48d143307088", + "sha256:9ed43fa22c6436f7957df036331f8fe4efa7af132054e1844918866cd228af6c", + "sha256:a09c1211959903a479e389685b7feb8a17f59ec5a4ef9afde7650bd5eabc2777", + "sha256:a1839d08406e4cba2953dcc0ffb312252f14d7c4c96919f70167611f4dee2623", + "sha256:a386c1061bf98e7ea4758e4313c0ab5ecf57af341ef0f43a0bf26c2477b5c268", + "sha256:a3b6a5f8b2524fd6c1066bc85bfd97e78709bb5e37b5b94911a6506b65f47186", + "sha256:a3d0e2087dba64c86a6b254f43e12d264b636a39e88c5cc0a01a7c71bcfdab7e", + "sha256:a61e37a403a778e2cda2a6a39abcc895f1d984071942a41074b5c7ee31642007", + "sha256:aef1747ede4bd8ca9cfc04cc3011516500c6891f1b33a94add3253f6f876b7b7", + "sha256:b56efee146c98dbf2cf5cffc61b9829d1e94442df4d7398b26892a53992d3547", + "sha256:b5c2705afa83f49bd91962a4094b6b082f94aef7626365ab3f8f4bd159c5acf3", + "sha256:b679e171f1c104a5668550ada700e3c4937110dbdd153b7ef9055c4f1a1ee3cc", + "sha256:b971bdefdd75096163dd4261c74be813c4508477e39ff7b92191dea19f24cd37", + "sha256:bab7ec4bb501743edc63609320aaec8cd9188b396354f482f4de4d40a9d10721", + "sha256:bc1fbea96343b53f65d5351d8fd3b34fd415a2670d7c300b06d3e14a5af4f552", + "sha256:c6f31f281012235ad08f9a560976cc2fc9c95c17604ff3ab20120fe480169bca", + "sha256:c770885b28fb399aaf2a65bbd1c12bf6f307ffd112d6a76c5231a94276f0c497", + "sha256:c79cae102bb3b1801e2ef1511fb50e91ec83a1ce466b2c7c25010d884336de46", + "sha256:c9f08ea03114a637dab06cedb2e914da9dc67fa52c6015c018ff43fdde25b9c2", + "sha256:ca61691ba8c5b6797deb221a0d09d7470364733ea9c69425a640f1f01b7c5bf0", + "sha256:cacb29f420cfeb9283b803263c3b9a068924474ff19ca126ba9103e1278dfa44", + "sha256:cc3f49e65ea6e0d5d9bd60368684fe52a704d46f9e7fc413918f18d046ec40e1", + "sha256:cdbcd376716d6b7fbfeedd687a6c4be019c5a5671b35f804ba76a4c0a778cba4", + "sha256:ce37f215223af94ef0f75ac68ea096f9f8e8c8ec7d6e8c346ee45c0d363f0479", + "sha256:ce9f3bde4e9b031eaf1eb61df95c1401427029ea1bfddb8621c1161dcb0fa02e", + "sha256:cee6291bb4fed184f1c2b663606a115c743df98a537c969c3c64b49989da96c2", + "sha256:cf9e6ff4ca908ca15c157c409d608da77a56a09877b97c889b98fb2c32b6465e", + "sha256:d06f4fc7acf3cabd6d74941d53329e06bab00a8fe10e4df2714f0b134bfc64ef", + "sha256:d66c0104aec3b75e5fd897e7940188ea1892ca1d0235316bf89286d6a22568c0", + "sha256:d91ebeac603812a09cf6a886ba6e464f3bbb367411904ae3790dfe28311b15ad", + "sha256:d9a03ec6cb9f40a5c360f138b88266fd8f58408d71e89f536b4f91d85721d075", + "sha256:dadbcce51a10c07b7c72b0ce4a25e4b6dcb0c0372846afb8e5b6307a121eb99f", + "sha256:dba82204769d78c3fd31b35c3d5f46e06511936c5019c39f98320e05b08f794d", + "sha256:dbbf012be5f32533a490709ad597ad8a8ff80c582a95adc8d62af664e532f9ca", + "sha256:df01d6c4c81e15a7c88337b795bb7595a8596e92310266b5072c7e301168efbd", + "sha256:e0eb0a2dcc62478eb5b4cbb80b97bdee852d7e280b90e81f11b407d0b81c4287", + "sha256:e24045453384e0ae2a587d562df2a04d852672eb63051d16096d3f08aa4c7c2f", + "sha256:e44a86a47bbdf83b0a3ea4d7df5410d6b1a0de984fbd805fa5101f3624b9abe0", + "sha256:e4dc07e95495923d6fd4d6c27bf70769425b71c89053083843fd78f378558996", + "sha256:e89641f5175d65e2dbb44db15fe4ea48fade5d5bbb9868fdc2b4fce22f4a469d", + "sha256:e9570ad567f880ef675673992222746a124b9595506826b210fbe0ce3f0499cd", + "sha256:eb53f1e8adeeb2e78962bade0c08bfdc461853c7969706ed901821e009b35e31", + "sha256:eb92e47c92fcbcdc692f428da67db33337fa213756f7adb6a011f7b5a7a20740", + "sha256:ef55537ff511b5e0a43edb4c50a7bf7ba1c3eea20b4f49b1490f1e8e0e42c591", + "sha256:f39ae2f63f37472c17b4990f794035c9890418b1b8cca75c01193f3c8d3e01be", + "sha256:f413ce6e07e0d0dc9c433228727b619871532674b45165abafe201f200cc215f", + "sha256:f91f927a3215b8907e214af77200250bb6aae36eca3f760f89780d13e495388d", + "sha256:f9ea02ef40bb83823b2b04964459d281688fe173e20643870bb5d2edf68bc836", + "sha256:fcc0a4aa589de34bc56e1a80a740ee0f8c47611bdfb28cd1849de60660f3799d", + "sha256:fcc15fc462707b0680cff6242c48625da7f9a16a28a41bb8fd7a4280920e676c" + ], + "index": "pypi", + "markers": "python_version >= '3.10'", + "version": "==7.11.0" + }, + "docutils": { + "hashes": [ + "sha256:9fdb771707c8784c8f2728b67cb2c691305933d68137ef95a75db5f4dfbc213d", + "sha256:b0e98d679283fc3bb0ead8a5da7f501baa632654e7056e9c5846842213d674d8" + ], + "markers": "python_version >= '3.9'", + "version": "==0.22.2" + }, + "emojiguessr": { + "editable": true, + "file": "." + }, + "id": { + "hashes": [ + "sha256:292cb8a49eacbbdbce97244f47a97b4c62540169c976552e497fd57df0734c1d", + "sha256:f1434e1cef91f2cbb8a4ec64663d5a23b9ed43ef44c4c957d02583d61714c658" + ], + "markers": "python_version >= '3.8'", + "version": "==1.5.0" + }, + "idna": { + "hashes": [ + "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", + "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902" + ], + "markers": "python_version >= '3.8'", + "version": "==3.11" + }, + "iniconfig": { + "hashes": [ + "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", + "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12" + ], + "markers": "python_version >= '3.10'", + "version": "==2.3.0" + }, + "jaraco.classes": { + "hashes": [ + "sha256:47a024b51d0239c0dd8c8540c6c7f484be3b8fcf0b2d85c13825780d3b3f3acd", + "sha256:f662826b6bed8cace05e7ff873ce0f9283b5c924470fe664fff1c2f00f581790" + ], + "markers": "python_version >= '3.8'", + "version": "==3.4.0" + }, + "jaraco.context": { + "hashes": [ + "sha256:9bae4ea555cf0b14938dc0aee7c9f32ed303aa20a3b73e7dc80111628792d1b3", + "sha256:f797fc481b490edb305122c9181830a3a5b76d84ef6d1aef2fb9b47ab956f9e4" + ], + "markers": "python_version >= '3.8'", + "version": "==6.0.1" + }, + "jaraco.functools": { + "hashes": [ + "sha256:227ff8ed6f7b8f62c56deff101545fa7543cf2c8e7b82a7c2116e672f29c26e8", + "sha256:cfd13ad0dd2c47a3600b439ef72d8615d482cedcff1632930d6f28924d92f294" + ], + "markers": "python_version >= '3.9'", + "version": "==4.3.0" + }, + "keyring": { + "hashes": [ + "sha256:0b39998aa941431eb3d9b0d4b2460bc773b9df6fed7621c2dfb291a7e0187a66", + "sha256:552a3f7af126ece7ed5c89753650eec89c7eaae8617d0aa4d9ad2b75111266bd" + ], + "markers": "python_version >= '3.9'", + "version": "==25.6.0" + }, + "lexid": { + "hashes": [ + "sha256:509a3a4cc926d3dbf22b203b18a4c66c25e6473fb7c0e0d30374533ac28bafe5", + "sha256:5526bb5606fd74c7add23320da5f02805bddd7c77916f2dc1943e6bada8605ed" + ], + "markers": "python_version >= '2.7'", + "version": "==2021.1006" + }, + "markdown-it-py": { + "hashes": [ + "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", + "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3" + ], + "markers": "python_version >= '3.10'", + "version": "==4.0.0" + }, + "mdurl": { + "hashes": [ + "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", + "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba" + ], + "markers": "python_version >= '3.7'", + "version": "==0.1.2" + }, + "more-itertools": { + "hashes": [ + "sha256:52d4362373dcf7c52546bc4af9a86ee7c4579df9a8dc268be0a2f949d376cc9b", + "sha256:f638ddf8a1a0d134181275fb5d58b086ead7c6a72429ad725c67503f13ba30bd" + ], + "markers": "python_version >= '3.9'", + "version": "==10.8.0" + }, + "nh3": { + "hashes": [ + "sha256:019ecbd007536b67fdf76fab411b648fb64e2257ca3262ec80c3425c24028c80", + "sha256:03d617e5c8aa7331bd2659c654e021caf9bba704b109e7b2b28b039a00949fe5", + "sha256:0dca4365db62b2d71ff1620ee4f800c4729849906c5dd504ee1a7b2389558e31", + "sha256:0fe7ee035dd7b2290715baf29cb27167dddd2ff70ea7d052c958dbd80d323c99", + "sha256:13398e676a14d6233f372c75f52d5ae74f98210172991f7a3142a736bd92b131", + "sha256:169db03df90da63286e0560ea0efa9b6f3b59844a9735514a1d47e6bb2c8c61b", + "sha256:1710f3901cd6440ca92494ba2eb6dc260f829fa8d9196b659fa10de825610ce0", + "sha256:1f9ba555a797dbdcd844b89523f29cdc90973d8bd2e836ea6b962cf567cadd93", + "sha256:2ab70e8c6c7d2ce953d2a58102eefa90c2d0a5ed7aa40c7e29a487bc5e613131", + "sha256:2c9850041b77a9147d6bbd6dbbf13eeec7009eb60b44e83f07fcb2910075bf9b", + "sha256:403c11563e50b915d0efdb622866d1d9e4506bce590ef7da57789bf71dd148b5", + "sha256:45c953e57028c31d473d6b648552d9cab1efe20a42ad139d78e11d8f42a36130", + "sha256:562da3dca7a17f9077593214a9781a94b8d76de4f158f8c895e62f09573945fe", + "sha256:6d66f41672eb4060cf87c037f760bdbc6847852ca9ef8e9c5a5da18f090abf87", + "sha256:7064ccf5ace75825bd7bf57859daaaf16ed28660c1c6b306b649a9eda4b54b1e", + "sha256:72d67c25a84579f4a432c065e8b4274e53b7cf1df8f792cf846abfe2c3090866", + "sha256:7bb18403f02b655a1bbe4e3a4696c2ae1d6ae8f5991f7cacb684b1ae27e6c9f7", + "sha256:91e9b001101fb4500a2aafe3e7c92928d85242d38bf5ac0aba0b7480da0a4cd6", + "sha256:a40202fd58e49129764f025bbaae77028e420f1d5b3c8e6f6fd3a6490d513868", + "sha256:c8745454cdd28bbbc90861b80a0111a195b0e3961b9fa2e672be89eb199fa5d8", + "sha256:cf5964d54edd405e68583114a7cba929468bcd7db5e676ae38ee954de1cfc104", + "sha256:d18957a90806d943d141cc5e4a0fefa1d77cf0d7a156878bf9a66eed52c9cc7d", + "sha256:dce4248edc427c9b79261f3e6e2b3ecbdd9b88c267012168b4a7b3fc6fd41d13", + "sha256:f2f55c4d2d5a207e74eefe4d828067bbb01300e06e2a7436142f915c5928de07", + "sha256:f394759a06df8b685a4ebfb1874fb67a9cbfd58c64fc5ed587a663c0e63ec376", + "sha256:f97f8b25cb2681d25e2338148159447e4d689aafdccfcf19e61ff7db3905768a" + ], + "markers": "python_version >= '3.8'", + "version": "==0.3.2" + }, + "packaging": { + "hashes": [ + "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", + "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f" + ], + "markers": "python_version >= '3.8'", + "version": "==25.0" + }, + "pluggy": { + "hashes": [ + "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", + "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746" + ], + "markers": "python_version >= '3.9'", + "version": "==1.6.0" + }, + "pygments": { + "hashes": [ + "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", + "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b" + ], + "markers": "python_version >= '3.8'", + "version": "==2.19.2" + }, + "pyproject-hooks": { + "hashes": [ + "sha256:1e859bd5c40fae9448642dd871adf459e5e2084186e8d2c2a79a824c970da1f8", + "sha256:9e5c6bfa8dcc30091c74b0cf803c81fdd29d94f01992a7707bc97babb1141913" + ], + "markers": "python_version >= '3.7'", + "version": "==1.2.0" + }, + "pytest": { + "hashes": [ + "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01", + "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==8.4.2" + }, + "pytest-cov": { + "hashes": [ + "sha256:33c97eda2e049a0c5298e91f519302a1334c26ac65c1a483d6206fd458361af1", + "sha256:3b8e9558b16cc1479da72058bdecf8073661c7f57f7d3c5f22a1c23507f2d861" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==7.0.0" + }, + "readme-renderer": { + "hashes": [ + "sha256:2fbca89b81a08526aadf1357a8c2ae889ec05fb03f5da67f9769c9a592166151", + "sha256:8712034eabbfa6805cacf1402b4eeb2a73028f72d1166d6f5cb7f9c047c5d1e1" + ], + "markers": "python_version >= '3.9'", + "version": "==44.0" + }, + "requests": { + "hashes": [ + "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", + "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf" + ], + "markers": "python_version >= '3.9'", + "version": "==2.32.5" + }, + "requests-toolbelt": { + "hashes": [ + "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6", + "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", + "version": "==1.0.0" + }, + "rfc3986": { + "hashes": [ + "sha256:50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd", + "sha256:97aacf9dbd4bfd829baad6e6309fa6573aaf1be3f6fa735c8ab05e46cecb261c" + ], + "markers": "python_version >= '3.7'", + "version": "==2.0.0" + }, + "rich": { + "hashes": [ + "sha256:73ff50c7c0c1c77c8243079283f4edb376f0f6442433aecb8ce7e6d0b92d1fe4", + "sha256:76bc51fe2e57d2b1be1f96c524b890b816e334ab4c1e45888799bfaab0021edd" + ], + "markers": "python_full_version >= '3.8.0'", + "version": "==14.2.0" + }, + "toml": { + "hashes": [ + "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", + "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" + ], + "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2'", + "version": "==0.10.2" + }, + "twine": { + "hashes": [ + "sha256:418ebf08ccda9a8caaebe414433b0ba5e25eb5e4a927667122fbe8f829f985d8", + "sha256:e5ed0d2fd70c9959770dce51c8f39c8945c574e18173a7b81802dab51b4b75cf" + ], + "index": "pypi", + "markers": "python_version >= '3.9'", + "version": "==6.2.0" + }, + "urllib3": { + "hashes": [ + "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", + "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc" + ], + "markers": "python_version >= '3.9'", + "version": "==2.5.0" + } + }, + "develop": {} +} diff --git a/README.md b/README.md index 6022e0e..ab980e2 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,36 @@ -# Python Package Exercise +# EmojiGuessr -An exercise to create a Python package, build it, test it, distribute it, and use it. See [instructions](./instructions.md) for details. + +[![](https://github.com/swe-students-fall2025/3-python-package-team_saffron/actions/workflows/build.yaml/badge.svg)](https://github.com/swe-students-fall2025/3-python-package-team_saffron/actions/workflows/build.yaml) + +[![](https://github.com/swe-students-fall2025/3-python-package-team_saffron/actions/workflows/deliver.yaml/badge.svg)](https://github.com/swe-students-fall2025/3-python-package-team_saffron/actions/workflows/deliver.yaml) + +Link to PyPI: []() + +EmojiGuessr is a Python package that turns emoji strings into quick guessing games. Pick a theme, get an emoji clue and guess the name! + +## Team Members +[Jason Liu](https://github.com/jsl1114) + +[David Shen](https://github.com/snazzybeatle115) + +member3 + +member4 + +member5 + +## Installation + +pipenv install -i https://test.pypi.org/simple/ emojiguessr==0.0.1 + +## Usage (code examples) + +## Develop and Contribute + +### Local build & run (using `pipenv`) +1. Get [`pipenv`](https://pipenv.pypa.io/en/latest/installation.html) installed +2. `cd` into the project directory +3. `pipenv install` +4. install the package in editable mode using `pipenv install -e .` +5. run the command line interface by using `pipenv run emojiguessr` followed by flags and configurations diff --git a/examples/demo.py b/examples/demo.py new file mode 100644 index 0000000..e69de29 diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..3b07c48 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,35 @@ +[build-system] +requires = ["setuptools>=68", "wheel"] +build-backend = "setuptools.build_meta" + +[bumpver] +current_version = "0.3.2" +version_pattern = "MAJOR.MINOR.PATCH" + + +[bumpver.file_patterns] +"pyproject.toml" = [ + 'version = "{version}"', +] + +[project] +name = "emojiguessr" +version = "0.3.2" +description = "A tiny emoji guessing game" +readme = "README.md" +requires-python = ">=3.9" +authors = [ + { name = "Team Saffron"} +] +license = { text = "GNU GENERAL PUBLIC LICENSE" } +dependencies = [] + +[project.urls] +Homepage = "https://github.com/swe-students-fall2025/3-python-package-team_saffron" +Issues = "https://github.com/swe-students-fall2025/3-python-package-team_saffron/issues" + +[project.scripts] +emojiguessr = "emojiguessr.__main__:main" + +[tool.setuptools.packages.find] +where = ["src"] diff --git a/src/emojiguessr/__init__.py b/src/emojiguessr/__init__.py new file mode 100644 index 0000000..cb4cfa2 --- /dev/null +++ b/src/emojiguessr/__init__.py @@ -0,0 +1,10 @@ +from .data import random_emojis +from .quiz import make_quiz_item, check_answer +from .score import score + +__all__ = [ + "random_emojis", + "make_quiz_item", + "check_answer", + "score", +] diff --git a/src/emojiguessr/__main__.py b/src/emojiguessr/__main__.py new file mode 100644 index 0000000..7058863 --- /dev/null +++ b/src/emojiguessr/__main__.py @@ -0,0 +1,130 @@ +import argparse +from emojiguessr import make_quiz_item, check_answer, score +from emojiguessr.data import _EMOJI_BANK + + +def run_quiz(num_questions, theme, case_sensitive, allow_partial, max_attempts): + s = 0 + for i in range(1, num_questions + 1): + item = make_quiz_item(theme=theme) + clue = item["clue"] + answer = item["answer"] + + print(f"\nQuestion {i}/{num_questions}") + print(f"Theme: {item['theme']}") + print(f"Emoji: {clue}") + + attempts_left = max_attempts + while attempts_left > 0: + guess = input("Your guess: ") + + is_right = check_answer( + correct=answer, + guess=guess, + case_sensitive=case_sensitive, + allow_partial=allow_partial, + ) + + s = score(s, correct=is_right) + + if is_right: + print("โœ… Correct!") + break + else: + attempts_left -= 1 + if attempts_left > 0: + print(f"โŒ Wrong! {attempts_left} attempts left.") + else: + print(f"โŒ Nope โ€” it was: {answer}") + + print(f"\nFinal score: {s}/{num_questions}") + + +def list_themes(): + print("Available themes:") + for theme in sorted(_EMOJI_BANK.keys()): + print(f" - {theme}") + + +def list_commands(): + print("Available commands:") + print(" --num-questions, -n : Number of questions to ask (default: 3)") + print(" --theme, -t : Emoji theme to use (default: food)") + print(" --case-sensitive : Make answers case-sensitive (default: off)") + print(" --no-partial : Disable partial matches") + print( + " --max-attempts, -a : Maximum number of attempts per question (default: 1)" + ) + print(" --list-themes, -lt : List available themes and exit") + print(" --list-commands, -lc : List available commands and exit") + + +def main(): + parser = argparse.ArgumentParser( + prog="emojiguessr", + description="Play a quick emoji guessing game in your terminal.", + ) + parser.add_argument( + "--num-questions", + "-n", + type=int, + default=3, + help="Number of questions to ask (default: 3)", + ) + parser.add_argument( + "--theme", + "-t", + default="food", + help="Emoji theme to use (default: food). Use --list-themes to see options.", + ) + parser.add_argument( + "--case-sensitive", + action="store_true", + help="Make answers case-sensitive (default: off)", + ) + parser.add_argument( + "--no-partial", + action="store_true", + help="Disable partial matches (so 'jurassic' won't match 'jurassic park')", + ) + parser.add_argument( + "--max-attempts", + "-a", + type=int, + default=1, + help="Maximum number of attempts per question (default: 1)", + ) + parser.add_argument( + "--list-themes", + "-lt", + action="store_true", + help="List available themes and exit.", + ) + parser.add_argument( + "--list-commands", + "-lc", + action="store_true", + help="List available commands and exit.", + ) + + args = parser.parse_args() + + if args.list_themes: + list_themes() + return + + if args.list_commands: + list_commands() + return + + run_quiz( + num_questions=args.num_questions, + theme=args.theme, + case_sensitive=args.case_sensitive, + allow_partial=not args.no_partial, + max_attempts=args.max_attempts, + ) + + +if __name__ == "__main__": + main() diff --git a/src/emojiguessr/data.py b/src/emojiguessr/data.py new file mode 100644 index 0000000..a7f1f21 --- /dev/null +++ b/src/emojiguessr/data.py @@ -0,0 +1,94 @@ +import random + +_EMOJI_BANK = { + "food": [ + ("๐Ÿ•", "pizza"), + ("๐Ÿฃ", "sushi"), + ("๐Ÿ”", "burger"), + ("๐ŸŸ", "fries"), + ("๐ŸŒฎ", "taco"), + ("๐Ÿœ", "ramen"), + ("๐Ÿฅ", "croissant"), + ("๐Ÿฉ", "donut"), + ("๐ŸŽ", "apple"), + ("๐Ÿฐ", "cake"), + ], + "animals": [ + ("๐Ÿถ", "dog"), + ("๐Ÿฑ", "cat"), + ("๐Ÿผ", "panda"), + ("๐Ÿฆ", "lion"), + ("๐Ÿธ", "frog"), + ("๐Ÿง", "penguin"), + ("๐ŸฆŠ", "fox"), + ("๐Ÿ˜", "elephant"), + ("๐Ÿข", "turtle"), + ("๐Ÿฆ„", "unicorn"), + ], + "movies": [ + ("๐Ÿง™โ€โ™‚๏ธ๐Ÿ’", "lord of the rings"), + ("๐Ÿšข๐ŸงŠ", "titanic"), + ("๐Ÿฆ–๐Ÿž๏ธ", "jurassic park"), + ("๐Ÿ‘ธ๐Ÿผโ„๏ธ", "frozen"), + ("๐Ÿง”โšก", "harry potter"), + ("๐Ÿ‘จโ€๐Ÿš€๐ŸŒ•", "space movie"), + ("๐Ÿฆธโ€โ™‚๏ธ", "superman"), + ("๐Ÿš—๐Ÿ’จ", "fast and furious"), + ], + "games": [ + ("๐ŸŽฎ", "video game"), + ("โ™Ÿ๏ธ", "chess"), + ("๐Ÿƒ", "card game"), + ("๐ŸŽฏ", "darts"), + ("๐Ÿ•น๏ธ", "arcade"), + ("๐ŸŽฒ", "board game"), + ], + "cities": [ + ("๐Ÿ‡บ๐Ÿ‡ธ๐Ÿ—ฝ", "new york"), + ("๐Ÿ‡ซ๐Ÿ‡ท๐Ÿ—ผ", "paris"), + ("๐Ÿ‡ฌ๐Ÿ‡ง๐ŸŽก", "london"), + ("โ›ฉ๏ธ๐ŸŒธ", "kyoto"), + ("๐Ÿ‡ฏ๐Ÿ‡ต๐Ÿ—ผ", "tokyo"), + ("๐Ÿ‡ฆ๐Ÿ‡บ๐ŸŒ‰", "sydney"), + ("๐Ÿ‡ฎ๐Ÿ‡น๐Ÿ›๏ธ", "rome"), + ("๐Ÿ‡ช๐Ÿ‡ฌ๐Ÿ•Œ", "cairo"), + ("๐Ÿ‡ง๐Ÿ‡ท๐ŸŽญ", "rio de janeiro"), + ("๐Ÿ‡จ๐Ÿ‡ณ๐Ÿผ", "chengdu"), + ], + "feelings": [ + ("๐Ÿ˜€", "happy"), + ("๐Ÿ˜ข", "sad"), + ("๐Ÿ˜ก", "angry"), + ("๐Ÿค”", "thinking"), + ("๐Ÿฅฑ", "tired"), + ("๐Ÿค’", "sick"), + ("๐Ÿ˜Ž", "cool"), + ("๐Ÿฅณ", "celebrating"), + ], + "dev": [ + ("๐Ÿ’ปโ˜•", "coding"), + ("๐Ÿ๐Ÿ“ฆ", "python package"), + ("๐Ÿ›๐Ÿ”", "debugging"), + ("๐Ÿ“ฆโฌ†๏ธ", "deploy"), + ("๐Ÿงชโœ…", "tests passing"), + ("โš ๏ธ๐Ÿ›", "bug"), + ], +} + + +def random_emojis(count=3, theme="food"): + items = _EMOJI_BANK.get(theme) + if not items: + all_emoji = [e for v in _EMOJI_BANK.values() for (e, _) in v] + random.shuffle(all_emoji) + return all_emoji[: min(count, len(all_emoji))] + emojis = [e for (e, _) in items] + random.shuffle(emojis) + return emojis[:count] + + +def get_theme_item(theme="food"): + items = _EMOJI_BANK.get(theme) + if not items: + items = _EMOJI_BANK["food"] + return random.choice(items) diff --git a/src/emojiguessr/quiz.py b/src/emojiguessr/quiz.py new file mode 100644 index 0000000..76fa056 --- /dev/null +++ b/src/emojiguessr/quiz.py @@ -0,0 +1,24 @@ +from .data import get_theme_item + + +def make_quiz_item(theme="food"): + emoji, answer = get_theme_item(theme) + return {"clue": emoji, "answer": answer, "theme": theme} + + +def _normalize(text): + return text.strip().lower() + + +def check_answer(correct, guess, case_sensitive=False, allow_partial=True): + if case_sensitive: + if allow_partial: + return correct.startswith(guess) + return correct == guess + + correct_n = _normalize(correct) + guess_n = _normalize(guess) + + if allow_partial: + return correct_n.startswith(guess_n) + return correct_n == guess_n diff --git a/src/emojiguessr/score.py b/src/emojiguessr/score.py new file mode 100644 index 0000000..979bd25 --- /dev/null +++ b/src/emojiguessr/score.py @@ -0,0 +1,4 @@ +def score(current_score, correct=True, points=1): + if correct: + return current_score + points + return current_score diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_data.py b/tests/test_data.py new file mode 100644 index 0000000..d6c3a00 --- /dev/null +++ b/tests/test_data.py @@ -0,0 +1,128 @@ +import pytest +from emojiguessr import data + +class Tests: + # + # Fixtures - these are functions that can do any optional setup or teardown before or after a test function is run. + # + + @pytest.fixture + def example_fixture(self): + """ + An example of a pytest fixture - a function that can be used for setup and teardown before and after test functions are run. + """ + + # place any setup you want to do before any test function that uses this fixture is run + + yield # at th=e yield point, the test function will run and do its business + + # place with any teardown you want to do after any test function that uses this fixture has completed + + + # + # Test functions + # + + def test_sanity_check(self, example_fixture): + """ + Test debugging... making sure that we can run a simple test that always passes. + Note the use of the example_fixture in the parameter list - any setup and teardown in that fixture will be run before and after this test function executes + From the main project directory, run the `python3 -m pytest` command to run all tests. + """ + expected = True # the value we expect to be present + actual = True # the value we see in reality + assert actual == expected, "Expected True to be equal to True!" + + def test_random_emojis_default(self): + """ + Verify random_emojis() function and make sure it returns the correct number of emojis. + """ + # test with default parameters + actual = data.random_emojis() + assert ( + len(actual) == 3 + ), f"Expected random_emojis() to return 3 emojis by default. Instead, it returned {len(actual)} emojis." + + # test with counts for food + default_len_actual = len(data._EMOJI_BANK["food"]) + for i in range(default_len_actual): + actual = data.random_emojis(i) + assert ( + len(actual) == i + ), f"Expected random_emojis({i}) to return {i} emojis. Instead, it returned {len(actual)} emojis." + + def test_random_emojis_all(self): + """ + Verify random_emojis() function when theme is invalid and it returns all emojis + """ + # test with invalid theme + all_emoji = [e for v in data._EMOJI_BANK.values() for (e, _) in v] + all_len_actual = len(all_emoji) + for i in range(all_len_actual): + actual = data.random_emojis(i, theme="invalid_theme") + assert ( + len(actual) == i + ), f"Expected random_emojis({i}, theme='invalid_theme') to return {i} emojis. Instead, it returned {len(actual)} emojis." + + def test_random_emojis_animals(self): + """ + Verify random_emojis() function for animals theme + """ + # test with counts for animals + animals_len_actual = len(data._EMOJI_BANK["animals"]) + for i in range(animals_len_actual): + actual = data.random_emojis(i, theme="animals") + assert ( + len(actual) == i + ), f"Expected random_emojis({i}, theme='animals') to return {i} emojis. Instead, it returned {len(actual)} emojis." + + def test_random_emojis_themes(self): + """ + Verify random_emojis() function works for all themes + """ + + for theme in data._EMOJI_BANK.keys(): + theme_len_actual = len(data._EMOJI_BANK[theme]) + for i in range(theme_len_actual): + actual = data.random_emojis(i, theme=theme) + assert ( + len(actual) == i + ), f"Expected random_emojis({i}, theme='{theme}') to return {i} emojis. Instead, it returned {len(actual)} emojis." + + + + + + def test_get_theme_item_default(self): + """ + Verify get_theme_item() function with default parameters + """ + + food_actual = data._EMOJI_BANK["food"] + actual = data.get_theme_item() + assert ( + actual in food_actual + ), f"Expected get_theme_item() to return an item from the food theme. Instead, it returned {actual}." + + def test_get_theme_item_invalid(self): + """ + Verify get_theme_item() function with invalid theme + """ + + food_actual = data._EMOJI_BANK["food"] + actual = data.get_theme_item("invalid") + assert ( + actual in food_actual + ), f"Expected get_theme_item() to return an item from the food theme. Instead, it returned {actual}." + + def test_get_theme_item_all(self): + """ + Verify get_theme_item() function works for all themes + """ + + for theme in data._EMOJI_BANK: + theme_actual = data._EMOJI_BANK[theme] + actual = data.get_theme_item(theme) + assert ( + actual in theme_actual + ) , f"Expected get_theme_item('{theme}') to return an item from the {theme} theme. Instead, it returned {actual}." \ No newline at end of file diff --git a/tests/test_score.py b/tests/test_score.py new file mode 100644 index 0000000..e69de29