├── .gitignore ├── README.md ├── algorithms ├── eratosthenes.js ├── fib.js ├── searching │ └── binary_search.js ├── shortest_paths │ ├── bellman-ford.js │ ├── dijkstra.js │ └── traversal.cs ├── sorting │ ├── bubble_sort.js │ ├── merge_sort.js │ ├── quicksort.js │ └── selection_sort.js └── swift │ └── Algorithms.playground │ ├── Contents.swift │ ├── Sources │ ├── Dynamic.swift │ ├── Searching.swift │ └── Sorting.swift │ ├── contents.xcplayground │ └── playground.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ └── mschroeder.xcuserdatad │ └── UserInterfaceState.xcuserstate ├── comp └── thing.cs ├── lamda_calculus ├── 01_basics.js ├── 01b-substitutions.js ├── 02_reductions.js ├── 03_booleans.js ├── 04_numbers.js └── 05_combinators.js ├── langs └── my_project │ ├── .gitignore │ ├── README.md │ ├── config │ └── config.exs │ ├── lib │ └── my_project.ex │ ├── mix.exs │ └── test │ ├── list_test.exs │ ├── my_project_test.exs │ ├── refactor_test.exs │ └── test_helper.exs ├── linux ├── cron │ └── pg_backup.sh ├── make-web │ ├── Makefile │ ├── assets │ │ ├── js │ │ │ ├── app.js │ │ │ ├── cart.js │ │ │ ├── checkout.js │ │ │ └── thing │ │ │ │ └── thing.js │ │ └── sass │ │ │ └── main.scss │ ├── package.json │ └── public │ │ ├── css │ │ └── app.css │ │ └── js │ │ └── app.js ├── make │ ├── Makefile │ ├── dist │ │ └── app.js │ └── src │ │ └── app.js ├── task-images │ ├── dist │ │ └── screenshots │ │ │ ├── ace.jpg │ │ │ ├── ae_plan.jpg │ │ │ ├── calculator.jpg │ │ │ └── difference_engine.jpg │ ├── images │ │ ├── doodles │ │ │ ├── 3nf2.png │ │ │ ├── gc-1.png │ │ │ ├── gc-2.png │ │ │ ├── lex-1.png │ │ │ └── snowflake.png │ │ ├── screenshots │ │ │ ├── ace.jpg │ │ │ ├── calc_mac.png │ │ │ ├── calculator.jpg │ │ │ └── difference_engine.jpg │ │ └── space │ │ │ ├── 17071818163_66adaafda2_k.0.jpg │ │ │ ├── 17504334828_6d727a0ecf_k.0.jpg │ │ │ └── 17504602910_a939b425ba_k.0.jpg │ ├── resizer.sh │ └── step_1.sh └── task-jekyll │ └── new_post.sh ├── software-design ├── bdd │ ├── .gitignore │ ├── .nuget │ │ └── packages.config │ ├── bdd.sln │ └── bdd │ │ ├── 01_start.cs │ │ ├── 02_payment_fails.cs │ │ ├── BillingSystemSpecs.cs │ │ ├── MyClass.cs │ │ ├── Properties │ │ └── AssemblyInfo.cs │ │ ├── bdd.csproj │ │ └── packages.config ├── patterns │ ├── .gitignore │ ├── Imposter.sln │ └── Imposter │ │ ├── Bridge.cs │ │ ├── Builder.cs │ │ ├── ChainOfResponsibility.cs │ │ ├── Command.cs │ │ ├── Composite.cs │ │ ├── Constructor.cs │ │ ├── Decorator.cs │ │ ├── Facade.cs │ │ ├── Factory.cs │ │ ├── Flyweight.cs │ │ ├── Imposter.csproj │ │ ├── Mediator.cs │ │ ├── Observer.cs │ │ ├── Program.cs │ │ ├── Properties │ │ └── AssemblyInfo.cs │ │ ├── Singleton.cs │ │ ├── State.cs │ │ └── Strategy.cs ├── solid │ ├── .gitignore │ ├── solid.sln │ └── solid │ │ ├── Program.cs │ │ ├── Properties │ │ └── AssemblyInfo.cs │ │ ├── dependency_inversion.cs │ │ ├── interface_segregation.cs │ │ ├── liskov.cs │ │ ├── solid.csproj │ │ └── srp.cs ├── structuraldesign │ ├── .gitignore │ ├── structuraldesign.sln │ └── structuraldesign │ │ ├── Program.cs │ │ ├── Properties │ │ └── AssemblyInfo.cs │ │ ├── demeter.cs │ │ ├── di.cs │ │ ├── interfaces.cs │ │ ├── structuraldesign.csproj │ │ └── tell_dont_ask.cs └── tdd │ ├── .gitignore │ ├── .nuget │ └── packages.config │ ├── tdd.sln │ └── tdd │ ├── 01_start.cs │ ├── 02_add_customer.cs │ ├── 03_mocks.cs │ ├── 04_happy_path.cs │ ├── 05_happy_path_green.cs │ ├── 06_sad_path.cs │ ├── 07_fixed_sad_path.cs │ ├── 08_problem.cs │ ├── Properties │ └── AssemblyInfo.cs │ ├── packages.config │ └── tdd.csproj └── theory ├── bigo.js ├── data_structures.cs └── data_structures.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | 3 | #Junk Files 4 | *.DS_Store 5 | [Tt]humbs.db 6 | 7 | #Visual Studio Files 8 | [Oo]bj 9 | [Bb]in 10 | [Dd]ebug 11 | [Bb]uild/ 12 | *.user 13 | *.suo 14 | *.exe 15 | *.pdb 16 | *.aps 17 | *_i.c 18 | *_p.c 19 | *.ncb 20 | *.tlb 21 | *.tlh 22 | *.[Cc]ache 23 | *.bak 24 | *.ncb 25 | *.ilk 26 | *.log 27 | *.lib 28 | *.sbr 29 | *.sdf 30 | ipch/ 31 | *.dbmdl 32 | *.csproj.user 33 | *.cache 34 | *.swp 35 | *.vspscc 36 | *.vssscc 37 | *.bak.* 38 | *.bak 39 | 40 | #Tools 41 | _ReSharper.* 42 | _ReSharper*/ 43 | *.resharper 44 | *.resharper.user 45 | [Nn][Dd]epend[Oo]ut*/ 46 | Ankh.NoLoad 47 | 48 | #Other 49 | .svn 50 | 51 | # Include DLLs if they're in the NuGet packages directory 52 | !/packages/*/lib/*.dll 53 | !/packages/*/lib/*/*.dll 54 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Source Code for [The Imposter's Handbook](http://impostershandbook.com) 2 | 3 | The code in this repository is a mix of C#, JavaScript, Bash and SQL, and is for the book The Imposter's Handbook. 4 | 5 | You should be able to download the code and, depending on the project type (Node, .NET) restore the packages and off you go. 6 | 7 | If you have any problems, please feel free to leave an issue. 8 | 9 | -------------------------------------------------------------------------------- /algorithms/eratosthenes.js: -------------------------------------------------------------------------------- 1 | const sieve = (n) => { 2 | //build the grid we'll use for multipliers 3 | //you can use an array here or an object 4 | //I think objects read easier 5 | var grid = {}; 6 | for (var i = 2; i <= n; i++) { 7 | grid[i]={marked: false}; 8 | } 9 | //the multiplier limit 10 | const limit = Math.sqrt(n); 11 | //loop up to limit 12 | for (var i = 2; i <= limit; i++) { 13 | //if i is already marked, all multiples 14 | //of it must already be marked, so skip 15 | if(grid[i].marked) continue; 16 | //figure out the multiples of i 17 | for(var x = i + i; x <= n; x += i){ 18 | //mark the multiples of i 19 | grid[x].marked = true; 20 | } 21 | } 22 | //the ouput - only return the numbers 23 | //from the grid that weren't marked 24 | var out =[]; 25 | for (var i = 2; i <= n; i++) { 26 | if(!grid[i].marked) out.push(i); 27 | } 28 | return out; 29 | }; 30 | console.log(sieve(100)); 31 | -------------------------------------------------------------------------------- /algorithms/fib.js: -------------------------------------------------------------------------------- 1 | const calculateFibAt = (n) => { 2 | fibCount = fibCount+1; 3 | if(n < 2){ 4 | return n; 5 | }else{ 6 | return calculateFibAt(n-2) + calculateFibAt(n-1); 7 | } 8 | } 9 | 10 | for(var i = 0; i<=10; i++){ 11 | console.log(calculateFibAt(i)); 12 | } 13 | 14 | var fibCount=0; 15 | var calculateFibAt = function(n){ 16 | fibCount = fibCount+1; 17 | var calc; 18 | if(n < 2){ 19 | return n; 20 | }else{ 21 | return calculateFibAt(n-2) + calculateFibAt(n-1); 22 | } 23 | } 24 | 25 | for(var i = 0; i<=10; i++){ 26 | var fib = calculateFibAt(i); 27 | console.log("The Fibonacci number at position " + i + " is " + fib + "; It took " + fibCount + " calls to fib to get here"); 28 | } 29 | 30 | 31 | 32 | var fibFaster = function(n){ 33 | var sequence = [0,1]; 34 | for(var i=2; i<=n; i++){ 35 | sequence.push(sequence[i -2] + sequence[i-1]); 36 | } 37 | return sequence; 38 | } 39 | 40 | console.log(fibFaster(10)); 41 | 42 | // 43 | // //the ES6 lambda way... 44 | // 45 | // const fib = n => n < 2 ? n : fib(n-2) + fib(n-1); 46 | // 47 | // //the fast way 48 | // const calculateFibFaster = (n) =>{ 49 | // var memoTable = [0,1]; 50 | // for(var i=2;i<=n;i++){ 51 | // memoTable.push(memoTable[i-2] + memoTable[i-1]); 52 | // } 53 | // return memoTable; 54 | // }; 55 | // 56 | 57 | var fibConstantSpace= function(n, fn){ 58 | let twoFibsAgo = 0, oneFibAgo=1, currentFib=0; 59 | //make sure to output the first two 60 | for(var i=2; i<=n; i++){ 61 | currentFib = twoFibsAgo+oneFibAgo; 62 | twoFibsAgo = oneFibAgo; 63 | oneFibAgo = currentFib; 64 | } 65 | return currentFib; 66 | } 67 | 68 | 69 | var fibConstantSpace= function(n, fn){ 70 | let twoFibsAgo = 0, oneFibAgo=1, currentFib=0; 71 | //make sure to output the first two 72 | if(fn){ 73 | fn(0); 74 | fn(1); 75 | } 76 | for(var i=2; i<=n; i++){ 77 | currentFib = twoFibsAgo+oneFibAgo; 78 | twoFibsAgo = oneFibAgo; 79 | oneFibAgo = currentFib; 80 | if(fn) fn(currentFib); 81 | } 82 | } 83 | fibConstantSpace(10, function(fib){ 84 | console.log(fib); 85 | }); 86 | // //run it the fast way 87 | 88 | const fib = function(n, twice=0, last=1){ 89 | if(n === 0) return last; 90 | return fib(n-1, twice + last, twice); 91 | } 92 | 93 | console.log(fib(10)); 94 | -------------------------------------------------------------------------------- /algorithms/searching/binary_search.js: -------------------------------------------------------------------------------- 1 | const list = [4,8,15,16,23,42]; 2 | 3 | const binarySearch = (list, lookFor) => { 4 | //define the range 5 | var min=0, max=list.length - 1; 6 | var middle; 7 | 8 | //while there is something to search for... 9 | while(min <= max){ 10 | //define the middle of the range 11 | middle = Math.floor((min + max) / 2); 12 | 13 | //if we've landed on it... 14 | if(list[middle] === lookFor) return middle; 15 | 16 | //if we haven't landed on it, where is it? 17 | //if the middle is less than the value we're 18 | //looking for, reset the min 19 | //otherwise reset the max 20 | if (list[middle] < lookFor) { 21 | min = middle + 1; //move min past middle 22 | } else { 23 | max = middle - 1; //move max before middle 24 | } 25 | } 26 | return -1; 27 | }; 28 | 29 | console.log(binarySearch(list,3)); 30 | -------------------------------------------------------------------------------- /algorithms/shortest_paths/bellman-ford.js: -------------------------------------------------------------------------------- 1 | 2 | //define the vertices - these can just be string values 3 | var vertices = ["S","A", "B", "C", "D", "E"]; 4 | 5 | //our memoization table, which I'll set to an object 6 | //defaulting as described 7 | var memo = { 8 | S : 0, 9 | A : Number.POSITIVE_INFINITY, 10 | B : Number.POSITIVE_INFINITY, 11 | C : Number.POSITIVE_INFINITY, 12 | D : Number.POSITIVE_INFINITY, 13 | E : Number.POSITIVE_INFINITY 14 | } 15 | 16 | //this is our graph, relationships between vertices 17 | //with costs associated 18 | var graph = [ 19 | {from : "S", to :"A", cost: 4}, 20 | {from : "S", to :"E", cost: -5}, 21 | {from : "A", to :"C", cost: 6}, 22 | {from : "B", to :"A", cost: 3}, 23 | {from : "C", to :"B", cost: -2}, 24 | {from : "D", to :"A", cost: 10}, 25 | {from : "D", to :"C", cost: 3}, 26 | {from : "E", to: "D", cost: 8} 27 | ]; 28 | 29 | var negativeCycleGraph = [ 30 | {from : "S", to :"A", cost: 4}, 31 | {from : "S", to :"E", cost: 5}, 32 | {from : "A", to :"C", cost: -6}, 33 | {from : "B", to :"A", cost: -3}, 34 | {from : "C", to :"B", cost: -2}, 35 | {from : "D", to :"A", cost: 10}, 36 | {from : "D", to :"C", cost: 3}, 37 | {from : "E", to: "D", cost: 8} 38 | ]; 39 | 40 | //represents a full iteration of Bellman-Ford on our graph 41 | const iterate = () => { 42 | //do we need another iteration? 43 | //decided below 44 | var doItAgain = false; 45 | //loop all vertices 46 | for(fromVertex of vertices){ 47 | //get the outgoing edges 48 | const edges = graph.filter(path => { 49 | return path.from === fromVertex; 50 | }); 51 | //loop the outgoing edges 52 | for(edge of edges){ 53 | const potentialCost = memo[edge.from] + edge.cost; 54 | //reset the cost as needed 55 | if(potentialCost < memo[edge.to]){ 56 | memo[edge.to] = potentialCost; 57 | //if the cost was changed we need to loop again 58 | doItAgain = true; 59 | } 60 | } 61 | } 62 | //return the flag 63 | return doItAgain; 64 | } 65 | 66 | const checkForNegativeCycles = (vertex, graph, memo) => { 67 | let negativeCycle = false; 68 | const edges = graph.filter(edge => edge.from === vertex) 69 | 70 | // evaluate a potential negative cycle 71 | edges.forEach(edge => { 72 | const costTo = memo[edge.to] 73 | const costFrom = memo[edge.from] + edge.cost 74 | if (costTo > costFrom) { 75 | negativeCycle = true; 76 | } 77 | }) 78 | return negativeCycle;; 79 | } 80 | 81 | 82 | const findShortestPath = (vertices, graph) => { 83 | 84 | let iterations = vertices.length - 1; 85 | while ( iterations > 0 ) { 86 | if (!iterate(graph, memo)){ iterations = 0; } 87 | iterations -= 1; 88 | } 89 | debugger; 90 | for (let vertex of vertices) { 91 | if (checkForNegativeCycles(vertex, graph, memo)) { 92 | return `Negative cycle!` 93 | } 94 | } 95 | 96 | return memo; 97 | } 98 | 99 | console.log(findShortestPath(vertices, graph)); 100 | console.log(findShortestPath(vertices, NegativeCycleGraph)); -------------------------------------------------------------------------------- /algorithms/shortest_paths/dijkstra.js: -------------------------------------------------------------------------------- 1 | //The memoization table, which needs to have some smarts 2 | //using an ES6 class here 3 | class MemoTable{ 4 | //build the table using the passed-in vertices 5 | constructor(vertices){ 6 | //set the root manually 7 | this.S = {name: "S", cost: 0, visited: false}; 8 | this.table = [this.S]; 9 | //add the vertices, defaulting cost to infinity and visited to false 10 | for(var vertex of vertices){ 11 | this.table.push({name: vertex, cost: Number.POSITIVE_INFINITY, visited: false}); 12 | } 13 | }; 14 | //all non-visited vertices 15 | getCandidateVertices(){ 16 | return this.table.filter(entry => { 17 | return entry.visited === false; 18 | }); 19 | }; 20 | //lowest cost, non-visited vertex 21 | nextVertex(){ 22 | const candidates = this.getCandidateVertices(); 23 | //if there are candidates, find the one 24 | //with lowest cost 25 | if(candidates.length > 0){ 26 | return candidates.reduce((prev, curr) => { 27 | return prev.cost < curr.cost ? prev : curr; 28 | }); 29 | }else{ 30 | //otherwise return null 31 | //this will help determine if we need to 32 | //iterate 33 | return null; 34 | } 35 | }; 36 | //update current cost 37 | setCurrentCost(vertex, cost){ 38 | this.getEntry(vertex).cost =cost; 39 | }; 40 | setAsVisited(vertex){ 41 | this.getEntry(vertex).visited = true; 42 | }; 43 | getEntry(vertex){ 44 | return this.table.find(entry => entry.name == vertex); 45 | }; 46 | getCost(vertex){ 47 | return this.getEntry(vertex).cost; 48 | }; 49 | toString(){ 50 | console.log(this.table); 51 | } 52 | }; 53 | //the vertices for our memo table 54 | //I could also use a filter or map on the graph below 55 | //to avoid duplication; but this is nice 56 | //and clear 57 | const vertices = ["A", "B","C", "D", "E"]; 58 | //our graph 59 | const graph = [ 60 | {from : "S", to :"A", cost: 4}, 61 | {from : "S", to :"E", cost: 2}, 62 | {from : "A", to :"D", cost: 3}, 63 | {from : "A", to :"C", cost: 6}, 64 | {from : "A", to :"B", cost: 5}, 65 | {from : "B", to :"A", cost: 3}, 66 | {from : "C", to :"B", cost: 1}, 67 | {from : "D", to :"C", cost: 3}, 68 | {from : "D", to :"A", cost: 1}, 69 | {from : "E", to: "D", cost: 1} 70 | ]; 71 | //create the table 72 | const memo = new MemoTable(vertices); 73 | //let's do this! 74 | const evaluate = vertex => { 75 | //get the outgoing edges of the vertex 76 | const edges = graph.filter(path => { 77 | return path.from === vertex.name; 78 | }); 79 | //loop the edges... 80 | for(edge of edges){ 81 | //calculate the costs 82 | const currentVertexCost = memo.getCost(edge.from); 83 | const toVertexCost = memo.getCost(edge.to); 84 | const tentativeCost = currentVertexCost + edge.cost; 85 | //if we can improve the cost to the 86 | //connected vertex... 87 | if(tentativeCost < toVertexCost){ 88 | //do it! 89 | memo.setCurrentCost(edge.to, tentativeCost); 90 | } 91 | }; 92 | //set this vertex as visited 93 | memo.setAsVisited(vertex.name); 94 | //get the next vertex 95 | const next = memo.nextVertex(); 96 | //if there is a next vertex, let's do this 97 | //again... 98 | if(next) evaluate(next); 99 | } 100 | //kick it off from the source vertex 101 | evaluate(memo.S); 102 | memo.toString(); 103 | 104 | 105 | 106 | [ { name: 'S', cost: 0, visited: true }, 107 | { name: 'A', cost: 4, visited: true }, 108 | { name: 'B', cost: 7, visited: true }, 109 | { name: 'C', cost: 6, visited: true }, 110 | { name: 'D', cost: 3, visited: true }, 111 | { name: 'E', cost: 2, visited: true } ] 112 | 113 | 114 | {keyword, "if"} 115 | {paren, } 116 | {variable, "x"} 117 | {operator, "=="} 118 | {number, "10"} 119 | {left-brace, } 120 | 121 | var x = 12; 122 | var squareIt = function(x){ 123 | return x * x; 124 | }; 125 | y = squareIt(x); 126 | console.log(y); 127 | 128 | var x; 129 | console.log(x); 130 | x = "Hello!"; -------------------------------------------------------------------------------- /algorithms/shortest_paths/traversal.cs: -------------------------------------------------------------------------------- 1 | public class BinaryNode 2 | { 3 | public int Value { get; } 4 | //child nodes 5 | public BinaryNode Left { get; set; } 6 | public BinaryNode Right { get; set; } 7 | 8 | public BinaryNode(int value) 9 | { 10 | Value = value; 11 | } 12 | public bool IsLeaf(){ 13 | return this.Left == null && this.Right == null; 14 | } 15 | public void Traverse(BinaryNode node){ 16 | if(node.Left != null){ 17 | Traverse(node.Left); 18 | } 19 | if(node.Right != null){ 20 | Traverse(node.Right); 21 | } 22 | //Leaf node! 23 | if(this.IsLeaf()){ 24 | //we're done! 25 | } 26 | } 27 | } 28 | 29 | var rootNode = new BinaryNode(0); 30 | rootNode.Left = new BinaryNode(1); 31 | rootNode.Right = new BinaryNode(2); 32 | rootNode.Left.Left = new BinaryNode(3); 33 | rootNode.Left.Right = new BinaryNode(4); 34 | rootNode.Right.Left = new BinaryNode(5); 35 | rootNode.Right.Right = new BinaryNode(6); 36 | 37 | 38 | public class DFS{ 39 | public void Traverse(BinaryNode root){ 40 | var stack = new Stack(); 41 | BinaryNode thisNode = null; 42 | //push the root onto the stack 43 | stack.Push(root); 44 | while(stack.Count > 0){ 45 | thisNode = stack.Pop(); 46 | Console.WriteLine(thisNode.Value); 47 | //push right then left 48 | if(thisNode.Right != null){ 49 | stack.Push(thisNode.Right); 50 | } 51 | if(thisNode.Left != null){ 52 | stack.Push(thisNode.Left); 53 | } 54 | } 55 | } 56 | } 57 | 58 | public class DFS{ 59 | public void Traverse(BinaryNode root){ 60 | //... 61 | } 62 | public void Run(){ 63 | var rootNode = new BinaryNode(0); 64 | rootNode.Left = new BinaryNode(1); 65 | rootNode.Right = new BinaryNode(2); 66 | rootNode.Left.Left = new BinaryNode(3); 67 | rootNode.Left.Right = new BinaryNode(4); 68 | rootNode.Right.Left = new BinaryNode(5); 69 | rootNode.Right.Right = new BinaryNode(6); 70 | this.Traverse(rootNode); 71 | } 72 | } 73 | 74 | public class BFS{ 75 | public void Traverse(BinaryNode root){ 76 | var queue = new Queue(); 77 | BinaryNode thisNode = null; 78 | //push the root onto the queue 79 | queue.Enqueue(root); 80 | while(queue.Count > 0){ 81 | //remove the next item from the queue 82 | thisNode = queue.Dequeue(); 83 | //do whatever calc 84 | Console.WriteLine(thisNode.Value); 85 | //add the children into the queue 86 | if(thisNode.Left != null){ 87 | queue.Enqueue(thisNode.Left); 88 | } 89 | if(thisNode.Right != null){ 90 | queue.Enqueue(thisNode.Right); 91 | } 92 | } 93 | } 94 | } -------------------------------------------------------------------------------- /algorithms/sorting/bubble_sort.js: -------------------------------------------------------------------------------- 1 | //the list we need to sort 2 | const list = [23,4,42,15,16,8]; 3 | 4 | const bubbleSort = (list) => { 5 | //a flag to tell us if we need to sort this list again 6 | var doItAgain = false; 7 | const limit = list.length; 8 | const defaultNextVal = Number.POSITIVE_INFINITY; 9 | //loop over the entries 10 | for (var i = 0; i < limit; i++) { 11 | let thisValue = list[i]; 12 | let nextValue = i + 1 < limit ? list[i+1] : defaultNextVal; 13 | //compare values 14 | if(nextValue < thisValue){ 15 | list[i] = nextValue; 16 | list[i+1] = thisValue; 17 | //since we made a switch we'll set a flag 18 | //as we'll need to execute the loop again 19 | doItAgain = true; 20 | } 21 | } 22 | if(doItAgain) bubbleSort(list); 23 | } 24 | bubbleSort(list); 25 | console.log(list); 26 | -------------------------------------------------------------------------------- /algorithms/sorting/merge_sort.js: -------------------------------------------------------------------------------- 1 | const list = [23,4,42,15,16,8,3]; 2 | const mergeSort = (list) => { 3 | //if there's only one item in the list 4 | //return. This is our recursion check. 5 | if(list.length <= 1) return list; 6 | 7 | //cut list in half 8 | const middle = list.length/2; 9 | const left = list.slice(0,middle); 10 | const right = list.slice(middle,list.length); 11 | 12 | //recursively run through the splits 13 | //left and right will be separated down to single elements 14 | return merge(mergeSort(left), mergeSort(right)); 15 | }; 16 | 17 | const merge = (left, right) => { 18 | var result = []; 19 | //if the left and right lists both have elements 20 | //run a comparison 21 | while(left.length || right.length){ 22 | //if there are items in both sides... 23 | if(left.length && right.length){ 24 | //if the first item on left is 25 | //less than right... 26 | if(left[0] < right[0]){ 27 | //take the first item on the left 28 | result.push(left.shift()); 29 | }else{ 30 | //take the first item on the right 31 | result.push(right.shift()); 32 | } 33 | }else if(left.length){ 34 | //just take left 35 | result.push(left.shift()); 36 | }else{ 37 | //just take right 38 | result.push(right.shift()); 39 | } 40 | } 41 | return result; 42 | } 43 | 44 | console.log(mergeSort(list)); 45 | -------------------------------------------------------------------------------- /algorithms/sorting/quicksort.js: -------------------------------------------------------------------------------- 1 | const list = [23,4,42,8,16,15]; 2 | const quickSort = (list) => { 3 | //recursion check. If list is empty or of length 1, return 4 | if(list.length < 2) return list; 5 | //these are the partition lists we'll need to use 6 | var left=[], right=[]; 7 | //default the pivot to the last item in the list 8 | const pivot = list.length -1; 9 | //set the pivot value 10 | const pivotValue = list[pivot]; 11 | //remove the pivot from the list as we don't want to compare it 12 | list = list.slice(0,pivot).concat(list.slice(pivot + 1)); 13 | //loop the list, comparing the partition values 14 | for (var item of list) { 15 | item < pivotValue ? left.push(item) : right.push(item); 16 | } 17 | //recursively move through left/right lists 18 | return quickSort(left).concat([pivotValue], quickSort(right)); 19 | }; 20 | 21 | console.log(quickSort(list)); 22 | -------------------------------------------------------------------------------- /algorithms/sorting/selection_sort.js: -------------------------------------------------------------------------------- 1 | const list = [23,4,42,8,16,15]; 2 | const selectionSort = (list) => { 3 | for (var i = 0; i < list.length; i++) { 4 | //default the min value to the first item in the list 5 | //all we need do is track the index for now 6 | var currentMinIndex = i; 7 | //loop over the list, skipping the currentMinIndex 8 | for(var x = currentMinIndex + 1; x < list.length; x++){ 9 | //if the current list item is less than the current min value... 10 | if(list[x] < list[currentMinIndex]){ 11 | //reset the index 12 | currentMinIndex = x; 13 | } 14 | } 15 | //has the index changed? 16 | if(currentMinIndex != i){ 17 | //if yes, switch the values in the list 18 | var oldMinValue = list[i]; 19 | list[i] = list[currentMinIndex]; 20 | list[currentMinIndex] = oldMinValue; 21 | } 22 | } 23 | return list; 24 | }; 25 | console.log(selectionSort(list)); 26 | 27 | 28 | 29 | const hasDuplicates = function(num){ 30 | //loop the list, our O(n) op 31 | for(let i = 0; i < nums.length; i++){ 32 | const thisNum = nums[i]; 33 | //loop the list again, the O(n^2) op 34 | for(let j = 0; j < nums.length; j++){ 35 | //make sure we're not checking same number 36 | if(j !== i){ 37 | const otherNum = nums[j]; 38 | //if there's an equal value, return 39 | if(otherNum === thisNum) return true; 40 | } 41 | } 42 | } 43 | //if we're here, no dups 44 | return false; 45 | } 46 | const nums = [1,2,3,4,5,5]; 47 | hasDuplicates(nums);//true 48 | -------------------------------------------------------------------------------- /algorithms/swift/Algorithms.playground/Contents.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | // The various implementations are in the Sources folder (⌘1) 4 | 5 | // the list we need to sort 6 | public var list = [23, 4, 42, 15, 16, 8, 3] 7 | // Try commenting this in for performance comparisons 8 | // list = Array(stride(from: 1000, to: 1, by: -1)) 9 | 10 | bubbleSort(&list) 11 | //mergeSort(&list) 12 | //quickSort(&list) 13 | //selectionSort(&list) 14 | 15 | let binaryList = [1,2,3,4,5,6] 16 | binarySearch(list: binaryList, lookFor: 3) 17 | 18 | calculateFibAt(20) 19 | fibFaster(20) 20 | 21 | sieve(50) 22 | sieveTwo(50) 23 | 24 | // Output is printed to the console (click triangle at bottom if necessary) 25 | bellmanFord() 26 | dykstra() 27 | -------------------------------------------------------------------------------- /algorithms/swift/Algorithms.playground/Sources/Dynamic.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | public func calculateFibAt(_ n: Int) -> Int { 4 | if n < 2 { 5 | return n 6 | } else { 7 | return calculateFibAt(n-2) + calculateFibAt(n-1) 8 | } 9 | } 10 | 11 | public func fibFaster(_ n: Int) -> [Int] { 12 | var sequence: [Int] = [0,1] 13 | 14 | for i in 2...n { 15 | sequence.append(sequence[i-2] + sequence[i-1]) 16 | } 17 | 18 | return sequence 19 | } 20 | 21 | public func sieve(_ n: Int) -> [Int] { 22 | var list = [Bool]() 23 | 24 | // load the list, defaulting to "true" as unmarked 25 | for _ in 0 ..< n { 26 | list.append(true) 27 | } 28 | 29 | // figure out our multiplier limit 30 | let limit = Int(sqrt(Double(n))) 31 | 32 | // run over the list, starting at 2 33 | for i in 2 ..< limit { 34 | for x in stride(from: i + i, to: n, by: i) { 35 | // set all multiples of i to false 36 | list[x] = false 37 | } 38 | } 39 | 40 | // build an output array 41 | var out = [Int]() 42 | for i in 2 ..< n { 43 | // if the list value is true, push the index 44 | if list[i] { 45 | out.append(i) 46 | } 47 | } 48 | 49 | return out 50 | } 51 | 52 | public func sieveTwo(_ n: Int) -> [Int] { 53 | var list = [(Int, Bool)]() 54 | 55 | // load the list, defaulting to "true" as unmarked 56 | for i in 0 ..< n { 57 | list.append((i, true)) 58 | } 59 | 60 | // figure out our multiplier limit 61 | let limit = Int(sqrt(Double(n))) 62 | 63 | func checkMultiples (_ i: Int, _ list: [(index: Int, value: Bool)]) -> [(Int,Bool)] { 64 | var newList = [(Int, Bool)]() 65 | guard var head = list.first else { 66 | return newList 67 | } 68 | 69 | // is it eligible? 70 | if (head.index > i && head.value) { 71 | 72 | // is it a multiple of i? 73 | if head.index % i == 0 { 74 | head.value = false 75 | } 76 | } 77 | newList.append(head) 78 | newList.append(contentsOf: checkMultiples(i, Array(list.dropFirst()))) 79 | 80 | return newList 81 | 82 | } 83 | for i in 2 ... limit { 84 | list = checkMultiples(i, list) 85 | } 86 | 87 | // build an output 88 | func buildOutput(_ input: [(index: Int, value: Bool)]) -> [Int] { 89 | var out = [Int]() 90 | 91 | guard let head = input.first else { 92 | return out 93 | } 94 | 95 | if head.value { 96 | out.append(head.index) 97 | } 98 | out.append(contentsOf: buildOutput(Array(input.dropFirst()))) 99 | 100 | return out 101 | } 102 | 103 | return buildOutput(list) 104 | } 105 | 106 | public func bellmanFord() { 107 | var vertices = ["S", "A", "B", "C", "D", "E"] 108 | 109 | var memo = [ 110 | "S": 0, 111 | "A": Int.max, 112 | "B": Int.max, 113 | "C": Int.max, 114 | "D": Int.max, 115 | "E": Int.max 116 | ] 117 | 118 | let graph: [(from: String, to: String, cost: Int)] = [ 119 | ("S", "A", 4), 120 | ("S", "E", -5), 121 | ("A", "C", 6), 122 | ("B", "A", 3), 123 | ("C", "B", -2), 124 | ("D", "C", 3), 125 | ("D", "A", 10), 126 | ("E", "D", 8) 127 | ] 128 | 129 | // represents a full iteration of Bellman-Ford on our graph 130 | func iterate() { 131 | 132 | // check each vertex 133 | for i in 0.. [MemoEntry] { 192 | return table.filter { $0.visited == false } 193 | } 194 | 195 | // returns the entry for vertex S 196 | func source() -> MemoEntry { 197 | return getEntry("S") 198 | } 199 | 200 | // return a single entry in our table 201 | func getEntry(_ vertex: String) -> MemoEntry { 202 | return table.filter { $0.name == vertex }.first! 203 | } 204 | 205 | // returns the next unvisited vertex with the least cost 206 | func nextVertex() -> MemoEntry? { 207 | let candidates = getCandidateVertices() 208 | // return the lowest 209 | if candidates.count > 0 { 210 | return candidates.reduce(candidates[0]) { (prev, curr) -> MemoEntry in 211 | return prev.cost < curr.cost ? prev : curr 212 | } 213 | } else { 214 | return nil 215 | } 216 | } 217 | 218 | // sets the cost of a given vertex in our table 219 | mutating func setCurrentCost(_ vertex: String, _ cost: Int) { 220 | table = table.map({ entry in 221 | if entry.name == vertex { 222 | return (name: entry.name, cost: cost, visited: entry.visited) 223 | } else { 224 | return entry 225 | } 226 | }) 227 | } 228 | 229 | // marks the vertex as visited 230 | mutating func setAsVisited(_ vertex: String) { 231 | table = table.map({ entry in 232 | if entry.name == vertex { 233 | return (name: entry.name, cost: entry.cost, visited: true) 234 | } else { 235 | return entry 236 | } 237 | }) 238 | } 239 | 240 | // returns the cost associated with reaching 241 | // a given vertex from the source 242 | func getCost(_ vertex: String) -> Int { 243 | return table.filter { $0.name == vertex }.first!.cost 244 | } 245 | 246 | // for display purposes 247 | func toString() { 248 | print(table) 249 | } 250 | } 251 | 252 | let graph: [(from: String, to: String, cost: Int)] = [ 253 | ("S", "A", 4), 254 | ("S", "E", 2), 255 | ("A", "D", 3), 256 | ("A", "C", 6), 257 | ("A", "B", 5), 258 | ("B", "A", 3), 259 | ("C", "B", 1), 260 | ("D", "C", 3), 261 | ("D", "A", 1), 262 | ("E", "D", 1) 263 | ] 264 | 265 | var memo = MemoTable() 266 | 267 | func evaluate(_ vertex: MemoEntry) { 268 | 269 | // get the outgoing edges for this vertex 270 | let edges = graph.filter { $0.from == vertex.name } 271 | 272 | // iterate over the edges and set the costs 273 | edges.forEach { edge in 274 | 275 | // the cost of the edge under evaluation 276 | let edgeCost = edge.cost 277 | 278 | let currentVertexCost = memo.getCost(edge.from) 279 | let toVertexCost = memo.getCost(edge.to) 280 | 281 | if currentVertexCost == Int.max { 282 | return 283 | } 284 | // the proposed cost from S to the current vertex 285 | let tentativeCost = currentVertexCost + edgeCost 286 | 287 | // if ti's less, update the memo table 288 | if tentativeCost < toVertexCost { 289 | memo.setCurrentCost(edge.to, tentativeCost) 290 | } 291 | } 292 | 293 | // this vertex has been visited 294 | memo.setAsVisited(vertex.name) 295 | 296 | // get the next vertex 297 | let next = memo.nextVertex() 298 | 299 | if next != nil { 300 | evaluate(next!) 301 | } 302 | } 303 | 304 | evaluate(memo.source()) 305 | memo.toString() 306 | } 307 | -------------------------------------------------------------------------------- /algorithms/swift/Algorithms.playground/Sources/Searching.swift: -------------------------------------------------------------------------------- 1 | public func binarySearch(list: [Int], lookFor: Int) -> Int { 2 | var min = 0 3 | var max = list.count - 1 4 | var middle = 0 5 | 6 | while min <= max { 7 | // find the middle of the list 8 | middle = (min + max) / 2 9 | 10 | // if we just happen to land on it… 11 | if list[middle] == lookFor { 12 | return middle 13 | } else { 14 | // the list is sorted, so if we're looking too low… 15 | if list[middle] < lookFor { 16 | // increase the minimum 17 | min = middle + 1 18 | } else { 19 | // decrease the max 20 | max = middle - 1 21 | } 22 | } 23 | } 24 | 25 | return -1 26 | } 27 | -------------------------------------------------------------------------------- /algorithms/swift/Algorithms.playground/Sources/Sorting.swift: -------------------------------------------------------------------------------- 1 | 2 | public func bubbleSort(_ list: inout [Int]) { 3 | // a flag to tell us if we need to sort this list again 4 | var doItAgain = false 5 | 6 | // loop variables 7 | let limit = list.count 8 | let defaultNextVal = Int.max 9 | 10 | // loop over the list entries… 11 | for i in 0 ..< limit { 12 | // the current list value 13 | let thisValue = list[i] 14 | 15 | // the next value, which defaults to a really high number 16 | let nextValue = i + 1 < limit ? list[i + 1] : defaultNextVal 17 | 18 | // is the next number lower than the current? 19 | if nextValue < thisValue { 20 | // if yes, we switch the values 21 | list[i] = nextValue 22 | list[i + 1] = thisValue 23 | 24 | // since we made a switch we'll set a flag 25 | // as we'll need to execute the loop again 26 | doItAgain = true 27 | } 28 | } 29 | 30 | // recurse over the list if the flag is set 31 | if doItAgain { 32 | bubbleSort(&list) 33 | } 34 | } 35 | 36 | 37 | public func mergeSort(_ list: inout [Int]) -> [Int] { 38 | // if there's only one item in the list, return 39 | if list.count <= 1 { 40 | return list 41 | } 42 | 43 | // cut the list in half 44 | let count = list.count 45 | let middle = count / 2 46 | var left = Array(list[0.. [Int] { 61 | var result = [Int]() 62 | 63 | // if the left an right lists both have elements 64 | // run a comparison 65 | while !left.isEmpty || !right.isEmpty { 66 | // if there are items on both sides… 67 | if !left.isEmpty && !right.isEmpty { 68 | // if the first item on left 69 | // is less than on right 70 | 71 | if left[0] < right[0] { 72 | // take the first item on the left 73 | result.append(left.removeFirst()) 74 | } else { 75 | // otherwise take the first item 76 | // on the right 77 | result.append(right.removeFirst()) 78 | } 79 | } else if !left.isEmpty { 80 | result.append(left.removeFirst()) 81 | } else { 82 | // there are items remaining on the right 83 | result.append(right.removeFirst()) 84 | } 85 | } 86 | 87 | return result 88 | } 89 | 90 | 91 | public func quickSort(_ list: inout [Int]) -> [Int] { 92 | // recursion check. If list is empty or of length 1, return 93 | if list.count < 2 { 94 | return list 95 | } 96 | 97 | // these are the partition lists we'll need to use 98 | var left = [Int]() 99 | var right = [Int]() 100 | 101 | // default the pivor to the last item in the list 102 | let pivot = list.count - 1 103 | 104 | // set the pivot value 105 | let pivotValue = list[pivot] 106 | 107 | // remove the pivot from the list as we don't want to compare it 108 | list.remove(at: pivot) 109 | 110 | // loop the list, comparing the partition values 111 | for i in 0.. [Int] { 128 | 129 | for i in 0.. 2 | 3 | 4 | -------------------------------------------------------------------------------- /algorithms/swift/Algorithms.playground/playground.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /algorithms/swift/Algorithms.playground/playground.xcworkspace/xcuserdata/mschroeder.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imposters-handbook/sample-code/f1ea98500a640d2dd153218d6b9efb9d8123fcce/algorithms/swift/Algorithms.playground/playground.xcworkspace/xcuserdata/mschroeder.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /comp/thing.cs: -------------------------------------------------------------------------------- 1 | public class MyClass { 2 | public MyClass(){ 3 | var x = 100; 4 | } 5 | } 6 | 7 | public class MyClass { 8 | int x; 9 | public MyClass(){ 10 | x = 100; 11 | } 12 | } 13 | 14 | if(1 === 1){ 15 | var x = 12; 16 | } 17 | console.log(x); //12 18 | 19 | public class ScopeTest 20 | { 21 | [Fact] 22 | public void TheScopeOfXIsLexical() 23 | { 24 | if(1 == 1){ 25 | var x = 12; 26 | } 27 | Console.WriteLine(x); 28 | } 29 | } 30 | 31 | error CS0103: The name 'x' does not exist in the current context 32 | 33 | 34 | public class MultiplyingByZero 35 | { 36 | [Fact] 37 | public void UsingNaN() 38 | { 39 | double x = Double.NaN; 40 | Console.WriteLine(x * 0); // NaN 41 | } 42 | } 43 | 44 | 45 | public class Customer{ 46 | public int ID {get;set;} 47 | //... 48 | 49 | public Order CurrentSalesOrder{get;set;} 50 | public Customer(int id){ 51 | //fetch the current order from the db 52 | this.CurrentSalesOrder = db.getCurrentOrder(id); 53 | } 54 | } 55 | 56 | public class Order{ 57 | public int ID {get;set;} 58 | //... 59 | 60 | public Customer Buyer{get;set;} 61 | public Order(GUID key){ 62 | this.Customer = db.getCustomerForOrder(key); 63 | } 64 | } -------------------------------------------------------------------------------- /lamda_calculus/01_basics.js: -------------------------------------------------------------------------------- 1 | //var lambda = (x => x)(5); 2 | //var lambda = (x => x)(y => y)(5); 3 | function thing(x){return x}; 4 | 5 | (x => x) 6 | 7 | //the identity function 8 | console.log((x => x)(5)); 9 | 10 | //the constant function 11 | let y=5; 12 | console.log((x => y)(100)); 13 | 14 | //multiple arguments, the ugly way 15 | console.log(((x,y) => x)(5)); 16 | 17 | //the Lambda Calculus way 18 | console.log((x => x)(y => y)(5)); 19 | 20 | //substitution 21 | console.log((x => x)(y => y)(30)); 22 | 23 | //x is both bound and free: 24 | let x = 10; 25 | console.log((x => x)(y => x)(5)); 26 | 27 | 28 | λx.x 29 | 30 | λx.x (y) 31 | 32 | (x => x)(y) 33 | //or 34 | function thing(x){return x}(y) //returns y; 35 | 36 | λx.y (z) 37 | 38 | let z = 3; 39 | function thing(x){return y}(z); 40 | 41 | λz.z y 42 | 43 | λx.x 3 44 | 45 | λx.x 3 46 | x[x:=3] 47 | 3 48 | 49 | let y = 3; 50 | const fn = (x => y)(1); 51 | 52 | let y = 3; 53 | const fn = (x => x)(1); 54 | 55 | λxy.t 56 | 57 | λx.λy.t 58 | 59 | (x => y => x + y); 60 | 61 | λx.λy.y x 62 | 63 | λx.λy.y x 64 | λy.y[x:=x] 65 | λy.y 66 | 67 | const first = (y => y); 68 | const second = (x => first(x)); 69 | console.log(second(first)); 70 | //[Function: first] 71 | 72 | 73 | (x => y => x + y)(2)(3); 74 | 75 | (x => x)(y => y)(2)(3); 76 | 77 | (x => x)(y => y)(2); //2 78 | 79 | 80 | λx.(λy.y x) 81 | 82 | 83 | λx.(λy.y x) 84 | λx.(y[y:=x]) 85 | λx.x 86 | 87 | 88 | λx.λy.y x 89 | (λy.y)[x:=x] 90 | λy.y 91 | 92 | 93 | if(true) x 94 | else y 95 | 96 | λx.λy.x 97 | 98 | λx.λy.y 99 | 100 | let True = (x => y => x); 101 | let False = (x => y => y); 102 | True(true)(false) //true 103 | False(true)(false) //false 104 | 105 | λx.λy.λz.x y z 106 | 107 | let If = (x => y => z => x(y)(z)); 108 | 109 | let True = (x => y => x); 110 | let False = (x => y => y); 111 | let If = (x => y => z => x(y)(z)); 112 | 113 | If(True)("TRUE")("oops..");//TRUE 114 | If(False)("oops")("FALSE");//FALSE 115 | 116 | -------------------------------------------------------------------------------- /lamda_calculus/01b-substitutions.js: -------------------------------------------------------------------------------- 1 | //substitutions 2 | //left-applicative: substitute from left to right 3 | 4 | let y = 3; 5 | let fn = (x => x)(1)//identity 6 | console.log(fn); 7 | -------------------------------------------------------------------------------- /lamda_calculus/02_reductions.js: -------------------------------------------------------------------------------- 1 | //a simple beta reduction 2 | let x = 10; 3 | console.log((x => x)(y => y)(x)); 4 | -------------------------------------------------------------------------------- /lamda_calculus/03_booleans.js: -------------------------------------------------------------------------------- 1 | //Church encoding 2 | //simple boolean construct 3 | //λx.λy.x //true 4 | //λx.λy.y //false 5 | //if true, return first value 6 | //if false, return second value 7 | const True = (x => y => x); 8 | const False = (x => y => y); 9 | console.log(True(true)(false)); 10 | console.log(False(true)(false)); 11 | 12 | //λz.λx.λy.z (x)(y) 13 | const If = (x => y => z => x(y)(z)); 14 | console.log(If(True)("TRUE")("oops")); 15 | console.log(If(False)("oops")("FALSE")); 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | // const True = (x => y => x); 31 | // 32 | // const False = (x => y => y); 33 | // 34 | // //conditional statement 35 | // const If = (x => y => z => x(y)(z)); 36 | // 37 | // console.log(If(True)("TRUE")("FALSE")); 38 | // console.log(If(False)("TRUE")("FALSE")); 39 | -------------------------------------------------------------------------------- /lamda_calculus/04_numbers.js: -------------------------------------------------------------------------------- 1 | λf.λx.x = 0 2 | λf.λx.f (x) = 1 3 | λf.λx.f (f(x)) = 2 4 | λf.λx.f (f(f(x))) = 3 5 | 6 | f(x) = x 7 | 8 | λf.λx.x 9 | 10 | λf.λx.f x 11 | (λx.f) x[f:=x] 12 | λx.x 13 | 14 | let calculate = f => f(x => x + 1)(0); 15 | 16 | 17 | let calculate = f => f(x => x + 1)(0); 18 | 19 | let zero = f => x => x; 20 | let one = f => x => f(x); 21 | let two = f => x => f(f(x)); 22 | let three = f => x => f(f(f(x))); 23 | 24 | calculate(zero) // 0 25 | calculate(one) // 1 26 | calculate(two) // 2 27 | calculate(three) // 3 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | const zero = f => x => x; 40 | const one = f => x => f(x); 41 | const two = f => x => f(f(x)); 42 | const three = f => x => f(f(f(x))); 43 | const four = f => x => f(f(f(f(x)))); 44 | 45 | //a helper to show us an integer equivalent 46 | //not Lambda Calc 47 | const calculate = f => f(x => x + 1)(0); 48 | 49 | console.log(calculate(one)); 50 | console.log(calculate(two)); 51 | console.log(calculate(three)); 52 | console.log(calculate(four)); 53 | 54 | //addition 55 | //https://github.com/benji6/church/blob/master/src/numerals.js 56 | const add = f => x => y => z => x(y)(f(y)(z)); 57 | const sum = add(one)(two); 58 | console.log(calculate(sum)); 59 | -------------------------------------------------------------------------------- /lamda_calculus/05_combinators.js: -------------------------------------------------------------------------------- 1 | λx.x (λx.x) 2 | x[x:=λx.x] 3 | λx.x 4 | 5 | let zero = f => x => x; 6 | let one = f => x => f(x); 7 | let two = f => x => f(f(x)); 8 | 9 | λx.x (λx.x) 10 | x[x:=λx.x] 11 | λx.x 12 | 13 | λx.xx (λx.xx) 14 | x[x:=λx.xx] 15 | λx.xx λx.xx 16 | 17 | let Omega = x => x(x); 18 | console.log(Omega(Omega)); 19 | //RangeError: Maximum call stack size exceeded 20 | 21 | 22 | let Y = f => (x => x(x))(x => f(y => x(x)(y))); 23 | 24 | let fib = f => n => n <= 1 ? n : f(n-1) + f(n-2); 25 | 26 | 1, 1, 2, 3, 5, 8, 13... 27 | 28 | let Y = f => (x => x(x))(x => f(y => x(x)(y))); 29 | let fib = f => n => n <= 1 ? n : f(n-1) + f(n-2); 30 | let yFib = Y(fib); 31 | yFib(10); 32 | //55 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | //self-selecting function 50 | const Omega = (x => x(x)); 51 | 52 | //run this to see an error 53 | //this is the Omega Combinator 54 | //console.log(Omega(Omega)); 55 | 56 | //the Y combinator 57 | //basicall a Lambda Calculus "for loop" 58 | const Y = f => (x => x(x))(x => f(y => x(x)(y))); 59 | 60 | //some functions we can loop over with Y 61 | const factorial = f => n => n > 1 ? n * f(n-1) : 1; 62 | const fib = f => n => n <= 1 ? n : f(n-1) + f(n-2); 63 | 64 | //declare a loop 65 | const loopFactorial = Y(factorial); 66 | const loopFib = Y(fib); 67 | 68 | //execute, passing in the loop constraint 69 | console.log(loopFactorial(10)); 70 | console.log(loopFib(10)); 71 | -------------------------------------------------------------------------------- /langs/my_project/.gitignore: -------------------------------------------------------------------------------- 1 | # The directory Mix will write compiled artifacts to. 2 | /_build 3 | 4 | # If you run "mix test --cover", coverage assets end up here. 5 | /cover 6 | 7 | # The directory Mix downloads your dependencies sources to. 8 | /deps 9 | 10 | # Where 3rd-party dependencies like ExDoc output generated docs. 11 | /doc 12 | 13 | # If the VM crashes, it generates a dump, let's ignore it too. 14 | erl_crash.dump 15 | 16 | # Also ignore archive artifacts (built via "mix archive.build"). 17 | *.ez 18 | -------------------------------------------------------------------------------- /langs/my_project/README.md: -------------------------------------------------------------------------------- 1 | # MyProject 2 | 3 | **TODO: Add description** 4 | 5 | ## Installation 6 | 7 | If [available in Hex](https://hex.pm/docs/publish), the package can be installed as: 8 | 9 | 1. Add `my_project` to your list of dependencies in `mix.exs`: 10 | 11 | ```elixir 12 | def deps do 13 | [{:my_project, "~> 0.1.0"}] 14 | end 15 | ``` 16 | 17 | 2. Ensure `my_project` is started before your application: 18 | 19 | ```elixir 20 | def application do 21 | [applications: [:my_project]] 22 | end 23 | ``` 24 | 25 | -------------------------------------------------------------------------------- /langs/my_project/config/config.exs: -------------------------------------------------------------------------------- 1 | # This file is responsible for configuring your application 2 | # and its dependencies with the aid of the Mix.Config module. 3 | use Mix.Config 4 | 5 | # This configuration is loaded before any dependency and is restricted 6 | # to this project. If another project depends on this project, this 7 | # file won't be loaded nor affect the parent project. For this reason, 8 | # if you want to provide default values for your application for 9 | # 3rd-party users, it should be done in your "mix.exs" file. 10 | 11 | # You can configure for your application as: 12 | # 13 | # config :my_project, key: :value 14 | # 15 | # And access this configuration in your application as: 16 | # 17 | # Application.get_env(:my_project, :key) 18 | # 19 | # Or configure a 3rd-party app: 20 | # 21 | # config :logger, level: :info 22 | # 23 | 24 | # It is also possible to import configuration files, relative to this 25 | # directory. For example, you can emulate configuration per environment 26 | # by uncommenting the line below and defining dev.exs, test.exs and such. 27 | # Configuration from the imported file will override the ones defined 28 | # here (which is why it is important to import them last). 29 | # 30 | # import_config "#{Mix.env}.exs" 31 | -------------------------------------------------------------------------------- /langs/my_project/lib/my_project.ex: -------------------------------------------------------------------------------- 1 | defmodule MyProject do 2 | end 3 | -------------------------------------------------------------------------------- /langs/my_project/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule MyProject.Mixfile do 2 | use Mix.Project 3 | 4 | def project do 5 | [app: :my_project, 6 | version: "0.1.0", 7 | elixir: "~> 1.3", 8 | build_embedded: Mix.env == :prod, 9 | start_permanent: Mix.env == :prod, 10 | deps: deps()] 11 | end 12 | 13 | # Configuration for the OTP application 14 | # 15 | # Type "mix help compile.app" for more information 16 | def application do 17 | [applications: [:logger]] 18 | end 19 | 20 | # Dependencies can be Hex packages: 21 | # 22 | # {:mydep, "~> 0.3.0"} 23 | # 24 | # Or git/path repositories: 25 | # 26 | # {:mydep, git: "https://github.com/elixir-lang/mydep.git", tag: "0.1.0"} 27 | # 28 | # Type "mix help deps" for more examples and options 29 | defp deps do 30 | [] 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /langs/my_project/test/list_test.exs: -------------------------------------------------------------------------------- 1 | defmodule ListTests do 2 | use ExUnit.Case 3 | 4 | test "a simple for loop" do 5 | for x <- 1..10, do: IO.inspect x 6 | end 7 | 8 | test "a filtered for loop" do 9 | for x <- 1..10, x > 5, do: IO.inspect x * x 10 | end 11 | 12 | test "a filtered for loop with multiple generators" do 13 | for x <- 1..10, y <-[2,3], x > 5, do: IO.inspect x * y 14 | end 15 | 16 | end 17 | -------------------------------------------------------------------------------- /langs/my_project/test/my_project_test.exs: -------------------------------------------------------------------------------- 1 | defmodule StringTests do 2 | use ExUnit.Case 3 | 4 | def great_again({:colour, y}) do 5 | "Red, White and #{y} for Brits too" 6 | end 7 | def great_again({:color, y}) do 8 | "Red, White and #{y}" 9 | end 10 | 11 | #Red, White and Green 12 | test "concatenating a string" do 13 | assert "This is" || " concatenation" == "This is concatenation" 14 | end 15 | 16 | test "capitalizing" do 17 | assert String.capitalize("horse") == "Horse" 18 | #assert "horse".capitlize == "Horse" FAILS 19 | end 20 | 21 | test "capitalizing with pipes" do 22 | assert "horse" |> String.capitalize == "Horse" 23 | {:colour, "Green"} |> great_again |> IO.inspect 24 | end 25 | 26 | test "humanize" do 27 | my_name = "Rob" 28 | assert "Say my name! #{my_name}!" == "Say my name! Rob!" 29 | end 30 | 31 | test "containment" do 32 | assert String.contains? "bunny foo foo", "foo" 33 | end 34 | end 35 | -------------------------------------------------------------------------------- /langs/my_project/test/refactor_test.exs: -------------------------------------------------------------------------------- 1 | 2 | 3 | defmodule RefactorTests do 4 | use ExUnit.Case 5 | 6 | def filter_values(%{} = map, filter_params) do 7 | Enum.into map, %{}, fn {k, v} -> {k, check_and_replace({k,v}, filter_params)} end 8 | end 9 | 10 | def check_and_replace({key,value}, look_for) when is_binary(key) do 11 | cond do 12 | String.contains?(key, look_for) -> "[FILTERED]" 13 | true -> value 14 | end 15 | end 16 | 17 | test "understanding what this thing does" do 18 | filtered = %{"name" => "Rob", "email" => "test@test.com", "password" => "chicken"} 19 | |> filter_values("password") 20 | 21 | assert filtered["password"] == "[FILTERED]" 22 | assert filtered["email"] == "test@test.com" 23 | 24 | end 25 | 26 | end 27 | -------------------------------------------------------------------------------- /langs/my_project/test/test_helper.exs: -------------------------------------------------------------------------------- 1 | ExUnit.start() 2 | -------------------------------------------------------------------------------- /linux/cron/pg_backup.sh: -------------------------------------------------------------------------------- 1 | BACKUP_DIRECTORY="/home/rob/backups" 2 | 3 | # Date stamp (formated YYYYMMDD) 4 | # just used in file name 5 | CURRENT_DATE=$(date "+%Y%m%d") 6 | 7 | # !!! Important pg_dump command does not export users/groups tables 8 | # still need to maintain a pg_dumpall for full disaster recovery !!! 9 | 10 | # this checks to see if the first command line argument is null 11 | if [ -z "$1" ] 12 | then 13 | # No database specified, do a full backup using pg_dumpall 14 | pg_dumpall | gzip - > $BACKUP_DIRECTORY/everything_$CURRENT_DATE.bak 15 | 16 | else 17 | # Database named (command line argument) use pg_dump for targed backup 18 | pg_dump -d $1 -Fc -f $BACKUP_DIRECTORY/$1_$CURRENT_DATE.bak 19 | 20 | fi 21 | -------------------------------------------------------------------------------- /linux/make-web/Makefile: -------------------------------------------------------------------------------- 1 | ###################### Step 1 2 | 3 | all: 4 | 5 | clean: 6 | 7 | .PHONY: all 8 | 9 | 10 | ###################### Step 2 11 | 12 | SASS=node_modules/.bin/node-sass 13 | SASS_FILES=assets/sass/main.scss 14 | JS_FILES=assets/js/*.js 15 | UGLIFY=node_modules/.bin/uglifyjs 16 | DIST_CSS=public/css 17 | DIST_JS=public/js 18 | 19 | all: 20 | 21 | clean: 22 | 23 | .PHONY: all 24 | 25 | 26 | ###################### Final 27 | SASS=node_modules/.bin/node-sass 28 | SASS_FILES=assets/sass/main.scss 29 | JS_FILES=assets/js/*.js assets/js/**/*.js 30 | UGLIFY=node_modules/.bin/uglifyjs 31 | DIST_CSS=public/css 32 | DIST_JS=public/js 33 | 34 | all: dist app.css app.js 35 | 36 | dist: 37 | mkdir $(DIST_CSS) $(DIST_JS) 38 | 39 | app.css: 40 | @ $(SASS) --output-style compressed $(SASS_FILES) > $(DIST_CSS)/$@ 41 | 42 | app.js: 43 | @ cat $(JS_FILES) | $(UGLIFY) > $(DIST_JS)/$@ 44 | 45 | clean: 46 | @rm -rf $(DIST_CSS) $(DIST_JS) 47 | 48 | .PHONY: all 49 | -------------------------------------------------------------------------------- /linux/make-web/assets/js/app.js: -------------------------------------------------------------------------------- 1 | var App = { 2 | storeName : "Amazing Place" 3 | }; 4 | 5 | App.sayHello = function(){ 6 | console.log("Hi there"); 7 | } 8 | -------------------------------------------------------------------------------- /linux/make-web/assets/js/cart.js: -------------------------------------------------------------------------------- 1 | App.Cart = function(){ 2 | console.log("Buy some stuff!"); 3 | }; 4 | -------------------------------------------------------------------------------- /linux/make-web/assets/js/checkout.js: -------------------------------------------------------------------------------- 1 | App.Checkout = function(){ 2 | console.log("Checking out!"); 3 | }; 4 | -------------------------------------------------------------------------------- /linux/make-web/assets/js/thing/thing.js: -------------------------------------------------------------------------------- 1 | App.Checkout = function(){ 2 | console.log("Puke on you"); 3 | }; 4 | -------------------------------------------------------------------------------- /linux/make-web/assets/sass/main.scss: -------------------------------------------------------------------------------- 1 | $font-stack: Helvetica, sans-serif; 2 | $primary-color: #333; 3 | 4 | body { 5 | font: 100% $font-stack; 6 | color: $primary-color; 7 | } 8 | 9 | @mixin border-radius($radius) { 10 | -webkit-border-radius: $radius; 11 | -moz-border-radius: $radius; 12 | -ms-border-radius: $radius; 13 | border-radius: $radius; 14 | } 15 | 16 | .box { @include border-radius(10px); } 17 | -------------------------------------------------------------------------------- /linux/make-web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "make-demo", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "node-sass": "^3.7.0", 13 | "uglifyjs": "^2.4.10" 14 | }, 15 | "devDependencies": { 16 | "jshint": "^2.9.2" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /linux/make-web/public/css/app.css: -------------------------------------------------------------------------------- 1 | body{font:100% Helvetica,sans-serif;color:#333}.box{-webkit-border-radius:10px;-moz-border-radius:10px;-ms-border-radius:10px;border-radius:10px} 2 | 3 | -------------------------------------------------------------------------------- /linux/make-web/public/js/app.js: -------------------------------------------------------------------------------- 1 | var App={storeName:"Amazing Place"};App.sayHello=function(){console.log("Hi there")};App.Cart=function(){console.log("Buy some stuff!")};App.Checkout=function(){console.log("Checking out!")};App.Checkout=function(){console.log("PPuke on you")}; -------------------------------------------------------------------------------- /linux/make/Makefile: -------------------------------------------------------------------------------- 1 | JS_FILES=src/app.js 2 | DIST=dist 3 | TODAY=$(shell date +%Y-%B-%d) 4 | TIMESTAMP="//Created at $(TODAY) \n\n" 5 | 6 | all: dist app.js 7 | 8 | dist: 9 | @ mkdir -p $(DIST) 10 | 11 | app.js: 12 | @ echo $(TIMESTAMP) > $(DIST)/$@ 13 | @ cat $(JS_FILES) >> $(DIST)/$@ 14 | 15 | clean: 16 | @ rm -rf $(DIST) 17 | 18 | .PHONY: all clean 19 | 20 | 21 | ###################### Step 1 22 | 23 | all: 24 | 25 | clean: 26 | 27 | .PHONY: all clean 28 | 29 | 30 | ###################### Step 2 31 | all: 32 | mkdir -p dist 33 | cp app.js dist/app.js 34 | 35 | clean: 36 | rm -rf dist 37 | 38 | .PHONY: all clean 39 | 40 | ###################### Step 3 41 | all: 42 | @ mkdir -p dist 43 | @ cp app.js dist/app.js 44 | 45 | clean: 46 | @ rm -rf dist 47 | 48 | .PHONY: all clean 49 | 50 | ###################### Step 4 51 | all: dist app.js 52 | 53 | dist: 54 | @ mkdir -p dist 55 | 56 | app.js: 57 | @ cp src/app.js dist/app.js 58 | 59 | clean: 60 | @ rm -rf dist 61 | 62 | .PHONY: all clean 63 | 64 | 65 | ###################### Step 4.5 66 | # all: dist app.js 67 | # 68 | # dist: 69 | # @ mkdir -p $@ 70 | # 71 | # app.js: 72 | # @ cp src/app.js dist/app.js 73 | # 74 | # clean: 75 | # @ rm -rf dist 76 | # 77 | # .PHONY: all clean 78 | 79 | 80 | ###################### Step 5 81 | JS_FILES=src/app.js 82 | DIST=dist 83 | TODAY=$(shell date +%Y-%B-%d) 84 | TIMESTAMP="//Created at $(TODAY) \n\n" 85 | 86 | all: dist app.js 87 | 88 | dist: 89 | @ mkdir -p $@ 90 | 91 | app.js: 92 | @ echo $(TIMESTAMP) > $(DIST)/$@ 93 | @ cat $(JS_FILES) >> $(DIST)/$@ 94 | 95 | clean: 96 | @ rm -rf $(DIST) 97 | 98 | .PHONY: all clean 99 | 100 | ###################### Final 101 | JS_FILES=src/app.js 102 | DIST=dist 103 | TODAY=$(shell date +%Y-%B-%d) 104 | TIMESTAMP="//Created at $(TODAY) \n\n" 105 | 106 | all: $(DIST) app.js 107 | 108 | $(DIST): 109 | @ mkdir -p $@ 110 | 111 | app.js: 112 | @ echo $(TIMESTAMP) > $(DIST)/$@ 113 | @ cat $(JS_FILES) >> $(DIST)/$@ 114 | 115 | 116 | clean: 117 | @ rm -rf $(DIST) 118 | 119 | .PHONY: all clean 120 | -------------------------------------------------------------------------------- /linux/make/dist/app.js: -------------------------------------------------------------------------------- 1 | //Created at 2016-October-19 2 | 3 | 4 | //some code 5 | -------------------------------------------------------------------------------- /linux/make/src/app.js: -------------------------------------------------------------------------------- 1 | var products = db.getAllProducts(); 2 | var occurrences = []; 3 | products.forEach(function(p){ 4 | var occurrenceCount = db.getOrderItemsWithSkus("X", p.sku); 5 | if(occurrenceCount > 0){ 6 | occurrences.push({target: "X", coSku: p.sku, count: occurrenceCount}); 7 | } 8 | }); 9 | if(occurrences.length > 0){ 10 | //filter it and take only the top 3 11 | } 12 | -------------------------------------------------------------------------------- /linux/task-images/dist/screenshots/ace.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imposters-handbook/sample-code/f1ea98500a640d2dd153218d6b9efb9d8123fcce/linux/task-images/dist/screenshots/ace.jpg -------------------------------------------------------------------------------- /linux/task-images/dist/screenshots/ae_plan.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imposters-handbook/sample-code/f1ea98500a640d2dd153218d6b9efb9d8123fcce/linux/task-images/dist/screenshots/ae_plan.jpg -------------------------------------------------------------------------------- /linux/task-images/dist/screenshots/calculator.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imposters-handbook/sample-code/f1ea98500a640d2dd153218d6b9efb9d8123fcce/linux/task-images/dist/screenshots/calculator.jpg -------------------------------------------------------------------------------- /linux/task-images/dist/screenshots/difference_engine.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imposters-handbook/sample-code/f1ea98500a640d2dd153218d6b9efb9d8123fcce/linux/task-images/dist/screenshots/difference_engine.jpg -------------------------------------------------------------------------------- /linux/task-images/images/doodles/3nf2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imposters-handbook/sample-code/f1ea98500a640d2dd153218d6b9efb9d8123fcce/linux/task-images/images/doodles/3nf2.png -------------------------------------------------------------------------------- /linux/task-images/images/doodles/gc-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imposters-handbook/sample-code/f1ea98500a640d2dd153218d6b9efb9d8123fcce/linux/task-images/images/doodles/gc-1.png -------------------------------------------------------------------------------- /linux/task-images/images/doodles/gc-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imposters-handbook/sample-code/f1ea98500a640d2dd153218d6b9efb9d8123fcce/linux/task-images/images/doodles/gc-2.png -------------------------------------------------------------------------------- /linux/task-images/images/doodles/lex-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imposters-handbook/sample-code/f1ea98500a640d2dd153218d6b9efb9d8123fcce/linux/task-images/images/doodles/lex-1.png -------------------------------------------------------------------------------- /linux/task-images/images/doodles/snowflake.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imposters-handbook/sample-code/f1ea98500a640d2dd153218d6b9efb9d8123fcce/linux/task-images/images/doodles/snowflake.png -------------------------------------------------------------------------------- /linux/task-images/images/screenshots/ace.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imposters-handbook/sample-code/f1ea98500a640d2dd153218d6b9efb9d8123fcce/linux/task-images/images/screenshots/ace.jpg -------------------------------------------------------------------------------- /linux/task-images/images/screenshots/calc_mac.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imposters-handbook/sample-code/f1ea98500a640d2dd153218d6b9efb9d8123fcce/linux/task-images/images/screenshots/calc_mac.png -------------------------------------------------------------------------------- /linux/task-images/images/screenshots/calculator.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imposters-handbook/sample-code/f1ea98500a640d2dd153218d6b9efb9d8123fcce/linux/task-images/images/screenshots/calculator.jpg -------------------------------------------------------------------------------- /linux/task-images/images/screenshots/difference_engine.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imposters-handbook/sample-code/f1ea98500a640d2dd153218d6b9efb9d8123fcce/linux/task-images/images/screenshots/difference_engine.jpg -------------------------------------------------------------------------------- /linux/task-images/images/space/17071818163_66adaafda2_k.0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imposters-handbook/sample-code/f1ea98500a640d2dd153218d6b9efb9d8123fcce/linux/task-images/images/space/17071818163_66adaafda2_k.0.jpg -------------------------------------------------------------------------------- /linux/task-images/images/space/17504334828_6d727a0ecf_k.0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imposters-handbook/sample-code/f1ea98500a640d2dd153218d6b9efb9d8123fcce/linux/task-images/images/space/17504334828_6d727a0ecf_k.0.jpg -------------------------------------------------------------------------------- /linux/task-images/images/space/17504602910_a939b425ba_k.0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imposters-handbook/sample-code/f1ea98500a640d2dd153218d6b9efb9d8123fcce/linux/task-images/images/space/17504602910_a939b425ba_k.0.jpg -------------------------------------------------------------------------------- /linux/task-images/resizer.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | function resize_jpegs(){ 3 | DIST=./dist/$1/ 4 | 5 | if [ -d "$DIST" ]; then 6 | rm -R $DIST 7 | fi 8 | 9 | mkdir -p $DIST 10 | 11 | for IMG in ./images/$1/*.jpg 12 | do 13 | convert $IMG -resize 600x400 "$DIST$(basename $IMG)" 14 | done 15 | } 16 | -------------------------------------------------------------------------------- /linux/task-images/step_1.sh: -------------------------------------------------------------------------------- 1 | #make a directory for our demo 2 | mkdir -p imposter/demos 3 | 4 | #move the demo files 5 | #assumes you downloaded to the Desktop, 6 | #adjust path as needed 7 | mv ~/Desktop/task-images ~/imposter/demos 8 | 9 | #change into the directory 10 | cd imposter/demos/task-images 11 | 12 | #list all images out 13 | ls **/*.jpg **/*.png 14 | 15 | #redirect STDOUT to a text file 16 | ls **/*.jpg **/*.png > images.txt 17 | -------------------------------------------------------------------------------- /linux/task-jekyll/new_post.sh: -------------------------------------------------------------------------------- 1 | function new_post(){ 2 | cd ~/sites/conery-io/_posts 3 | SLUGIFIED="$(echo -n "$1" | sed -e 's/[^[:alnum:]]/-/g' | tr -s '-' | tr A-Z a-z)" 4 | SLUG=$(date +"%Y-%m-%d"-$SLUGIFIED.md) 5 | 6 | cat < $SLUG 7 | --- 8 | layout: post-minimal 9 | title: '$1' 10 | image: '' 11 | comments: false 12 | categories: 13 | summary: '' 14 | --- 15 | 16 | ## Be Brilliant 17 | front_matter 18 | cd ../ 19 | subl . 20 | } 21 | -------------------------------------------------------------------------------- /software-design/bdd/.gitignore: -------------------------------------------------------------------------------- 1 | #Autosave files 2 | *~ 3 | 4 | #build 5 | [Oo]bj/ 6 | [Bb]in/ 7 | packages/ 8 | TestResults/ 9 | 10 | # globs 11 | Makefile.in 12 | *.DS_Store 13 | *.sln.cache 14 | *.suo 15 | *.cache 16 | *.pidb 17 | *.userprefs 18 | *.usertasks 19 | config.log 20 | config.make 21 | config.status 22 | aclocal.m4 23 | install-sh 24 | autom4te.cache/ 25 | *.user 26 | *.tar.gz 27 | tarballs/ 28 | test-results/ 29 | Thumbs.db 30 | 31 | #Mac bundle stuff 32 | *.dmg 33 | *.app 34 | 35 | #resharper 36 | *_Resharper.* 37 | *.Resharper 38 | 39 | #dotCover 40 | *.dotCover 41 | -------------------------------------------------------------------------------- /software-design/bdd/.nuget/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /software-design/bdd/bdd.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "bdd", "bdd\bdd.csproj", "{11504502-944C-41A5-8D81-8A5D316EA64E}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Any CPU = Debug|Any CPU 9 | Release|Any CPU = Release|Any CPU 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {11504502-944C-41A5-8D81-8A5D316EA64E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 13 | {11504502-944C-41A5-8D81-8A5D316EA64E}.Debug|Any CPU.Build.0 = Debug|Any CPU 14 | {11504502-944C-41A5-8D81-8A5D316EA64E}.Release|Any CPU.ActiveCfg = Release|Any CPU 15 | {11504502-944C-41A5-8D81-8A5D316EA64E}.Release|Any CPU.Build.0 = Release|Any CPU 16 | EndGlobalSection 17 | EndGlobal 18 | -------------------------------------------------------------------------------- /software-design/bdd/bdd/01_start.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xunit; 3 | 4 | namespace BillingSystem.Specs { 5 | 6 | [Trait ("Monthly Payment Is Due", "Payment Is Received")] 7 | public class PaymentReceived 8 | { 9 | [Fact] 10 | public void An_Invoice_Is_Created(){} 11 | 12 | [Fact] 13 | public void Subscription_Status_Is_Updated(){} 14 | 15 | [Fact] 16 | public void Next_Billing_Is_Set_1_Month_From_Now(){} 17 | 18 | [Fact] 19 | public void A_Notification_Is_Sent_To_Subscriber(){} 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /software-design/bdd/bdd/02_payment_fails.cs: -------------------------------------------------------------------------------- 1 | //... 2 | [Trait ("Monthly Billing", "Payment Fails")] 3 | public class SubscriptionPaymentIsDue 4 | { 5 | [Fact] 6 | public void An_Invoice_Is_Not_Created(){} 7 | 8 | [Fact] 9 | public void Next_Billing_Is_1_Day_From_Now(){} 10 | 11 | [Fact] 12 | public void A_Notification_Is_Sent_To_Subscriber(){} 13 | 14 | } 15 | 16 | //... 17 | -------------------------------------------------------------------------------- /software-design/bdd/bdd/BillingSystemSpecs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Xunit; 3 | 4 | namespace BillingSystem.Specs { 5 | 6 | [Trait ("Monthly Payment Is Due", "Payment Is Received")] 7 | public class PaymentReceived 8 | { 9 | [Fact] 10 | public void An_Invoice_Is_Created(){} 11 | 12 | [Fact] 13 | public void Subscription_Status_Is_Updated(){} 14 | 15 | [Fact] 16 | public void Next_Billing_Is_Set_1_Month_From_Now(){} 17 | 18 | [Fact] 19 | public void A_Notification_Is_Sent_To_Subscriber(){} 20 | 21 | } 22 | 23 | [Trait ("Monthly Billing", "Payment Fails")] 24 | public class SubscriptionPaymentIsDue 25 | { 26 | //... the constructor prepares the test data 27 | [Fact] 28 | public void An_Invoice_Is_Not_Created() 29 | { 30 | //... 31 | } 32 | [Fact] 33 | public void Next_Billing_Is_1_Day_From_Now() 34 | { 35 | //... 36 | } 37 | [Fact] 38 | public void A_Notification_Is_Sent_To_Subscriber() 39 | { 40 | //... 41 | } 42 | //... 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /software-design/bdd/bdd/MyClass.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using XUnit; 3 | 4 | namespace BillingSystem.Specs { 5 | 6 | [Trait("Monthly Payment Is Due", "Payment Is Received")] 7 | public class PaymentReceived{ 8 | //... the constructor prepares the test data 9 | [Fact] 10 | public void An_Invoice_Is_Created(){ 11 | //... 12 | } 13 | [Fact] 14 | public void Subscription_Status_Is_Updated(){ 15 | //... 16 | } 17 | [Fact] 18 | public void Next_Billing_Is_Set_1_Month_From_Now(){ 19 | //... 20 | } 21 | [Fact] 22 | public void A_Notification_Is_Sent_To_Subscriber(){ 23 | //... 24 | } 25 | //... 26 | } 27 | [Trait("Monthly Billing", "Payment Fails")] 28 | public class SubscriptionPaymentIsDue{ 29 | //... the constructor prepares the test data 30 | [Fact] 31 | public void An_Invoice_Is_Not_Created(){ 32 | //... 33 | } 34 | [Fact] 35 | public void Next_Billing_Is_1_Day_From_Now(){ 36 | //... 37 | } 38 | [Fact] 39 | public void A_Notification_Is_Sent_To_Subscriber(){ 40 | //... 41 | } 42 | //... 43 | } 44 | } -------------------------------------------------------------------------------- /software-design/bdd/bdd/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | 4 | // Information about this assembly is defined by the following attributes. 5 | // Change them to the values specific to your project. 6 | 7 | [assembly: AssemblyTitle ("bdd")] 8 | [assembly: AssemblyDescription ("")] 9 | [assembly: AssemblyConfiguration ("")] 10 | [assembly: AssemblyCompany ("")] 11 | [assembly: AssemblyProduct ("")] 12 | [assembly: AssemblyCopyright ("rob")] 13 | [assembly: AssemblyTrademark ("")] 14 | [assembly: AssemblyCulture ("")] 15 | 16 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". 17 | // The form "{Major}.{Minor}.*" will automatically update the build and revision, 18 | // and "{Major}.{Minor}.{Build}.*" will update just the revision. 19 | 20 | [assembly: AssemblyVersion ("1.0.*")] 21 | 22 | // The following attributes are used to specify the signing key for the assembly, 23 | // if desired. See the Mono documentation for more information about signing. 24 | 25 | //[assembly: AssemblyDelaySign(false)] 26 | //[assembly: AssemblyKeyFile("")] 27 | 28 | -------------------------------------------------------------------------------- /software-design/bdd/bdd/bdd.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {11504502-944C-41A5-8D81-8A5D316EA64E} 8 | Library 9 | bdd 10 | bdd 11 | v4.5 12 | 13 | 14 | true 15 | full 16 | false 17 | bin\Debug 18 | DEBUG; 19 | prompt 20 | 4 21 | false 22 | 23 | 24 | true 25 | bin\Release 26 | prompt 27 | 4 28 | false 29 | 30 | 31 | 32 | 33 | 34 | ..\packages\xunit.abstractions.2.0.0\lib\net35\xunit.abstractions.dll 35 | 36 | 37 | ..\packages\xunit.extensibility.core.2.1.0\lib\dotnet\xunit.core.dll 38 | 39 | 40 | ..\packages\xunit.extensibility.execution.2.1.0\lib\net45\xunit.execution.desktop.dll 41 | 42 | 43 | ..\packages\xunit.assert.2.1.0\lib\dotnet\xunit.assert.dll 44 | 45 | 46 | ..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll 47 | 48 | 49 | ..\packages\Moq.4.5.16\lib\net45\Moq.dll 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /software-design/bdd/bdd/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /software-design/patterns/.gitignore: -------------------------------------------------------------------------------- 1 | #Autosave files 2 | *~ 3 | 4 | #build 5 | [Oo]bj/ 6 | [Bb]in/ 7 | packages/ 8 | TestResults/ 9 | 10 | # globs 11 | Makefile.in 12 | *.DS_Store 13 | *.sln.cache 14 | *.suo 15 | *.cache 16 | *.pidb 17 | *.userprefs 18 | *.usertasks 19 | config.log 20 | config.make 21 | config.status 22 | aclocal.m4 23 | install-sh 24 | autom4te.cache/ 25 | *.user 26 | *.tar.gz 27 | tarballs/ 28 | test-results/ 29 | Thumbs.db 30 | 31 | #Mac bundle stuff 32 | *.dmg 33 | *.app 34 | 35 | #resharper 36 | *_Resharper.* 37 | *.Resharper 38 | 39 | #dotCover 40 | *.dotCover 41 | -------------------------------------------------------------------------------- /software-design/patterns/Imposter.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Imposter", "Imposter\Imposter.csproj", "{27C6FCE6-13ED-4216-8524-F1D2D6BD08D4}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|x86 = Debug|x86 9 | Release|x86 = Release|x86 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {27C6FCE6-13ED-4216-8524-F1D2D6BD08D4}.Debug|x86.ActiveCfg = Debug|x86 13 | {27C6FCE6-13ED-4216-8524-F1D2D6BD08D4}.Debug|x86.Build.0 = Debug|x86 14 | {27C6FCE6-13ED-4216-8524-F1D2D6BD08D4}.Release|x86.ActiveCfg = Release|x86 15 | {27C6FCE6-13ED-4216-8524-F1D2D6BD08D4}.Release|x86.Build.0 = Release|x86 16 | EndGlobalSection 17 | EndGlobal 18 | -------------------------------------------------------------------------------- /software-design/patterns/Imposter/Bridge.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Bridge 5 | { 6 | public abstract class GroovyQuery 7 | { 8 | //groovy interface 9 | public abstract T GetDocument (); 10 | public abstract T SaveDocument (); 11 | public abstract IList FetchDocuments (); 12 | 13 | public IDocumentQueryable Documents; 14 | //etc 15 | } 16 | 17 | public interface IDocumentQueryable 18 | { 19 | T Get(); 20 | T Save(); 21 | IList Fetch(); 22 | } 23 | 24 | //implementation of the document query interface for 25 | //relational systems. 26 | public class RelationalDocumentQueryable : IDocumentQueryable 27 | { 28 | GroovyQuery _adapter; 29 | public RelationalDocumentQueryable (GroovyQuery adapter) 30 | { 31 | this._adapter = adapter; 32 | } 33 | 34 | public IList Fetch () 35 | { 36 | throw new NotImplementedException (); 37 | } 38 | 39 | public T Get () 40 | { 41 | throw new NotImplementedException (); 42 | } 43 | 44 | public T Save () 45 | { 46 | throw new NotImplementedException (); 47 | } 48 | 49 | } 50 | public class GroovySQLServerAdapter : GroovyQuery 51 | { 52 | public GroovySQLServerAdapter () 53 | { 54 | this.Documents = new RelationalDocumentQueryable (this); 55 | } 56 | 57 | public override IList FetchDocuments () 58 | { 59 | throw new NotImplementedException (); 60 | } 61 | 62 | public override T GetDocument () 63 | { 64 | throw new NotImplementedException (); 65 | } 66 | 67 | public override T SaveDocument () 68 | { 69 | throw new NotImplementedException (); 70 | } 71 | 72 | } 73 | } 74 | 75 | -------------------------------------------------------------------------------- /software-design/patterns/Imposter/Builder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Builder 5 | { 6 | public class NaiveStringBuilder 7 | { 8 | IList _strings; 9 | public NaiveStringBuilder () 10 | { 11 | _strings = new List (); 12 | } 13 | public void Append (string val) 14 | { 15 | _strings.Add (val); 16 | } 17 | public override string ToString () 18 | { 19 | var result = ""; 20 | foreach (var s in _strings) { 21 | result = result + s + " "; // a new string is built each time 22 | } 23 | return result; 24 | } 25 | } 26 | 27 | 28 | 29 | public class Message 30 | { 31 | System.Text.StringBuilder _stringBuilder; 32 | public Message (string initialValue) 33 | { 34 | _stringBuilder = new System.Text.StringBuilder (); 35 | _stringBuilder.Append (initialValue); 36 | } 37 | public Message Add (string value) 38 | { 39 | _stringBuilder.Append (" "); 40 | _stringBuilder.Append (value); 41 | return this; 42 | } 43 | public override string ToString () 44 | { 45 | return _stringBuilder.ToString (); 46 | } 47 | } 48 | 49 | 50 | } 51 | 52 | -------------------------------------------------------------------------------- /software-design/patterns/Imposter/ChainOfResponsibility.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | 5 | namespace Chain 6 | { 7 | 8 | 9 | public class User 10 | { 11 | public string Name { get; set; } 12 | public int Age { get; set; } 13 | public bool IsValid = false; 14 | public System.Text.StringBuilder ValidationMessages; 15 | 16 | public User () 17 | { 18 | this.ValidationMessages = new System.Text.StringBuilder (); 19 | this.ValidationMessages.AppendLine ("Pending save"); 20 | } 21 | public void Validate () 22 | { 23 | var nameCheck = new NameValidator (); 24 | var ageCheck = new AgeValidator (); 25 | nameCheck.SetSuccessor (ageCheck); 26 | 27 | //kick it off 28 | nameCheck.Validate (this); 29 | } 30 | } 31 | 32 | public abstract class UserValidator 33 | { 34 | protected UserValidator Successor = null; 35 | public void SetSuccessor (UserValidator successor) 36 | { 37 | this.Successor = successor; 38 | } 39 | 40 | public abstract void Validate (User user); 41 | public void HandleNext (User user) 42 | { 43 | if (user.IsValid && this.Successor != null) { 44 | this.Successor.Validate (user); 45 | } 46 | } 47 | } 48 | 49 | public class NameValidator : UserValidator 50 | { 51 | public override void Validate (User user) 52 | { 53 | user.IsValid = !String.IsNullOrEmpty (user.Name); 54 | 55 | if (user.IsValid) { 56 | user.ValidationMessages.AppendLine ("Name validated"); 57 | } else { 58 | user.ValidationMessages.AppendLine ("No name given"); 59 | } 60 | HandleNext (user); 61 | } 62 | 63 | } 64 | 65 | public class AgeValidator : UserValidator 66 | { 67 | public override void Validate (User user) 68 | { 69 | user.IsValid = user.Age > 18; 70 | if (user.IsValid) { 71 | user.ValidationMessages.AppendLine ("Age validated"); 72 | } else { 73 | user.ValidationMessages.AppendLine ("Age is invalid - must be over 18"); 74 | } 75 | HandleNext (user); 76 | } 77 | } 78 | 79 | } -------------------------------------------------------------------------------- /software-design/patterns/Imposter/Command.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data; 4 | 5 | namespace Command 6 | { 7 | public class QueryParameter 8 | { 9 | public QueryParameter (string name, string value) 10 | { 11 | this.Name = name; 12 | this.Value = value; 13 | } 14 | public string Name { get; private set; } 15 | public string Value { get; private set; } 16 | } 17 | public interface IQueryCommand 18 | { 19 | string SQL { get; set; } 20 | IList Parameters { get; set; } 21 | IDbCommand BuildCommand (); 22 | } 23 | public class QueryCommand : IQueryCommand 24 | { 25 | public string SQL { get; set; } 26 | public IList Parameters { get; set; } 27 | public IDbCommand BuildCommand () 28 | { 29 | //return a command that can be executed 30 | //... 31 | return null; 32 | } 33 | } 34 | public class GroovyQuery 35 | { 36 | //the API 37 | //... 38 | public IDataReader Execute (IQueryCommand cmd) 39 | { 40 | //build the command and execute it 41 | var dbCommand = cmd.BuildCommand (); 42 | //... 43 | return null; 44 | } 45 | } 46 | 47 | public class CreateUserCommand : QueryCommand 48 | { 49 | public CreateUserCommand (string name, string email, string password) 50 | { 51 | this.SQL = @"insert into users(name, email, hashed_password) 52 | values(@1, @2, @3);"; 53 | 54 | this.Parameters = new List (); 55 | this.Parameters.Add (new QueryParameter("@1", name)); 56 | this.Parameters.Add (new QueryParameter("@2", email)); 57 | this.Parameters.Add (new QueryParameter("@3", SomeHashingAlgorithm (password))); 58 | } 59 | private string SomeHashingAlgorithm (string val) 60 | { 61 | //some solid hashing here... 62 | return ""; 63 | } 64 | } 65 | } 66 | 67 | -------------------------------------------------------------------------------- /software-design/patterns/Imposter/Composite.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Composite 5 | { 6 | public class Connection 7 | { 8 | public bool CheckedOut { get; set; } 9 | public Connection (string connectionString) 10 | { 11 | //connect 12 | } 13 | public void Close () 14 | { 15 | //close the connection 16 | } 17 | } 18 | 19 | public class ConnectionPool 20 | { 21 | public IList Pool; 22 | public ConnectionPool (string connectionString) 23 | { 24 | this.Pool = new List (); 25 | for (var i = 0; i < 10; i++) { 26 | this.Pool.Add (new Connection (connectionString)); 27 | } 28 | } 29 | public void Checkout () 30 | { 31 | //grab a list of connections which aren't checked out 32 | //return the first 33 | } 34 | public void Checkin () 35 | { 36 | //tick the boolean 37 | } 38 | public void Drain () 39 | { 40 | foreach (var connection in this.Pool) { 41 | connection.Close (); 42 | } 43 | this.Pool = new List (); 44 | } 45 | } 46 | } 47 | 48 | -------------------------------------------------------------------------------- /software-design/patterns/Imposter/Constructor.cs: -------------------------------------------------------------------------------- 1 | public class Thing { 2 | //the constructor 3 | public Thing(){ 4 | //set some class variables, etc 5 | } 6 | } 7 | var thing = new Thing(); //a constructor in C# 8 | 9 | thing = Thing.new 10 | 11 | var Thing = function(){ 12 | //body 13 | } 14 | var thing = new Thing(); 15 | 16 | -------------------------------------------------------------------------------- /software-design/patterns/Imposter/Decorator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Decorator 5 | { 6 | public abstract class GroovyQuery 7 | { 8 | //groovy interface 9 | public abstract T GetDocument (); 10 | public abstract T SaveDocument (); 11 | public abstract IList FetchDocuments (); 12 | 13 | public IDocumentQueryable Documents; 14 | //etc 15 | } 16 | 17 | public interface IDocumentQueryable 18 | { 19 | T Get (); 20 | T Save (); 21 | IList Fetch (); 22 | } 23 | 24 | //implementation of the document query interface for 25 | //relational systems. 26 | public class RelationalDocumentDecorator : IDocumentQueryable 27 | { 28 | GroovyQuery _adapter; 29 | 30 | //Find, Fetch, and Save use the _adapter passed in 31 | public RelationalDocumentDecorator (GroovyQuery adapter) 32 | { 33 | this._adapter = adapter; 34 | } 35 | 36 | public IList Fetch () 37 | { 38 | throw new NotImplementedException (); 39 | } 40 | 41 | public T Get () 42 | { 43 | throw new NotImplementedException (); 44 | } 45 | 46 | 47 | public T Save () 48 | { 49 | throw new NotImplementedException (); 50 | } 51 | //implement Get, Save, Fetch for Documents below 52 | } 53 | } 54 | 55 | -------------------------------------------------------------------------------- /software-design/patterns/Imposter/Facade.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Facade 5 | { 6 | 7 | //abstract base class 8 | public abstract class GroovyQuery 9 | { 10 | public GroovyQuery (string connectionString) { } 11 | } 12 | 13 | //implementation for PostgreSQL 14 | public class PostgreSQLQuery : GroovyQuery { 15 | public PostgreSQLQuery (string connectionString) : base (connectionString){} 16 | } 17 | 18 | //implementation for SQL Server 19 | public class SQlServerQuery : GroovyQuery 20 | { 21 | public SQlServerQuery (string connectionString) : base (connectionString) { } 22 | } 23 | 24 | 25 | //a simple class that hides the selection details 26 | public class QueryRunner 27 | { 28 | 29 | string _connectionString; 30 | 31 | //Find, Fetch, and Save use the _adapter passed in 32 | public QueryRunner (string connectionString) 33 | { 34 | _connectionString = connectionString; 35 | } 36 | 37 | public void Execute () 38 | { 39 | 40 | GroovyQuery runner; 41 | if (_connectionString.StartsWith ("postgresql://", StringComparison.InvariantCultureIgnoreCase)) { 42 | runner = new PostgreSQLQuery (_connectionString); 43 | } else if (_connectionString.StartsWith ("sqlserver://", StringComparison.InvariantCultureIgnoreCase)) { 44 | runner = new SQlServerQuery (_connectionString); 45 | } else { 46 | throw new InvalidOperationException ("We don't support that"); 47 | } 48 | 49 | //execute with the runner 50 | } 51 | 52 | } 53 | } 54 | 55 | -------------------------------------------------------------------------------- /software-design/patterns/Imposter/Factory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | 5 | namespace Factory 6 | { 7 | public class Administrator : Customer 8 | { 9 | //specific fields/methods for admins 10 | } 11 | 12 | public class Order 13 | { 14 | 15 | } 16 | 17 | public class Customer 18 | { 19 | public string Id { get; set; } 20 | public string Name { get; set; } 21 | public string Email { get; set; } 22 | public string Status { get; set; } 23 | public List Orders { get; set; } 24 | 25 | public static Customer FromDefaults () 26 | { 27 | var customer = new Customer { Status = "unregistered", Name = "Guest" }; 28 | customer.Orders = new List (); 29 | return customer; 30 | } 31 | 32 | public static Customer FromExisting (IDictionary values) 33 | { 34 | 35 | var customer = new Customer (); 36 | //populate the values on the class, validating etc. 37 | 38 | return customer; 39 | 40 | } 41 | } 42 | 43 | public class CustomerFactory 44 | { 45 | public Customer FromDefaults () 46 | { 47 | var customer = new Customer { Status = "unregistered", Name = "Guest" }; 48 | customer.Orders = new List (); 49 | return customer; 50 | } 51 | 52 | public Customer FromExisting (IDictionary values) 53 | { 54 | if (values.Contains ("Email")) { 55 | if (values ["Email"].ToString () == "admin@example.com") { 56 | var admin = new Administrator (); 57 | //populate values 58 | return admin; 59 | } else { 60 | var customer = new Customer (); 61 | //populate the values on the class, validating etc. 62 | 63 | return customer; 64 | } 65 | } else { 66 | return null; 67 | } 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /software-design/patterns/Imposter/Flyweight.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Flyweight 5 | { 6 | //our Flyweight class 7 | public class Table 8 | { 9 | public string Name { get; set; } 10 | public string PrimaryKeyField { get; set; } 11 | //column and data type information... 12 | } 13 | 14 | public abstract class GroovyQuery 15 | { 16 | //the API as we've come to know it 17 | List _tables; 18 | public void Initialize () 19 | { 20 | _tables = new List
(); 21 | //query the database for meta information 22 | //load up the _tables list 23 | } 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /software-design/patterns/Imposter/Imposter.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | x86 6 | {27C6FCE6-13ED-4216-8524-F1D2D6BD08D4} 7 | Exe 8 | Imposter 9 | Imposter 10 | v4.5 11 | 12 | 13 | true 14 | full 15 | false 16 | bin\Debug 17 | DEBUG; 18 | prompt 19 | 4 20 | true 21 | x86 22 | 23 | 24 | true 25 | bin\Release 26 | prompt 27 | 4 28 | true 29 | x86 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /software-design/patterns/Imposter/Mediator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Mediator 5 | { 6 | public interface IDocumentQueryable 7 | { 8 | T Get (); 9 | T Save (); 10 | IList Fetch (); 11 | } 12 | public abstract class GroovyQuery 13 | { 14 | //groovy interface 15 | public abstract T GetDocument (); 16 | public abstract T SaveDocument (); 17 | public abstract IList FetchDocuments (); 18 | 19 | public IDocumentQueryable Documents; 20 | //etc 21 | } 22 | public class DocumentStore 23 | { 24 | GroovyQuery _adapter; 25 | public DocumentStore (GroovyQuery adapter) 26 | { 27 | _adapter = adapter; 28 | } 29 | public T Save (T item) 30 | { 31 | //parse and save the object 32 | return item; 33 | } 34 | public T Get () 35 | { 36 | //pull the record, dehydrate 37 | return default(T); 38 | } 39 | public IList Fetch () 40 | { 41 | //pull the list, dehydrate 42 | return new List(); 43 | } 44 | string Dehydrate (T item) 45 | { 46 | //turn the object into JSON 47 | return ""; 48 | } 49 | T Hydrate (string json) 50 | { 51 | //resolve 52 | return default(T); 53 | } 54 | } 55 | } 56 | 57 | -------------------------------------------------------------------------------- /software-design/patterns/Imposter/Observer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data; 4 | 5 | namespace Observer 6 | { 7 | public interface IListener 8 | { 9 | void Notify (T result); 10 | void Notify (); 11 | } 12 | public abstract class GroovyQuery 13 | { 14 | //API methods etc 15 | //... 16 | public IList Listeners { get; set; } 17 | public GroovyQuery () 18 | { 19 | //constructor stuff 20 | //... 21 | this.Listeners = new List (); 22 | } 23 | public virtual IDataReader Execute (IDbCommand cmd) 24 | { 25 | //the execution stuff 26 | //notify all listeners 27 | foreach (var listener in this.Listeners) { 28 | listener.Notify ();//optionally send along some data 29 | } 30 | return null; 31 | } 32 | } 33 | } 34 | 35 | -------------------------------------------------------------------------------- /software-design/patterns/Imposter/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Imposter 4 | { 5 | class MainClass 6 | { 7 | public static void Main (string [] args) 8 | { 9 | //factory 10 | var customer = Factory.Customer.FromDefaults (); 11 | 12 | //factory class 13 | var customerFactory = new Factory.CustomerFactory (); 14 | var customer2 = customerFactory.FromDefaults (); 15 | 16 | //builder 17 | var naiveBuilder = new Builder.NaiveStringBuilder (); 18 | naiveBuilder.Append ("This"); 19 | naiveBuilder.Append ("could be"); 20 | naiveBuilder.Append ("very long"); 21 | naiveBuilder.Append ("and blow up"); 22 | naiveBuilder.Append ("your program..."); 23 | var badBuilderResult = naiveBuilder.ToString ();//OUCH 24 | 25 | var goodBuilder = new System.Text.StringBuilder (); 26 | goodBuilder.Append ("This "); 27 | goodBuilder.Append ("won't "); 28 | goodBuilder.Append ("blow up "); 29 | goodBuilder.Append ("my program "); 30 | var goodBuilderResult = goodBuilder.ToString (); //yay! 31 | 32 | var message = new Builder.Message ("Hello").Add ("I might be").Add ("a really long string").ToString (); 33 | 34 | //singleton 35 | var single = Singleton.SingleThing.Instance (); 36 | 37 | //composite 38 | var connectionPool = new Composite.ConnectionPool ("test"); 39 | 40 | //Facade 41 | var query = new Facade.QueryRunner ("postgresql://test"); 42 | 43 | 44 | //Chain of Command 45 | var user = new Chain.User { Name = "Larry", Age = 22 }; 46 | user.Validate (); 47 | 48 | var user2 = new Chain.User { Name = "Larry", Age = 16 }; 49 | user2.Validate (); 50 | 51 | Console.WriteLine (customer.Name); 52 | Console.WriteLine (customer2.Name); 53 | Console.WriteLine (badBuilderResult); 54 | Console.WriteLine (goodBuilderResult); 55 | Console.WriteLine (message.ToString()); 56 | Console.WriteLine (connectionPool.Pool.Count); 57 | Console.WriteLine (user.ValidationMessages.ToString()); 58 | Console.WriteLine (user2.ValidationMessages.ToString ()); 59 | Console.Read (); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /software-design/patterns/Imposter/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | 4 | // Information about this assembly is defined by the following attributes. 5 | // Change them to the values specific to your project. 6 | 7 | [assembly: AssemblyTitle ("Imposter")] 8 | [assembly: AssemblyDescription ("")] 9 | [assembly: AssemblyConfiguration ("")] 10 | [assembly: AssemblyCompany ("")] 11 | [assembly: AssemblyProduct ("")] 12 | [assembly: AssemblyCopyright ("rob")] 13 | [assembly: AssemblyTrademark ("")] 14 | [assembly: AssemblyCulture ("")] 15 | 16 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". 17 | // The form "{Major}.{Minor}.*" will automatically update the build and revision, 18 | // and "{Major}.{Minor}.{Build}.*" will update just the revision. 19 | 20 | [assembly: AssemblyVersion ("1.0.*")] 21 | 22 | // The following attributes are used to specify the signing key for the assembly, 23 | // if desired. See the Mono documentation for more information about signing. 24 | 25 | //[assembly: AssemblyDelaySign(false)] 26 | //[assembly: AssemblyKeyFile("")] 27 | 28 | -------------------------------------------------------------------------------- /software-design/patterns/Imposter/Singleton.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Singleton 3 | { 4 | public class SingleThing 5 | { 6 | //single instance holder 7 | private static SingleThing _instance; 8 | //disallow calling constructor directly 9 | protected SingleThing () { } 10 | //access to the instance 11 | public static SingleThing Instance () 12 | { 13 | if (_instance == null) { 14 | _instance = new SingleThing (); 15 | } 16 | return _instance; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /software-design/patterns/Imposter/State.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Imposter 3 | { 4 | public class State 5 | { 6 | public State () 7 | { 8 | } 9 | } 10 | } 11 | 12 | -------------------------------------------------------------------------------- /software-design/patterns/Imposter/Strategy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Imposter 3 | { 4 | public class Strategy 5 | { 6 | public Strategy () 7 | { 8 | } 9 | } 10 | } 11 | 12 | -------------------------------------------------------------------------------- /software-design/solid/.gitignore: -------------------------------------------------------------------------------- 1 | #Autosave files 2 | *~ 3 | 4 | #build 5 | [Oo]bj/ 6 | [Bb]in/ 7 | packages/ 8 | TestResults/ 9 | 10 | # globs 11 | Makefile.in 12 | *.DS_Store 13 | *.sln.cache 14 | *.suo 15 | *.cache 16 | *.pidb 17 | *.userprefs 18 | *.usertasks 19 | config.log 20 | config.make 21 | config.status 22 | aclocal.m4 23 | install-sh 24 | autom4te.cache/ 25 | *.user 26 | *.tar.gz 27 | tarballs/ 28 | test-results/ 29 | Thumbs.db 30 | 31 | #Mac bundle stuff 32 | *.dmg 33 | *.app 34 | 35 | #resharper 36 | *_Resharper.* 37 | *.Resharper 38 | 39 | #dotCover 40 | *.dotCover 41 | -------------------------------------------------------------------------------- /software-design/solid/solid.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "solid", "solid\solid.csproj", "{B3058C6E-3448-4AD0-BB86-8DBD477400B7}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|x86 = Debug|x86 9 | Release|x86 = Release|x86 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {B3058C6E-3448-4AD0-BB86-8DBD477400B7}.Debug|x86.ActiveCfg = Debug|x86 13 | {B3058C6E-3448-4AD0-BB86-8DBD477400B7}.Debug|x86.Build.0 = Debug|x86 14 | {B3058C6E-3448-4AD0-BB86-8DBD477400B7}.Release|x86.ActiveCfg = Release|x86 15 | {B3058C6E-3448-4AD0-BB86-8DBD477400B7}.Release|x86.Build.0 = Release|x86 16 | EndGlobalSection 17 | EndGlobal 18 | -------------------------------------------------------------------------------- /software-design/solid/solid/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Solid 4 | { 5 | class MainClass 6 | { 7 | public static void Main (string [] args) 8 | { 9 | Console.WriteLine ("Hello World!"); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /software-design/solid/solid/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | 4 | // Information about this assembly is defined by the following attributes. 5 | // Change them to the values specific to your project. 6 | 7 | [assembly: AssemblyTitle ("solid")] 8 | [assembly: AssemblyDescription ("")] 9 | [assembly: AssemblyConfiguration ("")] 10 | [assembly: AssemblyCompany ("")] 11 | [assembly: AssemblyProduct ("")] 12 | [assembly: AssemblyCopyright ("rob")] 13 | [assembly: AssemblyTrademark ("")] 14 | [assembly: AssemblyCulture ("")] 15 | 16 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". 17 | // The form "{Major}.{Minor}.*" will automatically update the build and revision, 18 | // and "{Major}.{Minor}.{Build}.*" will update just the revision. 19 | 20 | [assembly: AssemblyVersion ("1.0.*")] 21 | 22 | // The following attributes are used to specify the signing key for the assembly, 23 | // if desired. See the Mono documentation for more information about signing. 24 | 25 | //[assembly: AssemblyDelaySign(false)] 26 | //[assembly: AssemblyKeyFile("")] 27 | 28 | -------------------------------------------------------------------------------- /software-design/solid/solid/dependency_inversion.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace DI 3 | { 4 | public interface IMembershipStore 5 | { 6 | void Save (object item); 7 | } 8 | 9 | public class PostgreSQLAdapter : IMembershipStore 10 | { 11 | public void Save (object item) 12 | { 13 | //database call... 14 | } 15 | } 16 | public interface IRegisterable 17 | { 18 | string Name { get; set; } 19 | string Email { get; set; } 20 | string Status { get; set; } 21 | } 22 | public class User : IRegisterable 23 | { 24 | public string Name { get; set; } 25 | public string Email { get; set; } 26 | public string Status { get; set; } 27 | public User () 28 | { 29 | this.Name = "Guest"; 30 | this.Status = "Anonymous"; 31 | } 32 | } 33 | public class Membership 34 | { 35 | IMembershipStore _store; 36 | public Membership (IMembershipStore store) 37 | { 38 | _store = store; 39 | } 40 | public IRegisterable Register (IRegisterable user) 41 | { 42 | //validations etc 43 | user.Status = "Registered"; 44 | _store.Save (user); 45 | return user; 46 | } 47 | } 48 | } 49 | 50 | -------------------------------------------------------------------------------- /software-design/solid/solid/interface_segregation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace InterfaceSegregation 3 | { 4 | public interface IRegisterable 5 | { 6 | string Name { get; set; } 7 | string Email { get; set; } 8 | string Status { get; set; } 9 | } 10 | public class User : IRegisterable 11 | { 12 | public string Name { get; set; } 13 | public string Email { get; set; } 14 | public string Status { get; set; } 15 | public User () 16 | { 17 | this.Name = "Guest"; 18 | this.Status = "Anonymous"; 19 | } 20 | } 21 | public class Membership 22 | { 23 | public IRegisterable Register (IRegisterable user) 24 | { 25 | //validations etc 26 | user.Status = "Registered"; 27 | //save to the DB or something else 28 | return user; 29 | } 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /software-design/solid/solid/liskov.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Liskov 3 | { 4 | public class Rectangle 5 | { 6 | int _height; 7 | int _width; 8 | 9 | public virtual void SetHeight (int height) 10 | { 11 | _height = height; 12 | } 13 | public virtual void SetWidth (int width) 14 | { 15 | _width = width; 16 | } 17 | } 18 | public class Square : Rectangle 19 | { 20 | 21 | public override void SetHeight (int height) 22 | { 23 | this.SetHeight (height); 24 | this.SetWidth (height); 25 | } 26 | public override void SetWidth (int width) 27 | { 28 | this.SetHeight (width); 29 | this.SetWidth (width); 30 | } 31 | } 32 | } 33 | 34 | -------------------------------------------------------------------------------- /software-design/solid/solid/solid.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | x86 6 | {B3058C6E-3448-4AD0-BB86-8DBD477400B7} 7 | Exe 8 | solid 9 | solid 10 | v4.5 11 | 12 | 13 | true 14 | full 15 | false 16 | bin\Debug 17 | DEBUG; 18 | prompt 19 | 4 20 | true 21 | x86 22 | 23 | 24 | true 25 | bin\Release 26 | prompt 27 | 4 28 | true 29 | x86 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /software-design/solid/solid/srp.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace SRP 3 | { 4 | public class User 5 | { 6 | public string Name { get; set; } 7 | public string Email { get; set; } 8 | public string Status { get; set; } 9 | public User () 10 | { 11 | this.Name = "Guest"; 12 | this.Status = "Anonymous"; 13 | } 14 | } 15 | 16 | public class Membership 17 | { 18 | public User Register (string name, string email) 19 | { 20 | //validations etc 21 | var newUser = new User { Name = name, Email = email, Status = "Registered" }; 22 | //save to the DB or something else 23 | return newUser; 24 | } 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /software-design/structuraldesign/.gitignore: -------------------------------------------------------------------------------- 1 | #Autosave files 2 | *~ 3 | 4 | #build 5 | [Oo]bj/ 6 | [Bb]in/ 7 | packages/ 8 | TestResults/ 9 | 10 | # globs 11 | Makefile.in 12 | *.DS_Store 13 | *.sln.cache 14 | *.suo 15 | *.cache 16 | *.pidb 17 | *.userprefs 18 | *.usertasks 19 | config.log 20 | config.make 21 | config.status 22 | aclocal.m4 23 | install-sh 24 | autom4te.cache/ 25 | *.user 26 | *.tar.gz 27 | tarballs/ 28 | test-results/ 29 | Thumbs.db 30 | 31 | #Mac bundle stuff 32 | *.dmg 33 | *.app 34 | 35 | #resharper 36 | *_Resharper.* 37 | *.Resharper 38 | 39 | #dotCover 40 | *.dotCover 41 | -------------------------------------------------------------------------------- /software-design/structuraldesign/structuraldesign.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "structuraldesign", "structuraldesign\structuraldesign.csproj", "{5C3440C5-229E-4841-995D-CEEF4050E841}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|x86 = Debug|x86 9 | Release|x86 = Release|x86 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {5C3440C5-229E-4841-995D-CEEF4050E841}.Debug|x86.ActiveCfg = Debug|x86 13 | {5C3440C5-229E-4841-995D-CEEF4050E841}.Debug|x86.Build.0 = Debug|x86 14 | {5C3440C5-229E-4841-995D-CEEF4050E841}.Release|x86.ActiveCfg = Release|x86 15 | {5C3440C5-229E-4841-995D-CEEF4050E841}.Release|x86.Build.0 = Release|x86 16 | EndGlobalSection 17 | EndGlobal 18 | -------------------------------------------------------------------------------- /software-design/structuraldesign/structuraldesign/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace structuraldesign 4 | { 5 | class MainClass 6 | { 7 | public static void Main (string [] args) 8 | { 9 | Console.WriteLine ("Hello World!"); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /software-design/structuraldesign/structuraldesign/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | 4 | // Information about this assembly is defined by the following attributes. 5 | // Change them to the values specific to your project. 6 | 7 | [assembly: AssemblyTitle ("structuraldesign")] 8 | [assembly: AssemblyDescription ("")] 9 | [assembly: AssemblyConfiguration ("")] 10 | [assembly: AssemblyCompany ("")] 11 | [assembly: AssemblyProduct ("")] 12 | [assembly: AssemblyCopyright ("rob")] 13 | [assembly: AssemblyTrademark ("")] 14 | [assembly: AssemblyCulture ("")] 15 | 16 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". 17 | // The form "{Major}.{Minor}.*" will automatically update the build and revision, 18 | // and "{Major}.{Minor}.{Build}.*" will update just the revision. 19 | 20 | [assembly: AssemblyVersion ("1.0.*")] 21 | 22 | // The following attributes are used to specify the signing key for the assembly, 23 | // if desired. See the Mono documentation for more information about signing. 24 | 25 | //[assembly: AssemblyDelaySign(false)] 26 | //[assembly: AssemblyKeyFile("")] 27 | 28 | -------------------------------------------------------------------------------- /software-design/structuraldesign/structuraldesign/demeter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace Demeter 3 | { 4 | public class DB 5 | { 6 | public User GetUser (int id) 7 | { 8 | //call to the DB, getting record 9 | return new User (); 10 | } 11 | public void Save (object item) 12 | { 13 | //save to DB 14 | } 15 | } 16 | 17 | public class User 18 | { 19 | public String Status { get; set; } 20 | } 21 | 22 | public class Membership 23 | { 24 | DB _db; 25 | public Membership () 26 | { 27 | _db = new DB (); 28 | } 29 | public User GetUser (int id) 30 | { 31 | //get the user 32 | return _db.GetUser (id); 33 | } 34 | 35 | public void SuspendUser (int id) 36 | { 37 | var user = this.GetUser (id); 38 | user.Status = "suspended"; 39 | _db.Save (user); 40 | } 41 | } 42 | } 43 | 44 | -------------------------------------------------------------------------------- /software-design/structuraldesign/structuraldesign/di.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace DI 3 | { 4 | public class User 5 | { 6 | public String Status { get; set; } 7 | } 8 | 9 | public class DB 10 | { 11 | public User GetUser (int id) 12 | { 13 | //call to the DB, getting record 14 | return new User (); 15 | } 16 | public void Save (object item) 17 | { 18 | //save to DB 19 | } 20 | } 21 | 22 | public class Membership 23 | { 24 | DB _db; 25 | public Membership (DB db) 26 | { 27 | _db = db; 28 | } 29 | public User GetUser (int id) 30 | { 31 | //get the user 32 | return _db.GetUser (id); 33 | } 34 | public void SuspendUser (int id) 35 | { 36 | var user = this.GetUser (id); 37 | user.Status = "suspended"; 38 | _db.Save (user); //Coupling 39 | } 40 | } 41 | } 42 | 43 | -------------------------------------------------------------------------------- /software-design/structuraldesign/structuraldesign/interfaces.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Interfaces 5 | { 6 | public class User 7 | { 8 | public String Status { get; set; } 9 | } 10 | 11 | public interface IDataStore 12 | { 13 | void Save (T item); 14 | T Get (int id); 15 | IList Fetch (); 16 | } 17 | 18 | public class Membership 19 | { 20 | IDataStore _db; 21 | public Membership (IDataStore db) 22 | { 23 | _db = db; 24 | } 25 | public User GetUser (int id) 26 | { 27 | //get the user 28 | return _db.Get (id); 29 | } 30 | public void SuspendUser (int id) 31 | { 32 | var user = this.GetUser (id); 33 | user.Status = "suspended"; 34 | _db.Save (user); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /software-design/structuraldesign/structuraldesign/structuraldesign.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | x86 6 | {5C3440C5-229E-4841-995D-CEEF4050E841} 7 | Exe 8 | structuraldesign 9 | structuraldesign 10 | v4.5 11 | 12 | 13 | true 14 | full 15 | false 16 | bin\Debug 17 | DEBUG; 18 | prompt 19 | 4 20 | true 21 | x86 22 | 23 | 24 | true 25 | bin\Release 26 | prompt 27 | 4 28 | true 29 | x86 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /software-design/structuraldesign/structuraldesign/tell_dont_ask.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data; 3 | 4 | namespace TellDontAsk 5 | { 6 | public class GroovyQuery // Asking 7 | { 8 | public bool IsCommandValid (IDbCommand cmd) 9 | { 10 | //logic 11 | return true; 12 | } 13 | public bool IsConnectionAvailable () 14 | { 15 | //check connection pool to see if one is ready 16 | return true; 17 | } 18 | public IDataReader Execute (IDbCommand cmd) 19 | { 20 | //execution 21 | return null; 22 | } 23 | } 24 | 25 | public class GroovyQuery2 //Telling 26 | { 27 | bool CommandIsValid (IDbCommand cmd) 28 | { 29 | //logic 30 | return true; 31 | } 32 | bool ConnectionIsAvailable () 33 | { 34 | //check connection pool to see if one is ready 35 | return true; 36 | } 37 | public IDataReader Execute (IDbCommand cmd) 38 | { 39 | var commandIsValid = CommandIsValid (cmd); 40 | 41 | if (ConnectionIsAvailable () && commandIsValid) { 42 | //execution 43 | return null; 44 | } else { 45 | throw new InvalidOperationException ("Can't run this query"); 46 | } 47 | 48 | } 49 | } 50 | } 51 | 52 | -------------------------------------------------------------------------------- /software-design/tdd/.gitignore: -------------------------------------------------------------------------------- 1 | #Autosave files 2 | *~ 3 | 4 | #build 5 | [Oo]bj/ 6 | [Bb]in/ 7 | packages/ 8 | TestResults/ 9 | 10 | # globs 11 | Makefile.in 12 | *.DS_Store 13 | *.sln.cache 14 | *.suo 15 | *.cache 16 | *.pidb 17 | *.userprefs 18 | *.usertasks 19 | config.log 20 | config.make 21 | config.status 22 | aclocal.m4 23 | install-sh 24 | autom4te.cache/ 25 | *.user 26 | *.tar.gz 27 | tarballs/ 28 | test-results/ 29 | Thumbs.db 30 | 31 | #Mac bundle stuff 32 | *.dmg 33 | *.app 34 | 35 | #resharper 36 | *_Resharper.* 37 | *.Resharper 38 | 39 | #dotCover 40 | *.dotCover 41 | -------------------------------------------------------------------------------- /software-design/tdd/.nuget/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /software-design/tdd/tdd.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "tdd", "tdd\tdd.csproj", "{5A796E74-C8F5-4BFA-893E-B516C1515B1B}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Any CPU = Debug|Any CPU 9 | Release|Any CPU = Release|Any CPU 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {5A796E74-C8F5-4BFA-893E-B516C1515B1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 13 | {5A796E74-C8F5-4BFA-893E-B516C1515B1B}.Debug|Any CPU.Build.0 = Debug|Any CPU 14 | {5A796E74-C8F5-4BFA-893E-B516C1515B1B}.Release|Any CPU.ActiveCfg = Release|Any CPU 15 | {5A796E74-C8F5-4BFA-893E-B516C1515B1B}.Release|Any CPU.Build.0 = Release|Any CPU 16 | EndGlobalSection 17 | EndGlobal 18 | -------------------------------------------------------------------------------- /software-design/tdd/tdd/01_start.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Xunit; 6 | 7 | namespace BillingSystem.Tests 8 | { 9 | public class BillingDoohickeyTests 10 | { 11 | //Monthly billing 12 | //Grace period for missed payments 13 | //Not all customers are necessarily subscribers 14 | //Idle customers should be automatically unsubscribed 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /software-design/tdd/tdd/02_add_customer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Xunit; 6 | 7 | namespace BillingSystem.Tests2 8 | { 9 | public class BillingDoohickeyTests 10 | { 11 | //Monthly billing 12 | //Grace period for missed payments 13 | //Not all customers are necessarily subscribers 14 | //Idle customers should be automatically unsubscribed 15 | } 16 | 17 | public class Customer 18 | { 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /software-design/tdd/tdd/03_mocks.cs: -------------------------------------------------------------------------------- 1 | using Moq; 2 | using Xunit; 3 | namespace BillingSystem.Tests3 4 | { 5 | public interface ICustomerRepository { } 6 | public interface ICreditCardCharger { } 7 | public class BillingDoohickeyTests3 8 | { 9 | [Fact] 10 | public void Monkey () 11 | { 12 | var repo = new Mock (); 13 | var charger = new Mock (); 14 | BillingDoohickey thing = new BillingDoohickey (repo.Object, charger.Object); 15 | thing.ProcessMonth (2016, 8); 16 | } 17 | //Monthly billing 18 | //Grace period for missed payments 19 | //Not all customers are necessarily subscribers 20 | //Idle customers should be automatically unsubscribed 21 | } 22 | public class BillingDoohickey 23 | { 24 | public BillingDoohickey (ICustomerRepository repo, ICreditCardCharger charger){} 25 | public int ProcessMonth (int year, int month) {return 0;} 26 | } 27 | public class Customer{} 28 | } 29 | -------------------------------------------------------------------------------- /software-design/tdd/tdd/04_happy_path.cs: -------------------------------------------------------------------------------- 1 | using Moq; 2 | using Xunit; 3 | namespace BillingSystem.Tests4 { 4 | public interface ICustomerRepository { } 5 | public interface ICreditCardCharger { } 6 | public class MonthlyChargeTests { 7 | 8 | [Fact] 9 | public void Customers_With_Subscriptions_Due_Are_Charged () { 10 | var repo = new Mock (); 11 | var charger = new Mock (); 12 | BillingDoohickey thing = new BillingDoohickey (repo.Object, charger.Object); 13 | thing.ProcessMonth (2016, 8); 14 | } 15 | //Monthly billing 16 | //Grace period for missed payments 17 | //Not all customers are necessarily subscribers 18 | //Idle customers should be automatically unsubscribed 19 | } 20 | public class BillingDoohickey{ 21 | public BillingDoohickey (ICustomerRepository repo, 22 | ICreditCardCharger charger) {} 23 | public int ProcessMonth (int year, int month) { 24 | return 0; 25 | } 26 | } 27 | public class Customer{} 28 | } 29 | -------------------------------------------------------------------------------- /software-design/tdd/tdd/05_happy_path_green.cs: -------------------------------------------------------------------------------- 1 | using Moq; 2 | using Xunit; 3 | namespace BillingSystem.Tests5 { 4 | public interface ICustomerRepository { } 5 | public interface ICreditCardCharger { } 6 | public class MonthlyChargeTests { 7 | 8 | [Fact] 9 | public void Customers_With_Subscriptions_Due_Are_Charged () { 10 | var repo = new Mock (); 11 | var charger = new Mock (); 12 | BillingDoohickey thing = new BillingDoohickey (repo.Object, charger.Object); 13 | thing.ProcessMonth (2016, 8); 14 | } 15 | //Monthly billing 16 | //Grace period for missed payments 17 | //Not all customers are necessarily subscribers 18 | //Idle customers should be automatically unsubscribed 19 | } 20 | public class BillingDoohickey { 21 | public BillingDoohickey (ICustomerRepository repo, 22 | ICreditCardCharger charger){} 23 | public int ProcessMonth (int year, int month){ 24 | return 1; //do just enough 25 | } 26 | } 27 | public class Customer{} 28 | } 29 | -------------------------------------------------------------------------------- /software-design/tdd/tdd/06_sad_path.cs: -------------------------------------------------------------------------------- 1 | using Moq; 2 | using Xunit; 3 | 4 | namespace BillingSystem.Tests6 { 5 | public interface ICustomerRepository { } 6 | public interface ICreditCardCharger { } 7 | public class MonthlyChargeTests { 8 | 9 | ICustomerRepository repo; 10 | ICreditCardCharger charger; 11 | BillingDoohickey thing; 12 | 13 | public MonthlyChargeTests (){ 14 | repo = new Mock().Object; 15 | charger = new Mock().Object; 16 | thing = new BillingDoohickey (repo, charger); 17 | } 18 | 19 | [Fact] 20 | public void Customers_With_Subscriptions_Due_Are_Charged () { 21 | var processed = thing.ProcessMonth (2016, 8); 22 | Assert.True (processed > 0); 23 | } 24 | 25 | [Fact] 26 | public void Customers_With_No_Subscriptions_Due_Are_Not_Charged () { 27 | var processed = thing.ProcessMonth (2016, 8); 28 | Assert.True (processed == 0); 29 | } 30 | 31 | } 32 | //... 33 | 34 | public class BillingDoohickey 35 | { 36 | public BillingDoohickey (ICustomerRepository repo, 37 | ICreditCardCharger charger){ 38 | 39 | } 40 | public int ProcessMonth (int year, int month) { 41 | return 1; //do just enough 42 | } 43 | } 44 | public class Customer{} 45 | } 46 | -------------------------------------------------------------------------------- /software-design/tdd/tdd/07_fixed_sad_path.cs: -------------------------------------------------------------------------------- 1 | using Moq; 2 | using Xunit; 3 | 4 | namespace BillingSystem.Tests7 5 | { 6 | public interface ICustomerRepository { 7 | Customer [] Customers(); 8 | } 9 | public interface ICreditCardCharger { } 10 | public class MonthlyChargeTests { 11 | 12 | ICustomerRepository repo; 13 | ICreditCardCharger charger; 14 | BillingDoohickey thing; 15 | Mock repoMock; 16 | 17 | public MonthlyChargeTests () { 18 | repoMock = new Mock (); 19 | repo = repoMock.Object; 20 | charger = new Mock ().Object; 21 | thing = new BillingDoohickey (repo, charger); 22 | } 23 | 24 | [Fact] 25 | public void Customers_With_Subscriptions_Due_Are_Charged(){ 26 | repoMock.Setup (r => r.Customers()) 27 | .Returns (new Customer [] { new Customer () }); 28 | 29 | var processed = thing.ProcessMonth (2016, 8); 30 | Assert.True (processed > 0); 31 | } 32 | 33 | [Fact] 34 | public void Customers_With_No_Subscriptions_Due_Are_Not_Charged (){ 35 | repoMock.Setup (r => r.Customers()) 36 | .Returns (new Customer [] { }); 37 | 38 | var processed = thing.ProcessMonth (2016, 8); 39 | Assert.True (processed == 0); 40 | } 41 | 42 | } 43 | 44 | public class BillingDoohickey{ 45 | ICustomerRepository _repo; 46 | public BillingDoohickey (ICustomerRepository repo, 47 | ICreditCardCharger charger) { 48 | _repo = repo; 49 | } 50 | public int ProcessMonth (int year, int month){ 51 | return _repo.Customers().Length; 52 | } 53 | } 54 | public class Customer {} 55 | } 56 | -------------------------------------------------------------------------------- /software-design/tdd/tdd/08_problem.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using Moq; 4 | using Xunit; 5 | 6 | namespace BillingSystem.Tests8 7 | { 8 | public interface ICustomerRepository { 9 | Customer [] Customers (); 10 | } 11 | public interface ICreditCardCharger { } 12 | public class MonthlyChargeTests { 13 | 14 | ICustomerRepository repo; 15 | ICreditCardCharger charger; 16 | BillingDoohickey thing; 17 | Mock repoMock; 18 | 19 | public MonthlyChargeTests () { 20 | repoMock = new Mock (); 21 | repo = repoMock.Object; 22 | charger = new Mock ().Object; 23 | thing = new BillingDoohickey (repo, charger); 24 | } 25 | 26 | [Fact] 27 | public void Customers_With_Subscriptions_Due_Are_Charged () { 28 | repoMock.Setup (r => r.Customers ()) 29 | .Returns (new Customer [] { new Customer () }); 30 | 31 | var processed = thing.ProcessMonth (2016, 8); 32 | Assert.Equal (0, processed); 33 | } 34 | 35 | [Fact] 36 | public void Customers_With_No_Subscriptions_Due_Are_Not_Charged () { 37 | repoMock.Setup (r => r.Customers ()) 38 | .Returns (new Customer [] { }); 39 | 40 | var processed = thing.ProcessMonth (2016, 8); 41 | Assert.Equal (processed, 0); 42 | } 43 | 44 | [Fact] 45 | public void A_Customer_With_Two_Subscriptions_Due_Is_Charged_Twice () { 46 | var customer = new Customer (); 47 | customer.Subscriptions.Add (new Subscription ()); 48 | customer.Subscriptions.Add (new Subscription ()); 49 | 50 | repoMock.Setup (r => r.Customers()) 51 | .Returns (new Customer [] { customer }); 52 | 53 | var processed = thing.ProcessMonth (2016, 8); 54 | Assert.Equal (2, processed); 55 | } 56 | 57 | 58 | } 59 | public class BillingDoohickey 60 | { 61 | ICustomerRepository _repo; 62 | public BillingDoohickey (ICustomerRepository repo, ICreditCardCharger charger){ 63 | _repo = repo; 64 | } 65 | public int ProcessMonth (int year, int month){ 66 | var customer = _repo.Customers ().FirstOrDefault (); 67 | if (customer == null) { 68 | return 0; 69 | } else { 70 | return customer.Subscriptions.Count (); 71 | } 72 | 73 | } 74 | } 75 | public class Customer { 76 | public IList Subscriptions { get; set;} 77 | 78 | public Customer () { 79 | this.Subscriptions = new List (); 80 | } 81 | } 82 | public class Subscription { } 83 | } 84 | -------------------------------------------------------------------------------- /software-design/tdd/tdd/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | 4 | // Information about this assembly is defined by the following attributes. 5 | // Change them to the values specific to your project. 6 | 7 | [assembly: AssemblyTitle ("tdd")] 8 | [assembly: AssemblyDescription ("")] 9 | [assembly: AssemblyConfiguration ("")] 10 | [assembly: AssemblyCompany ("")] 11 | [assembly: AssemblyProduct ("")] 12 | [assembly: AssemblyCopyright ("rob")] 13 | [assembly: AssemblyTrademark ("")] 14 | [assembly: AssemblyCulture ("")] 15 | 16 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". 17 | // The form "{Major}.{Minor}.*" will automatically update the build and revision, 18 | // and "{Major}.{Minor}.{Build}.*" will update just the revision. 19 | 20 | [assembly: AssemblyVersion ("1.0.*")] 21 | 22 | // The following attributes are used to specify the signing key for the assembly, 23 | // if desired. See the Mono documentation for more information about signing. 24 | 25 | //[assembly: AssemblyDelaySign(false)] 26 | //[assembly: AssemblyKeyFile("")] 27 | 28 | -------------------------------------------------------------------------------- /software-design/tdd/tdd/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /software-design/tdd/tdd/tdd.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {5A796E74-C8F5-4BFA-893E-B516C1515B1B} 8 | Library 9 | tdd 10 | tdd 11 | v4.5 12 | 13 | 14 | true 15 | full 16 | false 17 | bin\Debug 18 | DEBUG; 19 | prompt 20 | 4 21 | false 22 | 23 | 24 | true 25 | bin\Release 26 | prompt 27 | 4 28 | false 29 | 30 | 31 | 32 | 33 | ..\packages\xunit.abstractions.2.0.0\lib\net35\xunit.abstractions.dll 34 | 35 | 36 | ..\packages\xunit.extensibility.core.2.1.0\lib\dotnet\xunit.core.dll 37 | 38 | 39 | ..\packages\xunit.extensibility.execution.2.1.0\lib\net45\xunit.execution.desktop.dll 40 | 41 | 42 | ..\packages\xunit.assert.2.1.0\lib\dotnet\xunit.assert.dll 43 | 44 | 45 | ..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll 46 | 47 | 48 | ..\packages\Moq.4.5.16\lib\net45\Moq.dll 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /theory/bigo.js: -------------------------------------------------------------------------------- 1 | const nums = [1,2,3,4,5]; 2 | 3 | const nums = [1,2,3,4,5]; 4 | const firstNumber = nums[0]; 5 | 6 | const nums = [1,2,3,4,5]; 7 | let sum = 0; 8 | for(let num of nums){ 9 | sum += num; 10 | } 11 | 12 | 13 | const sumContiguousArray = function(ary){ 14 | //get the last item 15 | const lastItem = ary[ary.length - 1]; 16 | //Gauss's trick 17 | return lastItem * (listItem + 1) / 2; 18 | } 19 | const nums = [1,2,3,4,5]; 20 | const sumOfArray = sumContiguousArray(nums); 21 | 22 | 23 | const hasDuplicates = function(num){ 24 | //loop the list, our O(n) op 25 | for(let i = 0; i < nums.length; i++){ 26 | const thisNum = nums[i]; 27 | //loop the list again, the O(n^2) op 28 | for(let j = 0; j < nums.length; j++){ 29 | //make sure we're not checking same number 30 | if(j !== i){ 31 | const otherNum = nums[j]; 32 | //if there's an equal value, return 33 | if(otherNum === thisNum) return true; 34 | } 35 | } 36 | } 37 | //if we're here, no dups 38 | return false; 39 | } 40 | const nums = [1,2,3,4,5,5]; 41 | hasDuplicates(nums);//true 42 | 43 | const nums = [1,2,3,4,5]; 44 | const searchFor = function(items, num){ 45 | //use binary search! 46 | //if found, return the number. Otherwise... 47 | //return null. We'll do this in a later chapter. 48 | } 49 | const hasDuplicates = function(nums){ 50 | for(let num of nums){ 51 | //let's go through the list again and have a look 52 | //at all the other numbers so we can compare 53 | if(searchFor(nums,num)){ 54 | return true; 55 | } 56 | } 57 | //only arrive here if there are no dups 58 | return false; 59 | } 60 | 61 | 62 | const findDuplicate = function(ary){ 63 | //sum what we're given 64 | let actualSum = 0; 65 | //our O(n) scan 66 | ary.forEach(x => actualSum += x); 67 | //get the last item 68 | const lastItem = ary[ary.length - 1]; 69 | //create a new array 70 | const shouldBe = lastItem * (lastItem + 1) / 2; 71 | return actualSum - shouldBe; 72 | } 73 | const nums = [1,2,3,4,4,5]; 74 | const duplicate = findDuplicate(nums); -------------------------------------------------------------------------------- /theory/data_structures.cs: -------------------------------------------------------------------------------- 1 | public class LinkedListNode{ 2 | public int Value { get; set; } 3 | public LinkedListNode Next { get; set; } 4 | public LinkedListNode(int Value) 5 | { 6 | this.Value = value; 7 | } 8 | } 9 | var a = new LinkedListNode(1); 10 | var b = new LinkedListNode(2); 11 | var c = new LinkedListNode(3); 12 | 13 | a.Next = b; 14 | b.Next = c; 15 | 16 | 17 | 18 | var thisNode = a; 19 | while(thisNode != null){ 20 | //do something 21 | //... 22 | //traverse 23 | thisNode = thisNode.Next; 24 | } 25 | 26 | -------------------------------------------------------------------------------- /theory/data_structures.js: -------------------------------------------------------------------------------- 1 | var value = "Rob"; 2 | const myLameHashFunction = function(val){ 3 | return val.length; 4 | } 5 | 6 | 7 | var nums = [23,4,42,15,16,8,3]; 8 | //this array is really a dictionary 9 | //which is also used to represent an object 10 | nums[0] == 23; //true 11 | nums[1] == 4; //true 12 | nums[2] == 42; //true 13 | 14 | var book = {title: "The Imposter's Handbook"}; 15 | book["title"]//The Imposter's Handbook --------------------------------------------------------------------------------