276276 < li class ="sidebar-item ">
277277 < div class ="sidebar-item-container ">
278278 < a href ="./appendix-python.html " class ="sidebar-item-text sidebar-link ">
279- < span class ="menu-text "> < span class ="chapter-number "> A</ span > < span class ="chapter-title "> A Python Primer</ span > </ span > </ a >
279+ < span class ="menu-text "> < span class ="chapter-number "> A</ span > < span class ="chapter-title "> Appendix: Python Primer</ span > </ span > </ a >
280280 </ div >
281281</ li >
282282 < li class ="sidebar-item ">
@@ -337,12 +337,21 @@ <h2 class="anchored" data-anchor-id="linear-search">Linear Search</h2>
337337< p > A sequence (< code > Sequence</ code > class) is an abstract data type that represents a collection of items with no inherent structure, other than each element has an index.</ p >
338338< div class ="sourceCode " id ="cb1 " data-export ="src/codex/search/linear.py "> < pre class ="sourceCode python code-with-copy "> < code class ="sourceCode python "> < span id ="cb1-1 "> < a href ="#cb1-1 " aria-hidden ="true " tabindex ="-1 "> </ a > < span class ="im "> from</ span > typing < span class ="im "> import</ span > Sequence</ span > </ code > < button title ="Copy to Clipboard " class ="code-copy-button "> < i class ="bi "> </ i > </ button > </ pre > </ div >
339339< p > Linear search is the most basic form of search. We have a sequence of elements, and we must determine whether one specific element is among them. Since we cannot assume anything at all from the sequence, our only option is to check them all.</ p >
340+ < div id ="lst-linear-search " class ="listing quarto-float quarto-figure quarto-figure-left anchored ">
341+ < figure class ="quarto-float quarto-float-lst figure ">
342+ < figcaption class ="quarto-float-caption-top quarto-float-caption quarto-float-lst " id ="lst-linear-search-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca ">
343+ Algorithm 1.1: < strong > Linear Search:</ strong > Check every item in a sequence until a match is found or the collection is exhausted.
344+ </ figcaption >
345+ < div aria-describedby ="lst-linear-search-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca ">
340346< div class ="sourceCode " id ="cb2 " data-export ="src/codex/search/linear.py "> < pre class ="sourceCode python code-with-copy "> < code class ="sourceCode python "> < span id ="cb2-1 "> < a href ="#cb2-1 " aria-hidden ="true " tabindex ="-1 "> </ a > < span class ="kw "> def</ span > find[T](x:T, items: Sequence[T]) < span class ="op "> -></ span > < span class ="bu "> bool</ span > :</ span >
341347< span id ="cb2-2 "> < a href ="#cb2-2 " aria-hidden ="true " tabindex ="-1 "> </ a > < span class ="cf "> for</ span > y < span class ="kw "> in</ span > items:</ span >
342348< span id ="cb2-3 "> < a href ="#cb2-3 " aria-hidden ="true " tabindex ="-1 "> </ a > < span class ="cf "> if</ span > x < span class ="op "> ==</ span > y:</ span >
343349< span id ="cb2-4 "> < a href ="#cb2-4 " aria-hidden ="true " tabindex ="-1 "> </ a > < span class ="cf "> return</ span > < span class ="va "> True</ span > </ span >
344350< span id ="cb2-5 "> < a href ="#cb2-5 " aria-hidden ="true " tabindex ="-1 "> </ a > </ span >
345351< span id ="cb2-6 "> < a href ="#cb2-6 " aria-hidden ="true " tabindex ="-1 "> </ a > < span class ="cf "> return</ span > < span class ="va "> False</ span > </ span > </ code > < button title ="Copy to Clipboard " class ="code-copy-button "> < i class ="bi "> </ i > </ button > </ pre > </ div >
352+ </ div >
353+ </ figure >
354+ </ div >
346355< p > Our first test will be a sanity check for simple cases:</ p >
347356< div class ="sourceCode " id ="cb3 " data-export ="tests/search/test_linear.py "> < pre class ="sourceCode python code-with-copy "> < code class ="sourceCode python "> < span id ="cb3-1 "> < a href ="#cb3-1 " aria-hidden ="true " tabindex ="-1 "> </ a > < span class ="im "> from</ span > codex.search.linear < span class ="im "> import</ span > find</ span >
348357< span id ="cb3-2 "> < a href ="#cb3-2 " aria-hidden ="true " tabindex ="-1 "> </ a > </ span >
@@ -387,12 +396,21 @@ <h4 class="anchored" data-anchor-id="is-it-optimal">Is it optimal?</h4>
387396< section id ="indexing-and-counting " class ="level2 ">
388397< h2 class ="anchored " data-anchor-id ="indexing-and-counting "> Indexing and Counting</ h2 >
389398< p > The < code > find</ code > method is good to know if an element exists in a sequence, but it doesn’t tell us < em > where</ em > . We can easily extend it to return an < em > index</ em > . We thus define the < code > index</ code > method, with the following condition: if < code > index(x,l) == i</ code > then < code > l[i] == x</ code > . That is, < code > index</ code > returns the < strong > first</ strong > index where we can find a given element < code > x</ code > .</ p >
399+ < div id ="lst-linear-index " class ="listing quarto-float quarto-figure quarto-figure-left anchored ">
400+ < figure class ="quarto-float quarto-float-lst figure ">
401+ < figcaption class ="quarto-float-caption-top quarto-float-caption quarto-float-lst " id ="lst-linear-index-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca ">
402+ Algorithm 1.2: < strong > Linear Index:</ strong > Check every item until found, and return the corresponding index, or < code > None</ code > .
403+ </ figcaption >
404+ < div aria-describedby ="lst-linear-index-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca ">
390405< div class ="sourceCode " id ="cb4 " data-export ="src/codex/search/linear.py "> < pre class ="sourceCode python code-with-copy "> < code class ="sourceCode python "> < span id ="cb4-1 "> < a href ="#cb4-1 " aria-hidden ="true " tabindex ="-1 "> </ a > < span class ="kw "> def</ span > index[T](x: T, items: Sequence[T]) < span class ="op "> -></ span > < span class ="bu "> int</ span > < span class ="op "> |</ span > < span class ="va "> None</ span > :</ span >
391406< span id ="cb4-2 "> < a href ="#cb4-2 " aria-hidden ="true " tabindex ="-1 "> </ a > < span class ="cf "> for</ span > i,y < span class ="kw "> in</ span > < span class ="bu "> enumerate</ span > (items):</ span >
392407< span id ="cb4-3 "> < a href ="#cb4-3 " aria-hidden ="true " tabindex ="-1 "> </ a > < span class ="cf "> if</ span > x < span class ="op "> ==</ span > y:</ span >
393408< span id ="cb4-4 "> < a href ="#cb4-4 " aria-hidden ="true " tabindex ="-1 "> </ a > < span class ="cf "> return</ span > i</ span >
394409< span id ="cb4-5 "> < a href ="#cb4-5 " aria-hidden ="true " tabindex ="-1 "> </ a > </ span >
395410< span id ="cb4-6 "> < a href ="#cb4-6 " aria-hidden ="true " tabindex ="-1 "> </ a > < span class ="cf "> return</ span > < span class ="va "> None</ span > </ span > </ code > < button title ="Copy to Clipboard " class ="code-copy-button "> < i class ="bi "> </ i > </ button > </ pre > </ div >
411+ </ div >
412+ </ figure >
413+ </ div >
396414< p > When the item is not present in the sequence, we return < code > None</ code > . We could raise an exception instead, but that would force a lot of defensive programming.</ p >
397415< p > Let’s write some tests!</ p >
398416< div class ="sourceCode " id ="cb5 " data-export ="tests/search/test_linear.py "> < pre class ="sourceCode python code-with-copy "> < code class ="sourceCode python "> < span id ="cb5-1 "> < a href ="#cb5-1 " aria-hidden ="true " tabindex ="-1 "> </ a > < span class ="im "> from</ span > codex.search.linear < span class ="im "> import</ span > index</ span >
@@ -403,6 +421,12 @@ <h2 class="anchored" data-anchor-id="indexing-and-counting">Indexing and Countin
403421< span id ="cb5-6 "> < a href ="#cb5-6 " aria-hidden ="true " tabindex ="-1 "> </ a > < span class ="cf "> assert</ span > index(< span class ="dv "> 3</ span > , [< span class ="dv "> 1</ span > ,< span class ="dv "> 2</ span > ,< span class ="dv "> 3</ span > ]) < span class ="op "> ==</ span > < span class ="dv "> 2</ span > </ span >
404422< span id ="cb5-7 "> < a href ="#cb5-7 " aria-hidden ="true " tabindex ="-1 "> </ a > < span class ="cf "> assert</ span > index(< span class ="dv "> 4</ span > , [< span class ="dv "> 1</ span > ,< span class ="dv "> 2</ span > ,< span class ="dv "> 3</ span > ]) < span class ="kw "> is</ span > < span class ="va "> None</ span > </ span > </ code > < button title ="Copy to Clipboard " class ="code-copy-button "> < i class ="bi "> </ i > </ button > </ pre > </ div >
405423< p > As a final step in the linear search paradigm, let’s consider the problem of finding not the first, but < em > all</ em > occurrences of a given item. We’ll call this function < code > count</ code > . It will return the number of occurrences of some item < code > x</ code > in a sequence.</ p >
424+ < div id ="lst-linear-count " class ="listing quarto-float quarto-figure quarto-figure-left anchored ">
425+ < figure class ="quarto-float quarto-float-lst figure ">
426+ < figcaption class ="quarto-float-caption-top quarto-float-caption quarto-float-lst " id ="lst-linear-count-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca ">
427+ Algorithm 1.3: < strong > Linear Count:</ strong > Check all items equal to the input and count them.
428+ </ figcaption >
429+ < div aria-describedby ="lst-linear-count-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca ">
406430< div class ="sourceCode " id ="cb6 " data-export ="src/codex/search/linear.py "> < pre class ="sourceCode python code-with-copy "> < code class ="sourceCode python "> < span id ="cb6-1 "> < a href ="#cb6-1 " aria-hidden ="true " tabindex ="-1 "> </ a > < span class ="kw "> def</ span > count[T](x: T, items: Sequence[T]) < span class ="op "> -></ span > < span class ="bu "> int</ span > :</ span >
407431< span id ="cb6-2 "> < a href ="#cb6-2 " aria-hidden ="true " tabindex ="-1 "> </ a > c < span class ="op "> =</ span > < span class ="dv "> 0</ span > </ span >
408432< span id ="cb6-3 "> < a href ="#cb6-3 " aria-hidden ="true " tabindex ="-1 "> </ a > </ span >
@@ -411,6 +435,9 @@ <h2 class="anchored" data-anchor-id="indexing-and-counting">Indexing and Countin
411435< span id ="cb6-6 "> < a href ="#cb6-6 " aria-hidden ="true " tabindex ="-1 "> </ a > c < span class ="op "> +=</ span > < span class ="dv "> 1</ span > </ span >
412436< span id ="cb6-7 "> < a href ="#cb6-7 " aria-hidden ="true " tabindex ="-1 "> </ a > </ span >
413437< span id ="cb6-8 "> < a href ="#cb6-8 " aria-hidden ="true " tabindex ="-1 "> </ a > < span class ="cf "> return</ span > c</ span > </ code > < button title ="Copy to Clipboard " class ="code-copy-button "> < i class ="bi "> </ i > </ button > </ pre > </ div >
438+ </ div >
439+ </ figure >
440+ </ div >
414441< p > Let’s write some simple tests for this method.</ p >
415442< div class ="sourceCode " id ="cb7 " data-export ="tests/search/test_linear.py "> < pre class ="sourceCode python code-with-copy "> < code class ="sourceCode python "> < span id ="cb7-1 "> < a href ="#cb7-1 " aria-hidden ="true " tabindex ="-1 "> </ a > < span class ="im "> from</ span > codex.search.linear < span class ="im "> import</ span > count</ span >
416443< span id ="cb7-2 "> < a href ="#cb7-2 " aria-hidden ="true " tabindex ="-1 "> </ a > </ span >
0 commit comments