diff --git a/config.json b/config.json index 4f3db86..61ab73e 100644 --- a/config.json +++ b/config.json @@ -122,6 +122,14 @@ "prerequisites": [], "difficulty": 2 }, + { + "slug": "space-age", + "name": "Space Age", + "uuid": "09b96007-c782-4b5e-b929-48bab73b5f69", + "practices": [], + "prerequisites": [], + "difficulty": 2 + }, { "slug": "allergies", "name": "Allergies", diff --git a/exercises/practice/space-age/.docs/instructions.md b/exercises/practice/space-age/.docs/instructions.md new file mode 100644 index 0000000..f23b5e2 --- /dev/null +++ b/exercises/practice/space-age/.docs/instructions.md @@ -0,0 +1,28 @@ +# Instructions + +Given an age in seconds, calculate how old someone would be on a planet in our Solar System. + +One Earth year equals 365.25 Earth days, or 31,557,600 seconds. +If you were told someone was 1,000,000,000 seconds old, their age would be 31.69 Earth-years. + +For the other planets, you have to account for their orbital period in Earth Years: + +| Planet | Orbital period in Earth Years | +| ------- | ----------------------------- | +| Mercury | 0.2408467 | +| Venus | 0.61519726 | +| Earth | 1.0 | +| Mars | 1.8808158 | +| Jupiter | 11.862615 | +| Saturn | 29.447498 | +| Uranus | 84.016846 | +| Neptune | 164.79132 | + +~~~~exercism/note +The actual length of one complete orbit of the Earth around the sun is closer to 365.256 days (1 sidereal year). +The Gregorian calendar has, on average, 365.2425 days. +While not entirely accurate, 365.25 is the value used in this exercise. +See [Year on Wikipedia][year] for more ways to measure a year. + +[year]: https://en.wikipedia.org/wiki/Year#Summary +~~~~ diff --git a/exercises/practice/space-age/.docs/introduction.md b/exercises/practice/space-age/.docs/introduction.md new file mode 100644 index 0000000..014d788 --- /dev/null +++ b/exercises/practice/space-age/.docs/introduction.md @@ -0,0 +1,20 @@ +# Introduction + +The year is 2525 and you've just embarked on a journey to visit all planets in the Solar System (Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus and Neptune). +The first stop is Mercury, where customs require you to fill out a form (bureaucracy is apparently _not_ Earth-specific). +As you hand over the form to the customs officer, they scrutinize it and frown. +"Do you _really_ expect me to believe you're just 50 years old? +You must be closer to 200 years old!" + +Amused, you wait for the customs officer to start laughing, but they appear to be dead serious. +You realize that you've entered your age in _Earth years_, but the officer expected it in _Mercury years_! +As Mercury's orbital period around the sun is significantly shorter than Earth, you're actually a lot older in Mercury years. +After some quick calculations, you're able to provide your age in Mercury Years. +The customs officer smiles, satisfied, and waves you through. +You make a mental note to pre-calculate your planet-specific age _before_ future customs checks, to avoid such mix-ups. + +~~~~exercism/note +If you're wondering why Pluto didn't make the cut, go watch [this YouTube video][pluto-video]. + +[pluto-video]: https://www.youtube.com/watch?v=Z_2gbGXzFbs +~~~~ diff --git a/exercises/practice/space-age/.meta/config.json b/exercises/practice/space-age/.meta/config.json new file mode 100644 index 0000000..5a04654 --- /dev/null +++ b/exercises/practice/space-age/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "jimmytty" + ], + "files": { + "solution": [ + "space-age.sql" + ], + "test": [ + "space-age_test.sql" + ], + "example": [ + ".meta/example.sql" + ] + }, + "blurb": "Given an age in seconds, calculate how old someone is in terms of a given planet's solar years.", + "source": "Partially inspired by Chapter 1 in Chris Pine's online Learn to Program tutorial.", + "source_url": "https://pine.fm/LearnToProgram/?Chapter=01" +} diff --git a/exercises/practice/space-age/.meta/example.sql b/exercises/practice/space-age/.meta/example.sql new file mode 100644 index 0000000..753e327 --- /dev/null +++ b/exercises/practice/space-age/.meta/example.sql @@ -0,0 +1,21 @@ +DROP TABLE IF EXISTS planets; +CREATE TEMPORARY TABLE planets ( + name TEXT UNIQUE NOT NULL, + period REAL NOT NULL +); +INSERT INTO planets (name, period) +VALUES ('Mercury', 0.2408467 ), + ('Venus' , 0.61519726), + ('Earth' , 1.0 ), + ('Mars' , 1.8808158 ), + ('Jupiter', 11.862615 ), + ('Saturn' , 29.447498 ), + ('Uranus' , 84.016846 ), + ('Neptune', 164.79132 ); + +UPDATE "space-age" + SET result = ROUND("space-age".seconds / 31557600.0 / planets.period, 2) + FROM planets + WHERE "space-age".planet = planets.name + AND "space-age".result ISNULL + ; diff --git a/exercises/practice/space-age/.meta/tests.toml b/exercises/practice/space-age/.meta/tests.toml new file mode 100644 index 0000000..cec74fb --- /dev/null +++ b/exercises/practice/space-age/.meta/tests.toml @@ -0,0 +1,39 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[84f609af-5a91-4d68-90a3-9e32d8a5cd34] +description = "age on Earth" + +[ca20c4e9-6054-458c-9312-79679ffab40b] +description = "age on Mercury" + +[502c6529-fd1b-41d3-8fab-65e03082b024] +description = "age on Venus" + +[9ceadf5e-a0d5-4388-9d40-2c459227ceb8] +description = "age on Mars" + +[42927dc3-fe5e-4f76-a5b5-f737fc19bcde] +description = "age on Jupiter" + +[8469b332-7837-4ada-b27c-00ee043ebcad] +description = "age on Saturn" + +[999354c1-76f8-4bb5-a672-f317b6436743] +description = "age on Uranus" + +[80096d30-a0d4-4449-903e-a381178355d8] +description = "age on Neptune" + +[57b96e2a-1178-40b7-b34d-f3c9c34e4bf4] +description = "invalid planet causes error" +include = false +comment = "error testing omitted on purpose" \ No newline at end of file diff --git a/exercises/practice/space-age/create_fixture.sql b/exercises/practice/space-age/create_fixture.sql new file mode 100644 index 0000000..1fb467f --- /dev/null +++ b/exercises/practice/space-age/create_fixture.sql @@ -0,0 +1,11 @@ +DROP TABLE IF EXISTS "space-age"; +CREATE TABLE "space-age" ( + planet TEXT NOT NULL, + seconds INTEGER NOT NULL, + result REAL +); + +.mode csv +.import ./data.csv "space-age" + +UPDATE "space-age" SET result = NULL; diff --git a/exercises/practice/space-age/create_test_table.sql b/exercises/practice/space-age/create_test_table.sql new file mode 100644 index 0000000..8be0074 --- /dev/null +++ b/exercises/practice/space-age/create_test_table.sql @@ -0,0 +1,28 @@ +DROP TABLE IF EXISTS tests; +CREATE TABLE IF NOT EXISTS tests ( + -- uuid and description are taken from the test.toml file + uuid TEXT PRIMARY KEY, + description TEXT NOT NULL, + -- The following section is needed by the online test-runner + status TEXT DEFAULT 'fail', + message TEXT, + output TEXT, + test_code TEXT, + task_id INTEGER DEFAULT NULL, + -- Here are columns for the actual tests + planet TEXT NOT NULL, + seconds INTEGER NOT NULL, + expected REAL +); + +INSERT INTO tests (uuid, description, planet, seconds, expected) + VALUES + ('84f609af-5a91-4d68-90a3-9e32d8a5cd34','age on Earth','Earth',1000000000,31.69), + ('ca20c4e9-6054-458c-9312-79679ffab40b','age on Mercury','Mercury',2134835688,280.88), + ('502c6529-fd1b-41d3-8fab-65e03082b024','age on Venus','Venus',189839836,9.78), + ('9ceadf5e-a0d5-4388-9d40-2c459227ceb8','age on Mars','Mars',2129871239,35.88), + ('42927dc3-fe5e-4f76-a5b5-f737fc19bcde','age on Jupiter','Jupiter',901876382,2.41), + ('8469b332-7837-4ada-b27c-00ee043ebcad','age on Saturn','Saturn',2000000000,2.15), + ('999354c1-76f8-4bb5-a672-f317b6436743','age on Uranus','Uranus',1210123456,0.46), + ('80096d30-a0d4-4449-903e-a381178355d8','age on Neptune','Neptune',1821023456,0.35); + diff --git a/exercises/practice/space-age/data.csv b/exercises/practice/space-age/data.csv new file mode 100644 index 0000000..ce1ae2d --- /dev/null +++ b/exercises/practice/space-age/data.csv @@ -0,0 +1,8 @@ +"Earth",1000000000,"" +"Mercury",2134835688,"" +"Venus",189839836,"" +"Mars",2129871239,"" +"Jupiter",901876382,"" +"Saturn",2000000000,"" +"Uranus",1210123456,"" +"Neptune",1821023456,"" diff --git a/exercises/practice/space-age/space-age.sql b/exercises/practice/space-age/space-age.sql new file mode 100644 index 0000000..eb00d79 --- /dev/null +++ b/exercises/practice/space-age/space-age.sql @@ -0,0 +1,7 @@ +-- Schema: CREATE TABLE "space-age" ( +-- planet TEXT NOT NULL, +-- seconds INTEGER NOT NULL, +-- result REAL +-- ); +-- Task: update the space-age table and set the result based on planet +-- and seconds. diff --git a/exercises/practice/space-age/space-age_test.sql b/exercises/practice/space-age/space-age_test.sql new file mode 100644 index 0000000..946be88 --- /dev/null +++ b/exercises/practice/space-age/space-age_test.sql @@ -0,0 +1,43 @@ +-- Create database: +.read ./create_fixture.sql + +-- Read user student solution and save any output as markdown in user_output.md: +.mode markdown +.output user_output.md +.read ./space-age.sql +.output + +-- Create a clean testing environment: +.read ./create_test_table.sql + +-- Comparison of user input and the tests updates the status for each test: +UPDATE tests +SET status = 'pass' +FROM (SELECT planet, seconds, result FROM "space-age") AS actual +WHERE (actual.planet, actual.seconds, JSON(actual.result)) = (tests.planet, tests.seconds, JSON(tests.expected)); + +-- Update message for failed tests to give helpful information: +UPDATE tests +SET message = ( + 'Result for "' + || JSON_OBJECT( + 'planet', tests.planet, + 'seconds', tests.seconds + ) + || '"' + || ' is <' || COALESCE(actual.result, 'NULL') + || '> but should be <' || tests.expected || '>' +) +FROM (SELECT planet, seconds, result FROM "space-age") AS actual +WHERE (actual.planet, actual.seconds) = (tests.planet, tests.seconds) AND tests.status = 'fail'; + +-- Save results to ./output.json (needed by the online test-runner) +.mode json +.once './output.json' +SELECT description, status, message, output, test_code, task_id +FROM tests; + +-- Display test results in readable form for the student: +.mode table +SELECT description, status, message +FROM tests;