Skip to content

Commit

Permalink
Adds Concept Exercise Squeaky Clean
Browse files Browse the repository at this point in the history
  • Loading branch information
pwadsworth committed Oct 4, 2023
1 parent 2b3423e commit 2e73495
Show file tree
Hide file tree
Showing 10 changed files with 438 additions and 0 deletions.
14 changes: 14 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,20 @@
"maybe"
],
"status": "beta"
},
{
"slug": "squeaky-clean",
"name": "Squeaky Clean",
"uuid": "ca425c58-26ec-48d3-8e2d-a9d5fb8cb74e",
"concepts": [
"strings"
],
"prerequisites": [
"lists",
"maybe",
"booleans"
],
"status": "beta"
}
],
"practice": [
Expand Down
35 changes: 35 additions & 0 deletions exercises/concept/squeaky-clean/.docs/hints.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Hints

## 1. Replace any spaces encountered with underscores
- [This tutorial][string-tutorial] is useful.
- [Reference documentation][string-docs] for `String`.
- `String` provides a [replace][replace] function.

## 2. Replace control characters with the upper case string "CTRL"
- The common control characters are: \n, \t, and \r.
- You can separate strings into a list of strings with `String.split`
- You can [concatenate][concat] or [append][append] multiple strings.

## 3. Convert kebab-case to camelCase
- `char` literals are enclosed in single quotes.
- [Char.toUpper][toUpper] converts a character to upper case.
- Consider the use of higher-order functions to work your way through the entire string.

## 4. Omit digits
- `Char` provides functions to detect digits and alphabetic characters.


## 5. Omit emoticons and Greek lower case letters
- `Char` can transform characters to/from their unicode decimal values.
- Emoticons have the Unicode decimal values 128512 to 128591.
- Lower case [Greek letters][greek] form a contiguous Unicode block.

[string-tutorial]:https://elmprogramming.com/string.html
[string-docs]: https://package.elm-lang.org/packages/elm/core/latest/String
[replace]: https://package.elm-lang.org/packages/elm/core/latest/String#replace
[concat]: https://package.elm-lang.org/packages/elm/core/latest/String#concat
[append]: https://package.elm-lang.org/packages/elm/core/latest/String#append
[whitespace]: https://en.wikipedia.org/wiki/Whitespace_character#Unicode
[controlChars]: https://en.wikipedia.org/wiki/Unicode_control_characters
[toUpper]: https://package.elm-lang.org/packages/elm/core/latest/Char#toUpper
[greek]: https://www.compart.com/en/unicode/scripts/Grek
53 changes: 53 additions & 0 deletions exercises/concept/squeaky-clean/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Instructions

In this exercise you will implement a partial set of utility functions to help a developer clean up identifier names.

In the 5 tasks you will gradually build up the `clean` function.
A valid identifier comprises zero or more letters and underscores.

If an empty string is passed to the `clean` function, an empty string should be returned.

## 1. Replace spaces with underscores

Implement a `clean1` function to replace any spaces with underscores. This also applies to leading and trailing spaces.

```elm
clean1 "my Id"
--> "my___Id"
```

## 2. Replace control characters with the upper case string "CTRL"

Implement `clean2` to do everything the previous function does and replace common control characters (\n, \t, and \r ) with the string `"[CTRL]"`.

```elm
clean2 "my\0Id"
--> "myCTRLId",
```

## 3. Convert kebab-case to camelCase

Implement `clean3` to do everything the previous function does and convert kebab-case to camelCase.

```elm
clean "à-ḃç"
--> "àḂç"
```

## 4. Omit digits

Implement 'clean4` to do everything the previous function does and omit all digits.

```elm
clean "123"
--> ""
```

## 5. Omit Greek lower case letters

Finally, implement `clean` to do everything the previous function does and omit any Greek letters in the range 'α' to 'ω'.

```elm
clean "My Οβιεγτ Finder"
--> "My_Ο_Finder"
```
17 changes: 17 additions & 0 deletions exercises/concept/squeaky-clean/.docs/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Introduction

## Chars

The `Char` type represents the smallest addressable components of text.
Multiple `Char`s can comprise a string such as `"word"` or they can be
processed independently. Their literals have single quotes e.g. `'A'`.

Elm `Char` and `String` support Unicode encoding so in addition to the latin character set pretty much all the writing systems in use can be represented, e.g. the Greek letter `'β'`.

There are many builtin functions to inspect and manipulate `Char`s and `String`.

## Strings

`Char`s are most often used in conjunction as part of the `String` type.
This module has many functions that allow a string to be constructed
character by character and manipulated.
99 changes: 99 additions & 0 deletions exercises/concept/squeaky-clean/.meta/Exemplar.elm
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
module SquakyClean exposing (clean1, clean2, clean3, clean4, clean5)


clean1 : String -> String
clean1 str =
String.replace " " "_" str


clean2 : String -> String
clean2 str =
let
isCtrl : String -> Bool
isCtrl s =
List.member s [ "\n", "\t", "\u{000D}", "\u{0000}" ]
in
String.split "" str
|> List.map
(\s ->
if isCtrl s then
"[CTRL]"

else
s
)
|> String.concat
|> clean1


clean3 : String -> String
clean3 str =
let
charWordPairs : List (Maybe ( Char, String ))
charWordPairs =
String.split "-" str
|> List.map String.uncons

capitalizedWords : String
capitalizedWords =
case charWordPairs of
wrd1 :: rest ->
List.map
(Maybe.map
(\( c, restOfStr ) ->
( Char.toUpper c, restOfStr )
)
)
rest
|> List.map
(Maybe.map
(\( c, restOfStr ) ->
String.cons c restOfStr
)
)
|> List.foldr
(\wrd ->
(++) (Maybe.withDefault "" wrd)
)
""
|> (\wrds ->
Maybe.map
(\( c, restOfStr ) ->
String.cons c restOfStr
)
wrd1
|> Maybe.withDefault ""
|> (\wrd -> wrd ++ wrds)
)

_ ->
""
in
capitalizedWords
|> clean2


clean4 : String -> String
clean4 str =
str
|> String.filter (\c -> not (Char.isDigit c))
|> clean3


clean5 : String -> String
clean5 str =
let
emoticons : List Char
emoticons =
List.map Char.fromCode <| List.range 128512 128591

greekLCase : List Char
greekLCase =
List.map Char.fromCode <| List.range 945 969

notGreekLCaseOrEmo : Char -> Bool
notGreekLCaseOrEmo c =
not <| List.member c (emoticons ++ greekLCase)
in
String.filter notGreekLCaseOrEmo str
|> clean4
17 changes: 17 additions & 0 deletions exercises/concept/squeaky-clean/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"authors": [
"pwadsworth"
],
"files": {
"solution": [
"SqueakyClean.elm"
],
"test": [
"Tests.elm"
],
"exemplar": [
".meta/Exemplar.elm"
]
},
"blurb": "Learn about characters and strings by cleaning strings."
}
36 changes: 36 additions & 0 deletions exercises/concept/squeaky-clean/.meta/design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Design

