[{"data":1,"prerenderedAt":4587},["ShallowReactive",2],{"item-lessons-light-ch20-the-io-layer-pattern":3,"item-examples-light-ch20-the-io-layer-pattern":444,"item-exercises-light-ch20-the-io-layer-pattern":753,"item-lesson-full-ch20-the-io-layer-pattern-20":1070,"item-example-full-ch20-the-io-layer-pattern-20":1505,"item-exercise-full-ch20-the-io-layer-pattern-20":2796},[4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140,144,148,152,156,160,164,168,172,176,180,184,188,192,196,200,204,208,212,216,220,224,228,232,236,240,244,248,252,256,260,264,268,272,276,280,284,288,292,296,300,304,308,312,316,320,324,328,332,336,340,344,348,352,356,360,364,368,372,376,380,384,388,392,396,400,404,408,412,416,420,424,428,432,436,440],{"path":5,"title":6,"stem":7},"\u002Fshockwave-curriculum\u002Flessons\u002Fch01-why-java-for-frc\u002F1-why-java-for-frc","Why Java for FRC?","shockwave-curriculum\u002Flessons\u002Fch01-why-java-for-frc\u002F1.1-why-java-for-frc",{"path":9,"title":10,"stem":11},"\u002Fshockwave-curriculum\u002Flessons\u002Fch01-why-java-for-frc\u002F2-intro-to-algorithms-programming-and-compilers","Intro to Algorithms, Programming and Compilers","shockwave-curriculum\u002Flessons\u002Fch01-why-java-for-frc\u002F1.2-intro-to-algorithms-programming-and-compilers",{"path":13,"title":14,"stem":15},"\u002Fshockwave-curriculum\u002Flessons\u002Fch02-variables-and-types\u002F1-variables-and-data-types","Variables & Data Types","shockwave-curriculum\u002Flessons\u002Fch02-variables-and-types\u002F2.1-variables-and-data-types",{"path":17,"title":18,"stem":19},"\u002Fshockwave-curriculum\u002Flessons\u002Fch02-variables-and-types\u002F2-expressions-and-output","Expressions & Output","shockwave-curriculum\u002Flessons\u002Fch02-variables-and-types\u002F2.2-expressions-and-output",{"path":21,"title":22,"stem":23},"\u002Fshockwave-curriculum\u002Flessons\u002Fch02-variables-and-types\u002F3-assignment-and-input","Assignment & Input","shockwave-curriculum\u002Flessons\u002Fch02-variables-and-types\u002F2.3-assignment-and-input",{"path":25,"title":26,"stem":27},"\u002Fshockwave-curriculum\u002Flessons\u002Fch02-variables-and-types\u002F4-casting-and-ranges-of-values","Casting & Ranges of Values","shockwave-curriculum\u002Flessons\u002Fch02-variables-and-types\u002F2.4-casting-and-ranges-of-values",{"path":29,"title":30,"stem":31},"\u002Fshockwave-curriculum\u002Flessons\u002Fch02-variables-and-types\u002F5-compound-assignment-operators","Compound Assignment Operators","shockwave-curriculum\u002Flessons\u002Fch02-variables-and-types\u002F2.5-compound-assignment-operators",{"path":33,"title":34,"stem":35},"\u002Fshockwave-curriculum\u002Flessons\u002Fch03-apis-libraries-and-documentation\u002F1-apis-and-libraries","APIs and Libraries","shockwave-curriculum\u002Flessons\u002Fch03-apis-libraries-and-documentation\u002F3.1-apis-and-libraries",{"path":37,"title":38,"stem":39},"\u002Fshockwave-curriculum\u002Flessons\u002Fch03-apis-libraries-and-documentation\u002F2-documentation-with-comments-and-preconditions","Documentation with Comments and Preconditions","shockwave-curriculum\u002Flessons\u002Fch03-apis-libraries-and-documentation\u002F3.2-documentation-with-comments-and-preconditions",{"path":41,"title":42,"stem":43},"\u002Fshockwave-curriculum\u002Flessons\u002Fch03-apis-libraries-and-documentation\u002F3-packages-and-imports","Packages & Imports","shockwave-curriculum\u002Flessons\u002Fch03-apis-libraries-and-documentation\u002F3.3-packages-and-imports",{"path":45,"title":46,"stem":47},"\u002Fshockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F1-methods-signatures-and-parameters","Methods, Signatures & Parameters","shockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F4.1-methods-signatures-and-parameters",{"path":49,"title":50,"stem":51},"\u002Fshockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F2-calling-class-methods","Calling Class Methods","shockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F4.2-calling-class-methods",{"path":53,"title":54,"stem":55},"\u002Fshockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F3-using-the-math-class","Using the Math Class","shockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F4.3-using-the-math-class",{"path":57,"title":58,"stem":59},"\u002Fshockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F4-objects-instances-of-classes","Objects — Instances of Classes","shockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F4.4-objects-instances-of-classes",{"path":61,"title":62,"stem":63},"\u002Fshockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F5-creating-and-initializing-objects-constructors","Creating & Initializing Objects: Constructors","shockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F4.5-creating-and-initializing-objects-constructors",{"path":65,"title":66,"stem":67},"\u002Fshockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F6-calling-instance-methods","Calling Instance Methods","shockwave-curriculum\u002Flessons\u002Fch04-using-objects-and-calling-methods\u002F4.6-calling-instance-methods",{"path":69,"title":70,"stem":71},"\u002Fshockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F1-5.2-if-statements-and-for-loops","Control Structures: if Statements & For Loops","shockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5.1-5.2-if-statements-and-for-loops",{"path":73,"title":74,"stem":75},"\u002Fshockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F10-nested-iteration","Nested Iteration","shockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5.10-nested-iteration",{"path":77,"title":78,"stem":79},"\u002Fshockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F11-informal-runtime-analysis-of-loops","Informal Runtime Analysis of Loops","shockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5.11-informal-runtime-analysis-of-loops",{"path":81,"title":82,"stem":83},"\u002Fshockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F12-switch-statements-and-expressions","switch Statements and Expressions","shockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5.12-switch-statements-and-expressions",{"path":85,"title":86,"stem":87},"\u002Fshockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F3-algorithms-with-selection-and-repetition","Algorithms with Selection and Repetition","shockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5.3-algorithms-with-selection-and-repetition",{"path":89,"title":90,"stem":91},"\u002Fshockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F4-boolean-expressions","Boolean Expressions","shockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5.4-boolean-expressions",{"path":93,"title":94,"stem":95},"\u002Fshockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5-nested-if-statements","Nested if Statements","shockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5.5-nested-if-statements",{"path":97,"title":98,"stem":99},"\u002Fshockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F6-compound-boolean-expressions","Compound Boolean Expressions","shockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5.6-compound-boolean-expressions",{"path":101,"title":102,"stem":103},"\u002Fshockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F7-comparing-boolean-expressions-de-morgans-laws","Comparing Boolean Expressions (De Morgan's Laws)","shockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5.7-comparing-boolean-expressions-de-morgans-laws",{"path":105,"title":106,"stem":107},"\u002Fshockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F8-while-loops","While Loops","shockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5.8-while-loops",{"path":109,"title":110,"stem":111},"\u002Fshockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F9-implementing-selection-and-iteration-algorithms","Implementing Selection and Iteration Algorithms","shockwave-curriculum\u002Flessons\u002Fch05-control-structures\u002F5.9-implementing-selection-and-iteration-algorithms",{"path":113,"title":114,"stem":115},"\u002Fshockwave-curriculum\u002Flessons\u002Fch06-strings\u002F1-strings","Strings","shockwave-curriculum\u002Flessons\u002Fch06-strings\u002F6.1-strings",{"path":117,"title":118,"stem":119},"\u002Fshockwave-curriculum\u002Flessons\u002Fch06-strings\u002F2-string-algorithms","String Algorithms","shockwave-curriculum\u002Flessons\u002Fch06-strings\u002F6.2-string-algorithms",{"path":121,"title":122,"stem":123},"\u002Fshockwave-curriculum\u002Flessons\u002Fch07-the-class-blueprint\u002F1-anatomy-of-a-java-class","The Class Blueprint","shockwave-curriculum\u002Flessons\u002Fch07-the-class-blueprint\u002F7.1-anatomy-of-a-java-class",{"path":125,"title":126,"stem":127},"\u002Fshockwave-curriculum\u002Flessons\u002Fch07-the-class-blueprint\u002F2-methods-how-to-write-them","Methods: How to Write Them","shockwave-curriculum\u002Flessons\u002Fch07-the-class-blueprint\u002F7.2-methods-how-to-write-them",{"path":129,"title":130,"stem":131},"\u002Fshockwave-curriculum\u002Flessons\u002Fch07-the-class-blueprint\u002F3-methods-passing-and-returning-references-of-an-object","Methods: Passing & Returning References of an Object","shockwave-curriculum\u002Flessons\u002Fch07-the-class-blueprint\u002F7.3-methods-passing-and-returning-references-of-an-object",{"path":133,"title":134,"stem":135},"\u002Fshockwave-curriculum\u002Flessons\u002Fch07-the-class-blueprint\u002F4-class-static-variables-and-methods","Class (static) Variables & Methods","shockwave-curriculum\u002Flessons\u002Fch07-the-class-blueprint\u002F7.4-class-static-variables-and-methods",{"path":137,"title":138,"stem":139},"\u002Fshockwave-curriculum\u002Flessons\u002Fch08-constructors-and-this\u002F1-8.2-constructors-and-this","Constructors & \"this\"","shockwave-curriculum\u002Flessons\u002Fch08-constructors-and-this\u002F8.1-8.2-constructors-and-this",{"path":141,"title":142,"stem":143},"\u002Fshockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F1-array-creation-and-access","Array Creation and Access","shockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F9.1-array-creation-and-access",{"path":145,"title":146,"stem":147},"\u002Fshockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F2-arraylist-and-its-methods","ArrayList and its Methods","shockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F9.2-arraylist-and-its-methods",{"path":149,"title":150,"stem":151},"\u002Fshockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F3-optional-hashmap-dictionary-data-structure","HashMap (Dictionary) Data Structure","shockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F9.3-optional-hashmap-dictionary-data-structure",{"path":153,"title":154,"stem":155},"\u002Fshockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F4-array-traversals","Array Traversals","shockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F9.4-array-traversals",{"path":157,"title":158,"stem":159},"\u002Fshockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F5-implementing-array-algorithms","Implementing Array Algorithms","shockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F9.5-implementing-array-algorithms",{"path":161,"title":162,"stem":163},"\u002Fshockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F6-arraylist-traversals","ArrayList Traversals","shockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F9.6-arraylist-traversals",{"path":165,"title":166,"stem":167},"\u002Fshockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F7-implementing-arraylist-algorithms","Implementing ArrayList Algorithms","shockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F9.7-implementing-arraylist-algorithms",{"path":169,"title":170,"stem":171},"\u002Fshockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F8-using-text-files","Using Text Files","shockwave-curriculum\u002Flessons\u002Fch09-storing-data\u002F9.8-using-text-files",{"path":173,"title":174,"stem":175},"\u002Fshockwave-curriculum\u002Flessons\u002Fch10-2d-arrays\u002F1-2d-array-creation-and-access","2D Array Creation and Access","shockwave-curriculum\u002Flessons\u002Fch10-2d-arrays\u002F10.1-2d-array-creation-and-access",{"path":177,"title":178,"stem":179},"\u002Fshockwave-curriculum\u002Flessons\u002Fch10-2d-arrays\u002F2-2d-array-traversals-nested-loops","2D Array Traversals: Nested Loops","shockwave-curriculum\u002Flessons\u002Fch10-2d-arrays\u002F10.2-2d-array-traversals-nested-loops",{"path":181,"title":182,"stem":183},"\u002Fshockwave-curriculum\u002Flessons\u002Fch10-2d-arrays\u002F3-implementing-2d-array-algorithms","Implementing 2D Array Algorithms","shockwave-curriculum\u002Flessons\u002Fch10-2d-arrays\u002F10.3-implementing-2d-array-algorithms",{"path":185,"title":186,"stem":187},"\u002Fshockwave-curriculum\u002Flessons\u002Fch11-enums-named-choices\u002F11-enums-named-choices","Enums: Named Choices","shockwave-curriculum\u002Flessons\u002Fch11-enums-named-choices\u002F11-enums-named-choices",{"path":189,"title":190,"stem":191},"\u002Fshockwave-curriculum\u002Flessons\u002Fch12-exceptions-and-try-catch\u002F12-exceptions-and-try-catch","Exceptions & try\u002Fcatch","shockwave-curriculum\u002Flessons\u002Fch12-exceptions-and-try-catch\u002F12-exceptions-and-try-catch",{"path":193,"title":194,"stem":195},"\u002Fshockwave-curriculum\u002Flessons\u002Fch13-common-gotchas\u002F13-common-gotchas","Common Gotchas","shockwave-curriculum\u002Flessons\u002Fch13-common-gotchas\u002F13-common-gotchas",{"path":197,"title":198,"stem":199},"\u002Fshockwave-curriculum\u002Flessons\u002Fch14-why-design-patterns\u002F14-why-design-patterns","Why Design Patterns?","shockwave-curriculum\u002Flessons\u002Fch14-why-design-patterns\u002F14-why-design-patterns",{"path":201,"title":202,"stem":203},"\u002Fshockwave-curriculum\u002Flessons\u002Fch15-advanced-collections\u002F15-advanced-collections","Advanced Collections (Set\u002FQueue\u002FMap)","shockwave-curriculum\u002Flessons\u002Fch15-advanced-collections\u002F15-advanced-collections",{"path":205,"title":206,"stem":207},"\u002Fshockwave-curriculum\u002Flessons\u002Fch16-writing-your-own-generics\u002F16-writing-your-own-generics","Writing Your Own Generics","shockwave-curriculum\u002Flessons\u002Fch16-writing-your-own-generics\u002F16-writing-your-own-generics",{"path":209,"title":210,"stem":211},"\u002Fshockwave-curriculum\u002Flessons\u002Fch17-inheritance-and-abstractions\u002F1-inheritance-superclass-subclass","Inheritance, Superclass, Subclass","shockwave-curriculum\u002Flessons\u002Fch17-inheritance-and-abstractions\u002F17.1-inheritance-superclass-subclass",{"path":213,"title":214,"stem":215},"\u002Fshockwave-curriculum\u002Flessons\u002Fch17-inheritance-and-abstractions\u002F2-inheritance-and-constructors","Inheritance and Constructors","shockwave-curriculum\u002Flessons\u002Fch17-inheritance-and-abstractions\u002F17.2-inheritance-and-constructors",{"path":217,"title":218,"stem":219},"\u002Fshockwave-curriculum\u002Flessons\u002Fch17-inheritance-and-abstractions\u002F3-inheritance-hierarchies","Inheritance Hierarchies","shockwave-curriculum\u002Flessons\u002Fch17-inheritance-and-abstractions\u002F17.3-inheritance-hierarchies",{"path":221,"title":222,"stem":223},"\u002Fshockwave-curriculum\u002Flessons\u002Fch17-inheritance-and-abstractions\u002F4-object-superclass","Object Superclass","shockwave-curriculum\u002Flessons\u002Fch17-inheritance-and-abstractions\u002F17.4-object-superclass",{"path":225,"title":226,"stem":227},"\u002Fshockwave-curriculum\u002Flessons\u002Fch17-inheritance-and-abstractions\u002F5-abstract-classes-and-methods","Abstract Classes and Methods","shockwave-curriculum\u002Flessons\u002Fch17-inheritance-and-abstractions\u002F17.5-abstract-classes-and-methods",{"path":229,"title":230,"stem":231},"\u002Fshockwave-curriculum\u002Flessons\u002Fch18-polymorphism-many-forms\u002F1-overriding-methods","Overriding Methods","shockwave-curriculum\u002Flessons\u002Fch18-polymorphism-many-forms\u002F18.1-overriding-methods",{"path":233,"title":234,"stem":235},"\u002Fshockwave-curriculum\u002Flessons\u002Fch18-polymorphism-many-forms\u002F2-super-keyword","super Keyword","shockwave-curriculum\u002Flessons\u002Fch18-polymorphism-many-forms\u002F18.2-super-keyword",{"path":237,"title":238,"stem":239},"\u002Fshockwave-curriculum\u002Flessons\u002Fch18-polymorphism-many-forms\u002F3-polymorphism","Polymorphism","shockwave-curriculum\u002Flessons\u002Fch18-polymorphism-many-forms\u002F18.3-polymorphism",{"path":241,"title":242,"stem":243},"\u002Fshockwave-curriculum\u002Flessons\u002Fch19-interfaces-as-contracts\u002F19-interfaces-as-contracts","Interfaces as Contracts","shockwave-curriculum\u002Flessons\u002Fch19-interfaces-as-contracts\u002F19-interfaces-as-contracts",{"path":245,"title":246,"stem":247},"\u002Fshockwave-curriculum\u002Flessons\u002Fch19-interfaces-as-contracts\u002F1-lambdas-and-method-references","Lambdas & Method References","shockwave-curriculum\u002Flessons\u002Fch19-interfaces-as-contracts\u002F19.1-lambdas-and-method-references",{"path":249,"title":250,"stem":251},"\u002Fshockwave-curriculum\u002Flessons\u002Fch20-the-io-layer-pattern\u002F20-the-io-layer-pattern","The IO-Layer Pattern","shockwave-curriculum\u002Flessons\u002Fch20-the-io-layer-pattern\u002F20-the-io-layer-pattern",{"path":253,"title":254,"stem":255},"\u002Fshockwave-curriculum\u002Flessons\u002Fch21-static-factories\u002F21-static-factories","Static Factories","shockwave-curriculum\u002Flessons\u002Fch21-static-factories\u002F21-static-factories",{"path":257,"title":258,"stem":259},"\u002Fshockwave-curriculum\u002Flessons\u002Fch22-the-builder-pattern\u002F22-the-builder-pattern","The Builder Pattern","shockwave-curriculum\u002Flessons\u002Fch22-the-builder-pattern\u002F22-the-builder-pattern",{"path":261,"title":262,"stem":263},"\u002Fshockwave-curriculum\u002Flessons\u002Fch23-encapsulation-and-final\u002F1-scope-and-access","Access, final, and Immutability","shockwave-curriculum\u002Flessons\u002Fch23-encapsulation-and-final\u002F23.1-scope-and-access",{"path":265,"title":266,"stem":267},"\u002Fshockwave-curriculum\u002Flessons\u002Fch24-optional-avoiding-null-pointer-exceptions\u002F24-optional-avoiding-null-pointer-exceptions","Optional: Avoiding Null Pointer Exceptions","shockwave-curriculum\u002Flessons\u002Fch24-optional-avoiding-null-pointer-exceptions\u002F24-optional-avoiding-null-pointer-exceptions",{"path":269,"title":270,"stem":271},"\u002Fshockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F1-what-is-command-based-programming","What Is Command-Based Programming?","shockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F25.1-what-is-command-based-programming",{"path":273,"title":274,"stem":275},"\u002Fshockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F2-commands-and-command-compositions","Commands & Command Compositions","shockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F25.2-commands-and-command-compositions",{"path":277,"title":278,"stem":279},"\u002Fshockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F3-the-command-scheduler","The Command Scheduler","shockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F25.3-the-command-scheduler",{"path":281,"title":282,"stem":283},"\u002Fshockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F4-state-machines-logic","State Machines: Logic","shockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F25.4-state-machines-logic",{"path":285,"title":286,"stem":287},"\u002Fshockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F5-managing-transitions","Managing Transitions","shockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F25.5-managing-transitions",{"path":289,"title":290,"stem":291},"\u002Fshockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F6-binding-commands-to-triggers","Binding Commands to Triggers","shockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F25.6-binding-commands-to-triggers",{"path":293,"title":294,"stem":295},"\u002Fshockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F7-structuring-a-command-based-robot-project","Structuring a Command-Based Robot Project","shockwave-curriculum\u002Flessons\u002Fch25-command-based-programming\u002F25.7-structuring-a-command-based-robot-project",{"path":297,"title":298,"stem":299},"\u002Fshockwave-curriculum\u002Flessons\u002Fch26-architecture-takeaways\u002F26-architecture-takeaways","Architecture Takeaways","shockwave-curriculum\u002Flessons\u002Fch26-architecture-takeaways\u002F26-architecture-takeaways",{"path":301,"title":302,"stem":303},"\u002Fshockwave-curriculum\u002Flessons\u002Fch27-program-design-and-abstraction\u002F1-abstraction-and-program-design","Abstraction and Program Design","shockwave-curriculum\u002Flessons\u002Fch27-program-design-and-abstraction\u002F27.1-abstraction-and-program-design",{"path":305,"title":306,"stem":307},"\u002Fshockwave-curriculum\u002Flessons\u002Fch27-program-design-and-abstraction\u002F2-impact-of-program-design","Impact of Program Design","shockwave-curriculum\u002Flessons\u002Fch27-program-design-and-abstraction\u002F27.2-impact-of-program-design",{"path":309,"title":310,"stem":311},"\u002Fshockwave-curriculum\u002Flessons\u002Fch28-algorithms-searching-sorting-recursion\u002F1-searching-algorithms","Searching Algorithms","shockwave-curriculum\u002Flessons\u002Fch28-algorithms-searching-sorting-recursion\u002F28.1-searching-algorithms",{"path":313,"title":314,"stem":315},"\u002Fshockwave-curriculum\u002Flessons\u002Fch28-algorithms-searching-sorting-recursion\u002F2-sorting-algorithms","Sorting Algorithms","shockwave-curriculum\u002Flessons\u002Fch28-algorithms-searching-sorting-recursion\u002F28.2-sorting-algorithms",{"path":317,"title":318,"stem":319},"\u002Fshockwave-curriculum\u002Flessons\u002Fch28-algorithms-searching-sorting-recursion\u002F3-recursion","Recursion","shockwave-curriculum\u002Flessons\u002Fch28-algorithms-searching-sorting-recursion\u002F28.3-recursion",{"path":321,"title":322,"stem":323},"\u002Fshockwave-curriculum\u002Flessons\u002Fch28-algorithms-searching-sorting-recursion\u002F4-recursive-searching-and-sorting","Recursive Searching and Sorting","shockwave-curriculum\u002Flessons\u002Fch28-algorithms-searching-sorting-recursion\u002F28.4-recursive-searching-and-sorting",{"path":325,"title":326,"stem":327},"\u002Fshockwave-curriculum\u002Flessons\u002Fch29-git-and-github-basics\u002F1-coming-soon","Git & GitHub Basics — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch29-git-and-github-basics\u002F29.1-coming-soon",{"path":329,"title":330,"stem":331},"\u002Fshockwave-curriculum\u002Flessons\u002Fch30-git-history-and-merging\u002F1-coming-soon","Git — History & Merging — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch30-git-history-and-merging\u002F30.1-coming-soon",{"path":333,"title":334,"stem":335},"\u002Fshockwave-curriculum\u002Flessons\u002Fch31-dev-environment-and-tooling\u002F1-coming-soon","Dev Environment & Tooling — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch31-dev-environment-and-tooling\u002F31.1-coming-soon",{"path":337,"title":338,"stem":339},"\u002Fshockwave-curriculum\u002Flessons\u002Fch32-unit-testing\u002F1-coming-soon","Unit Testing — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch32-unit-testing\u002F32.1-coming-soon",{"path":341,"title":342,"stem":343},"\u002Fshockwave-curriculum\u002Flessons\u002Fch33-advantagekit-autologging\u002F1-coming-soon","AdvantageKit — AutoLogging — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch33-advantagekit-autologging\u002F33.1-coming-soon",{"path":345,"title":346,"stem":347},"\u002Fshockwave-curriculum\u002Flessons\u002Fch34-log-replay\u002F1-coming-soon","Log Replay — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch34-log-replay\u002F34.1-coming-soon",{"path":349,"title":350,"stem":351},"\u002Fshockwave-curriculum\u002Flessons\u002Fch35-advantagescope-i-visualization\u002F1-coming-soon","AdvantageScope I: Visualization — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch35-advantagescope-i-visualization\u002F35.1-coming-soon",{"path":353,"title":354,"stem":355},"\u002Fshockwave-curriculum\u002Flessons\u002Fch36-advantagescope-ii-custom-3d-assets\u002F1-coming-soon","AdvantageScope II: Custom 3D Assets — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch36-advantagescope-ii-custom-3d-assets\u002F36.1-coming-soon",{"path":357,"title":358,"stem":359},"\u002Fshockwave-curriculum\u002Flessons\u002Fch37-autonomous-i\u002F1-coming-soon","Autonomous I — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch37-autonomous-i\u002F37.1-coming-soon",{"path":361,"title":362,"stem":363},"\u002Fshockwave-curriculum\u002Flessons\u002Fch38-autonomous-ii-pathplanner-and-trajectories\u002F1-coming-soon","Autonomous II: PathPlanner & Trajectories — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch38-autonomous-ii-pathplanner-and-trajectories\u002F38.1-coming-soon",{"path":365,"title":366,"stem":367},"\u002Fshockwave-curriculum\u002Flessons\u002Fch39-control-fundamentals\u002F1-coming-soon","Control Fundamentals — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch39-control-fundamentals\u002F39.1-coming-soon",{"path":369,"title":370,"stem":371},"\u002Fshockwave-curriculum\u002Flessons\u002Fch40-motion-profiles\u002F1-coming-soon","Motion Profiles — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch40-motion-profiles\u002F40.1-coming-soon",{"path":373,"title":374,"stem":375},"\u002Fshockwave-curriculum\u002Flessons\u002Fch41-hardware-fundamentals\u002F1-coming-soon","Hardware Fundamentals — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch41-hardware-fundamentals\u002F41.1-coming-soon",{"path":377,"title":378,"stem":379},"\u002Fshockwave-curriculum\u002Flessons\u002Fch42-photonvision\u002F1-coming-soon","PhotonVision — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch42-photonvision\u002F42.1-coming-soon",{"path":381,"title":382,"stem":383},"\u002Fshockwave-curriculum\u002Flessons\u002Fch43-apriltags-and-pose\u002F1-coming-soon","AprilTags & Pose — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch43-apriltags-and-pose\u002F43.1-coming-soon",{"path":385,"title":386,"stem":387},"\u002Fshockwave-curriculum\u002Flessons\u002Fch44-subsystems-i\u002F1-coming-soon","Subsystems I — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch44-subsystems-i\u002F44.1-coming-soon",{"path":389,"title":390,"stem":391},"\u002Fshockwave-curriculum\u002Flessons\u002Fch45-subsystems-ii-advanced\u002F1-coming-soon","Subsystems II — Advanced — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch45-subsystems-ii-advanced\u002F45.1-coming-soon",{"path":393,"title":394,"stem":395},"\u002Fshockwave-curriculum\u002Flessons\u002Fch46-team-utilities-i\u002F1-coming-soon","Team Utilities I — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch46-team-utilities-i\u002F46.1-coming-soon",{"path":397,"title":398,"stem":399},"\u002Fshockwave-curriculum\u002Flessons\u002Fch47-field-constants\u002F1-coming-soon","Field Constants — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch47-field-constants\u002F47.1-coming-soon",{"path":401,"title":402,"stem":403},"\u002Fshockwave-curriculum\u002Flessons\u002Fch48-troubleshooting-i-runtime-debug\u002F1-coming-soon","Troubleshooting I — Runtime Debug — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch48-troubleshooting-i-runtime-debug\u002F48.1-coming-soon",{"path":405,"title":406,"stem":407},"\u002Fshockwave-curriculum\u002Flessons\u002Fch49-troubleshooting-ii-can-and-sim\u002F1-coming-soon","Troubleshooting II: CAN & Sim — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch49-troubleshooting-ii-can-and-sim\u002F49.1-coming-soon",{"path":409,"title":410,"stem":411},"\u002Fshockwave-curriculum\u002Flessons\u002Fch50-vendor-libraries-talonfx\u002F1-coming-soon","Vendor Libraries: TalonFX — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch50-vendor-libraries-talonfx\u002F50.1-coming-soon",{"path":413,"title":414,"stem":415},"\u002Fshockwave-curriculum\u002Flessons\u002Fch51-robot-alerts\u002F1-coming-soon","Robot Alerts — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch51-robot-alerts\u002F51.1-coming-soon",{"path":417,"title":418,"stem":419},"\u002Fshockwave-curriculum\u002Flessons\u002Fch52-wpilib-commands\u002F1-coming-soon","WPILib Commands — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch52-wpilib-commands\u002F52.1-coming-soon",{"path":421,"title":422,"stem":423},"\u002Fshockwave-curriculum\u002Flessons\u002Fch53-wpilib-geometry\u002F1-coming-soon","WPILib Geometry — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch53-wpilib-geometry\u002F53.1-coming-soon",{"path":425,"title":426,"stem":427},"\u002Fshockwave-curriculum\u002Flessons\u002Fch54-networktables\u002F1-coming-soon","NetworkTables — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch54-networktables\u002F54.1-coming-soon",{"path":429,"title":430,"stem":431},"\u002Fshockwave-curriculum\u002Flessons\u002Fch55-command-scheduler\u002F1-coming-soon","Command Scheduler — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch55-command-scheduler\u002F55.1-coming-soon",{"path":433,"title":434,"stem":435},"\u002Fshockwave-curriculum\u002Flessons\u002Fch56-wpilib-timers\u002F1-coming-soon","WPILib Timers — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch56-wpilib-timers\u002F56.1-coming-soon",{"path":437,"title":438,"stem":439},"\u002Fshockwave-curriculum\u002Flessons\u002Fch57-wpilib-triggers\u002F1-coming-soon","WPILib Triggers — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch57-wpilib-triggers\u002F57.1-coming-soon",{"path":441,"title":442,"stem":443},"\u002Fshockwave-curriculum\u002Flessons\u002Fch58-vendor-units-and-conversions\u002F1-coming-soon","Vendor Units & Conversions — Coming Soon","shockwave-curriculum\u002Flessons\u002Fch58-vendor-units-and-conversions\u002F58.1-coming-soon",[445,449,453,457,461,465,469,473,477,481,485,489,493,497,501,505,509,513,517,521,525,529,533,537,541,545,549,553,557,561,565,569,573,577,581,585,589,593,597,601,605,609,613,617,621,625,629,633,637,641,645,649,653,657,661,665,669,673,677,681,685,689,693,697,701,705,709,713,717,721,725,729,733,737,741,745,749],{"path":446,"title":447,"stem":448},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch01-why-java-for-frc\u002F2-intro-to-algorithms-programming-and-compilers","Intro to Algorithms, Programming and Compilers — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch01-why-java-for-frc\u002F1.2-intro-to-algorithms-programming-and-compilers",{"path":450,"title":451,"stem":452},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch02-variables-and-types\u002F1-variables-and-data-types","Variables & Data Types — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch02-variables-and-types\u002F2.1-variables-and-data-types",{"path":454,"title":455,"stem":456},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch02-variables-and-types\u002F2-expressions-and-output","Expressions & Output — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch02-variables-and-types\u002F2.2-expressions-and-output",{"path":458,"title":459,"stem":460},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch02-variables-and-types\u002F3-assignment-and-input","Assignment & Input — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch02-variables-and-types\u002F2.3-assignment-and-input",{"path":462,"title":463,"stem":464},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch02-variables-and-types\u002F4-casting-and-ranges-of-values","Casting & Ranges of Values — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch02-variables-and-types\u002F2.4-casting-and-ranges-of-values",{"path":466,"title":467,"stem":468},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch02-variables-and-types\u002F5-compound-assignment-operators","Compound Assignment Operators — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch02-variables-and-types\u002F2.5-compound-assignment-operators",{"path":470,"title":471,"stem":472},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch03-apis-libraries-and-documentation\u002F1-apis-and-libraries","APIs and Libraries — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch03-apis-libraries-and-documentation\u002F3.1-apis-and-libraries",{"path":474,"title":475,"stem":476},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch03-apis-libraries-and-documentation\u002F2-documentation-with-comments-and-preconditions","Documentation with Comments and Preconditions — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch03-apis-libraries-and-documentation\u002F3.2-documentation-with-comments-and-preconditions",{"path":478,"title":479,"stem":480},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch03-apis-libraries-and-documentation\u002F3-packages-and-imports","Packages & Imports — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch03-apis-libraries-and-documentation\u002F3.3-packages-and-imports",{"path":482,"title":483,"stem":484},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F1-methods-signatures-and-parameters","Methods, Signatures & Parameters — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F4.1-methods-signatures-and-parameters",{"path":486,"title":487,"stem":488},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F2-calling-class-methods","Calling Class Methods — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F4.2-calling-class-methods",{"path":490,"title":491,"stem":492},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F3-using-the-math-class","Using the Math Class — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F4.3-using-the-math-class",{"path":494,"title":495,"stem":496},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F4-objects-instances-of-classes","Objects — Instances of Classes — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F4.4-objects-instances-of-classes",{"path":498,"title":499,"stem":500},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F5-creating-and-initializing-objects-constructors","Creating & Initializing Objects: Constructors — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F4.5-creating-and-initializing-objects-constructors",{"path":502,"title":503,"stem":504},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F6-calling-instance-methods","Calling Instance Methods — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch04-using-objects-and-calling-methods\u002F4.6-calling-instance-methods",{"path":506,"title":507,"stem":508},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F1-5.2-if-statements-and-for-loops","if Statements & For Loops — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5.1-5.2-if-statements-and-for-loops",{"path":510,"title":511,"stem":512},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F10-nested-iteration","Nested Iteration — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5.10-nested-iteration",{"path":514,"title":515,"stem":516},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F11-informal-runtime-analysis-of-loops","Informal Runtime Analysis of Loops — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5.11-informal-runtime-analysis-of-loops",{"path":518,"title":519,"stem":520},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F12-switch-statements-and-expressions","switch Statements and Expressions — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5.12-switch-statements-and-expressions",{"path":522,"title":523,"stem":524},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F3-algorithms-with-selection-and-repetition","Algorithms with Selection and Repetition — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5.3-algorithms-with-selection-and-repetition",{"path":526,"title":527,"stem":528},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F4-boolean-expressions","Boolean Expressions — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5.4-boolean-expressions",{"path":530,"title":531,"stem":532},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5-nested-if-statements","Nested if Statements — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5.5-nested-if-statements",{"path":534,"title":535,"stem":536},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F6-compound-boolean-expressions","Compound Boolean Expressions — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5.6-compound-boolean-expressions",{"path":538,"title":539,"stem":540},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F7-comparing-boolean-expressions-de-morgans-laws","Comparing Boolean Expressions (De Morgan's Laws) — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5.7-comparing-boolean-expressions-de-morgans-laws",{"path":542,"title":543,"stem":544},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F8-while-loops","While Loops — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5.8-while-loops",{"path":546,"title":547,"stem":548},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F9-implementing-selection-and-iteration-algorithms","Implementing Selection and Iteration Algorithms — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch05-control-structures\u002F5.9-implementing-selection-and-iteration-algorithms",{"path":550,"title":551,"stem":552},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch06-strings\u002F1-strings","Strings — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch06-strings\u002F6.1-strings",{"path":554,"title":555,"stem":556},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch06-strings\u002F2-string-algorithms","String Algorithms — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch06-strings\u002F6.2-string-algorithms",{"path":558,"title":559,"stem":560},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch07-the-class-blueprint\u002F1-anatomy-of-a-java-class","Anatomy of a Java Class — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch07-the-class-blueprint\u002F7.1-anatomy-of-a-java-class",{"path":562,"title":563,"stem":564},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch07-the-class-blueprint\u002F2-methods-how-to-write-them","Methods: How to Write Them — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch07-the-class-blueprint\u002F7.2-methods-how-to-write-them",{"path":566,"title":567,"stem":568},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch07-the-class-blueprint\u002F3-methods-passing-and-returning-references-of-an-object","Methods: Passing & Returning References of an Object — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch07-the-class-blueprint\u002F7.3-methods-passing-and-returning-references-of-an-object",{"path":570,"title":571,"stem":572},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch07-the-class-blueprint\u002F4-class-static-variables-and-methods","Class (static) Variables & Methods — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch07-the-class-blueprint\u002F7.4-class-static-variables-and-methods",{"path":574,"title":575,"stem":576},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch08-constructors-and-this\u002F1-8.2-constructors-and-this","Constructors & \"this\" — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch08-constructors-and-this\u002F8.1-8.2-constructors-and-this",{"path":578,"title":579,"stem":580},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F1-array-creation-and-access","Array Creation and Access — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F9.1-array-creation-and-access",{"path":582,"title":583,"stem":584},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F2-arraylist-and-its-methods","ArrayList and its Methods — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F9.2-arraylist-and-its-methods",{"path":586,"title":587,"stem":588},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F3-optional-hashmap-dictionary-data-structure","HashMap (Dictionary) Data Structure — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F9.3-optional-hashmap-dictionary-data-structure",{"path":590,"title":591,"stem":592},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F4-array-traversals","Array Traversals — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F9.4-array-traversals",{"path":594,"title":595,"stem":596},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F5-implementing-array-algorithms","Implementing Array Algorithms — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F9.5-implementing-array-algorithms",{"path":598,"title":599,"stem":600},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F6-arraylist-traversals","ArrayList Traversals — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F9.6-arraylist-traversals",{"path":602,"title":603,"stem":604},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F7-implementing-arraylist-algorithms","Implementing ArrayList Algorithms — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F9.7-implementing-arraylist-algorithms",{"path":606,"title":607,"stem":608},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F8-using-text-files","Using Text Files — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch09-storing-data\u002F9.8-using-text-files",{"path":610,"title":611,"stem":612},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch10-2d-arrays\u002F1-2d-array-creation-and-access","2D Array Creation and Access — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch10-2d-arrays\u002F10.1-2d-array-creation-and-access",{"path":614,"title":615,"stem":616},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch10-2d-arrays\u002F2-2d-array-traversals-nested-loops","2D Array Traversals: Nested Loops — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch10-2d-arrays\u002F10.2-2d-array-traversals-nested-loops",{"path":618,"title":619,"stem":620},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch10-2d-arrays\u002F3-implementing-2d-array-algorithms","Implementing 2D Array Algorithms — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch10-2d-arrays\u002F10.3-implementing-2d-array-algorithms",{"path":622,"title":623,"stem":624},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch11-enums-named-choices\u002F11-enums-named-choices","Enums: Named Choices — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch11-enums-named-choices\u002F11-enums-named-choices",{"path":626,"title":627,"stem":628},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch12-exceptions-and-try-catch\u002F12-exceptions-and-try-catch","Exceptions & try\u002Fcatch — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch12-exceptions-and-try-catch\u002F12-exceptions-and-try-catch",{"path":630,"title":631,"stem":632},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch13-common-gotchas\u002F13-common-gotchas","Common Gotchas — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch13-common-gotchas\u002F13-common-gotchas",{"path":634,"title":635,"stem":636},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch15-advanced-collections\u002F15-advanced-collections","Advanced Collections (Set\u002FQueue\u002FMap) — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch15-advanced-collections\u002F15-advanced-collections",{"path":638,"title":639,"stem":640},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch16-writing-your-own-generics\u002F16-writing-your-own-generics","Writing Your Own Generics — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch16-writing-your-own-generics\u002F16-writing-your-own-generics",{"path":642,"title":643,"stem":644},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch17-inheritance-and-abstractions\u002F1-inheritance-superclass-subclass","Inheritance, Superclass, Subclass — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch17-inheritance-and-abstractions\u002F17.1-inheritance-superclass-subclass",{"path":646,"title":647,"stem":648},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch17-inheritance-and-abstractions\u002F2-inheritance-and-constructors","Inheritance and Constructors — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch17-inheritance-and-abstractions\u002F17.2-inheritance-and-constructors",{"path":650,"title":651,"stem":652},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch17-inheritance-and-abstractions\u002F3-inheritance-hierarchies","Inheritance Hierarchies — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch17-inheritance-and-abstractions\u002F17.3-inheritance-hierarchies",{"path":654,"title":655,"stem":656},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch17-inheritance-and-abstractions\u002F4-object-superclass","Object Superclass — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch17-inheritance-and-abstractions\u002F17.4-object-superclass",{"path":658,"title":659,"stem":660},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch17-inheritance-and-abstractions\u002F5-abstract-classes-and-methods","Abstract Classes and Methods — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch17-inheritance-and-abstractions\u002F17.5-abstract-classes-and-methods",{"path":662,"title":663,"stem":664},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch18-polymorphism-many-forms\u002F1-overriding-methods","Overriding Methods — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch18-polymorphism-many-forms\u002F18.1-overriding-methods",{"path":666,"title":667,"stem":668},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch18-polymorphism-many-forms\u002F2-super-keyword","super Keyword — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch18-polymorphism-many-forms\u002F18.2-super-keyword",{"path":670,"title":671,"stem":672},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch18-polymorphism-many-forms\u002F3-polymorphism","Polymorphism — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch18-polymorphism-many-forms\u002F18.3-polymorphism",{"path":674,"title":675,"stem":676},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch19-interfaces-as-contracts\u002F19-interfaces-as-contracts","Interfaces as Contracts — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch19-interfaces-as-contracts\u002F19-interfaces-as-contracts",{"path":678,"title":679,"stem":680},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch19-interfaces-as-contracts\u002F1-lambdas-and-method-references","Lambdas & Method References — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch19-interfaces-as-contracts\u002F19.1-lambdas-and-method-references",{"path":682,"title":683,"stem":684},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch20-the-io-layer-pattern\u002F20-the-io-layer-pattern","The IO-Layer Pattern — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch20-the-io-layer-pattern\u002F20-the-io-layer-pattern",{"path":686,"title":687,"stem":688},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch21-static-factories\u002F21-static-factories","Static Factories — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch21-static-factories\u002F21-static-factories",{"path":690,"title":691,"stem":692},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch22-the-builder-pattern\u002F22-the-builder-pattern","The Builder Pattern — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch22-the-builder-pattern\u002F22-the-builder-pattern",{"path":694,"title":695,"stem":696},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch23-encapsulation-and-final\u002F1-scope-and-access","Access, final, and Immutability — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch23-encapsulation-and-final\u002F23.1-scope-and-access",{"path":698,"title":699,"stem":700},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch24-optional-avoiding-null-pointer-exceptions\u002F24-optional-avoiding-null-pointer-exceptions","Optional: Avoiding Null Pointer Exceptions — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch24-optional-avoiding-null-pointer-exceptions\u002F24-optional-avoiding-null-pointer-exceptions",{"path":702,"title":703,"stem":704},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F1-what-is-command-based-programming","What Is Command-Based Programming? — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F25.1-what-is-command-based-programming",{"path":706,"title":707,"stem":708},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F2-commands-and-command-compositions","Commands & Command Compositions — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F25.2-commands-and-command-compositions",{"path":710,"title":711,"stem":712},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F3-the-command-scheduler","The Command Scheduler — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F25.3-the-command-scheduler",{"path":714,"title":715,"stem":716},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F4-state-machines-logic","State Machines: Logic — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F25.4-state-machines-logic",{"path":718,"title":719,"stem":720},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F5-managing-transitions","Managing Transitions — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F25.5-managing-transitions",{"path":722,"title":723,"stem":724},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F6-binding-commands-to-triggers","Binding Commands to Triggers — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F25.6-binding-commands-to-triggers",{"path":726,"title":727,"stem":728},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F7-structuring-a-command-based-robot-project","Structuring a Command-Based Robot Project — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch25-command-based-programming\u002F25.7-structuring-a-command-based-robot-project",{"path":730,"title":731,"stem":732},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch26-architecture-takeaways\u002F26-architecture-takeaways","Architecture Takeaways — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch26-architecture-takeaways\u002F26-architecture-takeaways",{"path":734,"title":735,"stem":736},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch27-program-design-and-abstraction\u002F1-abstraction-and-program-design","Abstraction and Program Design — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch27-program-design-and-abstraction\u002F27.1-abstraction-and-program-design",{"path":738,"title":739,"stem":740},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch28-algorithms-searching-sorting-recursion\u002F1-searching-algorithms","Searching Algorithms — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch28-algorithms-searching-sorting-recursion\u002F28.1-searching-algorithms",{"path":742,"title":743,"stem":744},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch28-algorithms-searching-sorting-recursion\u002F2-sorting-algorithms","Sorting Algorithms — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch28-algorithms-searching-sorting-recursion\u002F28.2-sorting-algorithms",{"path":746,"title":747,"stem":748},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch28-algorithms-searching-sorting-recursion\u002F3-recursion","Recursion — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch28-algorithms-searching-sorting-recursion\u002F28.3-recursion",{"path":750,"title":751,"stem":752},"\u002Fshockwave-curriculum\u002Fexamples\u002Fch28-algorithms-searching-sorting-recursion\u002F4-recursive-searching-and-sorting","Recursive Searching and Sorting — Worked Example","shockwave-curriculum\u002Fexamples\u002Fch28-algorithms-searching-sorting-recursion\u002F28.4-recursive-searching-and-sorting",[754,758,762,766,770,774,778,782,786,790,794,798,802,806,810,814,818,822,826,830,834,838,842,846,850,854,858,862,866,870,874,878,882,886,890,894,898,902,906,910,914,918,922,926,930,934,938,942,946,950,954,958,962,966,970,974,978,982,986,990,994,998,1002,1006,1010,1014,1018,1022,1026,1030,1034,1038,1042,1046,1050,1054,1058,1062,1066],{"path":755,"title":756,"stem":757},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch01-why-java-for-frc\u002F2-intro-to-algorithms-programming-and-compilers","Intro to Algorithms, Programming and Compilers — Exercises","shockwave-curriculum\u002Fexercises\u002Fch01-why-java-for-frc\u002F1.2-intro-to-algorithms-programming-and-compilers",{"path":759,"title":760,"stem":761},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch02-variables-and-types\u002F1-variables-and-data-types","Variables & Data Types — Exercises","shockwave-curriculum\u002Fexercises\u002Fch02-variables-and-types\u002F2.1-variables-and-data-types",{"path":763,"title":764,"stem":765},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch02-variables-and-types\u002F2-expressions-and-output","Expressions & Output — Exercises","shockwave-curriculum\u002Fexercises\u002Fch02-variables-and-types\u002F2.2-expressions-and-output",{"path":767,"title":768,"stem":769},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch02-variables-and-types\u002F3-assignment-and-input","Assignment & Input — Exercises","shockwave-curriculum\u002Fexercises\u002Fch02-variables-and-types\u002F2.3-assignment-and-input",{"path":771,"title":772,"stem":773},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch02-variables-and-types\u002F4-casting-and-ranges-of-values","Casting & Ranges of Values — Exercises","shockwave-curriculum\u002Fexercises\u002Fch02-variables-and-types\u002F2.4-casting-and-ranges-of-values",{"path":775,"title":776,"stem":777},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch02-variables-and-types\u002F5-compound-assignment-operators","Compound Assignment Operators — Exercises","shockwave-curriculum\u002Fexercises\u002Fch02-variables-and-types\u002F2.5-compound-assignment-operators",{"path":779,"title":780,"stem":781},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch03-apis-libraries-and-documentation\u002F1-apis-and-libraries","APIs and Libraries — Exercises","shockwave-curriculum\u002Fexercises\u002Fch03-apis-libraries-and-documentation\u002F3.1-apis-and-libraries",{"path":783,"title":784,"stem":785},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch03-apis-libraries-and-documentation\u002F2-documentation-with-comments-and-preconditions","Documentation with Comments and Preconditions — Exercises","shockwave-curriculum\u002Fexercises\u002Fch03-apis-libraries-and-documentation\u002F3.2-documentation-with-comments-and-preconditions",{"path":787,"title":788,"stem":789},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch03-apis-libraries-and-documentation\u002F3-packages-and-imports","Packages & Imports — Exercises","shockwave-curriculum\u002Fexercises\u002Fch03-apis-libraries-and-documentation\u002F3.3-packages-and-imports",{"path":791,"title":792,"stem":793},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F1-methods-signatures-and-parameters","Methods, Signatures & Parameters — Exercises","shockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F4.1-methods-signatures-and-parameters",{"path":795,"title":796,"stem":797},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F2-calling-class-methods","Calling Class Methods — Exercises","shockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F4.2-calling-class-methods",{"path":799,"title":800,"stem":801},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F3-using-the-math-class","Using the Math Class — Exercises","shockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F4.3-using-the-math-class",{"path":803,"title":804,"stem":805},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F4-objects-instances-of-classes","Objects — Instances of Classes — Exercises","shockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F4.4-objects-instances-of-classes",{"path":807,"title":808,"stem":809},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F5-creating-and-initializing-objects-constructors","Creating & Initializing Objects: Constructors — Exercises","shockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F4.5-creating-and-initializing-objects-constructors",{"path":811,"title":812,"stem":813},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F6-calling-instance-methods","Calling Instance Methods — Exercises","shockwave-curriculum\u002Fexercises\u002Fch04-using-objects-and-calling-methods\u002F4.6-calling-instance-methods",{"path":815,"title":816,"stem":817},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F1-5.2-if-statements-and-for-loops","if Statements & For Loops — Exercises","shockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5.1-5.2-if-statements-and-for-loops",{"path":819,"title":820,"stem":821},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F10-nested-iteration","Nested Iteration — Exercises","shockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5.10-nested-iteration",{"path":823,"title":824,"stem":825},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F11-informal-runtime-analysis-of-loops","Informal Runtime Analysis of Loops — Exercises","shockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5.11-informal-runtime-analysis-of-loops",{"path":827,"title":828,"stem":829},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F12-switch-statements-and-expressions","switch Statements and Expressions — Exercises","shockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5.12-switch-statements-and-expressions",{"path":831,"title":832,"stem":833},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F3-algorithms-with-selection-and-repetition","Algorithms with Selection and Repetition — Exercises","shockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5.3-algorithms-with-selection-and-repetition",{"path":835,"title":836,"stem":837},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F4-boolean-expressions","Boolean Expressions — Exercises","shockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5.4-boolean-expressions",{"path":839,"title":840,"stem":841},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5-nested-if-statements","Nested if Statements — Exercises","shockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5.5-nested-if-statements",{"path":843,"title":844,"stem":845},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F6-compound-boolean-expressions","Compound Boolean Expressions — Exercises","shockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5.6-compound-boolean-expressions",{"path":847,"title":848,"stem":849},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F7-comparing-boolean-expressions-de-morgans-laws","Comparing Boolean Expressions (De Morgan's Laws) — Exercises","shockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5.7-comparing-boolean-expressions-de-morgans-laws",{"path":851,"title":852,"stem":853},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F8-while-loops","While Loops — Exercises","shockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5.8-while-loops",{"path":855,"title":856,"stem":857},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F9-implementing-selection-and-iteration-algorithms","Implementing Selection and Iteration Algorithms — Exercises","shockwave-curriculum\u002Fexercises\u002Fch05-control-structures\u002F5.9-implementing-selection-and-iteration-algorithms",{"path":859,"title":860,"stem":861},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch06-strings\u002F1-strings","Strings — Exercises","shockwave-curriculum\u002Fexercises\u002Fch06-strings\u002F6.1-strings",{"path":863,"title":864,"stem":865},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch06-strings\u002F2-string-algorithms","String Algorithms — Exercises","shockwave-curriculum\u002Fexercises\u002Fch06-strings\u002F6.2-string-algorithms",{"path":867,"title":868,"stem":869},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch07-the-class-blueprint\u002F1-anatomy-of-a-java-class","Anatomy of a Java Class — Exercises","shockwave-curriculum\u002Fexercises\u002Fch07-the-class-blueprint\u002F7.1-anatomy-of-a-java-class",{"path":871,"title":872,"stem":873},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch07-the-class-blueprint\u002F2-methods-how-to-write-them","Methods: How to Write Them — Exercises","shockwave-curriculum\u002Fexercises\u002Fch07-the-class-blueprint\u002F7.2-methods-how-to-write-them",{"path":875,"title":876,"stem":877},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch07-the-class-blueprint\u002F3-methods-passing-and-returning-references-of-an-object","Methods: Passing & Returning References of an Object — Exercises","shockwave-curriculum\u002Fexercises\u002Fch07-the-class-blueprint\u002F7.3-methods-passing-and-returning-references-of-an-object",{"path":879,"title":880,"stem":881},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch07-the-class-blueprint\u002F4-class-static-variables-and-methods","Class (static) Variables & Methods — Exercises","shockwave-curriculum\u002Fexercises\u002Fch07-the-class-blueprint\u002F7.4-class-static-variables-and-methods",{"path":883,"title":884,"stem":885},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch08-constructors-and-this\u002F1-8.2-constructors-and-this","Constructors & \"this\" — Exercises","shockwave-curriculum\u002Fexercises\u002Fch08-constructors-and-this\u002F8.1-8.2-constructors-and-this",{"path":887,"title":888,"stem":889},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F1-array-creation-and-access","Array Creation and Access — Exercises","shockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F9.1-array-creation-and-access",{"path":891,"title":892,"stem":893},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F2-arraylist-and-its-methods","ArrayList and its Methods — Exercises","shockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F9.2-arraylist-and-its-methods",{"path":895,"title":896,"stem":897},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F3-optional-hashmap-dictionary-data-structure","HashMap (Dictionary) Data Structure — Exercises","shockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F9.3-optional-hashmap-dictionary-data-structure",{"path":899,"title":900,"stem":901},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F4-array-traversals","Array Traversals — Exercises","shockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F9.4-array-traversals",{"path":903,"title":904,"stem":905},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F5-implementing-array-algorithms","Implementing Array Algorithms — Exercises","shockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F9.5-implementing-array-algorithms",{"path":907,"title":908,"stem":909},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F6-arraylist-traversals","ArrayList Traversals — Exercises","shockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F9.6-arraylist-traversals",{"path":911,"title":912,"stem":913},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F7-implementing-arraylist-algorithms","Implementing ArrayList Algorithms — Exercises","shockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F9.7-implementing-arraylist-algorithms",{"path":915,"title":916,"stem":917},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F8-using-text-files","Using Text Files — Exercises","shockwave-curriculum\u002Fexercises\u002Fch09-storing-data\u002F9.8-using-text-files",{"path":919,"title":920,"stem":921},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch10-2d-arrays\u002F1-2d-array-creation-and-access","2D Array Creation and Access — Exercises","shockwave-curriculum\u002Fexercises\u002Fch10-2d-arrays\u002F10.1-2d-array-creation-and-access",{"path":923,"title":924,"stem":925},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch10-2d-arrays\u002F2-2d-array-traversals-nested-loops","2D Array Traversals: Nested Loops — Exercises","shockwave-curriculum\u002Fexercises\u002Fch10-2d-arrays\u002F10.2-2d-array-traversals-nested-loops",{"path":927,"title":928,"stem":929},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch10-2d-arrays\u002F3-implementing-2d-array-algorithms","Implementing 2D Array Algorithms — Exercises","shockwave-curriculum\u002Fexercises\u002Fch10-2d-arrays\u002F10.3-implementing-2d-array-algorithms",{"path":931,"title":932,"stem":933},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch11-enums-named-choices\u002F11-enums-named-choices","Enums: Named Choices — Exercises","shockwave-curriculum\u002Fexercises\u002Fch11-enums-named-choices\u002F11-enums-named-choices",{"path":935,"title":936,"stem":937},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch12-exceptions-and-try-catch\u002F12-exceptions-and-try-catch","Exceptions & try\u002Fcatch — Exercises","shockwave-curriculum\u002Fexercises\u002Fch12-exceptions-and-try-catch\u002F12-exceptions-and-try-catch",{"path":939,"title":940,"stem":941},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch13-common-gotchas\u002F13-common-gotchas","Common Gotchas — Exercises","shockwave-curriculum\u002Fexercises\u002Fch13-common-gotchas\u002F13-common-gotchas",{"path":943,"title":944,"stem":945},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch14-why-design-patterns\u002F14-why-design-patterns","Why Design Patterns? — Exercises","shockwave-curriculum\u002Fexercises\u002Fch14-why-design-patterns\u002F14-why-design-patterns",{"path":947,"title":948,"stem":949},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch15-advanced-collections\u002F15-advanced-collections","Advanced Collections (Set\u002FQueue\u002FMap) — Exercises","shockwave-curriculum\u002Fexercises\u002Fch15-advanced-collections\u002F15-advanced-collections",{"path":951,"title":952,"stem":953},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch16-writing-your-own-generics\u002F16-writing-your-own-generics","Writing Your Own Generics — Exercises","shockwave-curriculum\u002Fexercises\u002Fch16-writing-your-own-generics\u002F16-writing-your-own-generics",{"path":955,"title":956,"stem":957},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch17-inheritance-and-abstractions\u002F1-inheritance-superclass-subclass","Inheritance, Superclass, Subclass — Exercises","shockwave-curriculum\u002Fexercises\u002Fch17-inheritance-and-abstractions\u002F17.1-inheritance-superclass-subclass",{"path":959,"title":960,"stem":961},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch17-inheritance-and-abstractions\u002F2-inheritance-and-constructors","Inheritance and Constructors — Exercises","shockwave-curriculum\u002Fexercises\u002Fch17-inheritance-and-abstractions\u002F17.2-inheritance-and-constructors",{"path":963,"title":964,"stem":965},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch17-inheritance-and-abstractions\u002F3-inheritance-hierarchies","Inheritance Hierarchies — Exercises","shockwave-curriculum\u002Fexercises\u002Fch17-inheritance-and-abstractions\u002F17.3-inheritance-hierarchies",{"path":967,"title":968,"stem":969},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch17-inheritance-and-abstractions\u002F4-object-superclass","Object Superclass — Exercises","shockwave-curriculum\u002Fexercises\u002Fch17-inheritance-and-abstractions\u002F17.4-object-superclass",{"path":971,"title":972,"stem":973},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch17-inheritance-and-abstractions\u002F5-abstract-classes-and-methods","Abstract Classes and Methods — Exercises","shockwave-curriculum\u002Fexercises\u002Fch17-inheritance-and-abstractions\u002F17.5-abstract-classes-and-methods",{"path":975,"title":976,"stem":977},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch18-polymorphism-many-forms\u002F1-overriding-methods","Overriding Methods — Exercises","shockwave-curriculum\u002Fexercises\u002Fch18-polymorphism-many-forms\u002F18.1-overriding-methods",{"path":979,"title":980,"stem":981},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch18-polymorphism-many-forms\u002F2-super-keyword","super Keyword — Exercises","shockwave-curriculum\u002Fexercises\u002Fch18-polymorphism-many-forms\u002F18.2-super-keyword",{"path":983,"title":984,"stem":985},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch18-polymorphism-many-forms\u002F3-polymorphism","Polymorphism — Exercises","shockwave-curriculum\u002Fexercises\u002Fch18-polymorphism-many-forms\u002F18.3-polymorphism",{"path":987,"title":988,"stem":989},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch19-interfaces-as-contracts\u002F19-interfaces-as-contracts","Interfaces as Contracts — Exercises","shockwave-curriculum\u002Fexercises\u002Fch19-interfaces-as-contracts\u002F19-interfaces-as-contracts",{"path":991,"title":992,"stem":993},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch19-interfaces-as-contracts\u002F1-lambdas-and-method-references","Lambdas & Method References — Exercises","shockwave-curriculum\u002Fexercises\u002Fch19-interfaces-as-contracts\u002F19.1-lambdas-and-method-references",{"path":995,"title":996,"stem":997},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch20-the-io-layer-pattern\u002F20-the-io-layer-pattern","The IO-Layer Pattern — Exercises","shockwave-curriculum\u002Fexercises\u002Fch20-the-io-layer-pattern\u002F20-the-io-layer-pattern",{"path":999,"title":1000,"stem":1001},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch21-static-factories\u002F21-static-factories","Static Factories — Exercises","shockwave-curriculum\u002Fexercises\u002Fch21-static-factories\u002F21-static-factories",{"path":1003,"title":1004,"stem":1005},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch22-the-builder-pattern\u002F22-the-builder-pattern","The Builder Pattern — Exercises","shockwave-curriculum\u002Fexercises\u002Fch22-the-builder-pattern\u002F22-the-builder-pattern",{"path":1007,"title":1008,"stem":1009},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch23-encapsulation-and-final\u002F1-scope-and-access","Access, final, and Immutability — Exercises","shockwave-curriculum\u002Fexercises\u002Fch23-encapsulation-and-final\u002F23.1-scope-and-access",{"path":1011,"title":1012,"stem":1013},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch24-optional-avoiding-null-pointer-exceptions\u002F24-optional-avoiding-null-pointer-exceptions","Optional: Avoiding Null Pointer Exceptions — Exercises","shockwave-curriculum\u002Fexercises\u002Fch24-optional-avoiding-null-pointer-exceptions\u002F24-optional-avoiding-null-pointer-exceptions",{"path":1015,"title":1016,"stem":1017},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F1-what-is-command-based-programming","What Is Command-Based Programming? — Exercises","shockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F25.1-what-is-command-based-programming",{"path":1019,"title":1020,"stem":1021},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F2-commands-and-command-compositions","Commands & Command Compositions — Exercises","shockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F25.2-commands-and-command-compositions",{"path":1023,"title":1024,"stem":1025},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F3-the-command-scheduler","The Command Scheduler — Exercises","shockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F25.3-the-command-scheduler",{"path":1027,"title":1028,"stem":1029},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F4-state-machines-logic","State Machines: Logic — Exercises","shockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F25.4-state-machines-logic",{"path":1031,"title":1032,"stem":1033},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F5-managing-transitions","Managing Transitions — Exercises","shockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F25.5-managing-transitions",{"path":1035,"title":1036,"stem":1037},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F6-binding-commands-to-triggers","Binding Commands to Triggers — Exercises","shockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F25.6-binding-commands-to-triggers",{"path":1039,"title":1040,"stem":1041},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F7-structuring-a-command-based-robot-project","Structuring a Command-Based Robot Project — Exercises","shockwave-curriculum\u002Fexercises\u002Fch25-command-based-programming\u002F25.7-structuring-a-command-based-robot-project",{"path":1043,"title":1044,"stem":1045},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch26-architecture-takeaways\u002F26-architecture-takeaways","Architecture Takeaways — Exercises","shockwave-curriculum\u002Fexercises\u002Fch26-architecture-takeaways\u002F26-architecture-takeaways",{"path":1047,"title":1048,"stem":1049},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch27-program-design-and-abstraction\u002F1-abstraction-and-program-design","Abstraction and Program Design — Exercises","shockwave-curriculum\u002Fexercises\u002Fch27-program-design-and-abstraction\u002F27.1-abstraction-and-program-design",{"path":1051,"title":1052,"stem":1053},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch27-program-design-and-abstraction\u002F2-impact-of-program-design","Impact of Program Design — Exercises","shockwave-curriculum\u002Fexercises\u002Fch27-program-design-and-abstraction\u002F27.2-impact-of-program-design",{"path":1055,"title":1056,"stem":1057},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch28-algorithms-searching-sorting-recursion\u002F1-searching-algorithms","Searching Algorithms — Exercises","shockwave-curriculum\u002Fexercises\u002Fch28-algorithms-searching-sorting-recursion\u002F28.1-searching-algorithms",{"path":1059,"title":1060,"stem":1061},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch28-algorithms-searching-sorting-recursion\u002F2-sorting-algorithms","Sorting Algorithms — Exercises","shockwave-curriculum\u002Fexercises\u002Fch28-algorithms-searching-sorting-recursion\u002F28.2-sorting-algorithms",{"path":1063,"title":1064,"stem":1065},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch28-algorithms-searching-sorting-recursion\u002F3-recursion","Recursion — Exercises","shockwave-curriculum\u002Fexercises\u002Fch28-algorithms-searching-sorting-recursion\u002F28.3-recursion",{"path":1067,"title":1068,"stem":1069},"\u002Fshockwave-curriculum\u002Fexercises\u002Fch28-algorithms-searching-sorting-recursion\u002F4-recursive-searching-and-sorting","Recursive Searching and Sorting — Exercises","shockwave-curriculum\u002Fexercises\u002Fch28-algorithms-searching-sorting-recursion\u002F28.4-recursive-searching-and-sorting",{"id":1071,"title":250,"body":1072,"description":1082,"extension":1499,"meta":1500,"navigation":1214,"path":249,"seo":1503,"stem":251,"__hash__":1504},"lessons\u002Fshockwave-curriculum\u002Flessons\u002Fch20-the-io-layer-pattern\u002F20-the-io-layer-pattern.md",{"type":1073,"value":1074,"toc":1490},"minimark",[1075,1079,1083,1088,1101,1108,1112,1132,1173,1187,1238,1244,1248,1258,1316,1333,1337,1352,1367,1374,1378,1414,1418,1449,1453,1471,1486],[1076,1077,250],"h1",{"id":1078},"the-io-layer-pattern",[1080,1081,1082],"p",{},"Everything Ch.17-19 built — inheritance, polymorphism, and especially interfaces as contracts — comes together here in a real, widely-used FRC architecture pattern: keeping hardware access completely separate from the logic that uses it.",[1084,1085,1087],"h2",{"id":1086},"the-problem-hardware-everywhere-makes-testing-and-logging-hard","The Problem: Hardware Everywhere Makes Testing (and Logging) Hard",[1080,1089,1090,1091,1095,1096,1100],{},"A subsystem that talks directly to real motor controllers and sensors is genuinely hard to reason about: it can't run at all without the physical robot present, and there's no clean seam where you could intercept its data. A stronger idea than typical FRC logging solves this: instead of just logging a handful of chosen values, log ",[1092,1093,1094],"em",{},"every"," input flowing into the robot code, every loop cycle. Since every input is captured, a match can later be ",[1097,1098,1099],"strong",{},"replayed"," off the robot with the exact same inputs, running the exact same logic — turning logging from \"a tool for checking specific values\" into a genuine safety net for verifying how any part of the code actually behaved. A logging framework (Ch.33) can record and replay data structured this way.",[1080,1102,1103,1104,1107],{},"That capability only works if hardware access is structured so all input data flows through one well-defined seam. This is what the ",[1097,1105,1106],{},"IO layer"," is for.",[1084,1109,1111],{"id":1110},"three-layers-of-a-subsystem","Three Layers of a Subsystem",[1080,1113,1114,1115,1118,1119,1122,1123,1126,1127,1131],{},"Traditionally, an FRC subsystem mixes three concerns in one class: its ",[1097,1116,1117],{},"public interface"," (methods the rest of the robot calls), its ",[1097,1120,1121],{},"control logic"," (deciding what to do with sensor data), and its ",[1097,1124,1125],{},"hardware interface"," (actually reading sensors, actually commanding motors). The IO-Layer Pattern pulls that third piece out into its own object. (Commands v3, Ch.25, calls this kind of class a ",[1128,1129,1130],"code",{},"Mechanism"," — this chapter keeps calling it a \"subsystem,\" the term used across the pattern's whole history.)",[1133,1134,1139],"pre",{"className":1135,"code":1136,"language":1137,"meta":1138,"style":1138},"language-java shiki shiki-themes github-light github-dark","public interface IntakeIO\n{\n    void updateInputs(IntakeInputs inputs);\n    void setVoltage(double volts);\n}\n","java","",[1128,1140,1141,1149,1155,1161,1167],{"__ignoreMap":1138},[1142,1143,1146],"span",{"class":1144,"line":1145},"line",1,[1142,1147,1148],{},"public interface IntakeIO\n",[1142,1150,1152],{"class":1144,"line":1151},2,[1142,1153,1154],{},"{\n",[1142,1156,1158],{"class":1144,"line":1157},3,[1142,1159,1160],{},"    void updateInputs(IntakeInputs inputs);\n",[1142,1162,1164],{"class":1144,"line":1163},4,[1142,1165,1166],{},"    void setVoltage(double volts);\n",[1142,1168,1170],{"class":1144,"line":1169},5,[1142,1171,1172],{},"}\n",[1080,1174,1175,1178,1179,1182,1183,1186],{},[1128,1176,1177],{},"IntakeIO"," is exactly the kind of contract from Lesson 19 — it says ",[1092,1180,1181],{},"what"," an intake can do (report its inputs, accept a voltage command), without saying ",[1092,1184,1185],{},"how",". Both methods are abstract, since neither one has a sensible default: two real implementations honor this same contract, and each one genuinely needs its own body (each class below is in its own file):",[1133,1188,1190],{"className":1135,"code":1189,"language":1137,"meta":1138,"style":1138},"public class IntakeIOReal implements IntakeIO\n{\n    \u002F\u002F uses real hardware APIs to move physical rollers\n}\n\npublic class IntakeIOSim implements IntakeIO\n{\n    \u002F\u002F uses physics math (moment of inertia) to \"fake\" the robot in code\n}\n",[1128,1191,1192,1197,1201,1206,1210,1216,1222,1227,1233],{"__ignoreMap":1138},[1142,1193,1194],{"class":1144,"line":1145},[1142,1195,1196],{},"public class IntakeIOReal implements IntakeIO\n",[1142,1198,1199],{"class":1144,"line":1151},[1142,1200,1154],{},[1142,1202,1203],{"class":1144,"line":1157},[1142,1204,1205],{},"    \u002F\u002F uses real hardware APIs to move physical rollers\n",[1142,1207,1208],{"class":1144,"line":1163},[1142,1209,1172],{},[1142,1211,1212],{"class":1144,"line":1169},[1142,1213,1215],{"emptyLinePlaceholder":1214},true,"\n",[1142,1217,1219],{"class":1144,"line":1218},6,[1142,1220,1221],{},"public class IntakeIOSim implements IntakeIO\n",[1142,1223,1225],{"class":1144,"line":1224},7,[1142,1226,1154],{},[1142,1228,1230],{"class":1144,"line":1229},8,[1142,1231,1232],{},"    \u002F\u002F uses physics math (moment of inertia) to \"fake\" the robot in code\n",[1142,1234,1236],{"class":1144,"line":1235},9,[1142,1237,1172],{},[1080,1239,1240,1241,1243],{},"The subsystem class itself only ever talks to the ",[1128,1242,1177],{}," interface — it never knows, and never needs to know, which concrete implementation is actually running underneath.",[1084,1245,1247],{"id":1246},"choosing-the-implementation-once-at-construction","Choosing the Implementation Once, at Construction",[1080,1249,1250,1251,1254,1255,1257],{},"The whole point is decided in exactly one place — typically the ",[1128,1252,1253],{},"Robot"," constructor, at startup — by simply constructing the subsystem with a different ",[1128,1256,1177],{}," implementation depending on whether the code is running on the real robot or in simulation:",[1133,1259,1261],{"className":1135,"code":1260,"language":1137,"meta":1138,"style":1138},"public Robot()\n{\n    if (RobotBase.isReal())\n    {\n        intake = new Intake(new IntakeIOReal());\n    }\n    else\n    {\n        intake = new Intake(new IntakeIOSim());\n    }\n}\n",[1128,1262,1263,1268,1272,1277,1282,1287,1292,1297,1301,1306,1311],{"__ignoreMap":1138},[1142,1264,1265],{"class":1144,"line":1145},[1142,1266,1267],{},"public Robot()\n",[1142,1269,1270],{"class":1144,"line":1151},[1142,1271,1154],{},[1142,1273,1274],{"class":1144,"line":1157},[1142,1275,1276],{},"    if (RobotBase.isReal())\n",[1142,1278,1279],{"class":1144,"line":1163},[1142,1280,1281],{},"    {\n",[1142,1283,1284],{"class":1144,"line":1169},[1142,1285,1286],{},"        intake = new Intake(new IntakeIOReal());\n",[1142,1288,1289],{"class":1144,"line":1218},[1142,1290,1291],{},"    }\n",[1142,1293,1294],{"class":1144,"line":1224},[1142,1295,1296],{},"    else\n",[1142,1298,1299],{"class":1144,"line":1229},[1142,1300,1281],{},[1142,1302,1303],{"class":1144,"line":1235},[1142,1304,1305],{},"        intake = new Intake(new IntakeIOSim());\n",[1142,1307,1309],{"class":1144,"line":1308},10,[1142,1310,1291],{},[1142,1312,1314],{"class":1144,"line":1313},11,[1142,1315,1172],{},[1080,1317,1318,1321,1322,1325,1326,1329,1330,1332],{},[1128,1319,1320],{},"RobotBase.isReal()"," (from ",[1128,1323,1324],{},"org.wpilib.framework",") is the actual check that's true only when the code is running on real SystemCore hardware. ",[1128,1327,1328],{},"Intake"," (the subsystem) accepts an ",[1128,1331,1177],{}," in its constructor and stores it — every call from then on goes through that reference, polymorphically (Lesson 18.3) dispatching to whichever implementation was actually supplied.",[1084,1334,1336],{"id":1335},"inputs-flow-through-a-shared-object","Inputs Flow Through a Shared Object",[1080,1338,1339,1340,1343,1344,1347,1348,1351],{},"Outputs (commands like ",[1128,1341,1342],{},"setVoltage",") are simple, one-way method calls. Inputs are handled more carefully, since they need to be read consistently ",[1092,1345,1346],{},"and"," stay replayable later: each IO interface has an accompanying inputs class holding ",[1097,1349,1350],{},"public"," fields for every value that comes off the hardware — a plain data holder with no logic of its own, so it's an intentional exception to the private-field style taught since Ch.7 (Lesson 7.1):",[1133,1353,1355],{"className":1135,"code":1354,"language":1137,"meta":1138,"style":1138},"\u002F\u002F pull fresh data from the IO layer into `inputs`, once per cycle\nio.updateInputs(inputs);\n",[1128,1356,1357,1362],{"__ignoreMap":1138},[1142,1358,1359],{"class":1144,"line":1145},[1142,1360,1361],{},"\u002F\u002F pull fresh data from the IO layer into `inputs`, once per cycle\n",[1142,1363,1364],{"class":1144,"line":1151},[1142,1365,1366],{},"io.updateInputs(inputs);\n",[1080,1368,1369,1370,1373],{},"The rest of the subsystem then reads from the ",[1128,1371,1372],{},"inputs"," object — never straight from the IO layer — for a critical reason: every piece of code within one loop cycle sees the exact same cached values, so the logic feeds off exactly the same numbers a replay later would see, instead of whatever the hardware happens to report at the exact instant each line runs.",[1084,1375,1377],{"id":1376},"the-general-pattern-behind-this-ports-and-adapters","The General Pattern Behind This: Ports and Adapters",[1080,1379,1380,1381,1384,1385,1388,1389,1392,1393,1395,1396,1399,1400,1403,1404,1407,1408,1410,1411,1413],{},"This isn't an FRC-specific trick — it's a specific application of a broader, well-known software architecture idea called ",[1097,1382,1383],{},"Hexagonal Architecture"," (or ",[1097,1386,1387],{},"Ports and Adapters","): keep core logic decoupled from whatever external system it happens to talk to (a database, a UI, real hardware), by defining a ",[1097,1390,1391],{},"port"," (the interface — ",[1128,1394,1177],{},") that any number of ",[1097,1397,1398],{},"adapters"," (",[1128,1401,1402],{},"IntakeIOReal",", ",[1128,1405,1406],{},"IntakeIOSim",") can plug into. The core logic only ever depends on the port, never on any specific adapter — exactly mirroring ",[1128,1409,1328],{}," only ever depending on ",[1128,1412,1177],{},". The tradeoff is real: it's more abstraction and more files than talking to hardware directly, which is overkill for a one-off script — but it pays for itself the moment testability, simulation, or swappable hardware actually matter, which for a competition robot, they do.",[1084,1415,1417],{"id":1416},"common-pitfalls","Common Pitfalls",[1419,1420,1421,1428,1443],"ul",{},[1422,1423,1424,1427],"li",{},[1097,1425,1426],{},"Letting the subsystem read hardware directly, bypassing the IO layer."," That reintroduces exactly the coupling the pattern exists to remove — no sim support, no clean replay.",[1422,1429,1430,1433,1434,1436,1437,1439,1440,1442],{},[1097,1431,1432],{},"Adding getters to the IO interface and calling them from the subsystem's logic, instead of reading the cached inputs object."," ",[1128,1435,1177],{}," itself has nothing to read — but as soon as an implementation grows one, reaching for it directly instead of ",[1128,1438,1372],{}," reintroduces values that can change mid-cycle in ways a replayed log never could — always read from ",[1128,1441,1372],{},".",[1422,1444,1445,1448],{},[1097,1446,1447],{},"Treating the IO layer as optional overhead on a small subsystem."," It's genuinely more files and more ceremony — but the payoff (simulation, replay, decoupled testing) is exactly why competitive FRC codebases use it anyway.",[1084,1450,1452],{"id":1451},"key-takeaways","Key Takeaways",[1419,1454,1455,1458,1461,1468],{},[1422,1456,1457],{},"The IO-Layer Pattern separates a subsystem's hardware access into its own interface (the \"IO\" layer), so the subsystem's own logic never touches real hardware APIs directly.",[1422,1459,1460],{},"One interface, multiple implementations (real hardware vs. simulated), chosen once at construction — everything else dispatches polymorphically through the shared interface.",[1422,1462,1463,1464,1467],{},"Inputs flow through a dedicated, shared object (",[1128,1465,1466],{},"updateInputs",", called once per cycle), so every piece of logic in that cycle reads the exact same snapshot — the structure a logging framework (Ch.33) needs to record and replay a match later.",[1422,1469,1470],{},"This is FRC's specific application of the general Hexagonal Architecture (Ports and Adapters) pattern: core logic depends only on a port (interface), never on a specific adapter (implementation).",[1080,1472,1473,1474,1477,1478,1481,1482,1485],{},"Derived from ",[1128,1475,1476],{},"other-reference-repo",": ",[1128,1479,1480],{},"java-design-patterns\u002Fhexagonal-architecture.md"," (JDP 50.1)\n",[1097,1483,1484],{},"Deck context:"," mechacoder-test\u002Fsrc\u002Flessons\u002Fjava-2.js, slide 7 (\"The IO-Layer Pattern\") — IntakeIOReal\u002FIntakeIOSim example",[1487,1488,1489],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":1138,"searchDepth":1151,"depth":1151,"links":1491},[1492,1493,1494,1495,1496,1497,1498],{"id":1086,"depth":1151,"text":1087},{"id":1110,"depth":1151,"text":1111},{"id":1246,"depth":1151,"text":1247},{"id":1335,"depth":1151,"text":1336},{"id":1376,"depth":1151,"text":1377},{"id":1416,"depth":1151,"text":1417},{"id":1451,"depth":1151,"text":1452},"md",{"outlineRef":1501,"status":1502},"20 — The IO-Layer Pattern (ADVKIT 40.1-11, JDP 50.1)","new — authored lesson (fuller depth than the teaser slide)",{"title":250,"description":1082},"tZvU33Jxd7_OtJg2WIM4L0KAnUCqhqqZcWC7MzRAZYY",{"id":1506,"title":683,"body":1507,"description":1138,"extension":1499,"meta":2791,"navigation":1214,"path":682,"seo":2794,"stem":684,"__hash__":2795},"examples\u002Fshockwave-curriculum\u002Fexamples\u002Fch20-the-io-layer-pattern\u002F20-the-io-layer-pattern.md",{"type":1073,"value":1508,"toc":2778},[1509,1512,1516,1519,1523,1552,1556,1559,1587,1590,1594,1621,1633,1637,1640,1710,1716,1809,1819,1823,1953,1956,1999,2003,2105,2137,2141,2159,2618,2622,2630,2633,2687,2700,2704,2731,2735,2776],[1076,1510,683],{"id":1511},"the-io-layer-pattern-worked-example",[1084,1513,1515],{"id":1514},"problem","Problem",[1080,1517,1518],{},"The robot's climber needs to raise itself until it reaches 0.6 m, then stop. The programming team wants to test that \"climb until 0.6 m\" logic on a laptop, with no robot attached, and then run exactly the same logic on the real robot later. Structure the climber with an IO layer so the climbing logic never touches hardware directly.",[1084,1520,1522],{"id":1521},"step-1-plan-it-first","Step 1: Plan It First",[1524,1525,1526,1529,1536,1539,1549],"ol",{},[1422,1527,1528],{},"Write an inputs class holding every value that comes off the climber's hardware.",[1422,1530,1531,1532,1535],{},"Write a ",[1128,1533,1534],{},"ClimberIO"," interface: the contract for \"report inputs\" and \"accept a voltage.\"",[1422,1537,1538],{},"Write two implementations of that contract: one for the real robot, one simulated.",[1422,1540,1541,1542,1545,1546,1548],{},"Write the ",[1128,1543,1544],{},"Climber"," subsystem so it only ever talks to ",[1128,1547,1534],{}," and only ever reads from its cached inputs.",[1422,1550,1551],{},"Pick the implementation once, at construction, then run a few loop cycles.",[1084,1553,1555],{"id":1554},"step-2-the-inputs-class","Step 2: The Inputs Class",[1080,1557,1558],{},"Every value the climber's hardware reports goes into one object with public fields:",[1133,1560,1562],{"className":1135,"code":1561,"language":1137,"meta":1138,"style":1138},"class ClimberInputs\n{\n    public double positionMeters = 0.0;\n    public double appliedVolts = 0.0;\n}\n",[1128,1563,1564,1569,1573,1578,1583],{"__ignoreMap":1138},[1142,1565,1566],{"class":1144,"line":1145},[1142,1567,1568],{},"class ClimberInputs\n",[1142,1570,1571],{"class":1144,"line":1151},[1142,1572,1154],{},[1142,1574,1575],{"class":1144,"line":1157},[1142,1576,1577],{},"    public double positionMeters = 0.0;\n",[1142,1579,1580],{"class":1144,"line":1163},[1142,1581,1582],{},"    public double appliedVolts = 0.0;\n",[1142,1584,1585],{"class":1144,"line":1169},[1142,1586,1172],{},[1080,1588,1589],{},"This is the object the rest of the subsystem reads from. (A logging framework, Ch.33, can record and replay a class shaped like this. This example leaves logging out and focuses on the structure.)",[1084,1591,1593],{"id":1592},"step-3-the-io-interface-the-port","Step 3: The IO Interface (the \"Port\")",[1133,1595,1597],{"className":1135,"code":1596,"language":1137,"meta":1138,"style":1138},"interface ClimberIO\n{\n    void updateInputs(ClimberInputs inputs);\n    void setVoltage(double volts);\n}\n",[1128,1598,1599,1604,1608,1613,1617],{"__ignoreMap":1138},[1142,1600,1601],{"class":1144,"line":1145},[1142,1602,1603],{},"interface ClimberIO\n",[1142,1605,1606],{"class":1144,"line":1151},[1142,1607,1154],{},[1142,1609,1610],{"class":1144,"line":1157},[1142,1611,1612],{},"    void updateInputs(ClimberInputs inputs);\n",[1142,1614,1615],{"class":1144,"line":1163},[1142,1616,1166],{},[1142,1618,1619],{"class":1144,"line":1169},[1142,1620,1172],{},[1080,1622,1623,1624,1626,1627,1629,1630,1632],{},"Just like the lesson's ",[1128,1625,1177],{},", this says ",[1092,1628,1181],{}," a climber can do and nothing about ",[1092,1631,1185],{},". Both methods are abstract (Lesson 19) — neither has a sensible default, since both real implementations below need their own body anyway.",[1084,1634,1636],{"id":1635},"step-4-two-implementations-the-adapters","Step 4: Two Implementations (the \"Adapters\")",[1080,1638,1639],{},"The real-robot version is where the actual motor controller and encoder calls would go. This laptop has no climber attached, so its bodies just print what they would do:",[1133,1641,1643],{"className":1135,"code":1642,"language":1137,"meta":1138,"style":1138},"class ClimberIOReal implements ClimberIO\n{\n    @Override\n    public void updateInputs(ClimberInputs inputs)\n    {\n        System.out.println(\"[real] would read the climber encoder here\");\n    }\n\n    @Override\n    public void setVoltage(double volts)\n    {\n        System.out.println(\"[real] would send \" + volts + \" V to the climber motor here\");\n    }\n}\n",[1128,1644,1645,1650,1654,1659,1664,1668,1673,1677,1681,1685,1690,1694,1700,1705],{"__ignoreMap":1138},[1142,1646,1647],{"class":1144,"line":1145},[1142,1648,1649],{},"class ClimberIOReal implements ClimberIO\n",[1142,1651,1652],{"class":1144,"line":1151},[1142,1653,1154],{},[1142,1655,1656],{"class":1144,"line":1157},[1142,1657,1658],{},"    @Override\n",[1142,1660,1661],{"class":1144,"line":1163},[1142,1662,1663],{},"    public void updateInputs(ClimberInputs inputs)\n",[1142,1665,1666],{"class":1144,"line":1169},[1142,1667,1281],{},[1142,1669,1670],{"class":1144,"line":1218},[1142,1671,1672],{},"        System.out.println(\"[real] would read the climber encoder here\");\n",[1142,1674,1675],{"class":1144,"line":1224},[1142,1676,1291],{},[1142,1678,1679],{"class":1144,"line":1229},[1142,1680,1215],{"emptyLinePlaceholder":1214},[1142,1682,1683],{"class":1144,"line":1235},[1142,1684,1658],{},[1142,1686,1687],{"class":1144,"line":1308},[1142,1688,1689],{},"    public void setVoltage(double volts)\n",[1142,1691,1692],{"class":1144,"line":1313},[1142,1693,1281],{},[1142,1695,1697],{"class":1144,"line":1696},12,[1142,1698,1699],{},"        System.out.println(\"[real] would send \" + volts + \" V to the climber motor here\");\n",[1142,1701,1703],{"class":1144,"line":1702},13,[1142,1704,1291],{},[1142,1706,1708],{"class":1144,"line":1707},14,[1142,1709,1172],{},[1080,1711,1712,1713,1715],{},"The simulated version fakes the physics with simple math. It remembers the last voltage it was given, and every time ",[1128,1714,1466],{}," runs it moves the climber a little and copies the results into the inputs object:",[1133,1717,1719],{"className":1135,"code":1718,"language":1137,"meta":1138,"style":1138},"class ClimberIOSim implements ClimberIO\n{\n    private double simPosition = 0.0;\n    private double simVolts = 0.0;\n\n    @Override\n    public void updateInputs(ClimberInputs inputs)\n    {\n        simPosition = simPosition + simVolts \u002F 32.0; \u002F\u002F fake physics: 8 V moves the climber 0.25 m per cycle\n        inputs.positionMeters = simPosition;\n        inputs.appliedVolts = simVolts;\n    }\n\n    @Override\n    public void setVoltage(double volts)\n    {\n        simVolts = volts;\n    }\n}\n",[1128,1720,1721,1726,1730,1735,1740,1744,1748,1752,1756,1761,1766,1771,1775,1779,1783,1788,1793,1799,1804],{"__ignoreMap":1138},[1142,1722,1723],{"class":1144,"line":1145},[1142,1724,1725],{},"class ClimberIOSim implements ClimberIO\n",[1142,1727,1728],{"class":1144,"line":1151},[1142,1729,1154],{},[1142,1731,1732],{"class":1144,"line":1157},[1142,1733,1734],{},"    private double simPosition = 0.0;\n",[1142,1736,1737],{"class":1144,"line":1163},[1142,1738,1739],{},"    private double simVolts = 0.0;\n",[1142,1741,1742],{"class":1144,"line":1169},[1142,1743,1215],{"emptyLinePlaceholder":1214},[1142,1745,1746],{"class":1144,"line":1218},[1142,1747,1658],{},[1142,1749,1750],{"class":1144,"line":1224},[1142,1751,1663],{},[1142,1753,1754],{"class":1144,"line":1229},[1142,1755,1281],{},[1142,1757,1758],{"class":1144,"line":1235},[1142,1759,1760],{},"        simPosition = simPosition + simVolts \u002F 32.0; \u002F\u002F fake physics: 8 V moves the climber 0.25 m per cycle\n",[1142,1762,1763],{"class":1144,"line":1308},[1142,1764,1765],{},"        inputs.positionMeters = simPosition;\n",[1142,1767,1768],{"class":1144,"line":1313},[1142,1769,1770],{},"        inputs.appliedVolts = simVolts;\n",[1142,1772,1773],{"class":1144,"line":1696},[1142,1774,1291],{},[1142,1776,1777],{"class":1144,"line":1702},[1142,1778,1215],{"emptyLinePlaceholder":1214},[1142,1780,1781],{"class":1144,"line":1707},[1142,1782,1658],{},[1142,1784,1786],{"class":1144,"line":1785},15,[1142,1787,1689],{},[1142,1789,1791],{"class":1144,"line":1790},16,[1142,1792,1281],{},[1142,1794,1796],{"class":1144,"line":1795},17,[1142,1797,1798],{},"        simVolts = volts;\n",[1142,1800,1802],{"class":1144,"line":1801},18,[1142,1803,1291],{},[1142,1805,1807],{"class":1144,"line":1806},19,[1142,1808,1172],{},[1080,1810,1811,1812,1815,1816,1818],{},"Both classes ",[1128,1813,1814],{},"implements ClimberIO",", so anywhere a ",[1128,1817,1534],{}," is expected, either one fits.",[1084,1820,1822],{"id":1821},"step-5-the-subsystem-only-knows-the-interface","Step 5: The Subsystem Only Knows the Interface",[1133,1824,1826],{"className":1135,"code":1825,"language":1137,"meta":1138,"style":1138},"class Climber\n{\n    private ClimberIO io;\n    private ClimberInputs inputs = new ClimberInputs();\n\n    public Climber(ClimberIO io)\n    {\n        this.io = io;\n    }\n\n    public void periodic()\n    {\n        io.updateInputs(inputs); \u002F\u002F refresh the cached inputs once, at the start of the cycle\n\n        System.out.println(\"Position: \" + inputs.positionMeters + \" m, volts: \" + inputs.appliedVolts);\n\n        if (inputs.positionMeters \u003C 0.6)\n        {\n            io.setVoltage(8.0); \u002F\u002F still below the target height: keep climbing\n        }\n        else\n        {\n            io.setVoltage(0.0); \u002F\u002F reached the target height: stop\n        }\n    }\n}\n",[1128,1827,1828,1833,1837,1842,1847,1851,1856,1860,1865,1869,1873,1878,1882,1887,1891,1896,1900,1905,1910,1915,1921,1927,1932,1938,1943,1948],{"__ignoreMap":1138},[1142,1829,1830],{"class":1144,"line":1145},[1142,1831,1832],{},"class Climber\n",[1142,1834,1835],{"class":1144,"line":1151},[1142,1836,1154],{},[1142,1838,1839],{"class":1144,"line":1157},[1142,1840,1841],{},"    private ClimberIO io;\n",[1142,1843,1844],{"class":1144,"line":1163},[1142,1845,1846],{},"    private ClimberInputs inputs = new ClimberInputs();\n",[1142,1848,1849],{"class":1144,"line":1169},[1142,1850,1215],{"emptyLinePlaceholder":1214},[1142,1852,1853],{"class":1144,"line":1218},[1142,1854,1855],{},"    public Climber(ClimberIO io)\n",[1142,1857,1858],{"class":1144,"line":1224},[1142,1859,1281],{},[1142,1861,1862],{"class":1144,"line":1229},[1142,1863,1864],{},"        this.io = io;\n",[1142,1866,1867],{"class":1144,"line":1235},[1142,1868,1291],{},[1142,1870,1871],{"class":1144,"line":1308},[1142,1872,1215],{"emptyLinePlaceholder":1214},[1142,1874,1875],{"class":1144,"line":1313},[1142,1876,1877],{},"    public void periodic()\n",[1142,1879,1880],{"class":1144,"line":1696},[1142,1881,1281],{},[1142,1883,1884],{"class":1144,"line":1702},[1142,1885,1886],{},"        io.updateInputs(inputs); \u002F\u002F refresh the cached inputs once, at the start of the cycle\n",[1142,1888,1889],{"class":1144,"line":1707},[1142,1890,1215],{"emptyLinePlaceholder":1214},[1142,1892,1893],{"class":1144,"line":1785},[1142,1894,1895],{},"        System.out.println(\"Position: \" + inputs.positionMeters + \" m, volts: \" + inputs.appliedVolts);\n",[1142,1897,1898],{"class":1144,"line":1790},[1142,1899,1215],{"emptyLinePlaceholder":1214},[1142,1901,1902],{"class":1144,"line":1795},[1142,1903,1904],{},"        if (inputs.positionMeters \u003C 0.6)\n",[1142,1906,1907],{"class":1144,"line":1801},[1142,1908,1909],{},"        {\n",[1142,1911,1912],{"class":1144,"line":1806},[1142,1913,1914],{},"            io.setVoltage(8.0); \u002F\u002F still below the target height: keep climbing\n",[1142,1916,1918],{"class":1144,"line":1917},20,[1142,1919,1920],{},"        }\n",[1142,1922,1924],{"class":1144,"line":1923},21,[1142,1925,1926],{},"        else\n",[1142,1928,1930],{"class":1144,"line":1929},22,[1142,1931,1909],{},[1142,1933,1935],{"class":1144,"line":1934},23,[1142,1936,1937],{},"            io.setVoltage(0.0); \u002F\u002F reached the target height: stop\n",[1142,1939,1941],{"class":1144,"line":1940},24,[1142,1942,1920],{},[1142,1944,1946],{"class":1144,"line":1945},25,[1142,1947,1291],{},[1142,1949,1951],{"class":1144,"line":1950},26,[1142,1952,1172],{},[1080,1954,1955],{},"Two things to notice:",[1419,1957,1958,1983],{},[1422,1959,1960,1961,1964,1965,1967,1968,1970,1971,1974,1975,1978,1979,1982],{},"The field ",[1128,1962,1963],{},"io"," has type ",[1128,1966,1534],{},", the interface. Nothing in ",[1128,1969,1544],{}," mentions ",[1128,1972,1973],{},"ClimberIOReal"," or ",[1128,1976,1977],{},"ClimberIOSim",". Each ",[1128,1980,1981],{},"io.setVoltage(...)"," call dispatches polymorphically (Lesson 18.3) to whichever implementation was passed into the constructor.",[1422,1984,1985,1988,1989,1992,1993,1995,1996,1998],{},[1128,1986,1987],{},"periodic()"," calls ",[1128,1990,1991],{},"io.updateInputs(inputs)"," exactly once, first, and then every decision reads from ",[1128,1994,1372],{},", never from ",[1128,1997,1963],{}," directly. That's the lesson's \"read from the cached inputs\" rule: every line in this cycle sees the same values.",[1084,2000,2002],{"id":2001},"step-6-choose-the-implementation-once-at-construction","Step 6: Choose the Implementation Once, at Construction",[1133,2004,2006],{"className":1135,"code":2005,"language":1137,"meta":1138,"style":1138},"public class ClimberDemo\n{\n    public static void main(String[] args)\n    {\n        boolean runningOnRobot = false; \u002F\u002F stand-in for the real \"am I on the robot?\" check\n\n        Climber climber;\n        if (runningOnRobot)\n        {\n            climber = new Climber(new ClimberIOReal());\n        }\n        else\n        {\n            climber = new Climber(new ClimberIOSim());\n        }\n\n        for (int cycle = 1; cycle \u003C= 5; cycle++)\n        {\n            climber.periodic();\n        }\n    }\n}\n",[1128,2007,2008,2013,2017,2022,2026,2031,2035,2040,2045,2049,2054,2058,2062,2066,2071,2075,2079,2084,2088,2093,2097,2101],{"__ignoreMap":1138},[1142,2009,2010],{"class":1144,"line":1145},[1142,2011,2012],{},"public class ClimberDemo\n",[1142,2014,2015],{"class":1144,"line":1151},[1142,2016,1154],{},[1142,2018,2019],{"class":1144,"line":1157},[1142,2020,2021],{},"    public static void main(String[] args)\n",[1142,2023,2024],{"class":1144,"line":1163},[1142,2025,1281],{},[1142,2027,2028],{"class":1144,"line":1169},[1142,2029,2030],{},"        boolean runningOnRobot = false; \u002F\u002F stand-in for the real \"am I on the robot?\" check\n",[1142,2032,2033],{"class":1144,"line":1218},[1142,2034,1215],{"emptyLinePlaceholder":1214},[1142,2036,2037],{"class":1144,"line":1224},[1142,2038,2039],{},"        Climber climber;\n",[1142,2041,2042],{"class":1144,"line":1229},[1142,2043,2044],{},"        if (runningOnRobot)\n",[1142,2046,2047],{"class":1144,"line":1235},[1142,2048,1909],{},[1142,2050,2051],{"class":1144,"line":1308},[1142,2052,2053],{},"            climber = new Climber(new ClimberIOReal());\n",[1142,2055,2056],{"class":1144,"line":1313},[1142,2057,1920],{},[1142,2059,2060],{"class":1144,"line":1696},[1142,2061,1926],{},[1142,2063,2064],{"class":1144,"line":1702},[1142,2065,1909],{},[1142,2067,2068],{"class":1144,"line":1707},[1142,2069,2070],{},"            climber = new Climber(new ClimberIOSim());\n",[1142,2072,2073],{"class":1144,"line":1785},[1142,2074,1920],{},[1142,2076,2077],{"class":1144,"line":1790},[1142,2078,1215],{"emptyLinePlaceholder":1214},[1142,2080,2081],{"class":1144,"line":1795},[1142,2082,2083],{},"        for (int cycle = 1; cycle \u003C= 5; cycle++)\n",[1142,2085,2086],{"class":1144,"line":1801},[1142,2087,1909],{},[1142,2089,2090],{"class":1144,"line":1806},[1142,2091,2092],{},"            climber.periodic();\n",[1142,2094,2095],{"class":1144,"line":1917},[1142,2096,1920],{},[1142,2098,2099],{"class":1144,"line":1923},[1142,2100,1291],{},[1142,2102,2103],{"class":1144,"line":1929},[1142,2104,1172],{},[1080,2106,2107,2108,2111,2112,2115,2116,2118,2119,2122,2123,2126,2127,2129,2130,2133,2134,2136],{},"This ",[1128,2109,2110],{},"if","\u002F",[1128,2113,2114],{},"else"," plays the same role as the lesson's ",[1128,2117,1253],{}," constructor: it's the one and only place that decides real vs. simulated. ",[1128,2120,2121],{},"runningOnRobot"," is hardcoded to ",[1128,2124,2125],{},"false"," here as a stand-in for the lesson's ",[1128,2128,1320],{}," check. The ",[1128,2131,2132],{},"for"," loop stands in for the robot calling ",[1128,2135,1987],{}," once per loop cycle.",[1084,2138,2140],{"id":2139},"step-7-the-whole-program","Step 7: The Whole Program",[1080,2142,2143,2144,2147,2148,2150,2151,2154,2155,2158],{},"All five pieces go in one file. Only ",[1128,2145,2146],{},"ClimberDemo"," is ",[1128,2149,1350],{},", since it holds ",[1128,2152,2153],{},"main"," — it comes first in the file (on Java 17, ",[1128,2156,2157],{},"java File.java"," source-launch only runs the first class in the file; Java 25 is more lenient, but leading with the public class works on both):",[1133,2160,2162],{"className":1135,"code":2161,"language":1137,"meta":1138,"style":1138},"public class ClimberDemo\n{\n    public static void main(String[] args)\n    {\n        boolean runningOnRobot = false; \u002F\u002F stand-in for the real \"am I on the robot?\" check\n\n        Climber climber;\n        if (runningOnRobot)\n        {\n            climber = new Climber(new ClimberIOReal());\n        }\n        else\n        {\n            climber = new Climber(new ClimberIOSim());\n        }\n\n        for (int cycle = 1; cycle \u003C= 5; cycle++)\n        {\n            climber.periodic();\n        }\n    }\n}\n\nclass ClimberInputs\n{\n    public double positionMeters = 0.0;\n    public double appliedVolts = 0.0;\n}\n\ninterface ClimberIO\n{\n    void updateInputs(ClimberInputs inputs);\n    void setVoltage(double volts);\n}\n\nclass ClimberIOReal implements ClimberIO\n{\n    @Override\n    public void updateInputs(ClimberInputs inputs)\n    {\n        System.out.println(\"[real] would read the climber encoder here\");\n    }\n\n    @Override\n    public void setVoltage(double volts)\n    {\n        System.out.println(\"[real] would send \" + volts + \" V to the climber motor here\");\n    }\n}\n\nclass ClimberIOSim implements ClimberIO\n{\n    private double simPosition = 0.0;\n    private double simVolts = 0.0;\n\n    @Override\n    public void updateInputs(ClimberInputs inputs)\n    {\n        simPosition = simPosition + simVolts \u002F 32.0; \u002F\u002F fake physics: 8 V moves the climber 0.25 m per cycle\n        inputs.positionMeters = simPosition;\n        inputs.appliedVolts = simVolts;\n    }\n\n    @Override\n    public void setVoltage(double volts)\n    {\n        simVolts = volts;\n    }\n}\n\nclass Climber\n{\n    private ClimberIO io;\n    private ClimberInputs inputs = new ClimberInputs();\n\n    public Climber(ClimberIO io)\n    {\n        this.io = io;\n    }\n\n    public void periodic()\n    {\n        io.updateInputs(inputs); \u002F\u002F refresh the cached inputs once, at the start of the cycle\n\n        System.out.println(\"Position: \" + inputs.positionMeters + \" m, volts: \" + inputs.appliedVolts);\n\n        if (inputs.positionMeters \u003C 0.6)\n        {\n            io.setVoltage(8.0); \u002F\u002F still below the target height: keep climbing\n        }\n        else\n        {\n            io.setVoltage(0.0); \u002F\u002F reached the target height: stop\n        }\n    }\n}\n",[1128,2163,2164,2168,2172,2176,2180,2184,2188,2192,2196,2200,2204,2208,2212,2216,2220,2224,2228,2232,2236,2240,2244,2248,2252,2256,2260,2264,2268,2273,2278,2283,2288,2293,2298,2303,2308,2313,2318,2323,2328,2333,2338,2343,2348,2353,2358,2363,2368,2373,2378,2383,2388,2393,2398,2403,2408,2413,2418,2423,2428,2433,2438,2443,2448,2453,2458,2463,2468,2473,2478,2483,2488,2493,2498,2503,2508,2513,2518,2523,2528,2533,2538,2543,2548,2553,2558,2563,2568,2573,2578,2583,2588,2593,2598,2603,2608,2613],{"__ignoreMap":1138},[1142,2165,2166],{"class":1144,"line":1145},[1142,2167,2012],{},[1142,2169,2170],{"class":1144,"line":1151},[1142,2171,1154],{},[1142,2173,2174],{"class":1144,"line":1157},[1142,2175,2021],{},[1142,2177,2178],{"class":1144,"line":1163},[1142,2179,1281],{},[1142,2181,2182],{"class":1144,"line":1169},[1142,2183,2030],{},[1142,2185,2186],{"class":1144,"line":1218},[1142,2187,1215],{"emptyLinePlaceholder":1214},[1142,2189,2190],{"class":1144,"line":1224},[1142,2191,2039],{},[1142,2193,2194],{"class":1144,"line":1229},[1142,2195,2044],{},[1142,2197,2198],{"class":1144,"line":1235},[1142,2199,1909],{},[1142,2201,2202],{"class":1144,"line":1308},[1142,2203,2053],{},[1142,2205,2206],{"class":1144,"line":1313},[1142,2207,1920],{},[1142,2209,2210],{"class":1144,"line":1696},[1142,2211,1926],{},[1142,2213,2214],{"class":1144,"line":1702},[1142,2215,1909],{},[1142,2217,2218],{"class":1144,"line":1707},[1142,2219,2070],{},[1142,2221,2222],{"class":1144,"line":1785},[1142,2223,1920],{},[1142,2225,2226],{"class":1144,"line":1790},[1142,2227,1215],{"emptyLinePlaceholder":1214},[1142,2229,2230],{"class":1144,"line":1795},[1142,2231,2083],{},[1142,2233,2234],{"class":1144,"line":1801},[1142,2235,1909],{},[1142,2237,2238],{"class":1144,"line":1806},[1142,2239,2092],{},[1142,2241,2242],{"class":1144,"line":1917},[1142,2243,1920],{},[1142,2245,2246],{"class":1144,"line":1923},[1142,2247,1291],{},[1142,2249,2250],{"class":1144,"line":1929},[1142,2251,1172],{},[1142,2253,2254],{"class":1144,"line":1934},[1142,2255,1215],{"emptyLinePlaceholder":1214},[1142,2257,2258],{"class":1144,"line":1940},[1142,2259,1568],{},[1142,2261,2262],{"class":1144,"line":1945},[1142,2263,1154],{},[1142,2265,2266],{"class":1144,"line":1950},[1142,2267,1577],{},[1142,2269,2271],{"class":1144,"line":2270},27,[1142,2272,1582],{},[1142,2274,2276],{"class":1144,"line":2275},28,[1142,2277,1172],{},[1142,2279,2281],{"class":1144,"line":2280},29,[1142,2282,1215],{"emptyLinePlaceholder":1214},[1142,2284,2286],{"class":1144,"line":2285},30,[1142,2287,1603],{},[1142,2289,2291],{"class":1144,"line":2290},31,[1142,2292,1154],{},[1142,2294,2296],{"class":1144,"line":2295},32,[1142,2297,1612],{},[1142,2299,2301],{"class":1144,"line":2300},33,[1142,2302,1166],{},[1142,2304,2306],{"class":1144,"line":2305},34,[1142,2307,1172],{},[1142,2309,2311],{"class":1144,"line":2310},35,[1142,2312,1215],{"emptyLinePlaceholder":1214},[1142,2314,2316],{"class":1144,"line":2315},36,[1142,2317,1649],{},[1142,2319,2321],{"class":1144,"line":2320},37,[1142,2322,1154],{},[1142,2324,2326],{"class":1144,"line":2325},38,[1142,2327,1658],{},[1142,2329,2331],{"class":1144,"line":2330},39,[1142,2332,1663],{},[1142,2334,2336],{"class":1144,"line":2335},40,[1142,2337,1281],{},[1142,2339,2341],{"class":1144,"line":2340},41,[1142,2342,1672],{},[1142,2344,2346],{"class":1144,"line":2345},42,[1142,2347,1291],{},[1142,2349,2351],{"class":1144,"line":2350},43,[1142,2352,1215],{"emptyLinePlaceholder":1214},[1142,2354,2356],{"class":1144,"line":2355},44,[1142,2357,1658],{},[1142,2359,2361],{"class":1144,"line":2360},45,[1142,2362,1689],{},[1142,2364,2366],{"class":1144,"line":2365},46,[1142,2367,1281],{},[1142,2369,2371],{"class":1144,"line":2370},47,[1142,2372,1699],{},[1142,2374,2376],{"class":1144,"line":2375},48,[1142,2377,1291],{},[1142,2379,2381],{"class":1144,"line":2380},49,[1142,2382,1172],{},[1142,2384,2386],{"class":1144,"line":2385},50,[1142,2387,1215],{"emptyLinePlaceholder":1214},[1142,2389,2391],{"class":1144,"line":2390},51,[1142,2392,1725],{},[1142,2394,2396],{"class":1144,"line":2395},52,[1142,2397,1154],{},[1142,2399,2401],{"class":1144,"line":2400},53,[1142,2402,1734],{},[1142,2404,2406],{"class":1144,"line":2405},54,[1142,2407,1739],{},[1142,2409,2411],{"class":1144,"line":2410},55,[1142,2412,1215],{"emptyLinePlaceholder":1214},[1142,2414,2416],{"class":1144,"line":2415},56,[1142,2417,1658],{},[1142,2419,2421],{"class":1144,"line":2420},57,[1142,2422,1663],{},[1142,2424,2426],{"class":1144,"line":2425},58,[1142,2427,1281],{},[1142,2429,2431],{"class":1144,"line":2430},59,[1142,2432,1760],{},[1142,2434,2436],{"class":1144,"line":2435},60,[1142,2437,1765],{},[1142,2439,2441],{"class":1144,"line":2440},61,[1142,2442,1770],{},[1142,2444,2446],{"class":1144,"line":2445},62,[1142,2447,1291],{},[1142,2449,2451],{"class":1144,"line":2450},63,[1142,2452,1215],{"emptyLinePlaceholder":1214},[1142,2454,2456],{"class":1144,"line":2455},64,[1142,2457,1658],{},[1142,2459,2461],{"class":1144,"line":2460},65,[1142,2462,1689],{},[1142,2464,2466],{"class":1144,"line":2465},66,[1142,2467,1281],{},[1142,2469,2471],{"class":1144,"line":2470},67,[1142,2472,1798],{},[1142,2474,2476],{"class":1144,"line":2475},68,[1142,2477,1291],{},[1142,2479,2481],{"class":1144,"line":2480},69,[1142,2482,1172],{},[1142,2484,2486],{"class":1144,"line":2485},70,[1142,2487,1215],{"emptyLinePlaceholder":1214},[1142,2489,2491],{"class":1144,"line":2490},71,[1142,2492,1832],{},[1142,2494,2496],{"class":1144,"line":2495},72,[1142,2497,1154],{},[1142,2499,2501],{"class":1144,"line":2500},73,[1142,2502,1841],{},[1142,2504,2506],{"class":1144,"line":2505},74,[1142,2507,1846],{},[1142,2509,2511],{"class":1144,"line":2510},75,[1142,2512,1215],{"emptyLinePlaceholder":1214},[1142,2514,2516],{"class":1144,"line":2515},76,[1142,2517,1855],{},[1142,2519,2521],{"class":1144,"line":2520},77,[1142,2522,1281],{},[1142,2524,2526],{"class":1144,"line":2525},78,[1142,2527,1864],{},[1142,2529,2531],{"class":1144,"line":2530},79,[1142,2532,1291],{},[1142,2534,2536],{"class":1144,"line":2535},80,[1142,2537,1215],{"emptyLinePlaceholder":1214},[1142,2539,2541],{"class":1144,"line":2540},81,[1142,2542,1877],{},[1142,2544,2546],{"class":1144,"line":2545},82,[1142,2547,1281],{},[1142,2549,2551],{"class":1144,"line":2550},83,[1142,2552,1886],{},[1142,2554,2556],{"class":1144,"line":2555},84,[1142,2557,1215],{"emptyLinePlaceholder":1214},[1142,2559,2561],{"class":1144,"line":2560},85,[1142,2562,1895],{},[1142,2564,2566],{"class":1144,"line":2565},86,[1142,2567,1215],{"emptyLinePlaceholder":1214},[1142,2569,2571],{"class":1144,"line":2570},87,[1142,2572,1904],{},[1142,2574,2576],{"class":1144,"line":2575},88,[1142,2577,1909],{},[1142,2579,2581],{"class":1144,"line":2580},89,[1142,2582,1914],{},[1142,2584,2586],{"class":1144,"line":2585},90,[1142,2587,1920],{},[1142,2589,2591],{"class":1144,"line":2590},91,[1142,2592,1926],{},[1142,2594,2596],{"class":1144,"line":2595},92,[1142,2597,1909],{},[1142,2599,2601],{"class":1144,"line":2600},93,[1142,2602,1937],{},[1142,2604,2606],{"class":1144,"line":2605},94,[1142,2607,1920],{},[1142,2609,2611],{"class":1144,"line":2610},95,[1142,2612,1291],{},[1142,2614,2616],{"class":1144,"line":2615},96,[1142,2617,1172],{},[1084,2619,2621],{"id":2620},"what-it-prints","What It Prints",[1133,2623,2628],{"className":2624,"code":2626,"language":2627},[2625],"language-text","Position: 0.0 m, volts: 0.0\nPosition: 0.25 m, volts: 8.0\nPosition: 0.5 m, volts: 8.0\nPosition: 0.75 m, volts: 8.0\nPosition: 0.75 m, volts: 0.0\n","text",[1128,2629,2626],{"__ignoreMap":1138},[1080,2631,2632],{},"Trace it cycle by cycle:",[1419,2634,2635,2648,2662,2675],{},[1422,2636,2637,2640,2641,2644,2645,2647],{},[1097,2638,2639],{},"Cycle 1:"," the sim starts at 0 V, so the position is ",[1128,2642,2643],{},"0.0",". That's below 0.6, so ",[1128,2646,1544],{}," commands 8 V.",[1422,2649,2650,2653,2654,2657,2658,2661],{},[1097,2651,2652],{},"Cycles 2-3:"," each update moves the sim 0.25 m (8 \u002F 32), so the position reads ",[1128,2655,2656],{},"0.25",", then ",[1128,2659,2660],{},"0.5",". Both are still below 0.6, so it keeps commanding 8 V.",[1422,2663,2664,2667,2668,2671,2672,2674],{},[1097,2665,2666],{},"Cycle 4:"," the position reads ",[1128,2669,2670],{},"0.75",", which has passed 0.6, so ",[1128,2673,1544],{}," commands 0 V.",[1422,2676,2677,2680,2681,2683,2684,2686],{},[1097,2678,2679],{},"Cycle 5:"," the sim got 0 V, so it doesn't move. It stays at ",[1128,2682,2670],{}," and reports ",[1128,2685,2643],{}," volts.",[1080,2688,2689,2690,2693,2694,2696,2697,2699],{},"The printed volts always show the voltage from the ",[1092,2691,2692],{},"previous"," cycle's command. That's because each cycle prints from the cached ",[1128,2695,1372],{},", which were filled in at the start of the cycle, before this cycle's new ",[1128,2698,1342],{}," call. This is exactly the \"one consistent snapshot per cycle\" behavior the lesson describes.",[1084,2701,2703],{"id":2702},"switching-to-the-real-robot","Switching to the Real Robot",[1080,2705,2706,2707,2709,2710,2713,2714,2716,2717,2720,2721,2723,2724,2726,2727,2730],{},"Changing ",[1128,2708,2121],{}," to ",[1128,2711,2712],{},"true"," is the only edit needed to run on the real robot. ",[1128,2715,2153],{}," then builds ",[1128,2718,2719],{},"new Climber(new ClimberIOReal())"," instead, and not one line of ",[1128,2722,1544],{}," changes. (On this laptop, ",[1128,2725,1973],{},"'s placeholder bodies would just print their ",[1128,2728,2729],{},"[real] would ..."," lines instead of moving anything.)",[1084,2732,2734],{"id":2733},"recap","Recap",[1419,2736,2737,2743,2752,2755,2761],{},[1422,2738,2739,2740,2742],{},"The IO layer is an interface (",[1128,2741,1534],{},") that says what the hardware can do. The real and simulated classes both implement it.",[1422,2744,2745,2746,2748,2749,2751],{},"The subsystem (",[1128,2747,1544],{},") stores a ",[1128,2750,1534],{}," and never names a specific implementation. Every call dispatches polymorphically to whichever one it was built with.",[1422,2753,2754],{},"Real vs. simulated is decided in exactly one place, when the subsystem is constructed.",[1422,2756,2757,2758,2760],{},"Each cycle calls ",[1128,2759,1466],{}," once, first, and then reads only from the cached inputs object. Every decision in that cycle sees the same snapshot.",[1422,2762,2763,2764,2766,2767,2769,2770,2772,2773,2775],{},"This is Ports and Adapters in miniature. ",[1128,2765,1534],{}," is the port, ",[1128,2768,1973],{}," and ",[1128,2771,1977],{}," are adapters, and ",[1128,2774,1544],{},"'s logic depends only on the port.",[1487,2777,1489],{},{"title":1138,"searchDepth":1151,"depth":1151,"links":2779},[2780,2781,2782,2783,2784,2785,2786,2787,2788,2789,2790],{"id":1514,"depth":1151,"text":1515},{"id":1521,"depth":1151,"text":1522},{"id":1554,"depth":1151,"text":1555},{"id":1592,"depth":1151,"text":1593},{"id":1635,"depth":1151,"text":1636},{"id":1821,"depth":1151,"text":1822},{"id":2001,"depth":1151,"text":2002},{"id":2139,"depth":1151,"text":2140},{"id":2620,"depth":1151,"text":2621},{"id":2702,"depth":1151,"text":2703},{"id":2733,"depth":1151,"text":2734},{"outlineRef":1501,"pairsWith":2792,"status":2793},"[`lessons\u002Fch20-the-io-layer-pattern\u002F20-the-io-layer-pattern.md`](..\u002F..\u002Flessons\u002Fch20-the-io-layer-pattern\u002F20-the-io-layer-pattern.md)","new — authored worked example (fully solved, walked step by step — not a problem to attempt)",{"title":683,"description":1138},"3nY76JhsiOi3AXESXfaKrzvXkm0-Fp1QkDfsOINTuDI",{"id":2797,"title":996,"body":2798,"description":1138,"extension":1499,"meta":4583,"navigation":1214,"path":995,"seo":4585,"stem":997,"__hash__":4586},"exercises\u002Fshockwave-curriculum\u002Fexercises\u002Fch20-the-io-layer-pattern\u002F20-the-io-layer-pattern.md",{"type":1073,"value":2799,"toc":4578},[2800,2803,2807,2821,2830,2844,2849,2891,2897,2911,2939,2943,2978,3208,3220,3238,3241,3313,3318,3324,3587,3684,3688,3694,3706,3732,3745,3783,3796,3801,3998,4003,4008,4014,4019,4025,4030,4034,4040,4044,4050,4055,4059,4065,4069,4075,4080,4084,4090,4094,4100,4105,4109,4115,4119,4125,4130,4134,4140,4144,4150,4155,4528,4576],[1076,2801,996],{"id":2802},"the-io-layer-pattern-exercises",[1084,2804,2806],{"id":2805},"multiple-choice","Multiple Choice",[1080,2808,2809,2812,2813,2816,2817,2820],{},[1097,2810,2811],{},"Question:"," A ",[1128,2814,2815],{},"Shooter"," subsystem is built with the IO-Layer Pattern. It stores a ",[1128,2818,2819],{},"ShooterIO"," field, and every one of its methods talks only to that field. Right now the robot code builds it like this:",[1133,2822,2824],{"className":1135,"code":2823,"language":1137,"meta":1138,"style":1138},"shooter = new Shooter(new ShooterIOReal());\n",[1128,2825,2826],{"__ignoreMap":1138},[1142,2827,2828],{"class":1144,"line":1145},[1142,2829,2823],{},[1080,2831,2832,2833,2836,2837,2840,2841,2843],{},"A ",[1128,2834,2835],{},"ShooterIOSim"," class that ",[1128,2838,2839],{},"implements ShooterIO"," already exists. What has to change so the exact same ",[1128,2842,2815],{}," logic runs in simulation?",[1080,2845,2846],{},[1097,2847,2848],{},"Options:",[1419,2850,2851,2857,2866,2879],{},[1422,2852,2853,2854],{},"A. Only the construction line, so it becomes ",[1128,2855,2856],{},"new Shooter(new ShooterIOSim())",[1422,2858,2859,2860,2862,2863,2865],{},"B. Every method inside ",[1128,2861,2815],{}," needs its own ",[1128,2864,2110],{}," check for \"real or simulated?\" around each hardware call",[1422,2867,2868,2869,2871,2872,2875,2876,2878],{},"C. ",[1128,2870,2815],{}," has to be rewritten to ",[1128,2873,2874],{},"extends ShooterIOSim"," instead of storing a ",[1128,2877,2819],{}," field",[1422,2880,2881,2882,2884,2885,2887,2888],{},"D. The ",[1128,2883,2819],{}," interface has to be edited so its methods match ",[1128,2886,2835],{}," instead of ",[1128,2889,2890],{},"ShooterIOReal",[1080,2892,2893,2896],{},[1097,2894,2895],{},"Answer:"," A",[1080,2898,2899,1433,2902,2904,2905,2907,2908,2910],{},[1097,2900,2901],{},"Why:",[1128,2903,2815],{}," only depends on the ",[1128,2906,2819],{}," interface, so any object that implements ",[1128,2909,2819],{}," can be passed into its constructor. Every call then dispatches polymorphically to whichever implementation was supplied. The choice between real and simulated lives in exactly one place, the line that constructs the subsystem.",[1419,2912,2913,2919,2931],{},[1422,2914,2915,2916,2918],{},"B is wrong. Scattering real-vs-sim checks through the subsystem is exactly the coupling the IO layer exists to remove. ",[1128,2917,2815],{}," never needs to know which implementation it has.",[1422,2920,2921,2922,2924,2925,1433,2927,2930],{},"C is wrong. ",[1128,2923,2815],{}," would then be permanently tied to the simulated class, and it could never run on the real robot. The pattern works because ",[1128,2926,2815],{},[1092,2928,2929],{},"holds"," an interface-typed reference, not because it inherits from a specific implementation.",[1422,2932,2933,2934,2769,2936,2938],{},"D is wrong. The interface is the shared contract that both ",[1128,2935,2890],{},[1128,2937,2835],{}," already honor. Nothing about it is specific to either one, so it doesn't change when you switch implementations.",[1084,2940,2942],{"id":2941},"micro-parsons","Micro-Parsons",[1080,2944,2945,2948,2949,2951,2952,2955,2956,2959,2960,2769,2963,2966,2967,2970,2971,2974,2975,2977],{},[1097,2946,2947],{},"Problem:"," You're given everything in the program below except the body of ",[1128,2950,2153],{},": the ",[1128,2953,2954],{},"FeederInputs"," class, the ",[1128,2957,2958],{},"FeederIO"," interface, its ",[1128,2961,2962],{},"FeederIOReal",[1128,2964,2965],{},"FeederIOSim"," implementations, the ",[1128,2968,2969],{},"Feeder"," subsystem, and the ",[1128,2972,2973],{},"FeederDemo"," class with ",[1128,2976,2153],{},"'s signature and braces.",[1133,2979,2981],{"className":1135,"code":2980,"language":1137,"meta":1138,"style":1138},"public class FeederDemo\n{\n    public static void main(String[] args)\n    {\n        \u002F\u002F main body goes here\n    }\n}\n\nclass FeederInputs\n{\n    public boolean noteDetected = false;\n}\n\ninterface FeederIO\n{\n    void updateInputs(FeederInputs inputs);\n}\n\nclass FeederIOReal implements FeederIO\n{\n    @Override\n    public void updateInputs(FeederInputs inputs)\n    {\n        System.out.println(\"[real] would read the beam-break sensor here\");\n    }\n}\n\nclass FeederIOSim implements FeederIO\n{\n    @Override\n    public void updateInputs(FeederInputs inputs)\n    {\n        inputs.noteDetected = true; \u002F\u002F simulation: pretend a note is always loaded\n    }\n}\n\nclass Feeder\n{\n    private FeederIO io;\n    private FeederInputs inputs = new FeederInputs();\n\n    public Feeder(FeederIO io)\n    {\n        this.io = io;\n    }\n\n    public void periodic()\n    {\n        io.updateInputs(inputs);\n        System.out.println(\"Note detected: \" + inputs.noteDetected);\n    }\n}\n",[1128,2982,2983,2988,2992,2996,3000,3005,3009,3013,3017,3022,3026,3031,3035,3039,3044,3048,3053,3057,3061,3066,3070,3074,3079,3083,3088,3092,3096,3100,3105,3109,3113,3117,3121,3126,3130,3134,3138,3143,3147,3152,3157,3161,3166,3170,3174,3178,3182,3186,3190,3195,3200,3204],{"__ignoreMap":1138},[1142,2984,2985],{"class":1144,"line":1145},[1142,2986,2987],{},"public class FeederDemo\n",[1142,2989,2990],{"class":1144,"line":1151},[1142,2991,1154],{},[1142,2993,2994],{"class":1144,"line":1157},[1142,2995,2021],{},[1142,2997,2998],{"class":1144,"line":1163},[1142,2999,1281],{},[1142,3001,3002],{"class":1144,"line":1169},[1142,3003,3004],{},"        \u002F\u002F main body goes here\n",[1142,3006,3007],{"class":1144,"line":1218},[1142,3008,1291],{},[1142,3010,3011],{"class":1144,"line":1224},[1142,3012,1172],{},[1142,3014,3015],{"class":1144,"line":1229},[1142,3016,1215],{"emptyLinePlaceholder":1214},[1142,3018,3019],{"class":1144,"line":1235},[1142,3020,3021],{},"class FeederInputs\n",[1142,3023,3024],{"class":1144,"line":1308},[1142,3025,1154],{},[1142,3027,3028],{"class":1144,"line":1313},[1142,3029,3030],{},"    public boolean noteDetected = false;\n",[1142,3032,3033],{"class":1144,"line":1696},[1142,3034,1172],{},[1142,3036,3037],{"class":1144,"line":1702},[1142,3038,1215],{"emptyLinePlaceholder":1214},[1142,3040,3041],{"class":1144,"line":1707},[1142,3042,3043],{},"interface FeederIO\n",[1142,3045,3046],{"class":1144,"line":1785},[1142,3047,1154],{},[1142,3049,3050],{"class":1144,"line":1790},[1142,3051,3052],{},"    void updateInputs(FeederInputs inputs);\n",[1142,3054,3055],{"class":1144,"line":1795},[1142,3056,1172],{},[1142,3058,3059],{"class":1144,"line":1801},[1142,3060,1215],{"emptyLinePlaceholder":1214},[1142,3062,3063],{"class":1144,"line":1806},[1142,3064,3065],{},"class FeederIOReal implements FeederIO\n",[1142,3067,3068],{"class":1144,"line":1917},[1142,3069,1154],{},[1142,3071,3072],{"class":1144,"line":1923},[1142,3073,1658],{},[1142,3075,3076],{"class":1144,"line":1929},[1142,3077,3078],{},"    public void updateInputs(FeederInputs inputs)\n",[1142,3080,3081],{"class":1144,"line":1934},[1142,3082,1281],{},[1142,3084,3085],{"class":1144,"line":1940},[1142,3086,3087],{},"        System.out.println(\"[real] would read the beam-break sensor here\");\n",[1142,3089,3090],{"class":1144,"line":1945},[1142,3091,1291],{},[1142,3093,3094],{"class":1144,"line":1950},[1142,3095,1172],{},[1142,3097,3098],{"class":1144,"line":2270},[1142,3099,1215],{"emptyLinePlaceholder":1214},[1142,3101,3102],{"class":1144,"line":2275},[1142,3103,3104],{},"class FeederIOSim implements FeederIO\n",[1142,3106,3107],{"class":1144,"line":2280},[1142,3108,1154],{},[1142,3110,3111],{"class":1144,"line":2285},[1142,3112,1658],{},[1142,3114,3115],{"class":1144,"line":2290},[1142,3116,3078],{},[1142,3118,3119],{"class":1144,"line":2295},[1142,3120,1281],{},[1142,3122,3123],{"class":1144,"line":2300},[1142,3124,3125],{},"        inputs.noteDetected = true; \u002F\u002F simulation: pretend a note is always loaded\n",[1142,3127,3128],{"class":1144,"line":2305},[1142,3129,1291],{},[1142,3131,3132],{"class":1144,"line":2310},[1142,3133,1172],{},[1142,3135,3136],{"class":1144,"line":2315},[1142,3137,1215],{"emptyLinePlaceholder":1214},[1142,3139,3140],{"class":1144,"line":2320},[1142,3141,3142],{},"class Feeder\n",[1142,3144,3145],{"class":1144,"line":2325},[1142,3146,1154],{},[1142,3148,3149],{"class":1144,"line":2330},[1142,3150,3151],{},"    private FeederIO io;\n",[1142,3153,3154],{"class":1144,"line":2335},[1142,3155,3156],{},"    private FeederInputs inputs = new FeederInputs();\n",[1142,3158,3159],{"class":1144,"line":2340},[1142,3160,1215],{"emptyLinePlaceholder":1214},[1142,3162,3163],{"class":1144,"line":2345},[1142,3164,3165],{},"    public Feeder(FeederIO io)\n",[1142,3167,3168],{"class":1144,"line":2350},[1142,3169,1281],{},[1142,3171,3172],{"class":1144,"line":2355},[1142,3173,1864],{},[1142,3175,3176],{"class":1144,"line":2360},[1142,3177,1291],{},[1142,3179,3180],{"class":1144,"line":2365},[1142,3181,1215],{"emptyLinePlaceholder":1214},[1142,3183,3184],{"class":1144,"line":2370},[1142,3185,1877],{},[1142,3187,3188],{"class":1144,"line":2375},[1142,3189,1281],{},[1142,3191,3192],{"class":1144,"line":2380},[1142,3193,3194],{},"        io.updateInputs(inputs);\n",[1142,3196,3197],{"class":1144,"line":2385},[1142,3198,3199],{},"        System.out.println(\"Note detected: \" + inputs.noteDetected);\n",[1142,3201,3202],{"class":1144,"line":2390},[1142,3203,1291],{},[1142,3205,3206],{"class":1144,"line":2395},[1142,3207,1172],{},[1080,3209,3210,3211,3213,3214,3216,3217,3219],{},"(",[1128,3212,2973],{},", the public class with ",[1128,3215,2153],{},", comes first in the file — on Java 17, ",[1128,3218,2157],{}," source-launch only runs the first class in the file; Java 25 is more lenient, but leading with the public class works on both.)",[1080,3221,3222,3223,3225,3226,3228,3229,3231,3232,3234,3235,1442],{},"Reorder the fragments below into the body of ",[1128,3224,2153],{},". It should pick the IO implementation once, based on ",[1128,3227,2121],{}," (hardcoded to ",[1128,3230,2125],{},", as a stand-in for a real robot check), build the ",[1128,3233,2969],{}," with it, and run one cycle. The program prints ",[1128,3236,3237],{},"Note detected: true",[1080,3239,3240],{},"Reorder the fragments below to complete it:",[1419,3242,3243,3249,3255,3261,3267,3273,3279,3285,3291,3296,3302,3307],{},[1422,3244,3245,3246],{},"a. ",[1128,3247,3248],{},"        Feeder feeder = new Feeder(feederIO);",[1422,3250,3251,3252],{},"b. ",[1128,3253,3254],{},"        FeederIO feederIO;",[1422,3256,3257,3258],{},"c. ",[1128,3259,3260],{},"        feeder.periodic();",[1422,3262,3263,3264],{},"d. ",[1128,3265,3266],{},"        if (runningOnRobot)",[1422,3268,3269,3270],{},"e. ",[1128,3271,3272],{},"        {",[1422,3274,3275,3276],{},"f. ",[1128,3277,3278],{},"            feederIO = new FeederIOReal();",[1422,3280,3281,3282],{},"g. ",[1128,3283,3284],{},"        }",[1422,3286,3287,3288],{},"h. ",[1128,3289,3290],{},"        else",[1422,3292,3293,3294],{},"i. ",[1128,3295,3272],{},[1422,3297,3298,3299],{},"j. ",[1128,3300,3301],{},"            feederIO = new FeederIOSim();",[1422,3303,3304,3305],{},"k. ",[1128,3306,3284],{},[1422,3308,3309,3310],{},"l. ",[1128,3311,3312],{},"        boolean runningOnRobot = false;",[1080,3314,3315,3317],{},[1097,3316,2895],{}," l, b, d, e, f, g, h, i, j, k, a, c",[1080,3319,3320,3323],{},[1097,3321,3322],{},"Interchangeable:"," (l, b)",[1133,3325,3327],{"className":1135,"code":3326,"language":1137,"meta":1138,"style":1138},"public class FeederDemo\n{\n    public static void main(String[] args)\n    {\n        boolean runningOnRobot = false;\n        FeederIO feederIO;\n        if (runningOnRobot)\n        {\n            feederIO = new FeederIOReal();\n        }\n        else\n        {\n            feederIO = new FeederIOSim();\n        }\n        Feeder feeder = new Feeder(feederIO);\n        feeder.periodic();\n    }\n}\n\nclass FeederInputs\n{\n    public boolean noteDetected = false;\n}\n\ninterface FeederIO\n{\n    void updateInputs(FeederInputs inputs);\n}\n\nclass FeederIOReal implements FeederIO\n{\n    @Override\n    public void updateInputs(FeederInputs inputs)\n    {\n        System.out.println(\"[real] would read the beam-break sensor here\");\n    }\n}\n\nclass FeederIOSim implements FeederIO\n{\n    @Override\n    public void updateInputs(FeederInputs inputs)\n    {\n        inputs.noteDetected = true; \u002F\u002F simulation: pretend a note is always loaded\n    }\n}\n\nclass Feeder\n{\n    private FeederIO io;\n    private FeederInputs inputs = new FeederInputs();\n\n    public Feeder(FeederIO io)\n    {\n        this.io = io;\n    }\n\n    public void periodic()\n    {\n        io.updateInputs(inputs);\n        System.out.println(\"Note detected: \" + inputs.noteDetected);\n    }\n}\n",[1128,3328,3329,3333,3337,3341,3345,3350,3355,3359,3363,3368,3372,3376,3380,3385,3389,3394,3399,3403,3407,3411,3415,3419,3423,3427,3431,3435,3439,3443,3447,3451,3455,3459,3463,3467,3471,3475,3479,3483,3487,3491,3495,3499,3503,3507,3511,3515,3519,3523,3527,3531,3535,3539,3543,3547,3551,3555,3559,3563,3567,3571,3575,3579,3583],{"__ignoreMap":1138},[1142,3330,3331],{"class":1144,"line":1145},[1142,3332,2987],{},[1142,3334,3335],{"class":1144,"line":1151},[1142,3336,1154],{},[1142,3338,3339],{"class":1144,"line":1157},[1142,3340,2021],{},[1142,3342,3343],{"class":1144,"line":1163},[1142,3344,1281],{},[1142,3346,3347],{"class":1144,"line":1169},[1142,3348,3349],{},"        boolean runningOnRobot = false;\n",[1142,3351,3352],{"class":1144,"line":1218},[1142,3353,3354],{},"        FeederIO feederIO;\n",[1142,3356,3357],{"class":1144,"line":1224},[1142,3358,2044],{},[1142,3360,3361],{"class":1144,"line":1229},[1142,3362,1909],{},[1142,3364,3365],{"class":1144,"line":1235},[1142,3366,3367],{},"            feederIO = new FeederIOReal();\n",[1142,3369,3370],{"class":1144,"line":1308},[1142,3371,1920],{},[1142,3373,3374],{"class":1144,"line":1313},[1142,3375,1926],{},[1142,3377,3378],{"class":1144,"line":1696},[1142,3379,1909],{},[1142,3381,3382],{"class":1144,"line":1702},[1142,3383,3384],{},"            feederIO = new FeederIOSim();\n",[1142,3386,3387],{"class":1144,"line":1707},[1142,3388,1920],{},[1142,3390,3391],{"class":1144,"line":1785},[1142,3392,3393],{},"        Feeder feeder = new Feeder(feederIO);\n",[1142,3395,3396],{"class":1144,"line":1790},[1142,3397,3398],{},"        feeder.periodic();\n",[1142,3400,3401],{"class":1144,"line":1795},[1142,3402,1291],{},[1142,3404,3405],{"class":1144,"line":1801},[1142,3406,1172],{},[1142,3408,3409],{"class":1144,"line":1806},[1142,3410,1215],{"emptyLinePlaceholder":1214},[1142,3412,3413],{"class":1144,"line":1917},[1142,3414,3021],{},[1142,3416,3417],{"class":1144,"line":1923},[1142,3418,1154],{},[1142,3420,3421],{"class":1144,"line":1929},[1142,3422,3030],{},[1142,3424,3425],{"class":1144,"line":1934},[1142,3426,1172],{},[1142,3428,3429],{"class":1144,"line":1940},[1142,3430,1215],{"emptyLinePlaceholder":1214},[1142,3432,3433],{"class":1144,"line":1945},[1142,3434,3043],{},[1142,3436,3437],{"class":1144,"line":1950},[1142,3438,1154],{},[1142,3440,3441],{"class":1144,"line":2270},[1142,3442,3052],{},[1142,3444,3445],{"class":1144,"line":2275},[1142,3446,1172],{},[1142,3448,3449],{"class":1144,"line":2280},[1142,3450,1215],{"emptyLinePlaceholder":1214},[1142,3452,3453],{"class":1144,"line":2285},[1142,3454,3065],{},[1142,3456,3457],{"class":1144,"line":2290},[1142,3458,1154],{},[1142,3460,3461],{"class":1144,"line":2295},[1142,3462,1658],{},[1142,3464,3465],{"class":1144,"line":2300},[1142,3466,3078],{},[1142,3468,3469],{"class":1144,"line":2305},[1142,3470,1281],{},[1142,3472,3473],{"class":1144,"line":2310},[1142,3474,3087],{},[1142,3476,3477],{"class":1144,"line":2315},[1142,3478,1291],{},[1142,3480,3481],{"class":1144,"line":2320},[1142,3482,1172],{},[1142,3484,3485],{"class":1144,"line":2325},[1142,3486,1215],{"emptyLinePlaceholder":1214},[1142,3488,3489],{"class":1144,"line":2330},[1142,3490,3104],{},[1142,3492,3493],{"class":1144,"line":2335},[1142,3494,1154],{},[1142,3496,3497],{"class":1144,"line":2340},[1142,3498,1658],{},[1142,3500,3501],{"class":1144,"line":2345},[1142,3502,3078],{},[1142,3504,3505],{"class":1144,"line":2350},[1142,3506,1281],{},[1142,3508,3509],{"class":1144,"line":2355},[1142,3510,3125],{},[1142,3512,3513],{"class":1144,"line":2360},[1142,3514,1291],{},[1142,3516,3517],{"class":1144,"line":2365},[1142,3518,1172],{},[1142,3520,3521],{"class":1144,"line":2370},[1142,3522,1215],{"emptyLinePlaceholder":1214},[1142,3524,3525],{"class":1144,"line":2375},[1142,3526,3142],{},[1142,3528,3529],{"class":1144,"line":2380},[1142,3530,1154],{},[1142,3532,3533],{"class":1144,"line":2385},[1142,3534,3151],{},[1142,3536,3537],{"class":1144,"line":2390},[1142,3538,3156],{},[1142,3540,3541],{"class":1144,"line":2395},[1142,3542,1215],{"emptyLinePlaceholder":1214},[1142,3544,3545],{"class":1144,"line":2400},[1142,3546,3165],{},[1142,3548,3549],{"class":1144,"line":2405},[1142,3550,1281],{},[1142,3552,3553],{"class":1144,"line":2410},[1142,3554,1864],{},[1142,3556,3557],{"class":1144,"line":2415},[1142,3558,1291],{},[1142,3560,3561],{"class":1144,"line":2420},[1142,3562,1215],{"emptyLinePlaceholder":1214},[1142,3564,3565],{"class":1144,"line":2425},[1142,3566,1877],{},[1142,3568,3569],{"class":1144,"line":2430},[1142,3570,1281],{},[1142,3572,3573],{"class":1144,"line":2435},[1142,3574,3194],{},[1142,3576,3577],{"class":1144,"line":2440},[1142,3578,3199],{},[1142,3580,3581],{"class":1144,"line":2445},[1142,3582,1291],{},[1142,3584,3585],{"class":1144,"line":2450},[1142,3586,1172],{},[1080,3588,3589,1433,3592,1399,3594,3597,3598,1399,3601,3604,3605,3607,3608,3610,3611,3613,3614,3617,3618,3620,3621,1399,3623,1403,3626,1403,3629,1403,3632,3635,3636,1399,3638,1403,3641,1403,3644,1403,3647,3650,3651,2111,3653,3655,3656,3658,3659,3661,3662,3665,3666,1399,3668,3671,3672,3675,3676,1403,3678,3680,3681,3683],{},[1097,3590,3591],{},"Why this order:",[1128,3593,2121],{},[1128,3595,3596],{},"l",") and the declaration of ",[1128,3599,3600],{},"feederIO",[1128,3602,3603],{},"b",") both have to exist before the ",[1128,3606,2110],{}," can read one and assign the other. Neither reads the other, so they can go in either order (hence ",[1097,3609,3322],{}," (l, b)). ",[1128,3612,3600],{}," is declared with the ",[1092,3615,3616],{},"interface"," type ",[1128,3619,2958],{},", so it can hold either implementation. The braced ",[1128,3622,2110],{},[1128,3624,3625],{},"d",[1128,3627,3628],{},"e",[1128,3630,3631],{},"f",[1128,3633,3634],{},"g",") has to come before its matching ",[1128,3637,2114],{},[1128,3639,3640],{},"h",[1128,3642,3643],{},"i",[1128,3645,3646],{},"j",[1128,3648,3649],{},"k",") — every ",[1128,3652,2110],{},[1128,3654,2114],{}," here uses braces (Lesson 5.1) — and between them, ",[1128,3657,3600],{}," is guaranteed to be assigned no matter which branch runs. This is the one place the program decides real vs. simulated. Only after that can the ",[1128,3660,2969],{}," be constructed with the chosen implementation (",[1128,3663,3664],{},"a","). ",[1128,3667,1987],{},[1128,3669,3670],{},"c",") runs last, since it needs a ",[1128,3673,3674],{},"feeder"," to call. Inside ",[1128,3677,1987],{},[1128,3679,2969],{}," pulls fresh values into its cached ",[1128,3682,1372],{}," and reads from them. It never knows it was handed the simulated version.",[1084,3685,3687],{"id":3686},"coding","Coding",[1080,3689,3690,3693],{},[1097,3691,3692],{},"Mode:"," full-program",[1080,3695,3696,3698,3699,3701,3702,3705],{},[1097,3697,2947],{}," Build the simulated hardware layer and the subsystem that uses it. ",[1128,3700,1177],{}," and the plain data holder ",[1128,3703,3704],{},"IntakeInputs","\nare given. You write two classes:",[1080,3707,3708,3713,3714,3716,3717,3720,3721,3724,3725,3728,3729,1442],{},[1097,3709,3710],{},[1128,3711,3712],{},"IntakeIOSim implements IntakeIO"," pretends to be the motor. It remembers the last voltage it was commanded (starting at ",[1128,3715,2643],{},").\n",[1128,3718,3719],{},"updateInputs(inputs)"," copies the current state into the inputs object: ",[1128,3722,3723],{},"inputs.appliedVolts"," gets that voltage and\n",[1128,3726,3727],{},"inputs.velocityRpm"," gets ",[1128,3730,3731],{},"volts * 400.0",[1080,3733,3734,3738,3739,3741,3742,3744],{},[1097,3735,3736],{},[1128,3737,1328],{}," is the subsystem. Its constructor takes an ",[1128,3740,1177],{}," (any implementation) and stores it, and it keeps its own ",[1128,3743,3704],{},"\nobject. It has four methods:",[1419,3746,3747,3756,3770],{},[1422,3748,3749,3752,3753,1442],{},[1128,3750,3751],{},"void run(double volts)"," sends the command with ",[1128,3754,3755],{},"io.setVoltage(volts)",[1422,3757,3758,3761,3762,3765,3766,3769],{},[1128,3759,3760],{},"void periodic()"," pulls fresh data ",[1097,3763,3764],{},"once",", with ",[1128,3767,3768],{},"io.updateInputs(...)"," into its inputs object.",[1422,3771,3772,2769,3775,3778,3779,3782],{},[1128,3773,3774],{},"double getAppliedVolts()",[1128,3776,3777],{},"double getVelocityRpm()"," read from the ",[1097,3780,3781],{},"cached inputs object",", never from the IO layer.",[1080,3784,3785,3786,3789,3790,3792,3793,3795],{},"So after ",[1128,3787,3788],{},"run(...)"," the reported values do not change until ",[1128,3791,1987],{}," is called. ",[1128,3794,2153],{}," reads commands until the input ends.",[1080,3797,3798],{},[1097,3799,3800],{},"Starter:",[1133,3802,3804],{"className":1135,"code":3803,"language":1137,"meta":1138,"style":1138},"import java.util.Scanner;\n\npublic class Main\n{\n    public static void main(String[] args) \u002F\u002F Don't change main\n    {\n        Scanner in = new Scanner(System.in);\n        Intake intake = new Intake(new IntakeIOSim());\n        while (in.hasNext())\n        {\n            String command = in.next();\n            if (command.equals(\"run\"))\n            {\n                intake.run(in.nextDouble());\n            }\n            else if (command.equals(\"periodic\"))\n            {\n                intake.periodic();\n            }\n            else if (command.equals(\"report\"))\n            {\n                System.out.println(\"Volts \" + intake.getAppliedVolts() + \", velocity \" + intake.getVelocityRpm());\n            }\n        }\n    }\n}\n\ninterface IntakeIO\n{\n    void updateInputs(IntakeInputs inputs);\n\n    void setVoltage(double volts);\n}\n\nclass IntakeInputs\n{\n    public double appliedVolts = 0.0;\n    public double velocityRpm = 0.0;\n}\n\n\u002F\u002F TODO: write the class IntakeIOSim\n\n\u002F\u002F TODO: write the class Intake\n",[1128,3805,3806,3811,3815,3820,3824,3829,3833,3838,3843,3848,3852,3857,3862,3867,3872,3877,3882,3886,3891,3895,3900,3904,3909,3913,3917,3921,3925,3929,3934,3938,3942,3946,3950,3954,3958,3963,3967,3971,3976,3980,3984,3989,3993],{"__ignoreMap":1138},[1142,3807,3808],{"class":1144,"line":1145},[1142,3809,3810],{},"import java.util.Scanner;\n",[1142,3812,3813],{"class":1144,"line":1151},[1142,3814,1215],{"emptyLinePlaceholder":1214},[1142,3816,3817],{"class":1144,"line":1157},[1142,3818,3819],{},"public class Main\n",[1142,3821,3822],{"class":1144,"line":1163},[1142,3823,1154],{},[1142,3825,3826],{"class":1144,"line":1169},[1142,3827,3828],{},"    public static void main(String[] args) \u002F\u002F Don't change main\n",[1142,3830,3831],{"class":1144,"line":1218},[1142,3832,1281],{},[1142,3834,3835],{"class":1144,"line":1224},[1142,3836,3837],{},"        Scanner in = new Scanner(System.in);\n",[1142,3839,3840],{"class":1144,"line":1229},[1142,3841,3842],{},"        Intake intake = new Intake(new IntakeIOSim());\n",[1142,3844,3845],{"class":1144,"line":1235},[1142,3846,3847],{},"        while (in.hasNext())\n",[1142,3849,3850],{"class":1144,"line":1308},[1142,3851,1909],{},[1142,3853,3854],{"class":1144,"line":1313},[1142,3855,3856],{},"            String command = in.next();\n",[1142,3858,3859],{"class":1144,"line":1696},[1142,3860,3861],{},"            if (command.equals(\"run\"))\n",[1142,3863,3864],{"class":1144,"line":1702},[1142,3865,3866],{},"            {\n",[1142,3868,3869],{"class":1144,"line":1707},[1142,3870,3871],{},"                intake.run(in.nextDouble());\n",[1142,3873,3874],{"class":1144,"line":1785},[1142,3875,3876],{},"            }\n",[1142,3878,3879],{"class":1144,"line":1790},[1142,3880,3881],{},"            else if (command.equals(\"periodic\"))\n",[1142,3883,3884],{"class":1144,"line":1795},[1142,3885,3866],{},[1142,3887,3888],{"class":1144,"line":1801},[1142,3889,3890],{},"                intake.periodic();\n",[1142,3892,3893],{"class":1144,"line":1806},[1142,3894,3876],{},[1142,3896,3897],{"class":1144,"line":1917},[1142,3898,3899],{},"            else if (command.equals(\"report\"))\n",[1142,3901,3902],{"class":1144,"line":1923},[1142,3903,3866],{},[1142,3905,3906],{"class":1144,"line":1929},[1142,3907,3908],{},"                System.out.println(\"Volts \" + intake.getAppliedVolts() + \", velocity \" + intake.getVelocityRpm());\n",[1142,3910,3911],{"class":1144,"line":1934},[1142,3912,3876],{},[1142,3914,3915],{"class":1144,"line":1940},[1142,3916,1920],{},[1142,3918,3919],{"class":1144,"line":1945},[1142,3920,1291],{},[1142,3922,3923],{"class":1144,"line":1950},[1142,3924,1172],{},[1142,3926,3927],{"class":1144,"line":2270},[1142,3928,1215],{"emptyLinePlaceholder":1214},[1142,3930,3931],{"class":1144,"line":2275},[1142,3932,3933],{},"interface IntakeIO\n",[1142,3935,3936],{"class":1144,"line":2280},[1142,3937,1154],{},[1142,3939,3940],{"class":1144,"line":2285},[1142,3941,1160],{},[1142,3943,3944],{"class":1144,"line":2290},[1142,3945,1215],{"emptyLinePlaceholder":1214},[1142,3947,3948],{"class":1144,"line":2295},[1142,3949,1166],{},[1142,3951,3952],{"class":1144,"line":2300},[1142,3953,1172],{},[1142,3955,3956],{"class":1144,"line":2305},[1142,3957,1215],{"emptyLinePlaceholder":1214},[1142,3959,3960],{"class":1144,"line":2310},[1142,3961,3962],{},"class IntakeInputs\n",[1142,3964,3965],{"class":1144,"line":2315},[1142,3966,1154],{},[1142,3968,3969],{"class":1144,"line":2320},[1142,3970,1582],{},[1142,3972,3973],{"class":1144,"line":2325},[1142,3974,3975],{},"    public double velocityRpm = 0.0;\n",[1142,3977,3978],{"class":1144,"line":2330},[1142,3979,1172],{},[1142,3981,3982],{"class":1144,"line":2335},[1142,3983,1215],{"emptyLinePlaceholder":1214},[1142,3985,3986],{"class":1144,"line":2340},[1142,3987,3988],{},"\u002F\u002F TODO: write the class IntakeIOSim\n",[1142,3990,3991],{"class":1144,"line":2345},[1142,3992,1215],{"emptyLinePlaceholder":1214},[1142,3994,3995],{"class":1144,"line":2350},[1142,3996,3997],{},"\u002F\u002F TODO: write the class Intake\n",[1080,3999,4000],{},[1097,4001,4002],{},"Scenario 1 (visible):",[1080,4004,4005],{},[1097,4006,4007],{},"Input:",[1133,4009,4012],{"className":4010,"code":4011,"language":2627,"meta":1138},[2625],"report\nrun 6.0\nreport\nperiodic\nreport\n",[1128,4013,4011],{"__ignoreMap":1138},[1080,4015,4016],{},[1097,4017,4018],{},"Expected output:",[1133,4020,4023],{"className":4021,"code":4022,"language":2627,"meta":1138},[2625],"Volts 0.0, velocity 0.0\nVolts 0.0, velocity 0.0\nVolts 6.0, velocity 2400.0\n",[1128,4024,4022],{"__ignoreMap":1138},[1080,4026,4027],{},[1097,4028,4029],{},"Scenario 2 (visible):",[1080,4031,4032],{},[1097,4033,4007],{},[1133,4035,4038],{"className":4036,"code":4037,"language":2627,"meta":1138},[2625],"run -3.5\nperiodic\nreport\n",[1128,4039,4037],{"__ignoreMap":1138},[1080,4041,4042],{},[1097,4043,4018],{},[1133,4045,4048],{"className":4046,"code":4047,"language":2627,"meta":1138},[2625],"Volts -3.5, velocity -1400.0\n",[1128,4049,4047],{"__ignoreMap":1138},[1080,4051,4052],{},[1097,4053,4054],{},"Scenario 3 (visible):",[1080,4056,4057],{},[1097,4058,4007],{},[1133,4060,4063],{"className":4061,"code":4062,"language":2627,"meta":1138},[2625],"report\n",[1128,4064,4062],{"__ignoreMap":1138},[1080,4066,4067],{},[1097,4068,4018],{},[1133,4070,4073],{"className":4071,"code":4072,"language":2627,"meta":1138},[2625],"Volts 0.0, velocity 0.0\n",[1128,4074,4072],{"__ignoreMap":1138},[1080,4076,4077],{},[1097,4078,4079],{},"Scenario 4 (hidden):",[1080,4081,4082],{},[1097,4083,4007],{},[1133,4085,4088],{"className":4086,"code":4087,"language":2627,"meta":1138},[2625],"run 5.0\nperiodic\nrun 10.0\nreport\nperiodic\nreport\n",[1128,4089,4087],{"__ignoreMap":1138},[1080,4091,4092],{},[1097,4093,4018],{},[1133,4095,4098],{"className":4096,"code":4097,"language":2627,"meta":1138},[2625],"Volts 5.0, velocity 2000.0\nVolts 10.0, velocity 4000.0\n",[1128,4099,4097],{"__ignoreMap":1138},[1080,4101,4102],{},[1097,4103,4104],{},"Scenario 5 (hidden):",[1080,4106,4107],{},[1097,4108,4007],{},[1133,4110,4113],{"className":4111,"code":4112,"language":2627,"meta":1138},[2625],"run 2.5\nrun 8.0\nperiodic\nreport\n",[1128,4114,4112],{"__ignoreMap":1138},[1080,4116,4117],{},[1097,4118,4018],{},[1133,4120,4123],{"className":4121,"code":4122,"language":2627,"meta":1138},[2625],"Volts 8.0, velocity 3200.0\n",[1128,4124,4122],{"__ignoreMap":1138},[1080,4126,4127],{},[1097,4128,4129],{},"Scenario 6 (hidden):",[1080,4131,4132],{},[1097,4133,4007],{},[1133,4135,4138],{"className":4136,"code":4137,"language":2627,"meta":1138},[2625],"run 1.0\nreport\nrun 0.0\nperiodic\nreport\n",[1128,4139,4137],{"__ignoreMap":1138},[1080,4141,4142],{},[1097,4143,4018],{},[1133,4145,4148],{"className":4146,"code":4147,"language":2627,"meta":1138},[2625],"Volts 0.0, velocity 0.0\nVolts 0.0, velocity 0.0\n",[1128,4149,4147],{"__ignoreMap":1138},[1080,4151,4152],{},[1097,4153,4154],{},"Solution:",[1133,4156,4158],{"className":1135,"code":4157,"language":1137,"meta":1138,"style":1138},"import java.util.Scanner;\n\npublic class Main\n{\n    public static void main(String[] args) \u002F\u002F Don't change main\n    {\n        Scanner in = new Scanner(System.in);\n        Intake intake = new Intake(new IntakeIOSim());\n        while (in.hasNext())\n        {\n            String command = in.next();\n            if (command.equals(\"run\"))\n            {\n                intake.run(in.nextDouble());\n            }\n            else if (command.equals(\"periodic\"))\n            {\n                intake.periodic();\n            }\n            else if (command.equals(\"report\"))\n            {\n                System.out.println(\"Volts \" + intake.getAppliedVolts() + \", velocity \" + intake.getVelocityRpm());\n            }\n        }\n    }\n}\n\ninterface IntakeIO\n{\n    void updateInputs(IntakeInputs inputs);\n\n    void setVoltage(double volts);\n}\n\nclass IntakeInputs\n{\n    public double appliedVolts = 0.0;\n    public double velocityRpm = 0.0;\n}\n\nclass IntakeIOSim implements IntakeIO\n{\n    private double volts = 0.0;\n\n    @Override\n    public void updateInputs(IntakeInputs inputs)\n    {\n        inputs.appliedVolts = volts;\n        inputs.velocityRpm = volts * 400.0;\n    }\n\n    @Override\n    public void setVoltage(double volts)\n    {\n        this.volts = volts;\n    }\n}\n\nclass Intake\n{\n    private final IntakeIO io;\n    private final IntakeInputs inputs = new IntakeInputs();\n\n    public Intake(IntakeIO io)\n    {\n        this.io = io;\n    }\n\n    public void run(double volts)\n    {\n        io.setVoltage(volts);\n    }\n\n    public void periodic()\n    {\n        io.updateInputs(inputs);\n    }\n\n    public double getAppliedVolts()\n    {\n        return inputs.appliedVolts;\n    }\n\n    public double getVelocityRpm()\n    {\n        return inputs.velocityRpm;\n    }\n}\n",[1128,4159,4160,4164,4168,4172,4176,4180,4184,4188,4192,4196,4200,4204,4208,4212,4216,4220,4224,4228,4232,4236,4240,4244,4248,4252,4256,4260,4264,4268,4272,4276,4280,4284,4288,4292,4296,4300,4304,4308,4312,4316,4320,4325,4329,4334,4338,4342,4347,4351,4356,4361,4365,4369,4373,4377,4381,4386,4390,4394,4398,4403,4407,4412,4417,4421,4426,4430,4434,4438,4442,4447,4451,4456,4460,4464,4468,4472,4476,4480,4484,4489,4493,4498,4502,4506,4511,4515,4520,4524],{"__ignoreMap":1138},[1142,4161,4162],{"class":1144,"line":1145},[1142,4163,3810],{},[1142,4165,4166],{"class":1144,"line":1151},[1142,4167,1215],{"emptyLinePlaceholder":1214},[1142,4169,4170],{"class":1144,"line":1157},[1142,4171,3819],{},[1142,4173,4174],{"class":1144,"line":1163},[1142,4175,1154],{},[1142,4177,4178],{"class":1144,"line":1169},[1142,4179,3828],{},[1142,4181,4182],{"class":1144,"line":1218},[1142,4183,1281],{},[1142,4185,4186],{"class":1144,"line":1224},[1142,4187,3837],{},[1142,4189,4190],{"class":1144,"line":1229},[1142,4191,3842],{},[1142,4193,4194],{"class":1144,"line":1235},[1142,4195,3847],{},[1142,4197,4198],{"class":1144,"line":1308},[1142,4199,1909],{},[1142,4201,4202],{"class":1144,"line":1313},[1142,4203,3856],{},[1142,4205,4206],{"class":1144,"line":1696},[1142,4207,3861],{},[1142,4209,4210],{"class":1144,"line":1702},[1142,4211,3866],{},[1142,4213,4214],{"class":1144,"line":1707},[1142,4215,3871],{},[1142,4217,4218],{"class":1144,"line":1785},[1142,4219,3876],{},[1142,4221,4222],{"class":1144,"line":1790},[1142,4223,3881],{},[1142,4225,4226],{"class":1144,"line":1795},[1142,4227,3866],{},[1142,4229,4230],{"class":1144,"line":1801},[1142,4231,3890],{},[1142,4233,4234],{"class":1144,"line":1806},[1142,4235,3876],{},[1142,4237,4238],{"class":1144,"line":1917},[1142,4239,3899],{},[1142,4241,4242],{"class":1144,"line":1923},[1142,4243,3866],{},[1142,4245,4246],{"class":1144,"line":1929},[1142,4247,3908],{},[1142,4249,4250],{"class":1144,"line":1934},[1142,4251,3876],{},[1142,4253,4254],{"class":1144,"line":1940},[1142,4255,1920],{},[1142,4257,4258],{"class":1144,"line":1945},[1142,4259,1291],{},[1142,4261,4262],{"class":1144,"line":1950},[1142,4263,1172],{},[1142,4265,4266],{"class":1144,"line":2270},[1142,4267,1215],{"emptyLinePlaceholder":1214},[1142,4269,4270],{"class":1144,"line":2275},[1142,4271,3933],{},[1142,4273,4274],{"class":1144,"line":2280},[1142,4275,1154],{},[1142,4277,4278],{"class":1144,"line":2285},[1142,4279,1160],{},[1142,4281,4282],{"class":1144,"line":2290},[1142,4283,1215],{"emptyLinePlaceholder":1214},[1142,4285,4286],{"class":1144,"line":2295},[1142,4287,1166],{},[1142,4289,4290],{"class":1144,"line":2300},[1142,4291,1172],{},[1142,4293,4294],{"class":1144,"line":2305},[1142,4295,1215],{"emptyLinePlaceholder":1214},[1142,4297,4298],{"class":1144,"line":2310},[1142,4299,3962],{},[1142,4301,4302],{"class":1144,"line":2315},[1142,4303,1154],{},[1142,4305,4306],{"class":1144,"line":2320},[1142,4307,1582],{},[1142,4309,4310],{"class":1144,"line":2325},[1142,4311,3975],{},[1142,4313,4314],{"class":1144,"line":2330},[1142,4315,1172],{},[1142,4317,4318],{"class":1144,"line":2335},[1142,4319,1215],{"emptyLinePlaceholder":1214},[1142,4321,4322],{"class":1144,"line":2340},[1142,4323,4324],{},"class IntakeIOSim implements IntakeIO\n",[1142,4326,4327],{"class":1144,"line":2345},[1142,4328,1154],{},[1142,4330,4331],{"class":1144,"line":2350},[1142,4332,4333],{},"    private double volts = 0.0;\n",[1142,4335,4336],{"class":1144,"line":2355},[1142,4337,1215],{"emptyLinePlaceholder":1214},[1142,4339,4340],{"class":1144,"line":2360},[1142,4341,1658],{},[1142,4343,4344],{"class":1144,"line":2365},[1142,4345,4346],{},"    public void updateInputs(IntakeInputs inputs)\n",[1142,4348,4349],{"class":1144,"line":2370},[1142,4350,1281],{},[1142,4352,4353],{"class":1144,"line":2375},[1142,4354,4355],{},"        inputs.appliedVolts = volts;\n",[1142,4357,4358],{"class":1144,"line":2380},[1142,4359,4360],{},"        inputs.velocityRpm = volts * 400.0;\n",[1142,4362,4363],{"class":1144,"line":2385},[1142,4364,1291],{},[1142,4366,4367],{"class":1144,"line":2390},[1142,4368,1215],{"emptyLinePlaceholder":1214},[1142,4370,4371],{"class":1144,"line":2395},[1142,4372,1658],{},[1142,4374,4375],{"class":1144,"line":2400},[1142,4376,1689],{},[1142,4378,4379],{"class":1144,"line":2405},[1142,4380,1281],{},[1142,4382,4383],{"class":1144,"line":2410},[1142,4384,4385],{},"        this.volts = volts;\n",[1142,4387,4388],{"class":1144,"line":2415},[1142,4389,1291],{},[1142,4391,4392],{"class":1144,"line":2420},[1142,4393,1172],{},[1142,4395,4396],{"class":1144,"line":2425},[1142,4397,1215],{"emptyLinePlaceholder":1214},[1142,4399,4400],{"class":1144,"line":2430},[1142,4401,4402],{},"class Intake\n",[1142,4404,4405],{"class":1144,"line":2435},[1142,4406,1154],{},[1142,4408,4409],{"class":1144,"line":2440},[1142,4410,4411],{},"    private final IntakeIO io;\n",[1142,4413,4414],{"class":1144,"line":2445},[1142,4415,4416],{},"    private final IntakeInputs inputs = new IntakeInputs();\n",[1142,4418,4419],{"class":1144,"line":2450},[1142,4420,1215],{"emptyLinePlaceholder":1214},[1142,4422,4423],{"class":1144,"line":2455},[1142,4424,4425],{},"    public Intake(IntakeIO io)\n",[1142,4427,4428],{"class":1144,"line":2460},[1142,4429,1281],{},[1142,4431,4432],{"class":1144,"line":2465},[1142,4433,1864],{},[1142,4435,4436],{"class":1144,"line":2470},[1142,4437,1291],{},[1142,4439,4440],{"class":1144,"line":2475},[1142,4441,1215],{"emptyLinePlaceholder":1214},[1142,4443,4444],{"class":1144,"line":2480},[1142,4445,4446],{},"    public void run(double volts)\n",[1142,4448,4449],{"class":1144,"line":2485},[1142,4450,1281],{},[1142,4452,4453],{"class":1144,"line":2490},[1142,4454,4455],{},"        io.setVoltage(volts);\n",[1142,4457,4458],{"class":1144,"line":2495},[1142,4459,1291],{},[1142,4461,4462],{"class":1144,"line":2500},[1142,4463,1215],{"emptyLinePlaceholder":1214},[1142,4465,4466],{"class":1144,"line":2505},[1142,4467,1877],{},[1142,4469,4470],{"class":1144,"line":2510},[1142,4471,1281],{},[1142,4473,4474],{"class":1144,"line":2515},[1142,4475,3194],{},[1142,4477,4478],{"class":1144,"line":2520},[1142,4479,1291],{},[1142,4481,4482],{"class":1144,"line":2525},[1142,4483,1215],{"emptyLinePlaceholder":1214},[1142,4485,4486],{"class":1144,"line":2530},[1142,4487,4488],{},"    public double getAppliedVolts()\n",[1142,4490,4491],{"class":1144,"line":2535},[1142,4492,1281],{},[1142,4494,4495],{"class":1144,"line":2540},[1142,4496,4497],{},"        return inputs.appliedVolts;\n",[1142,4499,4500],{"class":1144,"line":2545},[1142,4501,1291],{},[1142,4503,4504],{"class":1144,"line":2550},[1142,4505,1215],{"emptyLinePlaceholder":1214},[1142,4507,4508],{"class":1144,"line":2555},[1142,4509,4510],{},"    public double getVelocityRpm()\n",[1142,4512,4513],{"class":1144,"line":2560},[1142,4514,1281],{},[1142,4516,4517],{"class":1144,"line":2565},[1142,4518,4519],{},"        return inputs.velocityRpm;\n",[1142,4521,4522],{"class":1144,"line":2570},[1142,4523,1291],{},[1142,4525,4526],{"class":1144,"line":2575},[1142,4527,1172],{},[1080,4529,4530,1433,4532,4534,4535,4537,4538,4540,4541,4543,4544,4546,4547,4549,4550,4553,4554,1433,4557,1433,4560,4563,4564,4566,4567,4569,4570,4572,4573,4575],{},[1097,4531,2901],{},[1128,4533,1328],{}," only ever holds an ",[1128,4536,1177],{},", so it works with ",[1128,4539,1406],{}," today and a real-hardware class tomorrow. Commands go out through ",[1128,4542,1342],{},";\ninputs come in through ",[1128,4545,1466],{},", once per cycle, into one shared ",[1128,4548,3704],{}," object that every getter reads. The scenarios that call ",[1128,4551,4552],{},"run","\nand then ",[1128,4555,4556],{},"report",[1092,4558,4559],{},"before",[1128,4561,4562],{},"periodic"," expose the classic mistake: a getter or ",[1128,4565,4552],{}," that refreshes the inputs itself would show the new numbers immediately,\nwhile a correct subsystem still reports the snapshot from the last ",[1128,4568,1987],{},". Another mistake is ",[1128,4571,1987],{}," that never calls ",[1128,4574,1466],{},", so the reports stay at zero forever.",[1487,4577,1489],{},{"title":1138,"searchDepth":1151,"depth":1151,"links":4579},[4580,4581,4582],{"id":2805,"depth":1151,"text":2806},{"id":2941,"depth":1151,"text":2942},{"id":3686,"depth":1151,"text":3687},{"outlineRef":1501,"pairsWith":2792,"status":4584},"new — authored exercises (Multiple Choice + Micro-Parsons + Coding)",{"title":996,"description":1138},"mEBId9NI-fZl4CUfvwiuTk3ofoRk92FhjSIxy2JlojU",1792718166170]