Skip to content

Commit 5a2ea29

Browse files
glennjIsaacG
andauthored
Add Vehicle Purchase exercise for Patterns concept (#326)
* Add Vehicle Purchase exercise for Patterns concept Co-authored-by: Isaac Good <[email protected]>
1 parent 4723b18 commit 5a2ea29

File tree

10 files changed

+930
-1
lines changed

10 files changed

+930
-1
lines changed

config.json

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,18 @@
5555
"fundamentals"
5656
],
5757
"status": "wip"
58+
},
59+
{
60+
"slug": "vehicle-purchase",
61+
"name": "vehicle-purchase",
62+
"uuid": "9e4e4ec3-ee4e-4f66-8fe2-fd10ede24df7",
63+
"concepts": [
64+
"patterns"
65+
],
66+
"prerequisites": [
67+
"fundamentals"
68+
],
69+
"status": "wip"
5870
}
5971
],
6072
"practice": [
@@ -521,7 +533,7 @@
521533
"practices": [],
522534
"prerequisites": [],
523535
"difficulty": 4,
524-
"status": "deprecated"
536+
"status": "deprecated"
525537
},
526538
{
527539
"slug": "pig-latin",
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Hints
2+
3+
## General
4+
5+
- You can accomplish all of these tasks without using an `if` statement.
6+
7+
## 1. Determine if you will need a drivers license
8+
9+
- Use the [equality operator][cmp] to check whether the first field equals a certain string.
10+
- Use a a regular expression to check if the second field contains the required substrings.
11+
- Use one of the two [boolean operators][bool] to combine the two requirements.
12+
13+
## 2.Calculate an estimation for the price of a used vehicle
14+
15+
- Use the [comparison operators][cmp] to determine which discount to use.
16+
17+
[cmp]: https://www.gnu.org/software/gawk/manual/html_node/Comparison-Operators.html
18+
[bool]: https://www.gnu.org/software/gawk/manual/html_node/Boolean-Ops.html
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Instructions
2+
3+
In this exercise, you will write a program to help you prepare to buy a vehicle.
4+
5+
You have two tasks: determine if you will need to get a license, and estimate the acceptable price for a used vehicle.
6+
7+
## 1. Determine if you will need a drivers license
8+
9+
Some kinds of vehicles require a drivers license to operate them.
10+
Assume only vehicles containing `car` or `truck` require a license; everything else can be operated without a license.
11+
12+
Implement a `pattern {action}` pair that matches when the first field is `needs_license`.
13+
It should get the kind of vehicle from the second field, and print "true" if you need a license for that kind of vehicle.
14+
If you don't need a license, you don't need to print anything.
15+
16+
```sh
17+
echo "needs_license,dumptruck" | gawk -f vehicle-purchase.awk
18+
# => true
19+
20+
echo "needs_license,bike" | gawk -f vehicle-purchase.awk
21+
# => (empty output)
22+
```
23+
24+
## 2. Calculate an estimation for the price of a used vehicle
25+
26+
Now that you have made your decision, you want to make sure you get a fair price at the dealership.
27+
Since you are interested in buying a used vehicle, the price depends on how old the vehicle is.
28+
For a rough estimate, assume if the vehicle is less than 3 years old, it costs 80% of the original price it had when new.
29+
If it is more than 10 years old, it costs 50%.
30+
If the vehicle is at least 3 years old but not older than 10 years, it costs 70% of the original price.
31+
32+
Implement a `pattern {action}` pair that matches when the first field is `resell_price`.
33+
It should get the original price of the vehicle from the second field, and the age from the third field.
34+
The action should print the estimated price.
35+
36+
```sh
37+
echo "resell_price,1000,1" | gawk -f vehicle-purchase.awk
38+
# => 800
39+
40+
echo "resell_price,1000,5" | gawk -f vehicle-purchase.awk
41+
# => 700
42+
43+
echo "resell_price,1000,15" | gawk -f vehicle-purchase.awk
44+
# => 500
45+
```
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# Introduction
2+
3+
## More about Patterns
4+
5+
Recall from the Fundamentals concept, an AWK program is composed of **pattern-action pairs**.
6+
7+
```awk
8+
pattern1 { action1 }
9+
pattern2 { action2 }
10+
...
11+
```
12+
13+
### What do we mean by "pattern"?
14+
15+
The "pattern" is any AWK expression.
16+
The truthiness of the expression's result determines if the action is executed.
17+
18+
### The Empty Pattern
19+
20+
The pattern can be omitted.
21+
In this case, the action is performed for every record.
22+
23+
We can print all the usernames in the passwd file.
24+
25+
```sh
26+
awk -F: '{print $1}' /etc/passwd
27+
```
28+
29+
### Regular Expressions
30+
31+
AWK can compare strings against regular expressions to obtain a boolean result.
32+
33+
Use the `~` regex-matching operator to match a particular field.
34+
This operator takes a string as the left-hand operand and a regular expression as the right-hand operand.
35+
A regular expression literal is enclosed in `/` slashes.
36+
37+
To find the users in the passwd file who log in with bash:
38+
39+
```sh
40+
awk -F: '$7 ~ /bash/ {print $1}' /etc/passwd
41+
```
42+
43+
`!~` is the "regex does **not** match" operator.
44+
45+
To match a regex against the current record, you can do `$0 ~ /regex/`.
46+
This is so common there is a shorthand: you can drop the `$0` and `~` and simply write `/regex/`
47+
48+
```sh
49+
awk '/regex/' data.txt
50+
```
51+
52+
~~~~exercism/note
53+
Compare that AWK one-liner with the equivalent grep command
54+
55+
```sh
56+
grep 'regex' data.txt
57+
```
58+
59+
AWK gives you a whole programming language without sacrificing succinctness.
60+
~~~~
61+
62+
We'll get more into GNU AWK's regular expression flavor in a further concept.
63+
64+
### Expressions
65+
66+
AWK expressions (arithmetic, logical, or otherwise) can be used as patterns.
67+
68+
To extract all users with UID 1000 or above:
69+
70+
```sh
71+
awk -F: '$3 >= 1000' /etc/passwd
72+
```
73+
74+
Recall that AWK's false values are the number zero and the empty string, and all other numbers or strings are true.
75+
Any expression that evaluates to a number or a string can be used as a pattern.
76+
77+
### Functions
78+
79+
Any [builtin][builtins] or [user-defined][] function can be used in an expression, and hence in the pattern.
80+
A couple of examples:
81+
82+
```awk
83+
length($1) {print "first field is not empty"}
84+
```
85+
```awk
86+
toupper(substr($1, 1, 1)) ~ /[AEIOU]/ {print "starts with a vowel"}
87+
```
88+
89+
### Constant Patterns
90+
91+
A common AWK idiom is:
92+
93+
```sh
94+
{
95+
xyz() # some code that transforms each record
96+
}
97+
1
98+
```
99+
100+
`1` is a truthy pattern with no associated action.
101+
This means "print the current record."
102+
103+
[builtins]: https://www.gnu.org/software/gawk/manual/html_node/Built_002din.html
104+
[user-defined]: https://www.gnu.org/software/gawk/manual/html_node/User_002ddefined.html
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Introduction
2+
3+
%{concept:patterns}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"authors": [
3+
"glennj"
4+
],
5+
"files": {
6+
"solution": [
7+
"vehicle-purchase.awk"
8+
],
9+
"test": [
10+
"test-vehicle-purchase.bats"
11+
],
12+
"exemplar": [
13+
".meta/exemplar.awk"
14+
]
15+
},
16+
"forked_from": [
17+
"javascript/vehicle-purchase"
18+
],
19+
"blurb": "Learn about AWK patterns while preparing for your next vehicle purchase."
20+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
BEGIN {FS = ","}
2+
3+
$1 == "needs_license" && $2 ~ /car|truck/ {print "true"}
4+
5+
$1 == "resell_price" && $3 < 3 {print $2 * 0.8}
6+
$1 == "resell_price" && 3 <= $3 && $3 <= 10 {print $2 * 0.7}
7+
$1 == "resell_price" && $3 > 10 {print $2 * 0.5}

0 commit comments

Comments
 (0)