## Learning objectives

- Know of the existence of the `char` type.
- Know what a char represents (a Unicode character).
- Know how to define a `char`.
- Know that a `char` is not the same as a single character string
- Know how to access a `char` in a string by index.
- Know of some basic `char` methods (like converting to uppercase).
- Know that `char`s are immutable.
- Know how to compare characters
- Know how to insert unicode characters in strings
- Know how to verify Char properties
- Know how to use basic string functions
- Know how to split and join strings
- Know how to check for substrings
- Know how to format a string (toUpper, toLower)
- Know how to use some higher order functions (all, any, filter...)


## Out of scope

- Converting an integer to a character and vice versa.
- Cultural considerations and invariants

## Concepts

- `Char`: know of the existence of the `char` type; know that a `char` represents; know how to define a `char`; know how to access a `char` in a string; know of some basic `char` methods (like converting to uppercase).
- `String`: know how to use a strings.

## Prerequisites

- Booleans
- Maybe
- Lists
29 changes: 29 additions & 0 deletions exercises/concept/squeaky-clean/elm.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"type": "application",
"source-directories": [
"src"
],
"elm-version": "0.19.1",
"dependencies": {
"direct": {
"elm/core": "1.0.5",
"elm/json": "1.1.3",
"elm/parser": "1.1.0",
"elm/random": "1.0.0",
"elm/regex": "1.0.0",
"elm/time": "1.0.0"
},
"indirect": {}
},
"test-dependencies": {
"direct": {
"elm-explorations/test": "2.1.0",
"rtfeldman/elm-iso8601-date-strings": "1.1.4"
},
"indirect": {
"elm/bytes": "1.0.8",
"elm/html": "1.0.0",
"elm/virtual-dom": "1.0.3"
}
}
}
26 changes: 26 additions & 0 deletions exercises/concept/squeaky-clean/src/SquakyClean.elm
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
module SquakyClean exposing (clean1, clean2, clean3, clean4, clean5)


clean1 : String -> String
clean1 str =
"Implement this function"


clean2 : String -> String
clean2 str =
"Implement this function"


clean3 : String -> String
clean3 str =
"Implement this function"


clean4 : String -> String
clean4 str =
"Implement this function"


clean5 : String -> String
clean5 str =
"Implement this function"
Loading

0 comments on commit 2e73495

Please sign in to comment.