diff --git a/_chapters/06-ex3.md b/_chapters/06-ex3.md index 2d3efd3..3a119a6 100644 --- a/_chapters/06-ex3.md +++ b/_chapters/06-ex3.md @@ -323,7 +323,7 @@ In fact, `+` is the 'shorthand' for over a hundred methods. You can see all of t ```julia julia> import Base.+ - julia> function +{LSD}(a::LSD, b::LSD) + julia> function +(a::LSD, b::LSD) newpence = a.pence + b.pence newshillings = a.shillings + b.shillings newpounds = a.pounds + b.pounds @@ -346,7 +346,7 @@ Indeed, `methods(+)` shows that the new method for two `LSD`s is registered: +(x::Bool) at bool.jl:36 +(x::Bool,y::Bool) at bool.jl:39 ... - +{LSD}(a::LSD,b::LSD) at none:2 + +(a::LSD,b::LSD) at none:2 ``` And now we know the price of biscuits and gravy: diff --git a/_chapters/07-ex4.md b/_chapters/07-ex4.md index e839d27..239f7fa 100644 --- a/_chapters/07-ex4.md +++ b/_chapters/07-ex4.md @@ -69,7 +69,7 @@ Incidentally, `end` behaves like a number – so `prime_array[end-1]` returns th #### Setting -If the indexable collection you are using is also mutable (e.g. an array), any of these methods will act as a pseudo-variable and will allow you to assign a value to it. Thus `prime_array[end] = 12` would change the last element of `prime_array` to 12. You also aren't restricted to a single element: calling `prime_array[2:4] = 0` would result in +If the indexable collection you are using is also mutable (e.g. an array), any of these methods will act as a pseudo-variable and will allow you to assign a value to it. Thus `prime_array[end] = 12` would change the last element of `prime_array` to 12. You also aren't restricted to a single element: calling `prime_array[2:4] .= 0` would result in ```julia julia> prime_array @@ -213,7 +213,7 @@ Similarly to `push!`, `unshift!` puts an element to the front of the collection: #### `find` functions -There's a set of functions starting with find — such as `find()`, `findfirst()`, and `findnext()` — that you can use to get the index or indices of values within an indexable collection that match a specific value, or pass a test. These functions share three properties. +There's a set of functions starting with find — such as `findall()`, `findfirst()`, and `findnext()` — that you can use to get the index or indices of values within an indexable collection that match a specific value, or pass a test. These functions share three properties. 1. Their result is the _index or indices of the value sought or tested for_, with the _n\_th_ element's index being _n_, not _n-1_ as you might be used to from other languages. 2. You can use these functions in two principal forms: you can test for a value or you can test for a function, in which case the results will be the values for which the function returns `true`. @@ -226,7 +226,7 @@ Let's try to find things within the following `Array`: `primes_and_one = [1,2,3, `findfirst()` finds the first occurrence of a value and returns its index (or zero): ```julia - julia> findfirst(primes_and_one, 5) + julia> findfirst(isequal(5),primes_and_one) 4 ``` @@ -236,15 +236,14 @@ As noted above, we can feed the `find` functions a function as well – it will julia> findfirst(x -> x == 13, primes_and_one) 7 ``` +A lot more of this will be explored in Chapter [X]. -You might have noticed that unlike in the case where you were searching for a particular value, _where you're searching by a function, the function comes first_. This is a little idiosyncrasy, but has to do with the way Julia determines what to do based on what it is provided with. A lot more of this will be explored in Chapter [X]. +##### `findall()` -##### `find()` - -`find()` returns an array of results. Thus, for instance, let's use the `isinteger` function to see which of our primes are integers (yet again, the result should not come as a shock): +`findall()` returns an array of results. Thus, for instance, let's use the `isinteger` function to see which of our primes are integers (yet again, the result should not come as a shock): ```julia - julia> find(isinteger, primes_and_one) + julia> findall(isinteger, primes_and_one) 10-element Array{Int64,1}: 1 2 @@ -274,12 +273,20 @@ As you might have noticed, when you use a function as an argument, you do not us ##### Get elements, not indices -So far, we've only been getting indices. How do we get the actual elements? The answer is, of course, by using our magical `[]`(square brackets) syntax. We'll also use this as a good opportunity to introduce a very useful function, `isprime()`, which returns `true` for primes and false otherwise: +So far, we've only been getting indices. How do we get the actual elements? The answer is, of course, by using our magical `[]`(square brackets) syntax. We'll also use this as a good opportunity to introduce a very useful function, `isprime()`, which returns `true` for primes and false otherwise. + +First, you may have to add Primes package: + +```julia + julia> import Pkg; + julia> Pkg.add("Primes") +``` +If you already have it, let's import `isprime()` and use it: ```julia - julia> import Primes + julia> import Primes.isprime - julia> find(isprime, primes_and_one) + julia> findall(isprime, primes_and_one) 9-element Array{Int64,1}: 2 3 @@ -291,7 +298,7 @@ So far, we've only been getting indices. How do we get the actual elements? The 9 10 - julia> primes_and_one[find(isprime,primes_and_one)] + julia> primes_and_one[findall(isprime,primes_and_one)] 9-element Array{Int64,1}: 2 3 @@ -307,7 +314,7 @@ So far, we've only been getting indices. How do we get the actual elements? The #### Filtering -The `filter()` function works quite similar to `find`, except in this case returns only the elements that satisfy the condition (it is, effectively, a shorthand for the previous listing). +The `filter()` function works quite similar to `findall`, except in this case returns only the elements that satisfy the condition (it is, effectively, a shorthand for the previous listing). ```julia julia> filter(isodd, primes_and_one) @@ -397,10 +404,11 @@ For mutable indexable collections, such as arrays, you can use `sort!()`, which #### Existence of a particular value -To find out whether an array has a particular value among its elements, you can use `in()`: +To find out whether an array has a particular value among its elements, you can use `in()`. `primes(1,10)` returns a collection of prime numbers from 1 to 10. ```julia - julia> in(2, primes) + julia> import Primes.primes + julia> in(2, primes(1,10)) true ``` @@ -515,7 +523,7 @@ One drawback of the bracket syntax is that if there is no entry for the key prov in getindex at dict.jl:644 ``` -An alternative form of accessing a dictionary is using the `get()` function, which accepts a default value: +An alternative form of accessing a dictionary is using the `get()` function. `get()` takes three arguments, collection name, key, and a default value to print if the key is not present in the dictionary: ```julia julia> get(statisticians, "Pearson", "I'm sorry, I don't know when this person lived.") @@ -525,13 +533,6 @@ An alternative form of accessing a dictionary is using the `get()` function, whi "I'm sorry, I don't know when this person lived." ``` -An advantage of this is that you can create a default value, which the function will return if it cannot find the key requested. Unlike in some other programming languages, a default is _not optional_ for Julia: - -```julia - julia> get(statisticians, "Kendall") - ERROR: `get` has no method matching get(::Dict{String,String}, ::String) -``` - #### Get or create (`get!()`) Because dicts are mutable, `get!()` can try to access a value by its key and create it if not found, then return the new value. Its syntax is identical to `get()`: @@ -550,7 +551,7 @@ Because dicts are mutable, `get!()` can try to access a value by its key and cre #### `pop!()` -`pop!()` returns the key-value array matching the key. If the key does not exist, it returns an optional default value or throws an error: +`pop!()` delete and returns the value matching the key. If the key does not exist, it returns an optional default value or throws an error: ```julia julia> pop!(statisticians, "Gosset") @@ -592,20 +593,20 @@ To check for the existence of a key without retrieving it, you can use `haskey() false ``` -You can also check for the existence of a key-value pair in a dict using the `in()` function you might be familiar with from arrays. Note that the notation of a key-value pair in this case will be in the form of a tuple `(key, value)` rather than using the associative array symbol `=>`: +You can also check for the existence of a key-value pair in a dict using the `in()` function you might be familiar with from arrays. Dicts look for `key=>value` pairs: ```julia - julia> in(("Bayes", "1702-1761"), statisticians) + julia> in("Bayes"=>"1702-1761", statisticians) false ``` #### Retrieving keys or values -To retrieve all keys of a dict, use `keys()`. This will retrieve an object of type `KeyIterator`, which does just what the name suggests - it iterates through the keys of an array. This will be useful later on when we want to iterate through the dictionary by keys: +To retrieve all keys of a dict, use `keys()`. This will retrieve an object of type `KeySet`, which does just what the name suggests - it iterates through the keys of an array. This will be useful later on when we want to iterate through the dictionary by keys: ```julia julia> keys(statisticians) - KeyIterator for a Dict{String,String} with 3 entries. Keys: + KeySet for a Dict{String,String} with 3 entries. Keys: "Galton" "Pearson" "Kendall" @@ -627,7 +628,7 @@ You can retrieve values, predictably, by using the `values()` function: You may have noticed that dicts are unordered. Even a dict generated by reference to a range, such as the one seen above, will not be in any particular order: ```julia - julia> [i => sqrt(i) for i = 1:2:15] + julia> Dict([i => sqrt(i) for i = 1:2:15]) Dict{Int64,Float64} with 8 entries: 7 => 2.6457513110645907 9 => 3.0 @@ -731,21 +732,25 @@ To create a set, use the `Set()` constructor function. You can create a set that ```julia julia> primes = Set() - Set{Any}({}) + Set{Any}() ``` – or you can specify what sort of data types it would accept: ```julia julia> primes = Set{Int64}() - Set{Int64}({}) + Set{Int64}() ``` -You can create and fill sets in one go by listing elements surrounded by curly braces `{}`, and if you surround the elements with square brackets `[]` instead of curly braces `{}` Julia will guess the type: +You can create and fill sets in one go by listing elements surrounded by square brackets `[]`: ```julia julia> mersenne_primes_set = Set([3, 7, 31, 127]) - Set([7,31,3,127]) + Set{Int64} with 4 elements: + 7 + 31 + 3 + 127 ``` ### Set operations @@ -763,7 +768,8 @@ To find shared actors, we can use `intersect()`: ```julia julia> intersect(lotr_actors, matrix_actors) - Set(String["Hugo Weaving"]) + Set{String} with 1 element: + "Hugo Weaving" ``` To find actors who only starred in _Lord of the Rings_ but not in _The Matrix_, we can use `setdiff()`, which shows all elements that are in the first `Set` but not the second: @@ -777,7 +783,10 @@ Finally, we can see actors who played in either of the movies, by using `union() ```julia julia> union(lotr_actors, matrix_actors) - Set(String["Elijah Wood","Ian McKellen","Hugo Weaving","Keanu Reeves","Lawrence Fishburne","Viggo Mortensen"]) + Set{String} with 3 elements: + "Elijah Wood" + "Viggo Mortensen" + "Ian McKellen" ``` diff --git a/_chapters/08-ex5.md b/_chapters/08-ex5.md index 4fc314b..e1df162 100644 --- a/_chapters/08-ex5.md +++ b/_chapters/08-ex5.md @@ -244,20 +244,20 @@ If you are familiar with regular expressions, plod ahead! However, if looks like gobbledygook to you or you feel your regex fu is a little rusty, put down this book and consult the [Regex cheatsheet](http://www.rexegg.com/regex-quickstart.html#ref) or, even better, [Jeffrey Friedl's amazing book on mastering regexes](http://regex.info/book.html). -### Finding and replacing using the `search()` function +### Finding Substring -If you are only concerned with finding a single instance of a search term within a string, the `search()` function returns the range index of where the search expression appears: +If you are only concerned with finding a single instance of a search term within a string, the `findfirst()` function returns the range index of where the search expression appears: ```julia - julia> search(declaration, "Government") + julia> findfirst("Government",declaration) 241:250 ``` -`search()` also accepts regular expressions: +`findfirst()` also accepts regular expressions: ```julia - julia> search(declaration, r"th.{2,3}") + julia> findfirst(r"th.{2,3}", declaration) 9:13 ``` @@ -265,18 +265,18 @@ If you are only concerned with finding a single instance of a search term within To retrieve the result, rather than its index, you can pass the resulting index off to the string as the subsetting range, using the square bracket `[]` syntax: ```julia - julia> declaration[search(declaration, r"th.{2,3}")] + julia> declaration[findfirst(r"th.{2,3}", declaration)] "these" ``` Ah, so that's the word it found! -Where a search string is not found, `search()` will yield `0:-1`. That is an odd result, until you realise the reason: for any string `s`, `s[0:-1]` will necessarily yield `""` (that is, an empty string). +Where a search string is not found, `findfirst()` will yield `nothing`. ### Finding using the `match()` family of functions -The problem with `search()` is that it retrieves one, and only one, result – the first within the string passed to it. The `match()` family of functions can help us with finding more results: +The problem with `findfirst()` is that it retrieves one, and only one, result – the first within the string passed to it. The `match()` family of functions can help us with finding more results: - `match()` retrieves _either the first match or nothing_ within the text, - `matchall()` returns _an array of all matching substrings_, and @@ -299,7 +299,7 @@ is valid, while yields an error: ```julia - ERROR: `match` has no method matching match(::String, ::String) + ERROR: MethodError: no method matching match(::String, ::String) ``` @@ -329,7 +329,7 @@ To illustrate, let's consider the result of a `match()` call, which will be intr #### `match()` -`match()` retrieves the first match or nothing - in this sense, it is rather similar to `search()`: +`match()` retrieves the first match or nothing - in this sense, it is rather similar to `findfirst()`: ```julia julia> match(r"That .*?,", declaration) @@ -339,18 +339,6 @@ To illustrate, let's consider the result of a `match()` call, which will be intr The result is a `RegexMatch` object. The object can be inspected using `.match` (e.g. `match(r"truths", declaration).match`). -#### `matchall()` - -`matchall()` returns an array of matching substrings, which is sometimes a little easier to use: - -```julia - julia> matchall(r"That .*?,", declaration) - 2-element Array{SubString{UTF8String},1}: - "That to secure these rights," - "That whenever any Form of Government becomes destructive of these ends," - -``` - #### `eachmatch()` `eachmatch()` returns an object known as an iterator, specifically of the type `RegexMatchIterator`. We have on and off encountered iterators, but we will not really deal with them in depth until chapter [X], which deals with control flow. Suffice it to say an iterator is an object that contains a list of items that can be iterated through. The iterator will iterate over a list of `RegexMatch` objects, so if we want the results themselves, we will need to call the `.match` method on each of them: @@ -361,8 +349,7 @@ The result is a `RegexMatch` object. The object can be inspected using `.match` end ``` - -The result is quite similar to that returned by `matchall()`: +gives following result: ```julia A matching search result is: That to secure these rights, @@ -370,15 +357,15 @@ The result is quite similar to that returned by `matchall()`: ``` -#### `ismatch()` +#### `occursin()` -`ismatch()` returns a boolean value depending on whether the search text contains a match for the regex provided. +`occursin()` returns a boolean value depending on whether the search text contains a match for the regex provided. ```julia - julia> ismatch(r"truth(s)?", declaration) + julia> occursin(r"truth(s)?", declaration) true - julia> ismatch(r"sausage(s)?", declaration) + julia> occursin(r"sausage(s)?", declaration) false ``` @@ -388,18 +375,11 @@ The result is quite similar to that returned by `matchall()`: Julia can replace substrings using the `replace()` syntax... let's try putting some sausages into the Declaration of Independence! ```julia - julia> replace(declaration, "truth", "sausage") + julia> replace(declaration, "truth"=>"sausage",count=1) "We hold these sausages to be self-evident, that all men are created equal,..." ``` - -An interesting feature of `replace()` is that the replacement does not need to be a string. In fact, it is possible to pass a function as the third argument (as always, without the parentheses `()` that signify a function call). Julia will interpret this as 'replace the substring with the result of passing the substring to this function': - -```julia - julia> replace(declaration, "truth", uppercase) - "We hold these TRUTHs to be self-evident, that all men are created equal,..." - -``` +By increasing the value of count you can replace remaining "truth". Much more dignified than self-evident sausages, I'd say! At risk of repeating myself, it is important to note that since strings are immutable, `replace()` merely returns a copy of the string with the search string replaced by the replacement string or the result of the replacement function, and the original string itself will remain unaffected. @@ -435,8 +415,8 @@ Case transformations are functions that act on `String`s and transform character |:--------:|--------|--------| | `uppercase()` | Converts the entire string to upper-case characters | `WE HOLD THESE TRUTHS TO BE SELF-EVIDENT` | | `lowercase()` | Converts the entire string to lower-case characters | `we hold these truths to be self-evident` | -| `ucfirst()` | Converts the first character of the string to upper-case | `We hold these truths to be self-evident` | -| `lcfirst()` | Converts the first character of the string ot lower-case | `we hold these truths to be self-evident` | +| `uppercasefirst()` | Converts the first character of the string to upper-case | `We hold these truths to be self-evident` | +| `lowercasefirst()` | Converts the first character of the string ot lower-case | `we hold these truths to be self-evident` | ### Testing and attributes