Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,14 @@
"prerequisites": [],
"difficulty": 8
},
{
"slug": "proverb",
"name": "Proverb",
"uuid": "10c51241-2399-4a0c-84cf-390a000f3c3b",
"practices": [],
"prerequisites": [],
"difficulty": 8
},
{
"slug": "rest-api",
"name": "REST API",
Expand Down
7 changes: 7 additions & 0 deletions exercises/practice/proverb/.docs/instructions.append.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# SQLite-specific instructions

## JSON documentation

[JSON Functions And Operators][json-docs]

[json-docs]: https://www.sqlite.org/json1.html
19 changes: 19 additions & 0 deletions exercises/practice/proverb/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Instructions

For want of a horseshoe nail, a kingdom was lost, or so the saying goes.

Given a list of inputs, generate the relevant proverb.
For example, given the list `["nail", "shoe", "horse", "rider", "message", "battle", "kingdom"]`, you will output the full text of this proverbial rhyme:

```text
For want of a nail the shoe was lost.
For want of a shoe the horse was lost.
For want of a horse the rider was lost.
For want of a rider the message was lost.
For want of a message the battle was lost.
For want of a battle the kingdom was lost.
And all for the want of a nail.
```

Note that the list of inputs may vary; your solution should be able to handle lists of arbitrary length and content.
No line of the output text should be a static, unchanging string; all should vary according to the input given.
19 changes: 19 additions & 0 deletions exercises/practice/proverb/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"authors": [
"jimmytty"
],
"files": {
"solution": [
"proverb.sql"
],
"test": [
"proverb_test.sql"
],
"example": [
".meta/example.sql"
]
},
"blurb": "For want of a horseshoe nail, a kingdom was lost, or so the saying goes. Output the full text of this proverbial rhyme.",
"source": "Wikipedia",
"source_url": "https://en.wikipedia.org/wiki/For_Want_of_a_Nail"
}
33 changes: 33 additions & 0 deletions exercises/practice/proverb/.meta/example.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
UPDATE proverb
SET result = ''
WHERE JSON(strings) = '[]'
;

UPDATE proverb
SET result = (
WITH RECURSIVE to_pieces (strings, i, len, piece) AS (
VALUES(strings, 0, JSON_ARRAY_LENGTH(strings) - 1, NULL)
UNION ALL
SELECT strings, i+1, len,
PRINTF(
'For want of a %s the %s was lost.',
JSON_EXTRACT(strings, PRINTF('$[%d]', i)),
JSON_EXTRACT(strings, PRINTF('$[%d]', i+1))
)
FROM to_pieces
WHERE i < len
)
SELECT group_concat(piece, CHAR(10))
FROM (
SELECT piece
FROM to_pieces
WHERE piece NOTNULL
UNION ALL
SELECT PRINTF(
'And all for the want of a %s.',
JSON_EXTRACT(strings, '$[0]')
)
)
)
WHERE result ISNULL
;
28 changes: 28 additions & 0 deletions exercises/practice/proverb/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# 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.

[e974b73e-7851-484f-8d6d-92e07fe742fc]
description = "zero pieces"

[2fcd5f5e-8b82-4e74-b51d-df28a5e0faa4]
description = "one piece"

[d9d0a8a1-d933-46e2-aa94-eecf679f4b0e]
description = "two pieces"

[c95ef757-5e94-4f0d-a6cb-d2083f5e5a83]
description = "three pieces"

[433fb91c-35a2-4d41-aeab-4de1e82b2126]
description = "full proverb"

[c1eefa5a-e8d9-41c7-91d4-99fab6d6b9f7]
description = "four pieces modernized"
10 changes: 10 additions & 0 deletions exercises/practice/proverb/create_fixture.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
DROP TABLE IF EXISTS proverb;
CREATE TABLE proverb (
strings TEXT NOT NULL, -- json array containing the input words
result TEXT
);

.mode csv
.import ./data.csv proverb

UPDATE proverb SET result = NULL;
26 changes: 26 additions & 0 deletions exercises/practice/proverb/create_test_table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
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
strings TEXT NOT NULL, -- json array
expected TEXT NOT NULL
);

INSERT INTO tests (uuid, description, strings, expected)
VALUES
('e974b73e-7851-484f-8d6d-92e07fe742fc', 'zero pieces', '[]', ''),
('2fcd5f5e-8b82-4e74-b51d-df28a5e0faa4', 'one piece', '["nail"]', 'And all for the want of a nail.'),
('d9d0a8a1-d933-46e2-aa94-eecf679f4b0e', 'two pieces', '["nail","shoe"]', 'For want of a nail the shoe was lost.\nAnd all for the want of a nail.'),
('c95ef757-5e94-4f0d-a6cb-d2083f5e5a83', 'three pieces', '["nail","shoe","horse"]', 'For want of a nail the shoe was lost.\nFor want of a shoe the horse was lost.\nAnd all for the want of a nail.'),
('433fb91c-35a2-4d41-aeab-4de1e82b2126', 'full proverb', '["nail","shoe","horse","rider","message","battle","kingdom"]', 'For want of a nail the shoe was lost.\nFor want of a shoe the horse was lost.\nFor want of a horse the rider was lost.\nFor want of a rider the message was lost.\nFor want of a message the battle was lost.\nFor want of a battle the kingdom was lost.\nAnd all for the want of a nail.'),
('c1eefa5a-e8d9-41c7-91d4-99fab6d6b9f7', 'four pieces modernized', '["pin","gun","soldier","battle"]', 'For want of a pin the gun was lost.\nFor want of a gun the soldier was lost.\nFor want of a soldier the battle was lost.\nAnd all for the want of a pin.');

UPDATE tests SET expected = REPLACE(expected, '\n', CHAR(10));
6 changes: 6 additions & 0 deletions exercises/practice/proverb/data.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
"[]",
"[""nail""]",
"[""nail"",""shoe""]",
"[""nail"",""shoe"",""horse""]",
"[""nail"",""shoe"",""horse"",""rider"",""message"",""battle"",""kingdom""]",
"[""pin"",""gun"",""soldier"",""battle""]",
7 changes: 7 additions & 0 deletions exercises/practice/proverb/proverb.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-- Schema:
-- CREATE TABLE proverb (
-- strings TEXT NOT NULL, -- json array containing the input words
-- result TEXT
-- );
--
-- Task: update proverb table and set result column based on the strings.
40 changes: 40 additions & 0 deletions exercises/practice/proverb/proverb_test.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
-- 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 ./proverb.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 strings, result FROM proverb) AS actual
WHERE (actual.strings, actual.result) = (tests.strings, tests.expected);

-- Update message for failed tests to give helpful information:
UPDATE tests
SET message = (
'Result for "'
|| tests.strings
|| '"'
|| ' is <' || COALESCE(actual.result, 'NULL')
|| '> but should be <' || tests.expected || '>'
)
FROM (SELECT strings, result FROM proverb) AS actual
WHERE actual.strings = tests.strings 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;